libs: use GstVaapiObject for VA objects.
[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
32 #define DEBUG 1
33 #include "gstvaapidebug.h"
34
35 static void
36 gst_vaapi_surface_proxy_finalize(GstVaapiSurfaceProxy *proxy)
37 {
38     if (proxy->destroy_func)
39         proxy->destroy_func(proxy->destroy_data);
40
41     if (proxy->surface) {
42         if (proxy->pool)
43             gst_vaapi_video_pool_put_object(proxy->pool, proxy->surface);
44         gst_vaapi_object_unref(proxy->surface);
45         proxy->surface = NULL;
46     }
47     g_clear_object(&proxy->pool);
48 }
49
50 static inline const GstVaapiMiniObjectClass *
51 gst_vaapi_surface_proxy_class(void)
52 {
53     static const GstVaapiMiniObjectClass GstVaapiSurfaceProxyClass = {
54         sizeof(GstVaapiSurfaceProxy),
55         (GDestroyNotify)gst_vaapi_surface_proxy_finalize
56     };
57     return &GstVaapiSurfaceProxyClass;
58 }
59
60 GstVaapiSurfaceProxy *
61 gst_vaapi_surface_proxy_new_from_pool(GstVaapiSurfacePool *pool)
62 {
63     GstVaapiSurfaceProxy *proxy;
64
65     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), NULL);
66
67     proxy = (GstVaapiSurfaceProxy *)
68         gst_vaapi_mini_object_new(gst_vaapi_surface_proxy_class());
69     if (!proxy)
70         return NULL;
71
72     proxy->pool = g_object_ref(pool);
73     proxy->surface = gst_vaapi_video_pool_get_object(proxy->pool);
74     if (!proxy->surface)
75         goto error;
76     proxy->timestamp = GST_CLOCK_TIME_NONE;
77     proxy->duration = GST_CLOCK_TIME_NONE;
78     proxy->destroy_func = NULL;
79     gst_vaapi_object_ref(proxy->surface);
80     return proxy;
81
82 error:
83     gst_vaapi_surface_proxy_unref(proxy);
84     return NULL;
85 }
86
87 /**
88  * gst_vaapi_surface_proxy_ref:
89  * @proxy: a #GstVaapiSurfaceProxy
90  *
91  * Atomically increases the reference count of the given @proxy by one.
92  *
93  * Returns: The same @proxy argument
94  */
95 GstVaapiSurfaceProxy *
96 gst_vaapi_surface_proxy_ref(GstVaapiSurfaceProxy *proxy)
97 {
98     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL);
99
100     return GST_VAAPI_SURFACE_PROXY(gst_vaapi_mini_object_ref(
101                                        GST_VAAPI_MINI_OBJECT(proxy)));
102 }
103
104 /**
105  * gst_vaapi_surface_proxy_unref:
106  * @proxy: a #GstVaapiSurfaceProxy
107  *
108  * Atomically decreases the reference count of the @proxy by one. If
109  * the reference count reaches zero, the object will be free'd.
110  */
111 void
112 gst_vaapi_surface_proxy_unref(GstVaapiSurfaceProxy *proxy)
113 {
114     g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
115
116     gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(proxy));
117 }
118
119 /**
120  * gst_vaapi_surface_proxy_replace:
121  * @old_proxy_ptr: a pointer to a #GstVaapiSurfaceProxy
122  * @new_proxy: a #GstVaapiSurfaceProxy
123  *
124  * Atomically replaces the proxy object held in @old_proxy_ptr with
125  * @new_proxy. This means that @old_proxy_ptr shall reference a valid
126  * object. However, @new_proxy can be NULL.
127  */
128 void
129 gst_vaapi_surface_proxy_replace(GstVaapiSurfaceProxy **old_proxy_ptr,
130     GstVaapiSurfaceProxy *new_proxy)
131 {
132     g_return_if_fail(old_proxy_ptr != NULL);
133
134     gst_vaapi_mini_object_replace((GstVaapiMiniObject **)old_proxy_ptr,
135         GST_VAAPI_MINI_OBJECT(new_proxy));
136 }
137
138 /**
139  * gst_vaapi_surface_proxy_get_surface:
140  * @proxy: a #GstVaapiSurfaceProxy
141  *
142  * Returns the #GstVaapiSurface stored in the @proxy.
143  *
144  * Return value: the #GstVaapiSurface
145  */
146 GstVaapiSurface *
147 gst_vaapi_surface_proxy_get_surface(GstVaapiSurfaceProxy *proxy)
148 {
149     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL);
150
151     return GST_VAAPI_SURFACE_PROXY_SURFACE(proxy);
152 }
153
154 /**
155  * gst_vaapi_surface_proxy_get_flags:
156  * @proxy: a #GstVaapiSurfaceProxy
157  *
158  * Returns the #GstVaapiSurfaceProxyFlags associated with this surface
159  * @proxy.
160  *
161  * Return value: the set of #GstVaapiSurfaceProxyFlags
162  */
163 guint
164 gst_vaapi_surface_proxy_get_flags(GstVaapiSurfaceProxy *proxy)
165 {
166     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0);
167     
168     return GST_VAAPI_SURFACE_PROXY_FLAGS(proxy);
169 }
170
171 /**
172  * gst_vaapi_surface_proxy_get_surface_id:
173  * @proxy: a #GstVaapiSurfaceProxy
174  *
175  * Returns the VA surface ID stored in the @proxy.
176  *
177  * Return value: the #GstVaapiID
178  */
179 GstVaapiID
180 gst_vaapi_surface_proxy_get_surface_id(GstVaapiSurfaceProxy *proxy)
181 {
182     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), GST_VAAPI_ID_NONE);
183     g_return_val_if_fail(proxy->surface != NULL, GST_VAAPI_ID_NONE);
184
185     return GST_VAAPI_SURFACE_PROXY_SURFACE_ID(proxy);
186 }
187
188 /**
189  * gst_vaapi_surface_proxy_get_timestamp:
190  * @proxy: a #GstVaapiSurfaceProxy
191  *
192  * Returns the presentation timestamp for this surface @proxy.
193  *
194  * Return value: the presentation timestamp
195  */
196 GstClockTime
197 gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy)
198 {
199     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0);
200     
201     return GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy);
202 }
203
204 /**
205  * gst_vaapi_surface_proxy_get_duration:
206  * @proxy: a #GstVaapiSurfaceProxy
207  *
208  * Returns the presentation duration for this surface @proxy.
209  *
210  * Return value: the presentation duration
211  */
212 GstClockTime
213 gst_vaapi_surface_proxy_get_duration(GstVaapiSurfaceProxy *proxy)
214 {
215     g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 0);
216     
217     return GST_VAAPI_SURFACE_PROXY_DURATION(proxy);
218 }
219
220 /**
221  * gst_vaapi_surface_proxy_set_destroy_notify:
222  * @proxy: a @GstVaapiSurfaceProxy
223  * @destroy_func: a #GDestroyNotify function
224  * @user_data: some extra data to pass to the @destroy_func function
225  *
226  * Sets @destroy_func as the function to call when the surface @proxy
227  * was released. At this point, the proxy object is considered
228  * released, i.e. the underlying data storage is no longer valid and
229  * the callback function shall not expect anything from that.
230  */
231 void
232 gst_vaapi_surface_proxy_set_destroy_notify(GstVaapiSurfaceProxy *proxy,
233     GDestroyNotify destroy_func, gpointer user_data)
234 {
235     g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
236
237     proxy->destroy_func = destroy_func;
238     proxy->destroy_data = user_data;
239 }