2 * gstvaapiimage.c - VA image abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Author: Gwenole Beauchesne <gwenole.beauchesne@splitted-desktop.com>
6 * Copyright (C) 2011-2013 Intel Corporation
7 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA
26 * SECTION:gstvaapiimage
27 * @short_description: VA image abstraction
32 #include "gstvaapicompat.h"
33 #include "gstvaapiutils.h"
34 #include "gstvaapiimage.h"
35 #include "gstvaapiimage_priv.h"
36 #include "gstvaapiobject_priv.h"
39 #include "gstvaapidebug.h"
41 #define SWAP_UINT(a, b) do { \
48 _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image);
51 _gst_vaapi_image_unmap(GstVaapiImage *image);
54 _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image);
61 vaapi_image_is_linear(const VAImage *va_image)
63 guint i, width, height, width2, height2, data_size;
65 for (i = 1; i < va_image->num_planes; i++)
66 if (va_image->offsets[i] < va_image->offsets[i - 1])
69 width = va_image->width;
70 height = va_image->height;
71 width2 = (width + 1) / 2;
72 height2 = (height + 1) / 2;
74 switch (va_image->format.fourcc) {
75 case VA_FOURCC('N','V','1','2'):
76 case VA_FOURCC('Y','V','1','2'):
77 case VA_FOURCC('I','4','2','0'):
78 data_size = width * height + 2 * width2 * height2;
80 case VA_FOURCC('Y','U','Y','2'):
81 case VA_FOURCC('U','Y','V','Y'):
82 data_size = 2 * width * height;
84 case VA_FOURCC('Y','8','0','0'):
85 data_size = width * height;
87 case VA_FOURCC('A','Y','U','V'):
88 case VA_FOURCC('A','R','G','B'):
89 case VA_FOURCC('R','G','B','A'):
90 case VA_FOURCC('A','B','G','R'):
91 case VA_FOURCC('B','G','R','A'):
92 case VA_FOURCC('X','R','G','B'):
93 case VA_FOURCC('R','G','B','X'):
94 case VA_FOURCC('X','B','G','R'):
95 case VA_FOURCC('B','G','R','X'):
96 data_size = 4 * width * height;
99 g_error("FIXME: incomplete formats %" GST_FOURCC_FORMAT,
100 GST_FOURCC_ARGS(va_image->format.fourcc));
103 return va_image->data_size == data_size;
107 gst_vaapi_image_destroy(GstVaapiImage *image)
109 GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
113 _gst_vaapi_image_unmap(image);
115 image_id = GST_VAAPI_OBJECT_ID(image);
116 GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
118 if (image_id != VA_INVALID_ID) {
119 GST_VAAPI_DISPLAY_LOCK(display);
120 status = vaDestroyImage(GST_VAAPI_DISPLAY_VADISPLAY(display), image_id);
121 GST_VAAPI_DISPLAY_UNLOCK(display);
122 if (!vaapi_check_status(status, "vaDestroyImage()"))
123 g_warning("failed to destroy image %" GST_VAAPI_ID_FORMAT,
124 GST_VAAPI_ID_ARGS(image_id));
125 GST_VAAPI_OBJECT_ID(image) = VA_INVALID_ID;
130 _gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format)
132 GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
133 const VAImageFormat *va_format;
136 if (!gst_vaapi_display_has_image_format(display, format))
139 va_format = gst_vaapi_video_format_to_va_format(format);
143 GST_VAAPI_DISPLAY_LOCK(display);
144 status = vaCreateImage(
145 GST_VAAPI_DISPLAY_VADISPLAY(display),
146 (VAImageFormat *)va_format,
149 &image->internal_image
151 GST_VAAPI_DISPLAY_UNLOCK(display);
152 if (status != VA_STATUS_SUCCESS ||
153 image->internal_image.format.fourcc != va_format->fourcc)
156 image->internal_format = format;
161 gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format,
162 guint width, guint height)
164 const VAImageFormat *va_format;
167 image->format = format;
168 image->width = width;
169 image->height = height;
171 if (!_gst_vaapi_image_create(image, format)) {
173 case GST_VIDEO_FORMAT_I420:
174 format = GST_VIDEO_FORMAT_YV12;
176 case GST_VIDEO_FORMAT_YV12:
177 format = GST_VIDEO_FORMAT_I420;
183 if (!format || !_gst_vaapi_image_create(image, format))
186 image->image = image->internal_image;
187 image_id = image->image.image_id;
189 if (image->format != image->internal_format) {
190 switch (image->format) {
191 case GST_VIDEO_FORMAT_YV12:
192 case GST_VIDEO_FORMAT_I420:
193 va_format = gst_vaapi_video_format_to_va_format(image->format);
196 image->image.format = *va_format;
197 SWAP_UINT(image->image.offsets[1], image->image.offsets[2]);
198 SWAP_UINT(image->image.pitches[1], image->image.pitches[2]);
204 image->is_linear = vaapi_image_is_linear(&image->image);
206 GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
207 GST_VAAPI_OBJECT_ID(image) = image_id;
212 gst_vaapi_image_init(GstVaapiImage *image)
214 image->internal_image.image_id = VA_INVALID_ID;
215 image->internal_image.buf = VA_INVALID_ID;
216 image->image.image_id = VA_INVALID_ID;
217 image->image.buf = VA_INVALID_ID;
221 gst_vaapi_image_class_init(GstVaapiImageClass *klass)
223 GstVaapiObjectClass * const object_class =
224 GST_VAAPI_OBJECT_CLASS(klass);
226 object_class->init = (GstVaapiObjectInitFunc)gst_vaapi_image_init;
229 #define gst_vaapi_image_finalize gst_vaapi_image_destroy
230 GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(
233 gst_vaapi_image_class_init(&g_class))
236 * gst_vaapi_image_new:
237 * @display: a #GstVaapiDisplay
238 * @format: a #GstVideoFormat
239 * @width: the requested image width
240 * @height: the requested image height
242 * Creates a new #GstVaapiImage with the specified format and
245 * Return value: the newly allocated #GstVaapiImage object
249 GstVaapiDisplay *display,
250 GstVideoFormat format,
255 GstVaapiImage *image;
257 g_return_val_if_fail(width > 0, NULL);
258 g_return_val_if_fail(height > 0, NULL);
260 GST_DEBUG("format %s, size %ux%u", gst_vaapi_video_format_to_string(format),
263 image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
267 if (!gst_vaapi_image_create(image, format, width, height))
272 gst_vaapi_object_unref(image);
277 * gst_vaapi_image_new_with_image:
278 * @display: a #GstVaapiDisplay
279 * @va_image: a VA image
281 * Creates a new #GstVaapiImage from a foreign VA image. The image
282 * format and dimensions will be extracted from @va_image. This
283 * function is mainly used by gst_vaapi_surface_derive_image() to bind
284 * a VA image to a #GstVaapiImage object.
286 * Return value: the newly allocated #GstVaapiImage object
289 gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image)
291 GstVaapiImage *image;
293 g_return_val_if_fail(va_image, NULL);
294 g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL);
295 g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL);
297 GST_DEBUG("VA image 0x%08x, format %" GST_FOURCC_FORMAT ", size %ux%u",
299 GST_FOURCC_ARGS(va_image->format.fourcc),
300 va_image->width, va_image->height);
302 image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
306 if (!_gst_vaapi_image_set_image(image, va_image))
311 gst_vaapi_object_unref(image);
316 * gst_vaapi_image_get_id:
317 * @image: a #GstVaapiImage
319 * Returns the underlying VAImageID of the @image.
321 * Return value: the underlying VA image id
324 gst_vaapi_image_get_id(GstVaapiImage *image)
326 g_return_val_if_fail(image != NULL, VA_INVALID_ID);
328 return GST_VAAPI_OBJECT_ID(image);
332 * gst_vaapi_image_get_image:
333 * @image: a #GstVaapiImage
334 * @va_image: a VA image
336 * Fills @va_image with the VA image used internally.
338 * Return value: %TRUE on success
341 gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image)
343 g_return_val_if_fail(image != NULL, FALSE);
346 *va_image = image->image;
352 * _gst_vaapi_image_set_image:
353 * @image: a #GstVaapiImage
354 * @va_image: a VA image
356 * Initializes #GstVaapiImage with a foreign VA image. This function
357 * will try to "linearize" the VA image. i.e. making sure that the VA
358 * image offsets into the data buffer are in increasing order with the
359 * number of planes available in the image.
361 * This is an internal function used by gst_vaapi_image_new_with_image().
363 * Return value: %TRUE on success
366 _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image)
368 GstVideoFormat format;
369 VAImage alt_va_image;
370 const VAImageFormat *alt_va_format;
372 format = gst_vaapi_video_format_from_va_format(&va_image->format);
373 if (format == GST_VIDEO_FORMAT_UNKNOWN)
376 image->internal_image = *va_image;
377 image->internal_format = format;
378 image->is_linear = vaapi_image_is_linear(va_image);
379 image->image = *va_image;
380 image->format = format;
381 image->width = va_image->width;
382 image->height = va_image->height;
384 GST_VAAPI_OBJECT_ID(image) = va_image->image_id;
386 /* Try to linearize image */
387 if (!image->is_linear) {
389 case GST_VIDEO_FORMAT_I420:
390 format = GST_VIDEO_FORMAT_YV12;
392 case GST_VIDEO_FORMAT_YV12:
393 format = GST_VIDEO_FORMAT_I420;
400 (alt_va_format = gst_vaapi_video_format_to_va_format(format))) {
401 alt_va_image = *va_image;
402 alt_va_image.format = *alt_va_format;
403 SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]);
404 SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]);
405 if (vaapi_image_is_linear(&alt_va_image)) {
406 image->image = alt_va_image;
407 image->format = format;
408 image->is_linear = TRUE;
409 GST_DEBUG("linearized image to %s format",
410 gst_vaapi_video_format_to_string(format));
418 * gst_vaapi_image_get_format:
419 * @image: a #GstVaapiImage
421 * Returns the #GstVideoFormat the @image was created with.
423 * Return value: the #GstVideoFormat
426 gst_vaapi_image_get_format(GstVaapiImage *image)
428 g_return_val_if_fail(image != NULL, 0);
430 return image->format;
434 * gst_vaapi_image_get_width:
435 * @image: a #GstVaapiImage
437 * Returns the @image width.
439 * Return value: the image width, in pixels
442 gst_vaapi_image_get_width(GstVaapiImage *image)
444 g_return_val_if_fail(image != NULL, 0);
450 * gst_vaapi_image_get_height:
451 * @image: a #GstVaapiImage
453 * Returns the @image height.
455 * Return value: the image height, in pixels.
458 gst_vaapi_image_get_height(GstVaapiImage *image)
460 g_return_val_if_fail(image != NULL, 0);
462 return image->height;
466 * gst_vaapi_image_get_size:
467 * @image: a #GstVaapiImage
468 * @pwidth: return location for the width, or %NULL
469 * @pheight: return location for the height, or %NULL
471 * Retrieves the dimensions of a #GstVaapiImage.
474 gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight)
476 g_return_if_fail(image != NULL);
479 *pwidth = image->width;
482 *pheight = image->height;
486 * gst_vaapi_image_is_linear:
487 * @image: a #GstVaapiImage
489 * Checks whether the @image has data planes allocated from a single
490 * buffer and offsets into that buffer are in increasing order with
491 * the number of planes.
493 * Return value: %TRUE if image data planes are allocated from a single buffer
496 gst_vaapi_image_is_linear(GstVaapiImage *image)
498 g_return_val_if_fail(image != NULL, FALSE);
500 return image->is_linear;
504 * gst_vaapi_image_is_mapped:
505 * @image: a #GstVaapiImage
507 * Checks whether the @image is currently mapped or not.
509 * Return value: %TRUE if the @image is mapped
511 static inline gboolean
512 _gst_vaapi_image_is_mapped(GstVaapiImage *image)
514 return image->image_data != NULL;
518 gst_vaapi_image_is_mapped(GstVaapiImage *image)
520 g_return_val_if_fail(image != NULL, FALSE);
522 return _gst_vaapi_image_is_mapped(image);
526 * gst_vaapi_image_map:
527 * @image: a #GstVaapiImage
529 * Maps the image data buffer. The actual pixels are returned by the
530 * gst_vaapi_image_get_plane() function.
532 * Return value: %TRUE on success
535 gst_vaapi_image_map(GstVaapiImage *image)
537 g_return_val_if_fail(image != NULL, FALSE);
539 return _gst_vaapi_image_map(image, NULL);
543 _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image)
545 GstVaapiDisplay *display;
549 if (_gst_vaapi_image_is_mapped(image))
552 display = GST_VAAPI_OBJECT_DISPLAY(image);
556 GST_VAAPI_DISPLAY_LOCK(display);
557 status = vaMapBuffer(
558 GST_VAAPI_DISPLAY_VADISPLAY(display),
560 (void **)&image->image_data
562 GST_VAAPI_DISPLAY_UNLOCK(display);
563 if (!vaapi_check_status(status, "vaMapBuffer()"))
568 const VAImage * const va_image = &image->image;
569 raw_image->format = image->format;
570 raw_image->width = va_image->width;
571 raw_image->height = va_image->height;
572 raw_image->num_planes = va_image->num_planes;
573 for (i = 0; i < raw_image->num_planes; i++) {
574 raw_image->pixels[i] = (guchar *)image->image_data +
575 va_image->offsets[i];
576 raw_image->stride[i] = va_image->pitches[i];
583 * gst_vaapi_image_unmap:
584 * @image: a #GstVaapiImage
586 * Unmaps the image data buffer. Pointers to pixels returned by
587 * gst_vaapi_image_get_plane() are then no longer valid.
589 * Return value: %TRUE on success
592 gst_vaapi_image_unmap(GstVaapiImage *image)
594 g_return_val_if_fail(image != NULL, FALSE);
596 return _gst_vaapi_image_unmap(image);
600 _gst_vaapi_image_unmap(GstVaapiImage *image)
602 GstVaapiDisplay *display;
605 if (!_gst_vaapi_image_is_mapped(image))
608 display = GST_VAAPI_OBJECT_DISPLAY(image);
612 GST_VAAPI_DISPLAY_LOCK(display);
613 status = vaUnmapBuffer(
614 GST_VAAPI_DISPLAY_VADISPLAY(display),
617 GST_VAAPI_DISPLAY_UNLOCK(display);
618 if (!vaapi_check_status(status, "vaUnmapBuffer()"))
621 image->image_data = NULL;
626 * gst_vaapi_image_get_plane_count:
627 * @image: a #GstVaapiImage
629 * Retrieves the number of planes available in the @image. The @image
630 * must be mapped for this function to work properly.
632 * Return value: the number of planes available in the @image
635 gst_vaapi_image_get_plane_count(GstVaapiImage *image)
637 g_return_val_if_fail(image != NULL, 0);
638 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
640 return image->image.num_planes;
644 * gst_vaapi_image_get_plane:
645 * @image: a #GstVaapiImage
646 * @plane: the requested plane number
648 * Retrieves the pixels data to the specified @plane. The @image must
649 * be mapped for this function to work properly.
651 * Return value: the pixels data of the specified @plane
654 gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane)
656 g_return_val_if_fail(image != NULL, NULL);
657 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL);
658 g_return_val_if_fail(plane < image->image.num_planes, NULL);
660 return image->image_data + image->image.offsets[plane];
664 * gst_vaapi_image_get_pitch:
665 * @image: a #GstVaapiImage
666 * @plane: the requested plane number
668 * Retrieves the line size (stride) of the specified @plane. The
669 * @image must be mapped for this function to work properly.
671 * Return value: the line size (stride) of the specified plane
674 gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane)
676 g_return_val_if_fail(image != NULL, 0);
677 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
678 g_return_val_if_fail(plane < image->image.num_planes, 0);
680 return image->image.pitches[plane];
684 * gst_vaapi_image_get_data_size:
685 * @image: a #GstVaapiImage
687 * Retrieves the underlying image data size. This function could be
688 * used to determine whether the image has a compatible layout with
689 * another image structure.
691 * Return value: the whole image data size of the @image
694 gst_vaapi_image_get_data_size(GstVaapiImage *image)
696 g_return_val_if_fail(image != NULL, 0);
698 return image->image.data_size;
701 #if GST_CHECK_VERSION(1,0,0)
702 #include <gst/video/gstvideometa.h>
705 init_image_from_video_meta(GstVaapiImageRaw *raw_image, GstVideoMeta *vmeta)
707 GST_FIXME("map from GstVideoMeta + add fini_image_from_buffer()");
712 init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer)
714 GstVideoMeta * const vmeta = gst_buffer_get_video_meta(buffer);
716 return vmeta ? init_image_from_video_meta(raw_image, vmeta) : FALSE;
720 init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer)
728 data = GST_BUFFER_DATA(buffer);
729 data_size = GST_BUFFER_SIZE(buffer);
730 caps = GST_BUFFER_CAPS(buffer);
735 if (!gst_video_info_from_caps(&vi, caps))
736 goto error_unsupported_caps;
738 /* Check for compatible data size */
739 frame_size = GST_VIDEO_INFO_SIZE(&vi);
740 if (frame_size != data_size)
741 goto error_incompatible_size;
743 raw_image->format = GST_VIDEO_INFO_FORMAT(&vi);
744 raw_image->width = GST_VIDEO_INFO_WIDTH(&vi);
745 raw_image->height = GST_VIDEO_INFO_HEIGHT(&vi);
747 raw_image->num_planes = GST_VIDEO_INFO_N_PLANES(&vi);
748 for (i = 0; i < raw_image->num_planes; i++) {
749 raw_image->pixels[i] = data + GST_VIDEO_INFO_PLANE_OFFSET(&vi, i);
750 raw_image->stride[i] = GST_VIDEO_INFO_PLANE_STRIDE(&vi, i);
755 error_unsupported_caps:
756 GST_ERROR("unsupported caps %" GST_PTR_FORMAT, caps);
758 error_incompatible_size:
759 GST_ERROR("incompatible frame size (%u) with buffer size (%u)",
760 frame_size, data_size);
765 /* Copy N lines of an image */
778 for (i = 0; i < height; i++) {
779 memcpy(dst, src, len);
785 /* Copy NV12 images */
788 GstVaapiImageRaw *dst_image,
789 GstVaapiImageRaw *src_image,
790 const GstVaapiRectangle *rect
794 guint dst_stride, src_stride;
797 dst_stride = dst_image->stride[0];
798 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
799 src_stride = src_image->stride[0];
800 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
801 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height);
804 dst_stride = dst_image->stride[1];
805 dst = dst_image->pixels[1] + (rect->y / 2) * dst_stride + (rect->x & -2);
806 src_stride = src_image->stride[1];
807 src = src_image->pixels[1] + (rect->y / 2) * src_stride + (rect->x & -2);
808 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height / 2);
811 /* Copy YV12 images */
814 GstVaapiImageRaw *dst_image,
815 GstVaapiImageRaw *src_image,
816 const GstVaapiRectangle *rect
820 guint dst_stride, src_stride;
824 dst_stride = dst_image->stride[0];
825 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
826 src_stride = src_image->stride[0];
827 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
828 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height);
834 h = rect->height / 2;
835 for (i = 1; i < dst_image->num_planes; i++) {
836 dst_stride = dst_image->stride[i];
837 dst = dst_image->pixels[i] + y * dst_stride + x;
838 src_stride = src_image->stride[i];
839 src = src_image->pixels[i] + y * src_stride + x;
840 memcpy_pic(dst, dst_stride, src, src_stride, w, h);
844 /* Copy YUY2 images */
847 GstVaapiImageRaw *dst_image,
848 GstVaapiImageRaw *src_image,
849 const GstVaapiRectangle *rect
853 guint dst_stride, src_stride;
855 /* YUV 4:2:2, full vertical resolution */
856 dst_stride = dst_image->stride[0];
857 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x * 2;
858 src_stride = src_image->stride[0];
859 src = src_image->pixels[0] + rect->y * src_stride + rect->x * 2;
860 memcpy_pic(dst, dst_stride, src, src_stride, rect->width * 2, rect->height);
863 /* Copy RGBA images */
866 GstVaapiImageRaw *dst_image,
867 GstVaapiImageRaw *src_image,
868 const GstVaapiRectangle *rect
872 guint dst_stride, src_stride;
874 dst_stride = dst_image->stride[0];
875 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
876 src_stride = src_image->stride[0];
877 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
878 memcpy_pic(dst, dst_stride, src, src_stride, 4 * rect->width, rect->height);
883 GstVaapiImageRaw *dst_image,
884 GstVaapiImageRaw *src_image,
885 const GstVaapiRectangle *rect
888 GstVaapiRectangle default_rect;
890 if (dst_image->format != src_image->format ||
891 dst_image->width != src_image->width ||
892 dst_image->height != src_image->height)
896 if (rect->x >= src_image->width ||
897 rect->x + rect->width > src_image->width ||
898 rect->y >= src_image->height ||
899 rect->y + rect->height > src_image->height)
905 default_rect.width = src_image->width;
906 default_rect.height = src_image->height;
907 rect = &default_rect;
910 switch (dst_image->format) {
911 case GST_VIDEO_FORMAT_NV12:
912 copy_image_NV12(dst_image, src_image, rect);
914 case GST_VIDEO_FORMAT_YV12:
915 case GST_VIDEO_FORMAT_I420:
916 copy_image_YV12(dst_image, src_image, rect);
918 case GST_VIDEO_FORMAT_YUY2:
919 case GST_VIDEO_FORMAT_UYVY:
920 copy_image_YUY2(dst_image, src_image, rect);
922 case GST_VIDEO_FORMAT_ARGB:
923 case GST_VIDEO_FORMAT_RGBA:
924 case GST_VIDEO_FORMAT_ABGR:
925 case GST_VIDEO_FORMAT_BGRA:
926 copy_image_RGBA(dst_image, src_image, rect);
929 GST_ERROR("unsupported image format for copy");
936 * gst_vaapi_image_get_buffer:
937 * @image: a #GstVaapiImage
938 * @buffer: a #GstBuffer
939 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
942 * Transfers pixels data contained in the @image into the #GstBuffer.
943 * Both image structures shall have the same format.
945 * Return value: %TRUE on success
948 gst_vaapi_image_get_buffer(
949 GstVaapiImage *image,
951 GstVaapiRectangle *rect
954 GstVaapiImageRaw dst_image, src_image;
957 g_return_val_if_fail(image != NULL, FALSE);
958 g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
960 if (!init_image_from_buffer(&dst_image, buffer))
962 if (dst_image.format != image->format)
964 if (dst_image.width != image->width || dst_image.height != image->height)
967 if (!_gst_vaapi_image_map(image, &src_image))
970 success = copy_image(&dst_image, &src_image, rect);
972 if (!_gst_vaapi_image_unmap(image))
979 * gst_vaapi_image_get_raw:
980 * @image: a #GstVaapiImage
981 * @dst_image: a #GstVaapiImageRaw
982 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
985 * Transfers pixels data contained in the @image into the #GstVaapiImageRaw.
986 * Both image structures shall have the same format.
988 * Return value: %TRUE on success
991 gst_vaapi_image_get_raw(
992 GstVaapiImage *image,
993 GstVaapiImageRaw *dst_image,
994 GstVaapiRectangle *rect
997 GstVaapiImageRaw src_image;
1000 g_return_val_if_fail(image != NULL, FALSE);
1002 if (!_gst_vaapi_image_map(image, &src_image))
1005 success = copy_image(dst_image, &src_image, rect);
1007 if (!_gst_vaapi_image_unmap(image))
1014 * gst_vaapi_image_update_from_buffer:
1015 * @image: a #GstVaapiImage
1016 * @buffer: a #GstBuffer
1017 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
1020 * Transfers pixels data contained in the #GstBuffer into the
1021 * @image. Both image structures shall have the same format.
1023 * Return value: %TRUE on success
1026 gst_vaapi_image_update_from_buffer(
1027 GstVaapiImage *image,
1029 GstVaapiRectangle *rect
1032 GstVaapiImageRaw dst_image, src_image;
1035 g_return_val_if_fail(image != NULL, FALSE);
1036 g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
1038 if (!init_image_from_buffer(&src_image, buffer))
1040 if (src_image.format != image->format)
1042 if (src_image.width != image->width || src_image.height != image->height)
1045 if (!_gst_vaapi_image_map(image, &dst_image))
1048 success = copy_image(&dst_image, &src_image, rect);
1050 if (!_gst_vaapi_image_unmap(image))
1057 * gst_vaapi_image_update_from_raw:
1058 * @image: a #GstVaapiImage
1059 * @src_image: a #GstVaapiImageRaw
1060 * @buffer: a #GstBuffer
1061 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
1064 * Transfers pixels data contained in the #GstVaapiImageRaw into the
1065 * @image. Both image structures shall have the same format.
1067 * Return value: %TRUE on success
1070 gst_vaapi_image_update_from_raw(
1071 GstVaapiImage *image,
1072 GstVaapiImageRaw *src_image,
1073 GstVaapiRectangle *rect
1076 GstVaapiImageRaw dst_image;
1079 g_return_val_if_fail(image != NULL, FALSE);
1081 if (!_gst_vaapi_image_map(image, &dst_image))
1084 success = copy_image(&dst_image, src_image, rect);
1086 if (!_gst_vaapi_image_unmap(image))
1093 * gst_vaapi_image_copy:
1094 * @dst_image: the target #GstVaapiImage
1095 * @src_image: the source #GstVaapiImage
1097 * Copies pixels data from @src_image to @dst_image. Both images shall
1098 * have the same format and size.
1100 * Return value: %TRUE on success
1103 gst_vaapi_image_copy(GstVaapiImage *dst_image, GstVaapiImage *src_image)
1105 GstVaapiImageRaw dst_image_raw, src_image_raw;
1106 gboolean success = FALSE;
1108 g_return_val_if_fail(dst_image != NULL, FALSE);
1109 g_return_val_if_fail(src_image != NULL, FALSE);
1111 if (!_gst_vaapi_image_map(dst_image, &dst_image_raw))
1113 if (!_gst_vaapi_image_map(src_image, &src_image_raw))
1116 success = copy_image(&dst_image_raw, &src_image_raw, NULL);
1119 _gst_vaapi_image_unmap(src_image);
1120 _gst_vaapi_image_unmap(dst_image);