2 * gstvaapiimage.c - VA image abstraction
4 * Copyright (C) 2010-2011 Splitted-Desktop Systems
5 * Copyright (C) 2011-2012 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:gstvaapiimage
25 * @short_description: VA image abstraction
30 #include "gstvaapicompat.h"
31 #include "gstvaapiutils.h"
32 #include "gstvaapiimage.h"
33 #include "gstvaapiobject_priv.h"
36 #include "gstvaapidebug.h"
38 typedef struct _GstVaapiImageClass GstVaapiImageClass;
45 struct _GstVaapiImage {
47 GstVaapiObject parent_instance;
49 VAImage internal_image;
52 GstVideoFormat internal_format;
53 GstVideoFormat format;
62 * A VA image wrapper class
64 struct _GstVaapiImageClass {
66 GstVaapiObjectClass parent_class;
69 #define SWAP_UINT(a, b) do { \
76 _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image);
79 _gst_vaapi_image_unmap(GstVaapiImage *image);
82 _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image);
89 vaapi_image_is_linear(const VAImage *va_image)
91 guint i, width, height, width2, height2, data_size;
93 for (i = 1; i < va_image->num_planes; i++)
94 if (va_image->offsets[i] < va_image->offsets[i - 1])
97 width = va_image->width;
98 height = va_image->height;
99 width2 = (width + 1) / 2;
100 height2 = (height + 1) / 2;
102 switch (va_image->format.fourcc) {
103 case VA_FOURCC('N','V','1','2'):
104 case VA_FOURCC('Y','V','1','2'):
105 case VA_FOURCC('I','4','2','0'):
106 data_size = width * height + 2 * width2 * height2;
108 case VA_FOURCC('Y','U','Y','2'):
109 case VA_FOURCC('U','Y','V','Y'):
110 data_size = 2 * width * height;
112 case VA_FOURCC('Y','8','0','0'):
113 data_size = width * height;
115 case VA_FOURCC('A','Y','U','V'):
116 case VA_FOURCC('A','R','G','B'):
117 case VA_FOURCC('R','G','B','A'):
118 case VA_FOURCC('A','B','G','R'):
119 case VA_FOURCC('B','G','R','A'):
120 case VA_FOURCC('X','R','G','B'):
121 case VA_FOURCC('R','G','B','X'):
122 case VA_FOURCC('X','B','G','R'):
123 case VA_FOURCC('B','G','R','X'):
124 data_size = 4 * width * height;
127 g_error("FIXME: incomplete formats %" GST_FOURCC_FORMAT,
128 GST_FOURCC_ARGS(va_image->format.fourcc));
131 return va_image->data_size == data_size;
135 gst_vaapi_image_destroy(GstVaapiImage *image)
137 GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
141 _gst_vaapi_image_unmap(image);
143 image_id = GST_VAAPI_OBJECT_ID(image);
144 GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
146 if (image_id != VA_INVALID_ID) {
147 GST_VAAPI_DISPLAY_LOCK(display);
148 status = vaDestroyImage(GST_VAAPI_DISPLAY_VADISPLAY(display), image_id);
149 GST_VAAPI_DISPLAY_UNLOCK(display);
150 if (!vaapi_check_status(status, "vaDestroyImage()"))
151 g_warning("failed to destroy image %" GST_VAAPI_ID_FORMAT,
152 GST_VAAPI_ID_ARGS(image_id));
153 GST_VAAPI_OBJECT_ID(image) = VA_INVALID_ID;
158 _gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format)
160 GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
161 const VAImageFormat *va_format;
164 if (!gst_vaapi_display_has_image_format(display, format))
167 va_format = gst_vaapi_video_format_to_va_format(format);
171 GST_VAAPI_DISPLAY_LOCK(display);
172 status = vaCreateImage(
173 GST_VAAPI_DISPLAY_VADISPLAY(display),
174 (VAImageFormat *)va_format,
177 &image->internal_image
179 GST_VAAPI_DISPLAY_UNLOCK(display);
180 if (status != VA_STATUS_SUCCESS ||
181 image->internal_image.format.fourcc != va_format->fourcc)
184 image->internal_format = format;
189 gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format,
190 guint width, guint height)
192 const VAImageFormat *va_format;
195 image->format = format;
196 image->width = width;
197 image->height = height;
199 if (!_gst_vaapi_image_create(image, format)) {
201 case GST_VIDEO_FORMAT_I420:
202 format = GST_VIDEO_FORMAT_YV12;
204 case GST_VIDEO_FORMAT_YV12:
205 format = GST_VIDEO_FORMAT_I420;
211 if (!format || !_gst_vaapi_image_create(image, format))
214 image->image = image->internal_image;
215 image_id = image->image.image_id;
217 if (image->format != image->internal_format) {
218 switch (image->format) {
219 case GST_VIDEO_FORMAT_YV12:
220 case GST_VIDEO_FORMAT_I420:
221 va_format = gst_vaapi_video_format_to_va_format(image->format);
224 image->image.format = *va_format;
225 SWAP_UINT(image->image.offsets[1], image->image.offsets[2]);
226 SWAP_UINT(image->image.pitches[1], image->image.pitches[2]);
232 image->is_linear = vaapi_image_is_linear(&image->image);
234 GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
235 GST_VAAPI_OBJECT_ID(image) = image_id;
240 gst_vaapi_image_init(GstVaapiImage *image)
242 image->internal_image.image_id = VA_INVALID_ID;
243 image->internal_image.buf = VA_INVALID_ID;
244 image->image.image_id = VA_INVALID_ID;
245 image->image.buf = VA_INVALID_ID;
249 gst_vaapi_image_class_init(GstVaapiImageClass *klass)
251 GstVaapiObjectClass * const object_class =
252 GST_VAAPI_OBJECT_CLASS(klass);
254 object_class->init = (GstVaapiObjectInitFunc)gst_vaapi_image_init;
257 #define gst_vaapi_image_finalize gst_vaapi_image_destroy
258 GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(
261 gst_vaapi_image_class_init(&g_class))
264 * gst_vaapi_image_new:
265 * @display: a #GstVaapiDisplay
266 * @format: a #GstVideoFormat
267 * @width: the requested image width
268 * @height: the requested image height
270 * Creates a new #GstVaapiImage with the specified format and
273 * Return value: the newly allocated #GstVaapiImage object
277 GstVaapiDisplay *display,
278 GstVideoFormat format,
283 GstVaapiImage *image;
285 g_return_val_if_fail(width > 0, NULL);
286 g_return_val_if_fail(height > 0, NULL);
288 GST_DEBUG("format %s, size %ux%u", gst_vaapi_video_format_to_string(format),
291 image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
295 if (!gst_vaapi_image_create(image, format, width, height))
300 gst_vaapi_object_unref(image);
305 * gst_vaapi_image_new_with_image:
306 * @display: a #GstVaapiDisplay
307 * @va_image: a VA image
309 * Creates a new #GstVaapiImage from a foreign VA image. The image
310 * format and dimensions will be extracted from @va_image. This
311 * function is mainly used by gst_vaapi_surface_derive_image() to bind
312 * a VA image to a #GstVaapiImage object.
314 * Return value: the newly allocated #GstVaapiImage object
317 gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image)
319 GstVaapiImage *image;
321 g_return_val_if_fail(va_image, NULL);
322 g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL);
323 g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL);
325 GST_DEBUG("VA image 0x%08x, format %" GST_FOURCC_FORMAT ", size %ux%u",
327 GST_FOURCC_ARGS(va_image->format.fourcc),
328 va_image->width, va_image->height);
330 image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
334 if (!_gst_vaapi_image_set_image(image, va_image))
339 gst_vaapi_object_unref(image);
344 * gst_vaapi_image_get_id:
345 * @image: a #GstVaapiImage
347 * Returns the underlying VAImageID of the @image.
349 * Return value: the underlying VA image id
352 gst_vaapi_image_get_id(GstVaapiImage *image)
354 g_return_val_if_fail(image != NULL, VA_INVALID_ID);
356 return GST_VAAPI_OBJECT_ID(image);
360 * gst_vaapi_image_get_image:
361 * @image: a #GstVaapiImage
362 * @va_image: a VA image
364 * Fills @va_image with the VA image used internally.
366 * Return value: %TRUE on success
369 gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image)
371 g_return_val_if_fail(image != NULL, FALSE);
374 *va_image = image->image;
380 * _gst_vaapi_image_set_image:
381 * @image: a #GstVaapiImage
382 * @va_image: a VA image
384 * Initializes #GstVaapiImage with a foreign VA image. This function
385 * will try to "linearize" the VA image. i.e. making sure that the VA
386 * image offsets into the data buffer are in increasing order with the
387 * number of planes available in the image.
389 * This is an internal function used by gst_vaapi_image_new_with_image().
391 * Return value: %TRUE on success
394 _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image)
396 GstVideoFormat format;
397 VAImage alt_va_image;
398 const VAImageFormat *alt_va_format;
400 format = gst_vaapi_video_format_from_va_format(&va_image->format);
401 if (format == GST_VIDEO_FORMAT_UNKNOWN)
404 image->internal_image = *va_image;
405 image->internal_format = format;
406 image->is_linear = vaapi_image_is_linear(va_image);
407 image->image = *va_image;
408 image->format = format;
409 image->width = va_image->width;
410 image->height = va_image->height;
412 GST_VAAPI_OBJECT_ID(image) = va_image->image_id;
414 /* Try to linearize image */
415 if (!image->is_linear) {
417 case GST_VIDEO_FORMAT_I420:
418 format = GST_VIDEO_FORMAT_YV12;
420 case GST_VIDEO_FORMAT_YV12:
421 format = GST_VIDEO_FORMAT_I420;
428 (alt_va_format = gst_vaapi_video_format_to_va_format(format))) {
429 alt_va_image = *va_image;
430 alt_va_image.format = *alt_va_format;
431 SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]);
432 SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]);
433 if (vaapi_image_is_linear(&alt_va_image)) {
434 image->image = alt_va_image;
435 image->format = format;
436 image->is_linear = TRUE;
437 GST_DEBUG("linearized image to %s format",
438 gst_vaapi_video_format_to_string(format));
446 * gst_vaapi_image_get_format:
447 * @image: a #GstVaapiImage
449 * Returns the #GstVideoFormat the @image was created with.
451 * Return value: the #GstVideoFormat
454 gst_vaapi_image_get_format(GstVaapiImage *image)
456 g_return_val_if_fail(image != NULL, 0);
458 return image->format;
462 * gst_vaapi_image_get_width:
463 * @image: a #GstVaapiImage
465 * Returns the @image width.
467 * Return value: the image width, in pixels
470 gst_vaapi_image_get_width(GstVaapiImage *image)
472 g_return_val_if_fail(image != NULL, 0);
478 * gst_vaapi_image_get_height:
479 * @image: a #GstVaapiImage
481 * Returns the @image height.
483 * Return value: the image height, in pixels.
486 gst_vaapi_image_get_height(GstVaapiImage *image)
488 g_return_val_if_fail(image != NULL, 0);
490 return image->height;
494 * gst_vaapi_image_get_size:
495 * @image: a #GstVaapiImage
496 * @pwidth: return location for the width, or %NULL
497 * @pheight: return location for the height, or %NULL
499 * Retrieves the dimensions of a #GstVaapiImage.
502 gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight)
504 g_return_if_fail(image != NULL);
507 *pwidth = image->width;
510 *pheight = image->height;
514 * gst_vaapi_image_is_linear:
515 * @image: a #GstVaapiImage
517 * Checks whether the @image has data planes allocated from a single
518 * buffer and offsets into that buffer are in increasing order with
519 * the number of planes.
521 * Return value: %TRUE if image data planes are allocated from a single buffer
524 gst_vaapi_image_is_linear(GstVaapiImage *image)
526 g_return_val_if_fail(image != NULL, FALSE);
528 return image->is_linear;
532 * gst_vaapi_image_is_mapped:
533 * @image: a #GstVaapiImage
535 * Checks whether the @image is currently mapped or not.
537 * Return value: %TRUE if the @image is mapped
539 static inline gboolean
540 _gst_vaapi_image_is_mapped(GstVaapiImage *image)
542 return image->image_data != NULL;
546 gst_vaapi_image_is_mapped(GstVaapiImage *image)
548 g_return_val_if_fail(image != NULL, FALSE);
550 return _gst_vaapi_image_is_mapped(image);
554 * gst_vaapi_image_map:
555 * @image: a #GstVaapiImage
557 * Maps the image data buffer. The actual pixels are returned by the
558 * gst_vaapi_image_get_plane() function.
560 * Return value: %TRUE on success
563 gst_vaapi_image_map(GstVaapiImage *image)
565 g_return_val_if_fail(image != NULL, FALSE);
567 return _gst_vaapi_image_map(image, NULL);
571 _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image)
573 GstVaapiDisplay *display;
577 if (_gst_vaapi_image_is_mapped(image))
580 display = GST_VAAPI_OBJECT_DISPLAY(image);
584 GST_VAAPI_DISPLAY_LOCK(display);
585 status = vaMapBuffer(
586 GST_VAAPI_DISPLAY_VADISPLAY(display),
588 (void **)&image->image_data
590 GST_VAAPI_DISPLAY_UNLOCK(display);
591 if (!vaapi_check_status(status, "vaMapBuffer()"))
596 const VAImage * const va_image = &image->image;
597 raw_image->format = image->format;
598 raw_image->width = va_image->width;
599 raw_image->height = va_image->height;
600 raw_image->num_planes = va_image->num_planes;
601 for (i = 0; i < raw_image->num_planes; i++) {
602 raw_image->pixels[i] = (guchar *)image->image_data +
603 va_image->offsets[i];
604 raw_image->stride[i] = va_image->pitches[i];
611 * gst_vaapi_image_unmap:
612 * @image: a #GstVaapiImage
614 * Unmaps the image data buffer. Pointers to pixels returned by
615 * gst_vaapi_image_get_plane() are then no longer valid.
617 * Return value: %TRUE on success
620 gst_vaapi_image_unmap(GstVaapiImage *image)
622 g_return_val_if_fail(image != NULL, FALSE);
624 return _gst_vaapi_image_unmap(image);
628 _gst_vaapi_image_unmap(GstVaapiImage *image)
630 GstVaapiDisplay *display;
633 if (!_gst_vaapi_image_is_mapped(image))
636 display = GST_VAAPI_OBJECT_DISPLAY(image);
640 GST_VAAPI_DISPLAY_LOCK(display);
641 status = vaUnmapBuffer(
642 GST_VAAPI_DISPLAY_VADISPLAY(display),
645 GST_VAAPI_DISPLAY_UNLOCK(display);
646 if (!vaapi_check_status(status, "vaUnmapBuffer()"))
649 image->image_data = NULL;
654 * gst_vaapi_image_get_plane_count:
655 * @image: a #GstVaapiImage
657 * Retrieves the number of planes available in the @image. The @image
658 * must be mapped for this function to work properly.
660 * Return value: the number of planes available in the @image
663 gst_vaapi_image_get_plane_count(GstVaapiImage *image)
665 g_return_val_if_fail(image != NULL, 0);
666 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
668 return image->image.num_planes;
672 * gst_vaapi_image_get_plane:
673 * @image: a #GstVaapiImage
674 * @plane: the requested plane number
676 * Retrieves the pixels data to the specified @plane. The @image must
677 * be mapped for this function to work properly.
679 * Return value: the pixels data of the specified @plane
682 gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane)
684 g_return_val_if_fail(image != NULL, NULL);
685 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL);
686 g_return_val_if_fail(plane < image->image.num_planes, NULL);
688 return image->image_data + image->image.offsets[plane];
692 * gst_vaapi_image_get_pitch:
693 * @image: a #GstVaapiImage
694 * @plane: the requested plane number
696 * Retrieves the line size (stride) of the specified @plane. The
697 * @image must be mapped for this function to work properly.
699 * Return value: the line size (stride) of the specified plane
702 gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane)
704 g_return_val_if_fail(image != NULL, 0);
705 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
706 g_return_val_if_fail(plane < image->image.num_planes, 0);
708 return image->image.pitches[plane];
712 * gst_vaapi_image_get_data_size:
713 * @image: a #GstVaapiImage
715 * Retrieves the underlying image data size. This function could be
716 * used to determine whether the image has a compatible layout with
717 * another image structure.
719 * Return value: the whole image data size of the @image
722 gst_vaapi_image_get_data_size(GstVaapiImage *image)
724 g_return_val_if_fail(image != NULL, 0);
726 return image->image.data_size;
729 #if GST_CHECK_VERSION(1,0,0)
730 #include <gst/video/gstvideometa.h>
733 init_image_from_video_meta(GstVaapiImageRaw *raw_image, GstVideoMeta *vmeta)
735 GST_FIXME("map from GstVideoMeta + add fini_image_from_buffer()");
740 init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer)
742 GstVideoMeta * const vmeta = gst_buffer_get_video_meta(buffer);
744 return vmeta ? init_image_from_video_meta(raw_image, vmeta) : FALSE;
748 init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer)
756 data = GST_BUFFER_DATA(buffer);
757 data_size = GST_BUFFER_SIZE(buffer);
758 caps = GST_BUFFER_CAPS(buffer);
763 if (!gst_video_info_from_caps(&vi, caps))
764 goto error_unsupported_caps;
766 /* Check for compatible data size */
767 frame_size = GST_VIDEO_INFO_SIZE(&vi);
768 if (frame_size != data_size)
769 goto error_incompatible_size;
771 raw_image->format = GST_VIDEO_INFO_FORMAT(&vi);
772 raw_image->width = GST_VIDEO_INFO_WIDTH(&vi);
773 raw_image->height = GST_VIDEO_INFO_HEIGHT(&vi);
775 raw_image->num_planes = GST_VIDEO_INFO_N_PLANES(&vi);
776 for (i = 0; i < raw_image->num_planes; i++) {
777 raw_image->pixels[i] = data + GST_VIDEO_INFO_PLANE_OFFSET(&vi, i);
778 raw_image->stride[i] = GST_VIDEO_INFO_PLANE_STRIDE(&vi, i);
783 error_unsupported_caps:
784 GST_ERROR("unsupported caps %" GST_PTR_FORMAT, caps);
786 error_incompatible_size:
787 GST_ERROR("incompatible frame size (%u) with buffer size (%u)",
788 frame_size, data_size);
793 /* Copy N lines of an image */
806 for (i = 0; i < height; i++) {
807 memcpy(dst, src, len);
813 /* Copy NV12 images */
816 GstVaapiImageRaw *dst_image,
817 GstVaapiImageRaw *src_image,
818 const GstVaapiRectangle *rect
822 guint dst_stride, src_stride;
825 dst_stride = dst_image->stride[0];
826 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
827 src_stride = src_image->stride[0];
828 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
829 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height);
832 dst_stride = dst_image->stride[1];
833 dst = dst_image->pixels[1] + (rect->y / 2) * dst_stride + (rect->x & -2);
834 src_stride = src_image->stride[1];
835 src = src_image->pixels[1] + (rect->y / 2) * src_stride + (rect->x & -2);
836 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height / 2);
839 /* Copy YV12 images */
842 GstVaapiImageRaw *dst_image,
843 GstVaapiImageRaw *src_image,
844 const GstVaapiRectangle *rect
848 guint dst_stride, src_stride;
852 dst_stride = dst_image->stride[0];
853 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
854 src_stride = src_image->stride[0];
855 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
856 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height);
862 h = rect->height / 2;
863 for (i = 1; i < dst_image->num_planes; i++) {
864 dst_stride = dst_image->stride[i];
865 dst = dst_image->pixels[i] + y * dst_stride + x;
866 src_stride = src_image->stride[i];
867 src = src_image->pixels[i] + y * src_stride + x;
868 memcpy_pic(dst, dst_stride, src, src_stride, w, h);
872 /* Copy YUY2 images */
875 GstVaapiImageRaw *dst_image,
876 GstVaapiImageRaw *src_image,
877 const GstVaapiRectangle *rect
881 guint dst_stride, src_stride;
883 /* YUV 4:2:2, full vertical resolution */
884 dst_stride = dst_image->stride[0];
885 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x * 2;
886 src_stride = src_image->stride[0];
887 src = src_image->pixels[0] + rect->y * src_stride + rect->x * 2;
888 memcpy_pic(dst, dst_stride, src, src_stride, rect->width * 2, rect->height);
891 /* Copy RGBA images */
894 GstVaapiImageRaw *dst_image,
895 GstVaapiImageRaw *src_image,
896 const GstVaapiRectangle *rect
900 guint dst_stride, src_stride;
902 dst_stride = dst_image->stride[0];
903 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
904 src_stride = src_image->stride[0];
905 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
906 memcpy_pic(dst, dst_stride, src, src_stride, 4 * rect->width, rect->height);
911 GstVaapiImageRaw *dst_image,
912 GstVaapiImageRaw *src_image,
913 const GstVaapiRectangle *rect
916 GstVaapiRectangle default_rect;
918 if (dst_image->format != src_image->format ||
919 dst_image->width != src_image->width ||
920 dst_image->height != src_image->height)
924 if (rect->x >= src_image->width ||
925 rect->x + rect->width > src_image->width ||
926 rect->y >= src_image->height ||
927 rect->y + rect->height > src_image->height)
933 default_rect.width = src_image->width;
934 default_rect.height = src_image->height;
935 rect = &default_rect;
938 switch (dst_image->format) {
939 case GST_VIDEO_FORMAT_NV12:
940 copy_image_NV12(dst_image, src_image, rect);
942 case GST_VIDEO_FORMAT_YV12:
943 case GST_VIDEO_FORMAT_I420:
944 copy_image_YV12(dst_image, src_image, rect);
946 case GST_VIDEO_FORMAT_YUY2:
947 case GST_VIDEO_FORMAT_UYVY:
948 copy_image_YUY2(dst_image, src_image, rect);
950 case GST_VIDEO_FORMAT_ARGB:
951 case GST_VIDEO_FORMAT_RGBA:
952 case GST_VIDEO_FORMAT_ABGR:
953 case GST_VIDEO_FORMAT_BGRA:
954 copy_image_RGBA(dst_image, src_image, rect);
957 GST_ERROR("unsupported image format for copy");
964 * gst_vaapi_image_get_buffer:
965 * @image: a #GstVaapiImage
966 * @buffer: a #GstBuffer
967 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
970 * Transfers pixels data contained in the @image into the #GstBuffer.
971 * Both image structures shall have the same format.
973 * Return value: %TRUE on success
976 gst_vaapi_image_get_buffer(
977 GstVaapiImage *image,
979 GstVaapiRectangle *rect
982 GstVaapiImageRaw dst_image, src_image;
985 g_return_val_if_fail(image != NULL, FALSE);
986 g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
988 if (!init_image_from_buffer(&dst_image, buffer))
990 if (dst_image.format != image->format)
992 if (dst_image.width != image->width || dst_image.height != image->height)
995 if (!_gst_vaapi_image_map(image, &src_image))
998 success = copy_image(&dst_image, &src_image, rect);
1000 if (!_gst_vaapi_image_unmap(image))
1007 * gst_vaapi_image_get_raw:
1008 * @image: a #GstVaapiImage
1009 * @dst_image: a #GstVaapiImageRaw
1010 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
1013 * Transfers pixels data contained in the @image into the #GstVaapiImageRaw.
1014 * Both image structures shall have the same format.
1016 * Return value: %TRUE on success
1019 gst_vaapi_image_get_raw(
1020 GstVaapiImage *image,
1021 GstVaapiImageRaw *dst_image,
1022 GstVaapiRectangle *rect
1025 GstVaapiImageRaw src_image;
1028 g_return_val_if_fail(image != NULL, FALSE);
1030 if (!_gst_vaapi_image_map(image, &src_image))
1033 success = copy_image(dst_image, &src_image, rect);
1035 if (!_gst_vaapi_image_unmap(image))
1042 * gst_vaapi_image_update_from_buffer:
1043 * @image: a #GstVaapiImage
1044 * @buffer: a #GstBuffer
1045 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
1048 * Transfers pixels data contained in the #GstBuffer into the
1049 * @image. Both image structures shall have the same format.
1051 * Return value: %TRUE on success
1054 gst_vaapi_image_update_from_buffer(
1055 GstVaapiImage *image,
1057 GstVaapiRectangle *rect
1060 GstVaapiImageRaw dst_image, src_image;
1063 g_return_val_if_fail(image != NULL, FALSE);
1064 g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
1066 if (!init_image_from_buffer(&src_image, buffer))
1068 if (src_image.format != image->format)
1070 if (src_image.width != image->width || src_image.height != image->height)
1073 if (!_gst_vaapi_image_map(image, &dst_image))
1076 success = copy_image(&dst_image, &src_image, rect);
1078 if (!_gst_vaapi_image_unmap(image))
1085 * gst_vaapi_image_update_from_raw:
1086 * @image: a #GstVaapiImage
1087 * @src_image: a #GstVaapiImageRaw
1088 * @buffer: a #GstBuffer
1089 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
1092 * Transfers pixels data contained in the #GstVaapiImageRaw into the
1093 * @image. Both image structures shall have the same format.
1095 * Return value: %TRUE on success
1098 gst_vaapi_image_update_from_raw(
1099 GstVaapiImage *image,
1100 GstVaapiImageRaw *src_image,
1101 GstVaapiRectangle *rect
1104 GstVaapiImageRaw dst_image;
1107 g_return_val_if_fail(image != NULL, FALSE);
1109 if (!_gst_vaapi_image_map(image, &dst_image))
1112 success = copy_image(&dst_image, src_image, rect);
1114 if (!_gst_vaapi_image_unmap(image))