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('A','Y','U','V'):
109 case VA_FOURCC('A','R','G','B'):
110 case VA_FOURCC('R','G','B','A'):
111 case VA_FOURCC('A','B','G','R'):
112 case VA_FOURCC('B','G','R','A'):
113 data_size = 4 * width * height;
116 g_error("FIXME: incomplete formats");
119 return va_image->data_size == data_size;
123 gst_vaapi_image_destroy(GstVaapiImage *image)
125 GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
129 _gst_vaapi_image_unmap(image);
131 image_id = GST_VAAPI_OBJECT_ID(image);
132 GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
134 if (image_id != VA_INVALID_ID) {
135 GST_VAAPI_DISPLAY_LOCK(display);
136 status = vaDestroyImage(GST_VAAPI_DISPLAY_VADISPLAY(display), image_id);
137 GST_VAAPI_DISPLAY_UNLOCK(display);
138 if (!vaapi_check_status(status, "vaDestroyImage()"))
139 g_warning("failed to destroy image %" GST_VAAPI_ID_FORMAT,
140 GST_VAAPI_ID_ARGS(image_id));
141 GST_VAAPI_OBJECT_ID(image) = VA_INVALID_ID;
146 _gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format)
148 GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
149 const VAImageFormat *va_format;
152 if (!gst_vaapi_display_has_image_format(display, format))
155 va_format = gst_video_format_to_va_format(format);
159 GST_VAAPI_DISPLAY_LOCK(display);
160 status = vaCreateImage(
161 GST_VAAPI_DISPLAY_VADISPLAY(display),
162 (VAImageFormat *)va_format,
165 &image->internal_image
167 GST_VAAPI_DISPLAY_UNLOCK(display);
168 if (status != VA_STATUS_SUCCESS ||
169 image->internal_image.format.fourcc != va_format->fourcc)
172 image->internal_format = format;
177 gst_vaapi_image_create(GstVaapiImage *image, GstVideoFormat format,
178 guint width, guint height)
180 const VAImageFormat *va_format;
183 image->format = format;
184 image->width = width;
185 image->height = height;
187 if (!_gst_vaapi_image_create(image, format)) {
189 case GST_VIDEO_FORMAT_I420:
190 format = GST_VIDEO_FORMAT_YV12;
192 case GST_VIDEO_FORMAT_YV12:
193 format = GST_VIDEO_FORMAT_I420;
199 if (!format || !_gst_vaapi_image_create(image, format))
202 image->image = image->internal_image;
203 image_id = image->image.image_id;
205 if (image->format != image->internal_format) {
206 switch (image->format) {
207 case GST_VIDEO_FORMAT_YV12:
208 case GST_VIDEO_FORMAT_I420:
209 va_format = gst_video_format_to_va_format(image->format);
212 image->image.format = *va_format;
213 SWAP_UINT(image->image.offsets[1], image->image.offsets[2]);
214 SWAP_UINT(image->image.pitches[1], image->image.pitches[2]);
220 image->is_linear = vaapi_image_is_linear(&image->image);
222 GST_DEBUG("image %" GST_VAAPI_ID_FORMAT, GST_VAAPI_ID_ARGS(image_id));
223 GST_VAAPI_OBJECT_ID(image) = image_id;
228 gst_vaapi_image_init(GstVaapiImage *image)
230 image->internal_image.image_id = VA_INVALID_ID;
231 image->internal_image.buf = VA_INVALID_ID;
232 image->image.image_id = VA_INVALID_ID;
233 image->image.buf = VA_INVALID_ID;
237 gst_vaapi_image_class_init(GstVaapiImageClass *klass)
239 GstVaapiObjectClass * const object_class =
240 GST_VAAPI_OBJECT_CLASS(klass);
242 object_class->init = (GstVaapiObjectInitFunc)gst_vaapi_image_init;
245 #define gst_vaapi_image_finalize gst_vaapi_image_destroy
246 GST_VAAPI_OBJECT_DEFINE_CLASS_WITH_CODE(
249 gst_vaapi_image_class_init(&g_class))
252 * gst_vaapi_image_new:
253 * @display: a #GstVaapiDisplay
254 * @format: a #GstVideoFormat
255 * @width: the requested image width
256 * @height: the requested image height
258 * Creates a new #GstVaapiImage with the specified format and
261 * Return value: the newly allocated #GstVaapiImage object
265 GstVaapiDisplay *display,
266 GstVideoFormat format,
271 GstVaapiImage *image;
273 g_return_val_if_fail(width > 0, NULL);
274 g_return_val_if_fail(height > 0, NULL);
276 GST_DEBUG("format %s, size %ux%u", gst_video_format_to_string(format),
279 image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
283 if (!gst_vaapi_image_create(image, format, width, height))
288 gst_vaapi_object_unref(image);
293 * gst_vaapi_image_new_with_image:
294 * @display: a #GstVaapiDisplay
295 * @va_image: a VA image
297 * Creates a new #GstVaapiImage from a foreign VA image. The image
298 * format and dimensions will be extracted from @va_image. This
299 * function is mainly used by gst_vaapi_surface_derive_image() to bind
300 * a VA image to a #GstVaapiImage object.
302 * Return value: the newly allocated #GstVaapiImage object
305 gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image)
307 GstVaapiImage *image;
309 g_return_val_if_fail(va_image, NULL);
310 g_return_val_if_fail(va_image->image_id != VA_INVALID_ID, NULL);
311 g_return_val_if_fail(va_image->buf != VA_INVALID_ID, NULL);
313 GST_DEBUG("VA image 0x%08x, format %" GST_FOURCC_FORMAT ", size %ux%u",
315 GST_FOURCC_ARGS(va_image->format.fourcc),
316 va_image->width, va_image->height);
318 image = gst_vaapi_object_new(gst_vaapi_image_class(), display);
322 if (!_gst_vaapi_image_set_image(image, va_image))
327 gst_vaapi_object_unref(image);
332 * gst_vaapi_image_get_id:
333 * @image: a #GstVaapiImage
335 * Returns the underlying VAImageID of the @image.
337 * Return value: the underlying VA image id
340 gst_vaapi_image_get_id(GstVaapiImage *image)
342 g_return_val_if_fail(image != NULL, VA_INVALID_ID);
344 return GST_VAAPI_OBJECT_ID(image);
348 * gst_vaapi_image_get_image:
349 * @image: a #GstVaapiImage
350 * @va_image: a VA image
352 * Fills @va_image with the VA image used internally.
354 * Return value: %TRUE on success
357 gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image)
359 g_return_val_if_fail(image != NULL, FALSE);
362 *va_image = image->image;
368 * _gst_vaapi_image_set_image:
369 * @image: a #GstVaapiImage
370 * @va_image: a VA image
372 * Initializes #GstVaapiImage with a foreign VA image. This function
373 * will try to "linearize" the VA image. i.e. making sure that the VA
374 * image offsets into the data buffer are in increasing order with the
375 * number of planes available in the image.
377 * This is an internal function used by gst_vaapi_image_new_with_image().
379 * Return value: %TRUE on success
382 _gst_vaapi_image_set_image(GstVaapiImage *image, const VAImage *va_image)
384 GstVideoFormat format;
385 VAImage alt_va_image;
386 const VAImageFormat *alt_va_format;
388 format = gst_video_format_from_va_format(&va_image->format);
389 if (format == GST_VIDEO_FORMAT_UNKNOWN)
392 image->internal_image = *va_image;
393 image->internal_format = format;
394 image->is_linear = vaapi_image_is_linear(va_image);
395 image->image = *va_image;
396 image->format = format;
397 image->width = va_image->width;
398 image->height = va_image->height;
400 GST_VAAPI_OBJECT_ID(image) = va_image->image_id;
402 /* Try to linearize image */
403 if (!image->is_linear) {
405 case GST_VIDEO_FORMAT_I420:
406 format = GST_VIDEO_FORMAT_YV12;
408 case GST_VIDEO_FORMAT_YV12:
409 format = GST_VIDEO_FORMAT_I420;
416 (alt_va_format = gst_video_format_to_va_format(format))) {
417 alt_va_image = *va_image;
418 alt_va_image.format = *alt_va_format;
419 SWAP_UINT(alt_va_image.offsets[1], alt_va_image.offsets[2]);
420 SWAP_UINT(alt_va_image.pitches[1], alt_va_image.pitches[2]);
421 if (vaapi_image_is_linear(&alt_va_image)) {
422 image->image = alt_va_image;
423 image->format = format;
424 image->is_linear = TRUE;
425 GST_DEBUG("linearized image to %s format",
426 gst_video_format_to_string(format));
434 * gst_vaapi_image_get_format:
435 * @image: a #GstVaapiImage
437 * Returns the #GstVideoFormat the @image was created with.
439 * Return value: the #GstVideoFormat
442 gst_vaapi_image_get_format(GstVaapiImage *image)
444 g_return_val_if_fail(image != NULL, 0);
446 return image->format;
450 * gst_vaapi_image_get_width:
451 * @image: a #GstVaapiImage
453 * Returns the @image width.
455 * Return value: the image width, in pixels
458 gst_vaapi_image_get_width(GstVaapiImage *image)
460 g_return_val_if_fail(image != NULL, 0);
466 * gst_vaapi_image_get_height:
467 * @image: a #GstVaapiImage
469 * Returns the @image height.
471 * Return value: the image height, in pixels.
474 gst_vaapi_image_get_height(GstVaapiImage *image)
476 g_return_val_if_fail(image != NULL, 0);
478 return image->height;
482 * gst_vaapi_image_get_size:
483 * @image: a #GstVaapiImage
484 * @pwidth: return location for the width, or %NULL
485 * @pheight: return location for the height, or %NULL
487 * Retrieves the dimensions of a #GstVaapiImage.
490 gst_vaapi_image_get_size(GstVaapiImage *image, guint *pwidth, guint *pheight)
492 g_return_if_fail(image != NULL);
495 *pwidth = image->width;
498 *pheight = image->height;
502 * gst_vaapi_image_is_linear:
503 * @image: a #GstVaapiImage
505 * Checks whether the @image has data planes allocated from a single
506 * buffer and offsets into that buffer are in increasing order with
507 * the number of planes.
509 * Return value: %TRUE if image data planes are allocated from a single buffer
512 gst_vaapi_image_is_linear(GstVaapiImage *image)
514 g_return_val_if_fail(image != NULL, FALSE);
516 return image->is_linear;
520 * gst_vaapi_image_is_mapped:
521 * @image: a #GstVaapiImage
523 * Checks whether the @image is currently mapped or not.
525 * Return value: %TRUE if the @image is mapped
527 static inline gboolean
528 _gst_vaapi_image_is_mapped(GstVaapiImage *image)
530 return image->image_data != NULL;
534 gst_vaapi_image_is_mapped(GstVaapiImage *image)
536 g_return_val_if_fail(image != NULL, FALSE);
538 return _gst_vaapi_image_is_mapped(image);
542 * gst_vaapi_image_map:
543 * @image: a #GstVaapiImage
545 * Maps the image data buffer. The actual pixels are returned by the
546 * gst_vaapi_image_get_plane() function.
548 * Return value: %TRUE on success
551 gst_vaapi_image_map(GstVaapiImage *image)
553 g_return_val_if_fail(image != NULL, FALSE);
555 return _gst_vaapi_image_map(image, NULL);
559 _gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_image)
561 GstVaapiDisplay *display;
565 if (_gst_vaapi_image_is_mapped(image))
568 display = GST_VAAPI_OBJECT_DISPLAY(image);
572 GST_VAAPI_DISPLAY_LOCK(display);
573 status = vaMapBuffer(
574 GST_VAAPI_DISPLAY_VADISPLAY(display),
576 (void **)&image->image_data
578 GST_VAAPI_DISPLAY_UNLOCK(display);
579 if (!vaapi_check_status(status, "vaMapBuffer()"))
584 const VAImage * const va_image = &image->image;
585 raw_image->format = image->format;
586 raw_image->width = va_image->width;
587 raw_image->height = va_image->height;
588 raw_image->num_planes = va_image->num_planes;
589 for (i = 0; i < raw_image->num_planes; i++) {
590 raw_image->pixels[i] = (guchar *)image->image_data +
591 va_image->offsets[i];
592 raw_image->stride[i] = va_image->pitches[i];
599 * gst_vaapi_image_unmap:
600 * @image: a #GstVaapiImage
602 * Unmaps the image data buffer. Pointers to pixels returned by
603 * gst_vaapi_image_get_plane() are then no longer valid.
605 * Return value: %TRUE on success
608 gst_vaapi_image_unmap(GstVaapiImage *image)
610 g_return_val_if_fail(image != NULL, FALSE);
612 return _gst_vaapi_image_unmap(image);
616 _gst_vaapi_image_unmap(GstVaapiImage *image)
618 GstVaapiDisplay *display;
621 if (!_gst_vaapi_image_is_mapped(image))
624 display = GST_VAAPI_OBJECT_DISPLAY(image);
628 GST_VAAPI_DISPLAY_LOCK(display);
629 status = vaUnmapBuffer(
630 GST_VAAPI_DISPLAY_VADISPLAY(display),
633 GST_VAAPI_DISPLAY_UNLOCK(display);
634 if (!vaapi_check_status(status, "vaUnmapBuffer()"))
637 image->image_data = NULL;
642 * gst_vaapi_image_get_plane_count:
643 * @image: a #GstVaapiImage
645 * Retrieves the number of planes available in the @image. The @image
646 * must be mapped for this function to work properly.
648 * Return value: the number of planes available in the @image
651 gst_vaapi_image_get_plane_count(GstVaapiImage *image)
653 g_return_val_if_fail(image != NULL, 0);
654 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
656 return image->image.num_planes;
660 * gst_vaapi_image_get_plane:
661 * @image: a #GstVaapiImage
662 * @plane: the requested plane number
664 * Retrieves the pixels data to the specified @plane. The @image must
665 * be mapped for this function to work properly.
667 * Return value: the pixels data of the specified @plane
670 gst_vaapi_image_get_plane(GstVaapiImage *image, guint plane)
672 g_return_val_if_fail(image != NULL, NULL);
673 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), NULL);
674 g_return_val_if_fail(plane < image->image.num_planes, NULL);
676 return image->image_data + image->image.offsets[plane];
680 * gst_vaapi_image_get_pitch:
681 * @image: a #GstVaapiImage
682 * @plane: the requested plane number
684 * Retrieves the line size (stride) of the specified @plane. The
685 * @image must be mapped for this function to work properly.
687 * Return value: the line size (stride) of the specified plane
690 gst_vaapi_image_get_pitch(GstVaapiImage *image, guint plane)
692 g_return_val_if_fail(image != NULL, 0);
693 g_return_val_if_fail(_gst_vaapi_image_is_mapped(image), 0);
694 g_return_val_if_fail(plane < image->image.num_planes, 0);
696 return image->image.pitches[plane];
700 * gst_vaapi_image_get_data_size:
701 * @image: a #GstVaapiImage
703 * Retrieves the underlying image data size. This function could be
704 * used to determine whether the image has a compatible layout with
705 * another image structure.
707 * Return value: the whole image data size of the @image
710 gst_vaapi_image_get_data_size(GstVaapiImage *image)
712 g_return_val_if_fail(image != NULL, 0);
714 return image->image.data_size;
717 #if GST_CHECK_VERSION(1,0,0)
718 #include <gst/video/gstvideometa.h>
721 init_image_from_video_meta(GstVaapiImageRaw *raw_image, GstVideoMeta *vmeta)
723 GST_FIXME("map from GstVideoMeta + add fini_image_from_buffer()");
728 init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer)
730 GstVideoMeta * const vmeta = gst_buffer_get_video_meta(buffer);
732 return vmeta ? init_image_from_video_meta(raw_image, vmeta) : FALSE;
736 init_image_from_buffer(GstVaapiImageRaw *raw_image, GstBuffer *buffer)
744 data = GST_BUFFER_DATA(buffer);
745 data_size = GST_BUFFER_SIZE(buffer);
746 caps = GST_BUFFER_CAPS(buffer);
751 if (!gst_video_info_from_caps(&vi, caps))
752 goto error_unsupported_caps;
754 /* Check for compatible data size */
755 frame_size = GST_VIDEO_INFO_SIZE(&vi);
756 if (frame_size != data_size)
757 goto error_incompatible_size;
759 raw_image->format = GST_VIDEO_INFO_FORMAT(&vi);
760 raw_image->width = GST_VIDEO_INFO_WIDTH(&vi);
761 raw_image->height = GST_VIDEO_INFO_HEIGHT(&vi);
763 raw_image->num_planes = GST_VIDEO_INFO_N_PLANES(&vi);
764 for (i = 0; i < raw_image->num_planes; i++) {
765 raw_image->pixels[i] = data + GST_VIDEO_INFO_PLANE_OFFSET(&vi, i);
766 raw_image->stride[i] = GST_VIDEO_INFO_PLANE_STRIDE(&vi, i);
771 error_unsupported_caps:
772 GST_ERROR("unsupported caps %" GST_PTR_FORMAT, caps);
774 error_incompatible_size:
775 GST_ERROR("incompatible frame size (%u) with buffer size (%u)",
776 frame_size, data_size);
781 /* Copy N lines of an image */
794 for (i = 0; i < height; i++) {
795 memcpy(dst, src, len);
801 /* Copy NV12 images */
804 GstVaapiImageRaw *dst_image,
805 GstVaapiImageRaw *src_image,
806 const GstVaapiRectangle *rect
810 guint dst_stride, src_stride;
813 dst_stride = dst_image->stride[0];
814 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
815 src_stride = src_image->stride[0];
816 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
817 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height);
820 dst_stride = dst_image->stride[1];
821 dst = dst_image->pixels[1] + (rect->y / 2) * dst_stride + (rect->x & -2);
822 src_stride = src_image->stride[1];
823 src = src_image->pixels[1] + (rect->y / 2) * src_stride + (rect->x & -2);
824 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height / 2);
827 /* Copy YV12 images */
830 GstVaapiImageRaw *dst_image,
831 GstVaapiImageRaw *src_image,
832 const GstVaapiRectangle *rect
836 guint dst_stride, src_stride;
840 dst_stride = dst_image->stride[0];
841 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
842 src_stride = src_image->stride[0];
843 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
844 memcpy_pic(dst, dst_stride, src, src_stride, rect->width, rect->height);
850 h = rect->height / 2;
851 for (i = 1; i < dst_image->num_planes; i++) {
852 dst_stride = dst_image->stride[i];
853 dst = dst_image->pixels[i] + y * dst_stride + x;
854 src_stride = src_image->stride[i];
855 src = src_image->pixels[i] + y * src_stride + x;
856 memcpy_pic(dst, dst_stride, src, src_stride, w, h);
860 /* Copy RGBA images */
863 GstVaapiImageRaw *dst_image,
864 GstVaapiImageRaw *src_image,
865 const GstVaapiRectangle *rect
869 guint dst_stride, src_stride;
871 dst_stride = dst_image->stride[0];
872 dst = dst_image->pixels[0] + rect->y * dst_stride + rect->x;
873 src_stride = src_image->stride[0];
874 src = src_image->pixels[0] + rect->y * src_stride + rect->x;
875 memcpy_pic(dst, dst_stride, src, src_stride, 4 * rect->width, rect->height);
880 GstVaapiImageRaw *dst_image,
881 GstVaapiImageRaw *src_image,
882 const GstVaapiRectangle *rect
885 GstVaapiRectangle default_rect;
887 if (dst_image->format != src_image->format ||
888 dst_image->width != src_image->width ||
889 dst_image->height != src_image->height)
893 if (rect->x >= src_image->width ||
894 rect->x + rect->width > src_image->width ||
895 rect->y >= src_image->height ||
896 rect->y + rect->height > src_image->height)
902 default_rect.width = src_image->width;
903 default_rect.height = src_image->height;
904 rect = &default_rect;
907 switch (dst_image->format) {
908 case GST_VIDEO_FORMAT_NV12:
909 copy_image_NV12(dst_image, src_image, rect);
911 case GST_VIDEO_FORMAT_YV12:
912 case GST_VIDEO_FORMAT_I420:
913 copy_image_YV12(dst_image, src_image, rect);
915 case GST_VIDEO_FORMAT_ARGB:
916 case GST_VIDEO_FORMAT_RGBA:
917 case GST_VIDEO_FORMAT_ABGR:
918 case GST_VIDEO_FORMAT_BGRA:
919 copy_image_RGBA(dst_image, src_image, rect);
922 GST_ERROR("unsupported image format for copy");
929 * gst_vaapi_image_get_buffer:
930 * @image: a #GstVaapiImage
931 * @buffer: a #GstBuffer
932 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
935 * Transfers pixels data contained in the @image into the #GstBuffer.
936 * Both image structures shall have the same format.
938 * Return value: %TRUE on success
941 gst_vaapi_image_get_buffer(
942 GstVaapiImage *image,
944 GstVaapiRectangle *rect
947 GstVaapiImageRaw dst_image, src_image;
950 g_return_val_if_fail(image != NULL, FALSE);
951 g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
953 if (!init_image_from_buffer(&dst_image, buffer))
955 if (dst_image.format != image->format)
957 if (dst_image.width != image->width || dst_image.height != image->height)
960 if (!_gst_vaapi_image_map(image, &src_image))
963 success = copy_image(&dst_image, &src_image, rect);
965 if (!_gst_vaapi_image_unmap(image))
972 * gst_vaapi_image_get_raw:
973 * @image: a #GstVaapiImage
974 * @dst_image: a #GstVaapiImageRaw
975 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
978 * Transfers pixels data contained in the @image into the #GstVaapiImageRaw.
979 * Both image structures shall have the same format.
981 * Return value: %TRUE on success
984 gst_vaapi_image_get_raw(
985 GstVaapiImage *image,
986 GstVaapiImageRaw *dst_image,
987 GstVaapiRectangle *rect
990 GstVaapiImageRaw src_image;
993 g_return_val_if_fail(image != NULL, FALSE);
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_update_from_buffer:
1008 * @image: a #GstVaapiImage
1009 * @buffer: a #GstBuffer
1010 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
1013 * Transfers pixels data contained in the #GstBuffer into the
1014 * @image. Both image structures shall have the same format.
1016 * Return value: %TRUE on success
1019 gst_vaapi_image_update_from_buffer(
1020 GstVaapiImage *image,
1022 GstVaapiRectangle *rect
1025 GstVaapiImageRaw dst_image, src_image;
1028 g_return_val_if_fail(image != NULL, FALSE);
1029 g_return_val_if_fail(GST_IS_BUFFER(buffer), FALSE);
1031 if (!init_image_from_buffer(&src_image, buffer))
1033 if (src_image.format != image->format)
1035 if (src_image.width != image->width || src_image.height != image->height)
1038 if (!_gst_vaapi_image_map(image, &dst_image))
1041 success = copy_image(&dst_image, &src_image, rect);
1043 if (!_gst_vaapi_image_unmap(image))
1050 * gst_vaapi_image_update_from_raw:
1051 * @image: a #GstVaapiImage
1052 * @src_image: a #GstVaapiImageRaw
1053 * @buffer: a #GstBuffer
1054 * @rect: a #GstVaapiRectangle expressing a region, or %NULL for the
1057 * Transfers pixels data contained in the #GstVaapiImageRaw into the
1058 * @image. Both image structures shall have the same format.
1060 * Return value: %TRUE on success
1063 gst_vaapi_image_update_from_raw(
1064 GstVaapiImage *image,
1065 GstVaapiImageRaw *src_image,
1066 GstVaapiRectangle *rect
1069 GstVaapiImageRaw dst_image;
1072 g_return_val_if_fail(image != NULL, FALSE);
1074 if (!_gst_vaapi_image_map(image, &dst_image))
1077 success = copy_image(&dst_image, src_image, rect);
1079 if (!_gst_vaapi_image_unmap(image))