Restore the gst_vaapi_{surface,image,subpicture}_get_id() interfaces.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapisubpicture.c
1 /*
2  *  gstvaapisubpicture.c - VA subpicture abstraction
3  *
4  *  gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
19  */
20
21 /**
22  * SECTION:gstvaapisubpicture
23  * @short_description: VA subpicture abstraction
24  */
25
26 #include "config.h"
27 #include <string.h>
28 #include "gstvaapicompat.h"
29 #include "gstvaapiutils.h"
30 #include "gstvaapisubpicture.h"
31 #include "gstvaapiobject_priv.h"
32
33 #define DEBUG 1
34 #include "gstvaapidebug.h"
35
36 G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT);
37
38 #define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj)                   \
39     (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
40                                  GST_VAAPI_TYPE_SUBPICTURE,     \
41                                  GstVaapiSubpicturePrivate))
42
43 struct _GstVaapiSubpicturePrivate {
44     GstVaapiImage      *image;
45 };
46
47 enum {
48     PROP_0,
49
50     PROP_IMAGE
51 };
52
53 static void
54 gst_vaapi_subpicture_destroy(GstVaapiSubpicture *subpicture)
55 {
56     GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
57     GstVaapiSubpicturePrivate * const priv = subpicture->priv;
58     VASubpictureID subpicture_id;
59     VAStatus status;
60
61     subpicture_id = GST_VAAPI_OBJECT_ID(subpicture);
62     GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT,
63               GST_VAAPI_ID_ARGS(subpicture_id));
64
65     if (subpicture_id != VA_INVALID_ID) {
66         if (display) {
67             GST_VAAPI_DISPLAY_LOCK(display);
68             status = vaDestroySubpicture(
69                 GST_VAAPI_DISPLAY_VADISPLAY(display),
70                 subpicture_id
71             );
72             GST_VAAPI_DISPLAY_UNLOCK(display);
73             if (!vaapi_check_status(status, "vaDestroySubpicture()"))
74                 g_warning("failed to destroy subpicture %" GST_VAAPI_ID_FORMAT,
75                           GST_VAAPI_ID_ARGS(subpicture_id));
76         }
77         GST_VAAPI_OBJECT_ID(subpicture) = VA_INVALID_ID;
78     }
79
80     if (priv->image) {
81         g_object_unref(priv->image);
82         priv->image = NULL;
83     }
84 }
85
86 static gboolean
87 gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture)
88 {
89     GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(subpicture);
90     GstVaapiSubpicturePrivate * const priv = subpicture->priv;
91     VASubpictureID subpicture_id;
92     VAStatus status;
93
94     if (!priv->image)
95         return FALSE;
96
97     GST_VAAPI_DISPLAY_LOCK(display);
98     status = vaCreateSubpicture(
99         GST_VAAPI_DISPLAY_VADISPLAY(display),
100         GST_VAAPI_OBJECT_ID(priv->image),
101         &subpicture_id
102     );
103     GST_VAAPI_DISPLAY_UNLOCK(display);
104     if (!vaapi_check_status(status, "vaCreateSubpicture()"))
105         return FALSE;
106
107     GST_DEBUG("subpicture %" GST_VAAPI_ID_FORMAT,
108               GST_VAAPI_ID_ARGS(subpicture_id));
109     GST_VAAPI_OBJECT_ID(subpicture) = subpicture_id;
110     return TRUE;
111 }
112
113 static void
114 gst_vaapi_subpicture_finalize(GObject *object)
115 {
116     gst_vaapi_subpicture_destroy(GST_VAAPI_SUBPICTURE(object));
117
118     G_OBJECT_CLASS(gst_vaapi_subpicture_parent_class)->finalize(object);
119 }
120
121 static void
122 gst_vaapi_subpicture_set_property(
123     GObject      *object,
124     guint         prop_id,
125     const GValue *value,
126     GParamSpec   *pspec
127 )
128 {
129     GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
130
131     switch (prop_id) {
132     case PROP_IMAGE:
133         gst_vaapi_subpicture_set_image(subpicture, g_value_get_object(value));
134         break;
135     default:
136         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
137         break;
138     }
139 }
140
141 static void
142 gst_vaapi_subpicture_get_property(
143     GObject    *object,
144     guint       prop_id,
145     GValue     *value,
146     GParamSpec *pspec
147 )
148 {
149     GstVaapiSubpicture * const subpicture = GST_VAAPI_SUBPICTURE(object);
150
151     switch (prop_id) {
152     case PROP_IMAGE:
153         g_value_set_object(value, gst_vaapi_subpicture_get_image(subpicture));
154         break;
155     default:
156         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
157         break;
158     }
159 }
160
161 static void
162 gst_vaapi_subpicture_class_init(GstVaapiSubpictureClass *klass)
163 {
164     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
165
166     g_type_class_add_private(klass, sizeof(GstVaapiSubpicturePrivate));
167
168     object_class->finalize     = gst_vaapi_subpicture_finalize;
169     object_class->set_property = gst_vaapi_subpicture_set_property;
170     object_class->get_property = gst_vaapi_subpicture_get_property;
171
172     /**
173      * GstVaapiSubpicture:image:
174      *
175      * The #GstVaapiImage this subpicture is bound to.
176      */
177     g_object_class_install_property
178         (object_class,
179          PROP_IMAGE,
180          g_param_spec_object("image",
181                              "Image",
182                              "The GstVaapiImage this subpicture is bound to",
183                              GST_VAAPI_TYPE_IMAGE,
184                              G_PARAM_READWRITE));
185 }
186
187 static void
188 gst_vaapi_subpicture_init(GstVaapiSubpicture *subpicture)
189 {
190     GstVaapiSubpicturePrivate *priv = GST_VAAPI_SUBPICTURE_GET_PRIVATE(subpicture);
191
192     subpicture->priv    = priv;
193     priv->image         = NULL;
194 }
195
196 /**
197  * gst_vaapi_subpicture_new:
198  * @image: a #GstVaapiImage
199  *
200  * Creates a new #GstVaapiSubpicture with @image as source pixels. The
201  * newly created object holds a reference on @image.
202  *
203  * Return value: the newly allocated #GstVaapiSubpicture object
204  */
205 GstVaapiSubpicture *
206 gst_vaapi_subpicture_new(GstVaapiImage *image)
207 {
208     g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
209
210     GST_DEBUG("create from image %" GST_VAAPI_ID_FORMAT,
211               GST_VAAPI_ID_ARGS(GST_VAAPI_OBJECT_ID(image)));
212
213     return g_object_new(GST_VAAPI_TYPE_SUBPICTURE,
214                         "display", GST_VAAPI_OBJECT_DISPLAY(image),
215                         "id",      GST_VAAPI_ID(VA_INVALID_ID),
216                         "image",   image,
217                         NULL);
218 }
219
220 /**
221  * gst_vaapi_subpicture_get_id:
222  * @subpicture: a #GstVaapiSubpicture
223  *
224  * Returns the underlying VASubpictureID of the @subpicture.
225  *
226  * Return value: the underlying VA subpicture id
227  */
228 VASubpictureID
229 gst_vaapi_subpicture_get_id(GstVaapiSubpicture *subpicture)
230 {
231     g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), VA_INVALID_ID);
232
233     return GST_VAAPI_OBJECT_ID(subpicture);
234 }
235
236 /**
237  * gst_vaapi_subpicture_get_image:
238  * @subpicture: a #GstVaapiSubpicture
239  *
240  * Returns the #GstVaapiImage this @subpicture is bound to.
241  *
242  * Return value: the #GstVaapiImage this @subpicture is bound to
243  */
244 GstVaapiImage *
245 gst_vaapi_subpicture_get_image(GstVaapiSubpicture *subpicture)
246 {
247     g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL);
248
249     return subpicture->priv->image;
250 }
251
252 /**
253  * gst_vaapi_subpicture_set_image:
254  * @subpicture: a #GstVaapiSubpicture
255  * @image: a #GstVaapiImage
256  *
257  * Binds a new #GstVaapiImage to the @subpicture. The reference to the
258  * previous image is released a new one acquired on @image.
259  */
260 void
261 gst_vaapi_subpicture_set_image(
262     GstVaapiSubpicture *subpicture,
263     GstVaapiImage      *image
264 )
265 {
266     g_return_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture));
267     g_return_if_fail(GST_VAAPI_IS_IMAGE(image));
268
269     gst_vaapi_subpicture_destroy(subpicture);
270
271     subpicture->priv->image = g_object_ref(image);
272     gst_vaapi_subpicture_create(subpicture);
273 }