2 * gstvaapiimage.c - VA image abstraction
4 * gstreamer-vaapi (C) 2010 Splitted-Desktop Systems
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.
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.
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
23 #include "vaapi_utils.h"
24 #include "gstvaapiimage.h"
25 #include <va/va_backend.h>
28 #include "vaapi_debug.h"
30 G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, G_TYPE_OBJECT);
32 #define GST_VAAPI_IMAGE_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
34 GST_VAAPI_TYPE_IMAGE, \
35 GstVaapiImagePrivate))
37 struct _GstVaapiImagePrivate {
38 GstVaapiDisplay *display;
43 GstVaapiImageFormat format;
57 gst_vaapi_image_destroy(GstVaapiImage *image)
59 GstVaapiImagePrivate * const priv = image->priv;
60 VADisplay dpy = gst_vaapi_display_get_display(priv->display);
63 gst_vaapi_image_unmap(image);
65 if (priv->image.image_id != VA_INVALID_ID) {
66 status = vaDestroyImage(dpy, priv->image.image_id);
67 if (!vaapi_check_status(status, "vaDestroyImage()"))
68 g_warning("failed to destroy image 0x%08x\n", priv->image.image_id);
69 priv->image.image_id = VA_INVALID_ID;
73 g_object_unref(priv->display);
79 gst_vaapi_image_create(GstVaapiImage *image)
81 GstVaapiImagePrivate * const priv = image->priv;
82 const VAImageFormat *format;
85 if (!gst_vaapi_display_has_image_format(priv->display, priv->format))
88 format = gst_vaapi_image_format_get_va_format(priv->format);
90 g_return_val_if_fail(format, FALSE);
92 status = vaCreateImage(
93 gst_vaapi_display_get_display(priv->display),
94 (VAImageFormat *)format,
99 if (!vaapi_check_status(status, "vaCreateImage()"))
106 gst_vaapi_image_finalize(GObject *object)
108 gst_vaapi_image_destroy(GST_VAAPI_IMAGE(object));
110 G_OBJECT_CLASS(gst_vaapi_image_parent_class)->finalize(object);
114 gst_vaapi_image_set_property(
121 GstVaapiImage * const image = GST_VAAPI_IMAGE(object);
122 GstVaapiImagePrivate * const priv = image->priv;
126 priv->display = g_object_ref(g_value_get_pointer(value));
129 priv->width = g_value_get_uint(value);
132 priv->height = g_value_get_uint(value);
135 priv->format = g_value_get_uint(value);
138 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
144 gst_vaapi_image_get_property(
151 GstVaapiImage * const image = GST_VAAPI_IMAGE(object);
152 GstVaapiImagePrivate * const priv = image->priv;
156 g_value_set_pointer(value, g_object_ref(priv->display));
159 g_value_set_uint(value, gst_vaapi_image_get_id(image));
162 g_value_set_uint(value, gst_vaapi_image_get_width(image));
165 g_value_set_uint(value, gst_vaapi_image_get_height(image));
168 g_value_set_uint(value, gst_vaapi_image_get_format(image));
171 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
177 gst_vaapi_image_constructor(
180 GObjectConstructParam *params
183 GstVaapiImage *image;
184 GObjectClass *parent_class;
187 D(bug("gst_vaapi_image_constructor()\n"));
189 parent_class = G_OBJECT_CLASS(gst_vaapi_image_parent_class);
190 object = parent_class->constructor (type, n_params, params);
193 image = GST_VAAPI_IMAGE(object);
194 if (!gst_vaapi_image_create(image)) {
195 gst_vaapi_image_destroy(image);
203 gst_vaapi_image_class_init(GstVaapiImageClass *klass)
205 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
207 g_type_class_add_private(klass, sizeof(GstVaapiImagePrivate));
209 object_class->finalize = gst_vaapi_image_finalize;
210 object_class->set_property = gst_vaapi_image_set_property;
211 object_class->get_property = gst_vaapi_image_get_property;
212 object_class->constructor = gst_vaapi_image_constructor;
214 g_object_class_install_property
217 g_param_spec_object("display",
219 "GStreamer Va display",
220 GST_VAAPI_TYPE_DISPLAY,
221 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
223 g_object_class_install_property
226 g_param_spec_uint("id",
229 0, G_MAXUINT32, VA_INVALID_ID,
232 g_object_class_install_property
235 g_param_spec_uint("width",
239 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
241 g_object_class_install_property
244 g_param_spec_uint("height",
248 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
250 g_object_class_install_property
253 g_param_spec_uint("format",
257 G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
261 gst_vaapi_image_init(GstVaapiImage *image)
263 GstVaapiImagePrivate *priv = GST_VAAPI_IMAGE_GET_PRIVATE(image);
265 D(bug("gst_vaapi_image_init()\n"));
268 priv->display = NULL;
269 priv->image_data = NULL;
274 memset(&priv->image, 0, sizeof(priv->image));
275 priv->image.image_id = VA_INVALID_ID;
276 priv->image.buf = VA_INVALID_ID;
281 GstVaapiDisplay *display,
284 GstVaapiImageFormat format
287 D(bug("gst_vaapi_image_new(): size %ux%u, format 0x%x\n",
288 width, height, format));
290 return g_object_new(GST_VAAPI_TYPE_IMAGE,
299 gst_vaapi_image_get_id(GstVaapiImage *image)
301 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), VA_INVALID_ID);
303 return image->priv->image.image_id;
307 gst_vaapi_image_get_display(GstVaapiImage *image)
309 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
311 return g_object_ref(image->priv->display);
315 gst_vaapi_image_get_width(GstVaapiImage *image)
317 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
319 return image->priv->width;
323 gst_vaapi_image_get_height(GstVaapiImage *image)
325 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
327 return image->priv->height;
331 gst_vaapi_image_get_format(GstVaapiImage *image)
333 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
335 return image->priv->format;
338 static inline gboolean
339 _gst_vaapi_image_is_mapped(GstVaapiImage *image)
341 return image->priv->image_data != NULL;
345 gst_vaapi_image_is_mapped(GstVaapiImage *image)
347 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
349 return _gst_vaapi_image_is_mapped(image);
353 gst_vaapi_image_map(GstVaapiImage *image)
358 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
360 if (_gst_vaapi_image_is_mapped(image))
363 status = vaMapBuffer(
364 gst_vaapi_display_get_display(image->priv->display),
365 image->priv->image.buf,
368 if (!vaapi_check_status(status, "vaMapBuffer()"))
371 image->priv->image_data = image_data;
376 gst_vaapi_image_unmap(GstVaapiImage *image)
380 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), FALSE);
382 if (!_gst_vaapi_image_is_mapped(image))
385 status = vaUnmapBuffer(
386 gst_vaapi_display_get_display(image->priv->display),
387 image->priv->image.buf
389 if (!vaapi_check_status(status, "vaUnmapBuffer()"))
392 image->priv->image_data = NULL;
397 gst_vaapi_image_get_plane_count(GstVaapiImage *image)
399 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
400 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
402 return image->priv->image.num_planes;
406 gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane)
408 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
409 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL);
410 g_return_val_if_fail(plane < image->priv->image.num_planes, NULL);
412 return image->priv->image_data + image->priv->image.offsets[plane];
416 gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane)
418 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), 0);
419 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
420 g_return_val_if_fail(plane < image->priv->image.num_planes, 0);
422 return image->priv->image.pitches[plane];