2 * gstvaapiwindow.c - VA window abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011-2012 Intel Corporation
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
24 * SECTION:gstvaapiwindow
25 * @short_description: VA window abstraction
29 #include "gstvaapiwindow.h"
30 #include "gstvaapi_priv.h"
33 #include "gstvaapidebug.h"
35 G_DEFINE_TYPE(GstVaapiWindow, gst_vaapi_window, GST_VAAPI_TYPE_OBJECT);
37 #define GST_VAAPI_WINDOW_GET_PRIVATE(obj) \
38 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
39 GST_VAAPI_TYPE_WINDOW, \
40 GstVaapiWindowPrivate))
42 struct _GstVaapiWindowPrivate {
47 gboolean is_constructed : 1;
48 guint is_fullscreen : 1;
49 guint check_geometry : 1;
61 gst_vaapi_window_ensure_size(GstVaapiWindow *window)
63 GstVaapiWindowPrivate * const priv = window->priv;
64 GstVaapiWindowClass * const klass = GST_VAAPI_WINDOW_GET_CLASS(window);
66 if (!priv->check_geometry)
69 if (klass->get_geometry)
70 klass->get_geometry(window, NULL, NULL, &priv->width, &priv->height);
72 priv->check_geometry = FALSE;
73 priv->is_fullscreen = (priv->width == priv->display_width &&
74 priv->height == priv->display_height);
78 gst_vaapi_window_destroy(GstVaapiWindow *window)
80 GST_VAAPI_WINDOW_GET_CLASS(window)->destroy(window);
84 gst_vaapi_window_create(GstVaapiWindow *window)
86 GstVaapiWindowPrivate * const priv = window->priv;
90 height = priv->height;
92 gst_vaapi_display_get_size(
93 GST_VAAPI_OBJECT_DISPLAY(window),
98 if (!GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, &width, &height))
101 if (width != priv->width || height != priv->height) {
102 GST_DEBUG("backend resized window to %ux%u", width, height);
104 priv->height = height;
110 gst_vaapi_window_finalize(GObject *object)
112 gst_vaapi_window_destroy(GST_VAAPI_WINDOW(object));
114 G_OBJECT_CLASS(gst_vaapi_window_parent_class)->finalize(object);
118 gst_vaapi_window_set_property(
125 GstVaapiWindow * const window = GST_VAAPI_WINDOW(object);
129 gst_vaapi_window_set_width(window, g_value_get_uint(value));
132 gst_vaapi_window_set_height(window, g_value_get_uint(value));
134 case PROP_FULLSCREEN:
135 gst_vaapi_window_set_fullscreen(window, g_value_get_boolean(value));
138 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
144 gst_vaapi_window_get_property(
151 GstVaapiWindow * const window = GST_VAAPI_WINDOW(object);
155 g_value_set_uint(value, gst_vaapi_window_get_width(window));
158 g_value_set_uint(value, gst_vaapi_window_get_height(window));
160 case PROP_FULLSCREEN:
161 g_value_set_boolean(value, window->priv->is_fullscreen);
164 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
170 gst_vaapi_window_constructed(GObject *object)
172 GstVaapiWindow * const window = GST_VAAPI_WINDOW(object);
173 GObjectClass *parent_class;
175 window->priv->is_constructed = gst_vaapi_window_create(window);
177 parent_class = G_OBJECT_CLASS(gst_vaapi_window_parent_class);
178 if (parent_class->constructed)
179 parent_class->constructed(object);
183 gst_vaapi_window_class_init(GstVaapiWindowClass *klass)
185 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
187 g_type_class_add_private(klass, sizeof(GstVaapiWindowPrivate));
189 object_class->finalize = gst_vaapi_window_finalize;
190 object_class->set_property = gst_vaapi_window_set_property;
191 object_class->get_property = gst_vaapi_window_get_property;
192 object_class->constructed = gst_vaapi_window_constructed;
194 g_object_class_install_property
197 g_param_spec_uint("width",
203 g_object_class_install_property
206 g_param_spec_uint("height",
212 g_object_class_install_property
215 g_param_spec_boolean("fullscreen",
217 "The fullscreen state of the window",
223 gst_vaapi_window_init(GstVaapiWindow *window)
225 GstVaapiWindowPrivate *priv = GST_VAAPI_WINDOW_GET_PRIVATE(window);
230 priv->is_constructed = FALSE;
231 priv->is_fullscreen = FALSE;
232 priv->check_geometry = FALSE;
236 * gst_vaapi_window_get_display:
237 * @window: a #GstVaapiWindow
239 * Returns the #GstVaapiDisplay this @window is bound to.
241 * Return value: the parent #GstVaapiDisplay object
244 gst_vaapi_window_get_display(GstVaapiWindow *window)
246 g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), NULL);
248 return GST_VAAPI_OBJECT_DISPLAY(window);
252 * gst_vaapi_window_show:
253 * @window: a #GstVaapiWindow
255 * Flags a window to be displayed. Any window that is not shown will
256 * not appear on the screen.
259 gst_vaapi_window_show(GstVaapiWindow *window)
261 g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
262 g_return_if_fail(window->priv->is_constructed);
264 GST_VAAPI_WINDOW_GET_CLASS(window)->show(window);
265 window->priv->check_geometry = TRUE;
269 * gst_vaapi_window_hide:
270 * @window: a #GstVaapiWindow
272 * Reverses the effects of gst_vaapi_window_show(), causing the window
273 * to be hidden (invisible to the user).
276 gst_vaapi_window_hide(GstVaapiWindow *window)
278 g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
279 g_return_if_fail(window->priv->is_constructed);
281 GST_VAAPI_WINDOW_GET_CLASS(window)->hide(window);
285 * gst_vaapi_window_get_fullscreen:
286 * @window: a #GstVaapiWindow
288 * Retrieves whether the @window is fullscreen or not
290 * Return value: %TRUE if the window is fullscreen
293 gst_vaapi_window_get_fullscreen(GstVaapiWindow *window)
295 g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE);
297 gst_vaapi_window_ensure_size(window);
299 return window->priv->is_fullscreen;
303 * gst_vaapi_window_set_fullscreen:
304 * @window: a #GstVaapiWindow
305 * @fullscreen: %TRUE to request window to get fullscreen
307 * Requests to place the @window in fullscreen or unfullscreen states.
310 gst_vaapi_window_set_fullscreen(GstVaapiWindow *window, gboolean fullscreen)
312 GstVaapiWindowClass *klass;
314 g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
316 klass = GST_VAAPI_WINDOW_GET_CLASS(window);
318 if (window->priv->is_fullscreen != fullscreen &&
319 klass->set_fullscreen && klass->set_fullscreen(window, fullscreen)) {
320 window->priv->is_fullscreen = fullscreen;
321 window->priv->check_geometry = TRUE;
326 * gst_vaapi_window_get_width:
327 * @window: a #GstVaapiWindow
329 * Retrieves the width of a #GstVaapiWindow.
331 * Return value: the width of the @window, in pixels
334 gst_vaapi_window_get_width(GstVaapiWindow *window)
336 g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0);
337 g_return_val_if_fail(window->priv->is_constructed, 0);
339 gst_vaapi_window_ensure_size(window);
341 return window->priv->width;
345 * gst_vaapi_window_get_height:
346 * @window: a #GstVaapiWindow
348 * Retrieves the height of a #GstVaapiWindow
350 * Return value: the height of the @window, in pixels
353 gst_vaapi_window_get_height(GstVaapiWindow *window)
355 g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), 0);
356 g_return_val_if_fail(window->priv->is_constructed, 0);
358 gst_vaapi_window_ensure_size(window);
360 return window->priv->height;
364 * gst_vaapi_window_get_size:
365 * @window: a #GstVaapiWindow
366 * @pwidth: return location for the width, or %NULL
367 * @pheight: return location for the height, or %NULL
369 * Retrieves the dimensions of a #GstVaapiWindow.
372 gst_vaapi_window_get_size(GstVaapiWindow *window, guint *pwidth, guint *pheight)
374 g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
375 g_return_if_fail(window->priv->is_constructed);
377 gst_vaapi_window_ensure_size(window);
380 *pwidth = window->priv->width;
383 *pheight = window->priv->height;
387 * gst_vaapi_window_set_width:
388 * @window: a #GstVaapiWindow
389 * @width: requested new width for the window, in pixels
391 * Resizes the @window to match the specified @width.
394 gst_vaapi_window_set_width(GstVaapiWindow *window, guint width)
396 g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
398 gst_vaapi_window_set_size(window, width, window->priv->height);
402 * gst_vaapi_window_set_height:
403 * @window: a #GstVaapiWindow
404 * @height: requested new height for the window, in pixels
406 * Resizes the @window to match the specified @height.
409 gst_vaapi_window_set_height(GstVaapiWindow *window, guint height)
411 g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
413 gst_vaapi_window_set_size(window, window->priv->width, height);
417 * gst_vaapi_window_set_size:
418 * @window: a #GstVaapiWindow
419 * @width: requested new width for the window, in pixels
420 * @height: requested new height for the window, in pixels
422 * Resizes the @window to match the specified @width and @height.
425 gst_vaapi_window_set_size(GstVaapiWindow *window, guint width, guint height)
427 g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
429 if (width == window->priv->width && height == window->priv->height)
432 window->priv->width = width;
433 window->priv->height = height;
435 if (window->priv->is_constructed)
436 GST_VAAPI_WINDOW_GET_CLASS(window)->resize(window, width, height);
440 get_surface_rect(GstVaapiSurface *surface, GstVaapiRectangle *rect)
444 gst_vaapi_surface_get_size(surface, &width, &height);
448 rect->height = height;
452 get_window_rect(GstVaapiWindow *window, GstVaapiRectangle *rect)
456 gst_vaapi_window_get_size(window, &width, &height);
460 rect->height = height;
464 * gst_vaapi_window_put_surface:
465 * @window: a #GstVaapiWindow
466 * @surface: a #GstVaapiSurface
467 * @src_rect: the sub-rectangle of the source surface to
468 * extract and process. If %NULL, the entire surface will be used.
469 * @dst_rect: the sub-rectangle of the destination
470 * window into which the surface is rendered. If %NULL, the entire
471 * window will be used.
472 * @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags
474 * Renders the @surface region specified by @src_rect into the @window
475 * region specified by @dst_rect. The @flags specify how de-interlacing
476 * (if needed), color space conversion, scaling and other postprocessing
477 * transformations are performed.
479 * Return value: %TRUE on success
482 gst_vaapi_window_put_surface(
483 GstVaapiWindow *window,
484 GstVaapiSurface *surface,
485 const GstVaapiRectangle *src_rect,
486 const GstVaapiRectangle *dst_rect,
490 GstVaapiWindowClass *klass;
491 GstVaapiRectangle src_rect_default, dst_rect_default;
493 g_return_val_if_fail(GST_VAAPI_IS_WINDOW(window), FALSE);
494 g_return_val_if_fail(window->priv->is_constructed, FALSE);
495 g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), FALSE);
497 klass = GST_VAAPI_WINDOW_GET_CLASS(window);
502 src_rect = &src_rect_default;
503 get_surface_rect(surface, &src_rect_default);
507 dst_rect = &dst_rect_default;
508 get_window_rect(window, &dst_rect_default);
511 return klass->render(window, surface, src_rect, dst_rect, flags);