2 * gstvaapivideobuffer.c - Gst VA video buffer
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011 Intel Corporation
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.
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.
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
24 * SECTION:gstvaapivideobuffer
25 * @short_description: VA video buffer for GStreamer
29 #include "gstvaapivideobuffer.h"
30 #include "gstvaapivideobuffer_priv.h"
31 #include "gstvaapiimagepool.h"
32 #include "gstvaapisurfacepool.h"
33 #include "gstvaapiobject_priv.h"
36 #include "gstvaapidebug.h"
38 G_DEFINE_TYPE(GstVaapiVideoBuffer, gst_vaapi_video_buffer, GST_TYPE_SURFACE_BUFFER);
40 #define GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(obj) \
41 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
42 GST_VAAPI_TYPE_VIDEO_BUFFER, \
43 GstVaapiVideoBufferPrivate))
45 struct _GstVaapiVideoBufferPrivate {
46 GstVaapiDisplay *display;
47 GstVaapiVideoPool *image_pool;
49 GstVaapiVideoPool *surface_pool;
50 GstVaapiSurface *surface;
51 GstVaapiSurfaceProxy *proxy;
57 set_display(GstVaapiVideoBuffer *buffer, GstVaapiDisplay *display)
59 GstVaapiVideoBufferPrivate * const priv = buffer->priv;
61 g_clear_object(&priv->display);
64 priv->display = g_object_ref(display);
68 set_image(GstVaapiVideoBuffer *buffer, GstVaapiImage *image)
70 buffer->priv->image = g_object_ref(image);
71 set_display(buffer, GST_VAAPI_OBJECT_DISPLAY(image));
75 set_surface(GstVaapiVideoBuffer *buffer, GstVaapiSurface *surface)
77 buffer->priv->surface = g_object_ref(surface);
78 set_display(buffer, GST_VAAPI_OBJECT_DISPLAY(surface));
82 gst_vaapi_video_buffer_destroy_image(GstVaapiVideoBuffer *buffer)
84 GstVaapiVideoBufferPrivate * const priv = buffer->priv;
88 gst_vaapi_video_pool_put_object(priv->image_pool, priv->image);
89 g_object_unref(priv->image);
93 g_clear_object(&priv->image_pool);
97 gst_vaapi_video_buffer_destroy_surface(GstVaapiVideoBuffer *buffer)
99 GstVaapiVideoBufferPrivate * const priv = buffer->priv;
101 g_clear_object(&priv->proxy);
104 if (priv->surface_pool)
105 gst_vaapi_video_pool_put_object(priv->surface_pool, priv->surface);
106 g_object_unref(priv->surface);
107 priv->surface = NULL;
110 g_clear_object(&priv->surface_pool);
113 gst_buffer_unref(priv->buffer);
119 gst_vaapi_video_buffer_finalize(GstMiniObject *object)
121 GstVaapiVideoBuffer * const buffer = GST_VAAPI_VIDEO_BUFFER(object);
122 GstMiniObjectClass *parent_class;
124 gst_vaapi_video_buffer_destroy_image(buffer);
125 gst_vaapi_video_buffer_destroy_surface(buffer);
127 set_display(buffer, NULL);
129 parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_video_buffer_parent_class);
130 if (parent_class->finalize)
131 parent_class->finalize(object);
135 gst_vaapi_video_buffer_class_init(GstVaapiVideoBufferClass *klass)
137 GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass);
139 g_type_class_add_private(klass, sizeof(GstVaapiVideoBufferPrivate));
141 object_class->finalize = gst_vaapi_video_buffer_finalize;
145 gst_vaapi_video_buffer_init(GstVaapiVideoBuffer *buffer)
147 GstVaapiVideoBufferPrivate *priv;
149 priv = GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(buffer);
151 priv->display = NULL;
152 priv->image_pool = NULL;
154 priv->surface_pool = NULL;
155 priv->surface = NULL;
158 priv->render_flags = 0;
161 static inline gboolean
162 gst_vaapi_video_buffer_is_a(GstBuffer *buffer, GType type)
164 return G_TYPE_CHECK_INSTANCE_TYPE(buffer, type);
167 static inline gpointer
168 _gst_vaapi_video_buffer_typed_new(GType type)
170 g_return_val_if_fail(g_type_is_a(type, GST_VAAPI_TYPE_VIDEO_BUFFER), NULL);
172 return gst_mini_object_new(type);
176 * gst_vaapi_video_buffer_typed_new:
177 * @display: a #GstVaapiDisplay
179 * Creates an empty #GstBuffer. The caller is responsible for completing
180 * the initialization of the buffer with the gst_vaapi_video_buffer_set_*()
183 * This function shall only be called from within gstreamer-vaapi
186 * Return value: the newly allocated #GstBuffer, or %NULL or error
189 gst_vaapi_video_buffer_typed_new(GType type, GstVaapiDisplay *display)
193 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
195 buffer = _gst_vaapi_video_buffer_typed_new(type);
199 set_display(GST_VAAPI_VIDEO_BUFFER(buffer), display);
204 * gst_vaapi_video_buffer_typed_new_from_pool:
205 * @pool: a #GstVaapiVideoPool
207 * Creates a #GstBuffer with a video object allocated from a @pool.
208 * Only #GstVaapiSurfacePool and #GstVaapiImagePool pools are supported.
210 * The buffer is destroyed through the last call to gst_buffer_unref()
211 * and the video objects are pushed back to their respective pools.
213 * Return value: the newly allocated #GstBuffer, or %NULL on error
216 gst_vaapi_video_buffer_typed_new_from_pool(GType type, GstVaapiVideoPool *pool)
218 GstVaapiVideoBuffer *buffer;
219 gboolean is_image_pool, is_surface_pool;
221 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
223 is_image_pool = GST_VAAPI_IS_IMAGE_POOL(pool);
224 is_surface_pool = GST_VAAPI_IS_SURFACE_POOL(pool);
226 if (!is_image_pool && !is_surface_pool)
229 buffer = _gst_vaapi_video_buffer_typed_new(type);
232 gst_vaapi_video_buffer_set_image_from_pool(buffer, pool)) ||
234 gst_vaapi_video_buffer_set_surface_from_pool(buffer, pool)))) {
235 set_display(buffer, gst_vaapi_video_pool_get_display(pool));
236 return GST_BUFFER(buffer);
239 gst_mini_object_unref(GST_MINI_OBJECT(buffer));
244 * gst_vaapi_video_buffer_typed_new_from_buffer:
245 * @buffer: a #GstBuffer
247 * Creates a #GstBuffer with video objects bound to @buffer video
250 * This function shall only be called from within gstreamer-vaapi
253 * Return value: the newly allocated #GstBuffer, or %NULL on error
256 gst_vaapi_video_buffer_typed_new_from_buffer(GType type, GstBuffer *buffer)
258 GstVaapiVideoBuffer *inbuf, *outbuf;
260 if (!gst_vaapi_video_buffer_is_a(buffer, type)) {
261 if (!buffer->parent ||
262 !gst_vaapi_video_buffer_is_a(buffer->parent, type))
264 buffer = buffer->parent;
266 inbuf = GST_VAAPI_VIDEO_BUFFER(buffer);
268 outbuf = _gst_vaapi_video_buffer_typed_new(type);
272 if (inbuf->priv->image)
273 gst_vaapi_video_buffer_set_image(outbuf, inbuf->priv->image);
274 if (inbuf->priv->surface)
275 gst_vaapi_video_buffer_set_surface(outbuf, inbuf->priv->surface);
276 if (inbuf->priv->proxy)
277 gst_vaapi_video_buffer_set_surface_proxy(outbuf, inbuf->priv->proxy);
279 outbuf->priv->buffer = gst_buffer_ref(buffer);
280 return GST_BUFFER(outbuf);
284 * gst_vaapi_video_buffer_typed_new_with_image:
285 * @image: a #GstVaapiImage
287 * Creates a #GstBuffer with the specified @image. The resulting
288 * buffer holds an additional reference to the @image.
290 * This function shall only be called from within gstreamer-vaapi
293 * Return value: the newly allocated #GstBuffer, or %NULL on error
296 gst_vaapi_video_buffer_typed_new_with_image(GType type, GstVaapiImage *image)
298 GstVaapiVideoBuffer *buffer;
300 g_return_val_if_fail(GST_VAAPI_IS_IMAGE(image), NULL);
302 buffer = _gst_vaapi_video_buffer_typed_new(type);
304 gst_vaapi_video_buffer_set_image(buffer, image);
305 return GST_BUFFER(buffer);
309 * gst_vaapi_video_buffer_typed_new_with_surface:
310 * @surface: a #GstVaapiSurface
312 * Creates a #GstBuffer with the specified @surface. The resulting
313 * buffer holds an additional reference to the @surface.
315 * This function shall only be called from within gstreamer-vaapi
318 * Return value: the newly allocated #GstBuffer, or %NULL on error
321 gst_vaapi_video_buffer_typed_new_with_surface(
323 GstVaapiSurface *surface
326 GstVaapiVideoBuffer *buffer;
328 g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL);
330 buffer = _gst_vaapi_video_buffer_typed_new(type);
332 gst_vaapi_video_buffer_set_surface(buffer, surface);
333 return GST_BUFFER(buffer);
337 * gst_vaapi_video_buffer_typed_new_with_surface_proxy:
338 * @proxy: a #GstVaapiSurfaceProxy
340 * Creates a #GstBuffer with the specified surface @proxy. The
341 * resulting buffer holds an additional reference to the @proxy.
343 * This function shall only be called from within gstreamer-vaapi
346 * Return value: the newly allocated #GstBuffer, or %NULL on error
349 gst_vaapi_video_buffer_typed_new_with_surface_proxy(
351 GstVaapiSurfaceProxy *proxy
354 GstVaapiVideoBuffer *buffer;
356 g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), NULL);
358 buffer = _gst_vaapi_video_buffer_typed_new(type);
360 gst_vaapi_video_buffer_set_surface_proxy(buffer, proxy);
361 return GST_BUFFER(buffer);
365 * gst_vaapi_video_buffer_get_display:
366 * @buffer: a #GstVaapiVideoBuffer
368 * Retrieves the #GstVaapiDisplay the @buffer is bound to. The @buffer
369 * owns the returned #GstVaapiDisplay object so the caller is
370 * responsible for calling g_object_ref() when needed.
372 * Return value: the #GstVaapiDisplay the @buffer is bound to
375 gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer)
377 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL);
379 return buffer->priv->display;
383 * gst_vaapi_video_buffer_get_image:
384 * @buffer: a #GstVaapiVideoBuffer
386 * Retrieves the #GstVaapiImage bound to the @buffer. The @buffer owns
387 * the #GstVaapiImage so the caller is responsible for calling
388 * g_object_ref() when needed.
390 * Return value: the #GstVaapiImage bound to the @buffer, or %NULL if
394 gst_vaapi_video_buffer_get_image(GstVaapiVideoBuffer *buffer)
396 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL);
398 return buffer->priv->image;
402 * gst_vaapi_video_buffer_set_image:
403 * @buffer: a #GstVaapiVideoBuffer
404 * @image: a #GstVaapiImage
406 * Binds @image to the @buffer. If the @buffer contains another image
407 * previously allocated from a pool, it's pushed back to its parent
408 * pool and the pool is also released.
411 gst_vaapi_video_buffer_set_image(
412 GstVaapiVideoBuffer *buffer,
416 g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer));
417 g_return_if_fail(GST_VAAPI_IS_IMAGE(image));
419 gst_vaapi_video_buffer_destroy_image(buffer);
422 set_image(buffer, image);
426 * gst_vaapi_video_buffer_set_image_from_pool
427 * @buffer: a #GstVaapiVideoBuffer
428 * @pool: a #GstVaapiVideoPool
430 * Binds a newly allocated video object from the @pool. The @pool
431 * shall be of type #GstVaapiImagePool. Previously allocated objects
432 * are released and returned to their parent pools, if any.
434 * Return value: %TRUE on success
437 gst_vaapi_video_buffer_set_image_from_pool(
438 GstVaapiVideoBuffer *buffer,
439 GstVaapiVideoPool *pool
442 GstVaapiImage *image;
444 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE);
445 g_return_val_if_fail(GST_VAAPI_IS_IMAGE_POOL(pool), FALSE);
447 gst_vaapi_video_buffer_destroy_image(buffer);
450 image = gst_vaapi_video_pool_get_object(pool);
453 set_image(buffer, image);
454 buffer->priv->image_pool = g_object_ref(pool);
460 * gst_vaapi_video_buffer_get_surface:
461 * @buffer: a #GstVaapiVideoBuffer
463 * Retrieves the #GstVaapiSurface bound to the @buffer. The @buffer
464 * owns the #GstVaapiSurface so the caller is responsible for calling
465 * g_object_ref() when needed.
467 * Return value: the #GstVaapiSurface bound to the @buffer, or %NULL if
471 gst_vaapi_video_buffer_get_surface(GstVaapiVideoBuffer *buffer)
473 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL);
475 return buffer->priv->surface;
479 * gst_vaapi_video_buffer_set_surface:
480 * @buffer: a #GstVaapiVideoBuffer
481 * @surface: a #GstVaapiSurface
483 * Binds @surface to the @buffer. If the @buffer contains another
484 * surface previously allocated from a pool, it's pushed back to its
485 * parent pool and the pool is also released.
488 gst_vaapi_video_buffer_set_surface(
489 GstVaapiVideoBuffer *buffer,
490 GstVaapiSurface *surface
493 g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer));
494 g_return_if_fail(GST_VAAPI_IS_SURFACE(surface));
496 gst_vaapi_video_buffer_destroy_surface(buffer);
499 set_surface(buffer, surface);
503 * gst_vaapi_video_buffer_set_surface_from_pool
504 * @buffer: a #GstVaapiVideoBuffer
505 * @pool: a #GstVaapiVideoPool
507 * Binds a newly allocated video object from the @pool. The @pool
508 * shall be of type #GstVaapiSurfacePool. Previously allocated objects
509 * are released and returned to their parent pools, if any.
511 * Return value: %TRUE on success
514 gst_vaapi_video_buffer_set_surface_from_pool(
515 GstVaapiVideoBuffer *buffer,
516 GstVaapiVideoPool *pool
519 GstVaapiSurface *surface;
521 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE);
522 g_return_val_if_fail(GST_VAAPI_IS_SURFACE_POOL(pool), FALSE);
524 gst_vaapi_video_buffer_destroy_surface(buffer);
527 surface = gst_vaapi_video_pool_get_object(pool);
530 set_surface(buffer, surface);
531 buffer->priv->surface_pool = g_object_ref(pool);
537 * gst_vaapi_video_buffer_get_surface_proxy:
538 * @buffer: a #GstVaapiVideoBuffer
540 * Retrieves the #GstVaapiSurfaceProxy bound to the @buffer. The @buffer
541 * owns the #GstVaapiSurfaceProxy so the caller is responsible for calling
542 * g_object_ref() when needed.
544 * Return value: the #GstVaapiSurfaceProxy bound to the @buffer, or
545 * %NULL if there is none
547 GstVaapiSurfaceProxy *
548 gst_vaapi_video_buffer_get_surface_proxy(GstVaapiVideoBuffer *buffer)
550 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), NULL);
552 return buffer->priv->proxy;
556 * gst_vaapi_video_buffer_set_surface_proxy:
557 * @buffer: a #GstVaapiVideoBuffer
558 * @proxy: a #GstVaapiSurfaceProxy
560 * Binds surface @proxy to the @buffer. If the @buffer contains another
561 * surface previously allocated from a pool, it's pushed back to its
562 * parent pool and the pool is also released.
565 gst_vaapi_video_buffer_set_surface_proxy(
566 GstVaapiVideoBuffer *buffer,
567 GstVaapiSurfaceProxy *proxy
570 GstVaapiSurface *surface;
572 g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer));
573 g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
575 gst_vaapi_video_buffer_destroy_surface(buffer);
578 surface = GST_VAAPI_SURFACE_PROXY_SURFACE(proxy);
581 set_surface(buffer, surface);
582 buffer->priv->proxy = g_object_ref(proxy);
587 * gst_vaapi_video_buffer_get_render_flags:
588 * @buffer: a #GstVaapiVideoBuffer
590 * Retrieves the surface render flags bound to the @buffer.
592 * Return value: a combination for #GstVaapiSurfaceRenderFlags
595 gst_vaapi_video_buffer_get_render_flags(GstVaapiVideoBuffer *buffer)
597 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), 0);
598 g_return_val_if_fail(GST_VAAPI_IS_SURFACE(buffer->priv->surface), 0);
600 return buffer->priv->render_flags;
604 * gst_vaapi_video_buffer_set_render_flags:
605 * @buffer: a #GstVaapiVideoBuffer
606 * @flags: a set of surface render flags
608 * Sets #GstVaapiSurfaceRenderFlags to the @buffer.
611 gst_vaapi_video_buffer_set_render_flags(GstVaapiVideoBuffer *buffer, guint flags)
613 g_return_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer));
614 g_return_if_fail(GST_VAAPI_IS_SURFACE(buffer->priv->surface));
616 buffer->priv->render_flags = flags;
620 * gst_vaapi_video_buffer_ensure_pointer:
621 * @buffer: a #GstVaapiVideoBuffer
623 * Maps image data buffer to #GstBuffer of @buffer.
625 * Return value: %TRUE on success
628 gst_vaapi_video_buffer_ensure_pointer(GstVaapiVideoBuffer *buffer)
630 GstVaapiVideoBufferPrivate * const priv = buffer->priv;
631 GstVaapiImage *image = NULL;
632 gboolean is_image_derived = FALSE;
633 gboolean ret = FALSE;
635 g_return_val_if_fail(GST_VAAPI_IS_VIDEO_BUFFER(buffer), FALSE);
636 g_return_val_if_fail (priv->image || priv->surface, FALSE);
639 image = gst_vaapi_surface_derive_image(priv->surface);
640 g_return_val_if_fail(image, FALSE);
641 is_image_derived = TRUE;
644 is_image_derived = FALSE;
647 if (!gst_vaapi_image_map(image))
650 if(!gst_vaapi_image_ensure_mapped_buffer(image))
653 GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0);
654 GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image);
656 if (!gst_vaapi_image_unmap(image))
662 if (image && is_image_derived)
663 g_object_unref(image);