surface: add simple surface info accessors as helper macros.
[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 "gstvaapisurfaceproxy_priv.h"
31 #include "gstvaapivideopool_priv.h"
32
33 #define DEBUG 1
34 #include "gstvaapidebug.h"
35
36 static inline void
37 set_crop_rect_from_surface(GstVaapiSurfaceProxy *proxy)
38 {
39     proxy->crop_rect.x = 0;
40     proxy->crop_rect.y = 0;
41     proxy->crop_rect.width = GST_VAAPI_SURFACE_WIDTH(proxy->surface);
42     proxy->crop_rect.height = GST_VAAPI_SURFACE_HEIGHT(proxy->surface);
43 }
44
45 static inline void
46 set_crop_rect(GstVaapiSurfaceProxy *proxy, const GstVaapiRectangle *crop_rect)
47 {
48     if (crop_rect)
49         proxy->crop_rect = *crop_rect;
50     else
51         set_crop_rect_from_surface(proxy);
52 }
53
54 static void
55 gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy)
56 {
57     if (proxy->destroy_func)
58         proxy->destroy_func(proxy->destroy_data);
59
60     if (proxy->surface) {
61         if (proxy->pool)
62             gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface);
63         gst_vaapi_object_unref(proxy->surface);
64         proxy->surface = NULL;
65     }
66     gst_vaapi_video_pool_replace(&proxy->pool, NULL);
67 }
68
69 static inline const GstVaapiMiniObjectClass *
70 gst_vaapi_surface_proxy_class(void)
71 {
72     static const GstVaapiMiniObjectClass GstVaapiSurfaceProxyClass = {
73         sizeof(GstVaapiSurfaceProxy),
74         (GDestroyNotify)gst_vaapi_surface_proxy_finalize
75     };
76     return &GstVaapiSurfaceProxyClass;
77 }
78
79 GstVaapiSurfaceProxy *
80 gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool)
81 {
82     GstVaapiSurfaceProxy *proxy;
83
84     g_return_val_if_fail(pool != NULL, NULL);
85
86     proxy = (GstVaapiSurfaceProxy *)
87         gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class());
88     if (!proxy)
89         return NULL;
90
91     proxy->pool = gst_vaapi_video_pool_ref(pool);
92     proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool);
93     if (!proxy->surface)
94         goto error;
95     set_crop_rect_from_surface(proxy);
96
97     proxy->timestamp = GST_CLOCK_TIME_NONE;
98     proxy->duration = GST_CLOCK_TIME_NONE;
99     proxy->destroy_func = NULL;
100     gst_vaapi_object_ref(proxy->surface);
101     return proxy;
102
103 error:
104     gst_vaapi_surface_proxy_unref(proxy);
105     return NULL;
106 }
107
108 /**
109  * gst_vaapi_surface_proxy_ref:
110  * @proxy: a #GstVaapiSurfaceProxy
111  *
112  * Atomically increases the reference count of the given @proxy by one.
113  *
114  * Returns: The same @proxy argument
115  */
116 GstVaapiSurfaceProxy *
117 gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy)
118 {
119     g_return_val_if_fail(proxy != NULL, NULL);
120
121     return GST_VAAPI_SURFACE_PROXY(gst_vaapi_mini_object_ref(
122                                        GST_VAAPI_MINI_OBJECT(proxy)));
123 }
124
125 /**
126  * gst_vaapi_surface_proxy_unref:
127  * @proxy: a #GstVaapiSurfaceProxy
128  *
129  * Atomically decreases the reference count of the @proxy by one. If
130  * the reference count reaches zero, the object will be free'd.
131  */
132 void
133 gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy)
134 {
135     g_return_if_fail(proxy != NULL);
136
137     gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(proxy));
138 }
139
140 /**
141  * gst_vaapi_surface_proxy_replace:
142  * @old_proxy_ptr: a pointer to a #GstVaapiSurfaceProxy
143  * @new_proxy: a #GstVaapiSurfaceProxy
144  *
145  * Atomically replaces the proxy object held in @old_proxy_ptr with
146  * @new_proxy. This means that @old_proxy_ptr shall reference a valid
147  * object. However, @new_proxy can be NULL.
148  */
149 void
150 gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr,
151     GstVaapiSurfaceProxy *new_proxy)
152 {
153     g_return_if_fail(old_proxy_ptr != NULL);
154
155     gst_vaapi_mini_object_replace((GstVaapiMiniObject **)old_proxy_ptr,
156         GST_VAAPI_MINI_OBJECT(new_proxy));
157 }
158
159 /**
160  * gst_vaapi_surface_proxy_get_surface:
161  * @proxy: a #GstVaapiSurfaceProxy
162  *
163  * Returns the #GstVaapiSurface stored in the @proxy.
164  *
165  * Return value: the #GstVaapiSurface
166  */
167 GstVaapiSurface *
168 gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy)
169 {
170     g_return_val_if_fail(proxy != NULL, NULL);
171
172     return GST_VAAPI_SURFACE_PROXY_SURFACE(proxy);
173 }
174
175 /**
176  * gst_vaapi_surface_proxy_get_flags:
177  * @proxy: a #GstVaapiSurfaceProxy
178  *
179  * Returns the #GstVaapiSurfaceProxyFlags associated with this surface
180  * @proxy.
181  *
182  * Return value: the set of #GstVaapiSurfaceProxyFlags
183  */
184 guint
185 gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy)
186 {
187     g_return_val_if_fail(proxy != NULL, 0);
188     
189     return GST_VAAPI_SURFACE_PROXY_FLAGS(proxy);
190 }
191
192 /**
193  * gst_vaapi_surface_proxy_get_surface_id:
194  * @proxy: a #GstVaapiSurfaceProxy
195  *
196  * Returns the VA surface ID stored in the @proxy.
197  *
198  * Return value: the #GstVaapiID
199  */
200 GstVaapiID
201 gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy)
202 {
203     g_return_val_if_fail(proxy != NULL, 0);
204     g_return_val_if_fail(proxy->surface != NULL, 0);
205
206     return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy);
207 }
208
209 /**
210  * gst_vaapi_surface_proxy_get_timestamp:
211  * @proxy: a #GstVaapiSurfaceProxy
212  *
213  * Returns the presentation timestamp for this surface @proxy.
214  *
215  * Return value: the presentation timestamp
216  */
217 GstClockTime
218 gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy)
219 {
220     g_return_val_if_fail(proxy != NULL, 0);
221     
222     return GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy);
223 }
224
225 /**
226  * gst_vaapi_surface_proxy_get_duration:
227  * @proxy: a #GstVaapiSurfaceProxy
228  *
229  * Returns the presentation duration for this surface @proxy.
230  *
231  * Return value: the presentation duration
232  */
233 GstClockTime
234 gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy)
235 {
236     g_return_val_if_fail(proxy != NULL, 0);
237     
238     return GST_VAAPI_SURFACE_PROXY_DURATION(proxy);
239 }
240
241 /**
242  * gst_vaapi_surface_proxy_set_destroy_notify:
243  * @proxy: a @GstVaapiSurfaceProxy
244  * @destroy_func: a #GDestroyNotify function
245  * @user_data: some extra data to pass to the @destroy_func function
246  *
247  * Sets @destroy_func as the function to call when the surface @proxy
248  * was released. At this point, the proxy object is considered
249  * released, i.e. the underlying data storage is no longer valid and
250  * the callback function shall not expect anything from that.
251  */
252 void
253 gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy,
254     GDestroyNotify destroy_func, gpointer user_data)
255 {
256     g_return_if_fail(proxy != NULL);
257
258     proxy->destroy_func = destroy_func;
259     proxy->destroy_data = user_data;
260 }
261
262 /**
263  * gst_vaapi_surface_proxy_get_crop_rect:
264  * @proxy: a #GstVaapiSurfaceProxy
265  *
266  * Returns the #GstVaapiRectangle stored in the @proxy and that
267  * represents the cropping rectangle for the underlying surface to be
268  * used for rendering.
269  *
270  * Return value: the #GstVaapiRectangle
271  */
272 const GstVaapiRectangle *
273 gst_vaapi_surface_proxy_get_crop_rect(GstVaapiSurfaceProxy *proxy)
274 {
275     g_return_val_if_fail(proxy != NULL, NULL);
276
277     return GST_VAAPI_SURFACE_PROXY_CROP_RECT(proxy);
278 }
279
280 /**
281  * gst_vaapi_surface_proxy_set_crop_rect:
282  * @proxy: #GstVaapiSurfaceProxy
283  * @crop_rect: the #GstVaapiRectangle to be stored in @proxy
284  *
285  * Associates the @crop_rect with the @proxy
286  */
287 void
288 gst_vaapi_surface_proxy_set_crop_rect(GstVaapiSurfaceProxy *proxy,
289     const GstVaapiRectangle *crop_rect)
290 {
291     g_return_if_fail(proxy != NULL);
292
293     set_crop_rect(proxy, crop_rect);
294 }