libs: fix build in strict ISO C mode.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapisurfaceproxy.c
1 /*
2  *  gstvaapisurfaceproxy.c - VA surface proxy
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *  Copyright (C) 2011-2012 Intel Corporation
6  *
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.
11  *
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.
16  *
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
21  */
22
23 /**
24  * SECTION:gstvaapisurfaceproxy
25  * @short_description: VA surface proxy
26  */
27
28 #include "sysdeps.h"
29 #include "gstvaapisurfaceproxy.h"
30 #include "gstvaapiobject_priv.h"
31
32 #define DEBUG 1
33 #include "gstvaapidebug.h"
34
35 G_DEFINE_TYPE(GstVaapiSurfaceProxy, gst_vaapi_surface_proxy, G_TYPE_OBJECT)
36
37 #define GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(obj)                \
38     (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
39                                  GST_VAAPI_TYPE_SURFACE_PROXY,  \
40                                  GstVaapiSurfaceProxyPrivate))
41
42 struct _GstVaapiSurfaceProxyPrivate {
43     GstVaapiContext    *context;
44     GstVaapiSurface    *surface;
45     GstClockTime        timestamp;
46     guint               is_interlaced   : 1;
47     guint               tff             : 1;
48 };
49
50 enum {
51     PROP_0,
52
53     PROP_CONTEXT,
54     PROP_SURFACE,
55     PROP_TIMESTAMP,
56     PROP_INTERLACED,
57     PROP_TFF
58 };
59
60 static void
61 gst_vaapi_surface_proxy_finalize(GObject *object)
62 {
63     GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object);
64
65     gst_vaapi_surface_proxy_set_surface(proxy, NULL);
66     gst_vaapi_surface_proxy_set_context(proxy, NULL);
67
68     G_OBJECT_CLASS(gst_vaapi_surface_proxy_parent_class)->finalize(object);
69 }
70
71 static void
72 gst_vaapi_surface_proxy_set_property(
73     GObject      *object,
74     guint         prop_id,
75     const GValue *value,
76     GParamSpec   *pspec
77 )
78 {
79     GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object);
80
81     switch (prop_id) {
82     case PROP_CONTEXT:
83         gst_vaapi_surface_proxy_set_context(proxy, g_value_get_pointer(value));
84         break;
85     case PROP_SURFACE:
86         gst_vaapi_surface_proxy_set_surface(proxy, g_value_get_pointer(value));
87         break;
88     case PROP_TIMESTAMP:
89         gst_vaapi_surface_proxy_set_timestamp(proxy, g_value_get_uint64(value));
90         break;
91     case PROP_INTERLACED:
92         gst_vaapi_surface_proxy_set_interlaced(proxy, g_value_get_boolean(value));
93         break;
94     case PROP_TFF:
95         gst_vaapi_surface_proxy_set_tff(proxy, g_value_get_boolean(value));
96         break;
97     default:
98         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
99         break;
100     }
101 }
102
103 static void
104 gst_vaapi_surface_proxy_get_property(
105     GObject    *object,
106     guint       prop_id,
107     GValue     *value,
108     GParamSpec *pspec
109 )
110 {
111     GstVaapiSurfaceProxy * const proxy = GST_VAAPI_SURFACE_PROXY(object);
112
113     switch (prop_id) {
114     case PROP_CONTEXT:
115         g_value_set_pointer(value, gst_vaapi_surface_proxy_get_context(proxy));
116         break;
117     case PROP_SURFACE:
118         g_value_set_pointer(value, gst_vaapi_surface_proxy_get_surface(proxy));
119         break;
120     case PROP_TIMESTAMP:
121         g_value_set_uint64(value, gst_vaapi_surface_proxy_get_timestamp(proxy));
122         break;
123     case PROP_INTERLACED:
124         g_value_set_boolean(value, gst_vaapi_surface_proxy_get_interlaced(proxy));
125         break;
126     case PROP_TFF:
127         g_value_set_boolean(value, gst_vaapi_surface_proxy_get_tff(proxy));
128         break;
129     default:
130         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
131         break;
132     }
133 }
134
135 static void
136 gst_vaapi_surface_proxy_class_init(GstVaapiSurfaceProxyClass *klass)
137 {
138     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
139
140     g_type_class_add_private(klass, sizeof(GstVaapiSurfaceProxyPrivate));
141
142     object_class->finalize     = gst_vaapi_surface_proxy_finalize;
143     object_class->set_property = gst_vaapi_surface_proxy_set_property;
144     object_class->get_property = gst_vaapi_surface_proxy_get_property;
145
146     g_object_class_install_property
147         (object_class,
148          PROP_CONTEXT,
149          g_param_spec_pointer("context",
150                               "Context",
151                               "The context stored in the proxy",
152                               G_PARAM_READWRITE));
153
154     g_object_class_install_property
155         (object_class,
156          PROP_SURFACE,
157          g_param_spec_pointer("surface",
158                               "Surface",
159                               "The surface stored in the proxy",
160                               G_PARAM_READWRITE));
161
162     g_object_class_install_property
163         (object_class,
164          PROP_TIMESTAMP,
165          g_param_spec_uint64("timestamp",
166                              "Timestamp",
167                              "The presentation time of the surface",
168                              0, G_MAXUINT64, GST_CLOCK_TIME_NONE,
169                              G_PARAM_READWRITE));
170
171     g_object_class_install_property
172         (object_class,
173          PROP_INTERLACED,
174          g_param_spec_boolean("interlaced",
175                               "Interlaced",
176                               "Flag indicating whether surface is interlaced",
177                               FALSE,
178                               G_PARAM_READWRITE));
179
180     g_object_class_install_property
181         (object_class,
182          PROP_TFF,
183          g_param_spec_boolean("tff",
184                               "Top-Field-First",
185                               "Flag indicating for interlaced surfaces whether Top Field is First",
186                               FALSE,
187                               G_PARAM_READWRITE));
188 }
189
190 static void
191 gst_vaapi_surface_proxy_init(GstVaapiSurfaceProxy *proxy)
192
193     GstVaapiSurfaceProxyPrivate *priv;
194
195     priv                = GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(proxy);
196     proxy->priv         = priv;
197     priv->context       = NULL;
198     priv->surface       = NULL;
199     priv->timestamp     = GST_CLOCK_TIME_NONE;
200     priv->is_interlaced = FALSE;
201     priv->tff           = FALSE;
202 }
203
204 /**
205  * gst_vaapi_surface_proxy_new:
206  * @context: a #GstVaapiContext
207  * @surface: a #GstVaapiSurface
208  *
209  * Creates a new #GstVaapiSurfaceProxy with the specified context and
210  * surface.
211  *
212  * Return value: the newly allocated #GstVaapiSurfaceProxy object
213  */
214 GstVaapiSurfaceProxy *
215 gst_vaapi_surface_proxy_new(GstVaapiContext *context, GstVaapiSurface *surface)
216 {
217     g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
218     g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL);
219
220     return g_object_new(GST_VAAPI_TYPE_SURFACE_PROXY,
221                         "context",  context,
222                         "surface",  surface,
223                         NULL);
224 }
225
226 /**
227  * gst_vaapi_surface_proxy_get_context:
228  * @proxy: a #GstVaapiSurfaceProxy
229  *
230  * Returns the #GstVaapiContext stored in the @proxy.
231  *
232  * Return value: the #GstVaapiContext
233  */
234 GstVaapiContext *
235 gst_vaapi_surface_proxy_get_context(GstVaapiSurfaceProxy *proxy)
236 {
237     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL);
238
239     return proxy->priv->context;
240 }
241
242 /**
243  * gst_vaapi_surface_proxy_set_context:
244  * @proxy: a #GstVaapiSurfaceProxy
245  * @context: the new #GstVaapiContext to be stored in @proxy
246  *
247  * Stores a new @context into the @proxy. The proxy releases the
248  * previous reference, if any, and then holds a reference to the new
249  * @context.
250  */
251 void
252 gst_vaapi_surface_proxy_set_context(
253     GstVaapiSurfaceProxy *proxy,
254     GstVaapiContext      *context
255 )
256 {
257     GstVaapiSurfaceProxyPrivate *priv;
258
259     g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
260
261     priv = proxy->priv;
262
263     g_clear_object(&priv->context);
264
265     if (context)
266         priv->context = g_object_ref(context);
267 }
268
269 /**
270  * gst_vaapi_surface_proxy_get_surface:
271  * @proxy: a #GstVaapiSurfaceProxy
272  *
273  * Returns the #GstVaapiSurface stored in the @proxy.
274  *
275  * Return value: the #GstVaapiSurface
276  */
277 GstVaapiSurface *
278 gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy)
279 {
280     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL);
281
282     return proxy->priv->surface;
283 }
284
285 /**
286  * gst_vaapi_surface_proxy_get_surface_id:
287  * @proxy: a #GstVaapiSurfaceProxy
288  *
289  * Returns the VA surface ID stored in the @proxy.
290  *
291  * Return value: the #GstVaapiID
292  */
293 GstVaapiID
294 gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy)
295 {
296     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_VAAPI_ID_NONE);
297     g_return_val_if_fail(proxy->priv->surface != NULL, GST_VAAPI_ID_NONE);
298
299     return GST_VAAPI_OBJECT_ID(proxy->priv->surface);
300 }
301
302 /**
303  * gst_vaapi_surface_proxy_set_surface:
304  * @proxy: a #GstVaapiSurfaceProxy
305  * @surface: the new #GstVaapiSurface to be stored in @proxy
306  *
307  * Stores a new @surface into the @proxy. The proxy releases the
308  * previous reference, if any, and then holds a reference to the new
309  * @surface.
310  */
311 void
312 gst_vaapi_surface_proxy_set_surface(
313     GstVaapiSurfaceProxy *proxy,
314     GstVaapiSurface      *surface
315 )
316 {
317     GstVaapiSurfaceProxyPrivate *priv;
318
319     g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
320
321     priv = proxy->priv;
322
323     if (priv->surface) {
324         if (priv->context)
325             gst_vaapi_context_put_surface(priv->context, priv->surface);
326         g_object_unref(priv->surface);
327         priv->surface = NULL;
328     }
329
330     if (surface)
331         priv->surface = g_object_ref(surface);
332 }
333
334 /**
335  * gst_vaapi_surface_proxy_get_timestamp:
336  * @proxy: a #GstVaapiSurfaceProxy
337  *
338  * Returns the presentation timestamp of the #GstVaapiSurface held by @proxy.
339  *
340  * Return value: the presentation timestamp of the surface, or
341  *   %GST_CLOCK_TIME_NONE is none was set
342  */
343 GstClockTime
344 gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy)
345 {
346     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_CLOCK_TIME_NONE);
347
348     return proxy->priv->timestamp;
349 }
350
351 /**
352  * gst_vaapi_surface_proxy_set_timestamp:
353  * @proxy: a #GstVaapiSurfaceProxy
354  * @timestamp: the new presentation timestamp as a #GstClockTime
355  *
356  * Sets the presentation timestamp of the @proxy surface to @timestamp.
357  */
358 void
359 gst_vaapi_surface_proxy_set_timestamp(
360     GstVaapiSurfaceProxy *proxy,
361     GstClockTime          timestamp
362 )
363 {
364     g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
365
366     proxy->priv->timestamp = timestamp;
367 }
368
369 /**
370  * gst_vaapi_surface_proxy_get_interlaced:
371  * @proxy: a #GstVaapiSurfaceProxy
372  *
373  * Returns whether the @proxy holds an interlaced #GstVaapiSurface or not.
374  *
375  * Return value: %TRUE if the underlying surface is interlaced, %FALSE
376  *     otherwise.
377  */
378 gboolean
379 gst_vaapi_surface_proxy_get_interlaced(GstVaapiSurfaceProxy *proxy)
380 {
381     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE);
382
383     return proxy->priv->is_interlaced;
384 }
385
386 /**
387  * gst_vaapi_surface_proxy_set_interlaced:
388  * @proxy: a #GstVaapiSurfaceProxy
389  * @b: a boolean value
390  *
391  * Sets whether the underlying #GstVaapiSurface for @proxy is interlaced
392  * or not.
393  */
394 void
395 gst_vaapi_surface_proxy_set_interlaced(GstVaapiSurfaceProxy *proxy, gboolean b)
396 {
397     g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
398
399     proxy->priv->is_interlaced = b;
400 }
401
402 /**
403  * gst_vaapi_surface_proxy_get_tff:
404  * @proxy: a #GstVaapiSurfaceProxy
405  *
406  * Returns the TFF flag of the #GstVaapiSurface held by @proxy.
407  *
408  * Return value: the TFF flag of the surface
409  */
410 gboolean
411 gst_vaapi_surface_proxy_get_tff(GstVaapiSurfaceProxy *proxy)
412 {
413     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), FALSE);
414
415     return proxy->priv->is_interlaced && proxy->priv->tff;
416 }
417
418 /**
419  * gst_vaapi_surface_proxy_set_tff:
420  * @proxy: a #GstVaapiSurfaceProxy
421  * @tff: the new value of the TFF flag
422  *
423  * Sets the TFF flag of the @proxy surface to @tff.
424  */
425 void
426 gst_vaapi_surface_proxy_set_tff(GstVaapiSurfaceProxy *proxy, gboolean tff)
427 {
428     g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
429
430     proxy->priv->tff = tff;
431 }