window: re-indent all GstVaapiWindow related source code.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapiwindow.c
1 /*
2  *  gstvaapiwindow.c - VA window abstraction
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6  *  Copyright (C) 2011-2013 Intel Corporation
7  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public License
11  *  as published by the Free Software Foundation; either version 2.1
12  *  of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free
21  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301 USA
23  */
24
25 /**
26  * SECTION:gstvaapiwindow
27  * @short_description: VA window abstraction
28  */
29
30 #include "sysdeps.h"
31 #include "gstvaapiwindow.h"
32 #include "gstvaapiwindow_priv.h"
33 #include "gstvaapisurface_priv.h"
34
35 #define DEBUG 1
36 #include "gstvaapidebug.h"
37
38 /* Ensure those symbols are actually defined in the resulting libraries */
39 #undef gst_vaapi_window_ref
40 #undef gst_vaapi_window_unref
41 #undef gst_vaapi_window_replace
42
43 static void
44 gst_vaapi_window_ensure_size (GstVaapiWindow * window)
45 {
46   const GstVaapiWindowClass *const klass = GST_VAAPI_WINDOW_GET_CLASS (window);
47
48   if (!window->check_geometry)
49     return;
50
51   if (klass->get_geometry)
52     klass->get_geometry (window, NULL, NULL, &window->width, &window->height);
53
54   window->check_geometry = FALSE;
55   window->is_fullscreen = (window->width == window->display_width &&
56       window->height == window->display_height);
57 }
58
59 static gboolean
60 gst_vaapi_window_create (GstVaapiWindow * window, guint width, guint height)
61 {
62   gst_vaapi_display_get_size (GST_VAAPI_OBJECT_DISPLAY (window),
63       &window->display_width, &window->display_height);
64
65   if (!GST_VAAPI_WINDOW_GET_CLASS (window)->create (window, &width, &height))
66     return FALSE;
67
68   if (width != window->width || height != window->height) {
69     GST_DEBUG ("backend resized window to %ux%u", width, height);
70     window->width = width;
71     window->height = height;
72   }
73   return TRUE;
74 }
75
76 GstVaapiWindow *
77 gst_vaapi_window_new (const GstVaapiWindowClass * window_class,
78     GstVaapiDisplay * display, guint width, guint height)
79 {
80   GstVaapiWindow *window;
81
82   g_return_val_if_fail (width > 0, NULL);
83   g_return_val_if_fail (height > 0, NULL);
84
85   window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class),
86       display);
87   if (!window)
88     return NULL;
89
90   GST_VAAPI_OBJECT_ID (window) = 0;
91   if (!gst_vaapi_window_create (window, width, height))
92     goto error;
93   return window;
94
95 error:
96   gst_vaapi_window_unref_internal (window);
97   return NULL;
98 }
99
100 GstVaapiWindow *
101 gst_vaapi_window_new_from_native (const GstVaapiWindowClass * window_class,
102     GstVaapiDisplay * display, gpointer native_window)
103 {
104   GstVaapiWindow *window;
105
106   window = gst_vaapi_object_new (GST_VAAPI_OBJECT_CLASS (window_class),
107       display);
108   if (!window)
109     return NULL;
110
111   GST_VAAPI_OBJECT_ID (window) = GPOINTER_TO_SIZE (native_window);
112   window->use_foreign_window = TRUE;
113   if (!gst_vaapi_window_create (window, 0, 0))
114     goto error;
115   return window;
116
117 error:
118   gst_vaapi_window_unref_internal (window);
119   return NULL;
120 }
121
122 /**
123  * gst_vaapi_window_ref:
124  * @window: a #GstVaapiWindow
125  *
126  * Atomically increases the reference count of the given @window by one.
127  *
128  * Returns: The same @window argument
129  */
130 GstVaapiWindow *
131 gst_vaapi_window_ref (GstVaapiWindow * window)
132 {
133   return gst_vaapi_window_ref_internal (window);
134 }
135
136 /**
137  * gst_vaapi_window_unref:
138  * @window: a #GstVaapiWindow
139  *
140  * Atomically decreases the reference count of the @window by one. If
141  * the reference count reaches zero, the window will be free'd.
142  */
143 void
144 gst_vaapi_window_unref (GstVaapiWindow * window)
145 {
146   gst_vaapi_window_unref_internal (window);
147 }
148
149 /**
150  * gst_vaapi_window_replace:
151  * @old_window_ptr: a pointer to a #GstVaapiWindow
152  * @new_window: a #GstVaapiWindow
153  *
154  * Atomically replaces the window window held in @old_window_ptr with
155  * @new_window. This means that @old_window_ptr shall reference a
156  * valid window. However, @new_window can be NULL.
157  */
158 void
159 gst_vaapi_window_replace (GstVaapiWindow ** old_window_ptr,
160     GstVaapiWindow * new_window)
161 {
162   gst_vaapi_window_replace_internal (old_window_ptr, new_window);
163 }
164
165 /**
166  * gst_vaapi_window_get_display:
167  * @window: a #GstVaapiWindow
168  *
169  * Returns the #GstVaapiDisplay this @window is bound to.
170  *
171  * Return value: the parent #GstVaapiDisplay object
172  */
173 GstVaapiDisplay *
174 gst_vaapi_window_get_display (GstVaapiWindow * window)
175 {
176   g_return_val_if_fail (window != NULL, NULL);
177
178   return GST_VAAPI_OBJECT_DISPLAY (window);
179 }
180
181 /**
182  * gst_vaapi_window_show:
183  * @window: a #GstVaapiWindow
184  *
185  * Flags a window to be displayed. Any window that is not shown will
186  * not appear on the screen.
187  */
188 void
189 gst_vaapi_window_show (GstVaapiWindow * window)
190 {
191   g_return_if_fail (window != NULL);
192
193   GST_VAAPI_WINDOW_GET_CLASS (window)->show (window);
194   window->check_geometry = TRUE;
195 }
196
197 /**
198  * gst_vaapi_window_hide:
199  * @window: a #GstVaapiWindow
200  *
201  * Reverses the effects of gst_vaapi_window_show(), causing the window
202  * to be hidden (invisible to the user).
203  */
204 void
205 gst_vaapi_window_hide (GstVaapiWindow * window)
206 {
207   g_return_if_fail (window != NULL);
208
209   GST_VAAPI_WINDOW_GET_CLASS (window)->hide (window);
210 }
211
212 /**
213  * gst_vaapi_window_get_fullscreen:
214  * @window: a #GstVaapiWindow
215  *
216  * Retrieves whether the @window is fullscreen or not
217  *
218  * Return value: %TRUE if the window is fullscreen
219  */
220 gboolean
221 gst_vaapi_window_get_fullscreen (GstVaapiWindow * window)
222 {
223   g_return_val_if_fail (window != NULL, FALSE);
224
225   gst_vaapi_window_ensure_size (window);
226
227   return window->is_fullscreen;
228 }
229
230 /**
231  * gst_vaapi_window_set_fullscreen:
232  * @window: a #GstVaapiWindow
233  * @fullscreen: %TRUE to request window to get fullscreen
234  *
235  * Requests to place the @window in fullscreen or unfullscreen states.
236  */
237 void
238 gst_vaapi_window_set_fullscreen (GstVaapiWindow * window, gboolean fullscreen)
239 {
240   const GstVaapiWindowClass *klass;
241
242   g_return_if_fail (window != NULL);
243
244   klass = GST_VAAPI_WINDOW_GET_CLASS (window);
245
246   if (window->is_fullscreen != fullscreen &&
247       klass->set_fullscreen && klass->set_fullscreen (window, fullscreen)) {
248     window->is_fullscreen = fullscreen;
249     window->check_geometry = TRUE;
250   }
251 }
252
253 /**
254  * gst_vaapi_window_get_width:
255  * @window: a #GstVaapiWindow
256  *
257  * Retrieves the width of a #GstVaapiWindow.
258  *
259  * Return value: the width of the @window, in pixels
260  */
261 guint
262 gst_vaapi_window_get_width (GstVaapiWindow * window)
263 {
264   g_return_val_if_fail (window != NULL, 0);
265
266   gst_vaapi_window_ensure_size (window);
267
268   return window->width;
269 }
270
271 /**
272  * gst_vaapi_window_get_height:
273  * @window: a #GstVaapiWindow
274  *
275  * Retrieves the height of a #GstVaapiWindow
276  *
277  * Return value: the height of the @window, in pixels
278  */
279 guint
280 gst_vaapi_window_get_height (GstVaapiWindow * window)
281 {
282   g_return_val_if_fail (window != NULL, 0);
283
284   gst_vaapi_window_ensure_size (window);
285
286   return window->height;
287 }
288
289 /**
290  * gst_vaapi_window_get_size:
291  * @window: a #GstVaapiWindow
292  * @width_ptr: return location for the width, or %NULL
293  * @height_ptr: return location for the height, or %NULL
294  *
295  * Retrieves the dimensions of a #GstVaapiWindow.
296  */
297 void
298 gst_vaapi_window_get_size (GstVaapiWindow * window, guint * width_ptr,
299     guint * height_ptr)
300 {
301   g_return_if_fail (window != NULL);
302
303   gst_vaapi_window_ensure_size (window);
304
305   if (width_ptr)
306     *width_ptr = window->width;
307
308   if (height_ptr)
309     *height_ptr = window->height;
310 }
311
312 /**
313  * gst_vaapi_window_set_width:
314  * @window: a #GstVaapiWindow
315  * @width: requested new width for the window, in pixels
316  *
317  * Resizes the @window to match the specified @width.
318  */
319 void
320 gst_vaapi_window_set_width (GstVaapiWindow * window, guint width)
321 {
322   g_return_if_fail (window != NULL);
323
324   gst_vaapi_window_set_size (window, width, window->height);
325 }
326
327 /**
328  * gst_vaapi_window_set_height:
329  * @window: a #GstVaapiWindow
330  * @height: requested new height for the window, in pixels
331  *
332  * Resizes the @window to match the specified @height.
333  */
334 void
335 gst_vaapi_window_set_height (GstVaapiWindow * window, guint height)
336 {
337   g_return_if_fail (window != NULL);
338
339   gst_vaapi_window_set_size (window, window->width, height);
340 }
341
342 /**
343  * gst_vaapi_window_set_size:
344  * @window: a #GstVaapiWindow
345  * @width: requested new width for the window, in pixels
346  * @height: requested new height for the window, in pixels
347  *
348  * Resizes the @window to match the specified @width and @height.
349  */
350 void
351 gst_vaapi_window_set_size (GstVaapiWindow * window, guint width, guint height)
352 {
353   g_return_if_fail (window != NULL);
354
355   if (width == window->width && height == window->height)
356     return;
357
358   if (!GST_VAAPI_WINDOW_GET_CLASS (window)->resize (window, width, height))
359     return;
360
361   window->width = width;
362   window->height = height;
363 }
364
365 static inline void
366 get_surface_rect (GstVaapiSurface * surface, GstVaapiRectangle * rect)
367 {
368   rect->x = 0;
369   rect->y = 0;
370   rect->width = GST_VAAPI_SURFACE_WIDTH (surface);
371   rect->height = GST_VAAPI_SURFACE_HEIGHT (surface);
372 }
373
374 static inline void
375 get_window_rect (GstVaapiWindow * window, GstVaapiRectangle * rect)
376 {
377   guint width, height;
378
379   gst_vaapi_window_get_size (window, &width, &height);
380   rect->x = 0;
381   rect->y = 0;
382   rect->width = width;
383   rect->height = height;
384 }
385
386 /**
387  * gst_vaapi_window_put_surface:
388  * @window: a #GstVaapiWindow
389  * @surface: a #GstVaapiSurface
390  * @src_rect: the sub-rectangle of the source surface to
391  *   extract and process. If %NULL, the entire surface will be used.
392  * @dst_rect: the sub-rectangle of the destination
393  *   window into which the surface is rendered. If %NULL, the entire
394  *   window will be used.
395  * @flags: postprocessing flags. See #GstVaapiSurfaceRenderFlags
396  *
397  * Renders the @surface region specified by @src_rect into the @window
398  * region specified by @dst_rect. The @flags specify how de-interlacing
399  * (if needed), color space conversion, scaling and other postprocessing
400  * transformations are performed.
401  *
402  * Return value: %TRUE on success
403  */
404 gboolean
405 gst_vaapi_window_put_surface (GstVaapiWindow * window,
406     GstVaapiSurface * surface,
407     const GstVaapiRectangle * src_rect,
408     const GstVaapiRectangle * dst_rect, guint flags)
409 {
410   const GstVaapiWindowClass *klass;
411   GstVaapiRectangle src_rect_default, dst_rect_default;
412
413   g_return_val_if_fail (window != NULL, FALSE);
414   g_return_val_if_fail (surface != NULL, FALSE);
415
416   klass = GST_VAAPI_WINDOW_GET_CLASS (window);
417   if (!klass->render)
418     return FALSE;
419
420   if (!src_rect) {
421     src_rect = &src_rect_default;
422     get_surface_rect (surface, &src_rect_default);
423   }
424
425   if (!dst_rect) {
426     dst_rect = &dst_rect_default;
427     get_window_rect (window, &dst_rect_default);
428   }
429
430   return klass->render (window, surface, src_rect, dst_rect, flags);
431 }
432
433 static inline void
434 get_pixmap_rect (GstVaapiPixmap * pixmap, GstVaapiRectangle * rect)
435 {
436   guint width, height;
437
438   gst_vaapi_pixmap_get_size (pixmap, &width, &height);
439   rect->x = 0;
440   rect->y = 0;
441   rect->width = width;
442   rect->height = height;
443 }
444
445 /**
446  * gst_vaapi_window_put_pixmap:
447  * @window: a #GstVaapiWindow
448  * @pixmap: a #GstVaapiPixmap
449  * @src_rect: the sub-rectangle of the source pixmap to
450  *   extract and process. If %NULL, the entire pixmap will be used.
451  * @dst_rect: the sub-rectangle of the destination
452  *   window into which the pixmap is rendered. If %NULL, the entire
453  *   window will be used.
454  *
455  * Renders the @pixmap region specified by @src_rect into the @window
456  * region specified by @dst_rect.
457  *
458  * Return value: %TRUE on success
459  */
460 gboolean
461 gst_vaapi_window_put_pixmap (GstVaapiWindow * window,
462     GstVaapiPixmap * pixmap,
463     const GstVaapiRectangle * src_rect, const GstVaapiRectangle * dst_rect)
464 {
465   const GstVaapiWindowClass *klass;
466   GstVaapiRectangle src_rect_default, dst_rect_default;
467
468   g_return_val_if_fail (window != NULL, FALSE);
469   g_return_val_if_fail (pixmap != NULL, FALSE);
470
471   klass = GST_VAAPI_WINDOW_GET_CLASS (window);
472   if (!klass->render_pixmap)
473     return FALSE;
474
475   if (!src_rect) {
476     src_rect = &src_rect_default;
477     get_pixmap_rect (pixmap, &src_rect_default);
478   }
479
480   if (!dst_rect) {
481     dst_rect = &dst_rect_default;
482     get_window_rect (window, &dst_rect_default);
483   }
484   return klass->render_pixmap (window, pixmap, src_rect, dst_rect);
485 }