2 * gstvaapiupload.c - VA-API video uploader
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:gstvaapiupload
25 * @short_description: A video to VA flow filter
27 * vaapiupload uploads from raw YUV pixels to VA surfaces suitable
28 * for the vaapisink element, for example.
31 #include "gst/vaapi/sysdeps.h"
33 #include <gst/video/video.h>
34 #include <gst/video/videocontext.h>
35 #include <gst/vaapi/gstvaapivideobuffer.h>
36 #include <gst/vaapi/gstvaapidebug.h>
38 #include "gstvaapiupload.h"
39 #include "gstvaapipluginutil.h"
40 #include "gstvaapipluginbuffer.h"
42 #define GST_PLUGIN_NAME "vaapiupload"
43 #define GST_PLUGIN_DESC "A video to VA flow filter"
45 GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapiupload);
46 #define GST_CAT_DEFAULT gst_debug_vaapiupload
48 /* ElementFactory information */
49 static const GstElementDetails gst_vaapiupload_details =
51 "VA-API colorspace uploader",
52 "Filter/Converter/Video",
54 "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
56 /* Default templates */
57 static const char gst_vaapiupload_yuv_caps_str[] =
59 "width = (int) [ 1, MAX ], "
60 "height = (int) [ 1, MAX ]; ";
62 static const char gst_vaapiupload_vaapi_caps_str[] =
63 GST_VAAPI_SURFACE_CAPS;
65 static GstStaticPadTemplate gst_vaapiupload_sink_factory =
66 GST_STATIC_PAD_TEMPLATE(
70 GST_STATIC_CAPS(gst_vaapiupload_yuv_caps_str));
72 static GstStaticPadTemplate gst_vaapiupload_src_factory =
73 GST_STATIC_PAD_TEMPLATE(
77 GST_STATIC_CAPS(gst_vaapiupload_vaapi_caps_str));
80 gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface);
83 gst_video_context_interface_init(GstVideoContextInterface *iface);
85 #define GstVideoContextClass GstVideoContextInterface
86 G_DEFINE_TYPE_WITH_CODE(
89 GST_TYPE_BASE_TRANSFORM,
90 G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE,
91 gst_vaapiupload_implements_iface_init);
92 G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT,
93 gst_video_context_interface_init))
96 * Direct rendering levels (direct-rendering)
97 * 0: upstream allocated YUV pixels
98 * 1: vaapiupload allocated YUV pixels (mapped from VA image)
99 * 2: vaapiupload allocated YUV pixels (mapped from VA surface)
101 #define DIRECT_RENDERING_DEFAULT 2
106 PROP_DIRECT_RENDERING,
110 gst_vaapiupload_start(GstBaseTransform *trans);
113 gst_vaapiupload_stop(GstBaseTransform *trans);
116 gst_vaapiupload_transform(
117 GstBaseTransform *trans,
123 gst_vaapiupload_transform_caps(
124 GstBaseTransform *trans,
125 GstPadDirection direction,
130 gst_vaapiupload_set_caps(
131 GstBaseTransform *trans,
137 gst_vaapiupload_get_unit_size(
138 GstBaseTransform *trans,
144 gst_vaapiupload_sinkpad_buffer_alloc(
153 gst_vaapiupload_prepare_output_buffer(
154 GstBaseTransform *trans,
162 gst_vaapiupload_query(
167 /* GstImplementsInterface interface */
170 gst_vaapiupload_implements_interface_supported(
171 GstImplementsInterface *iface,
175 return (type == GST_TYPE_VIDEO_CONTEXT);
179 gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface)
181 iface->supported = gst_vaapiupload_implements_interface_supported;
184 /* GstVideoContext interface */
187 gst_vaapiupload_set_video_context(GstVideoContext *context, const gchar *type,
190 GstVaapiUpload *upload = GST_VAAPIUPLOAD (context);
191 gst_vaapi_set_display (type, value, &upload->display);
195 gst_video_context_interface_init(GstVideoContextInterface *iface)
197 iface->set_context = gst_vaapiupload_set_video_context;
201 gst_vaapiupload_destroy(GstVaapiUpload *upload)
203 g_clear_object(&upload->images);
204 g_clear_object(&upload->surfaces);
205 g_clear_object(&upload->display);
209 gst_vaapiupload_finalize(GObject *object)
211 gst_vaapiupload_destroy(GST_VAAPIUPLOAD(object));
213 G_OBJECT_CLASS(gst_vaapiupload_parent_class)->finalize(object);
218 gst_vaapiupload_set_property(
225 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object);
228 case PROP_DIRECT_RENDERING:
229 GST_OBJECT_LOCK(upload);
230 upload->direct_rendering = g_value_get_uint(value);
231 GST_OBJECT_UNLOCK(upload);
234 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
240 gst_vaapiupload_get_property(
247 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(object);
250 case PROP_DIRECT_RENDERING:
251 g_value_set_uint(value, upload->direct_rendering);
254 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
260 gst_vaapiupload_class_init(GstVaapiUploadClass *klass)
262 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
263 GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
264 GstBaseTransformClass * const trans_class = GST_BASE_TRANSFORM_CLASS(klass);
265 GstPadTemplate *pad_template;
267 GST_DEBUG_CATEGORY_INIT(gst_debug_vaapiupload,
268 GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
270 object_class->finalize = gst_vaapiupload_finalize;
271 object_class->set_property = gst_vaapiupload_set_property;
272 object_class->get_property = gst_vaapiupload_get_property;
274 trans_class->start = gst_vaapiupload_start;
275 trans_class->stop = gst_vaapiupload_stop;
276 trans_class->transform = gst_vaapiupload_transform;
277 trans_class->transform_caps = gst_vaapiupload_transform_caps;
278 trans_class->set_caps = gst_vaapiupload_set_caps;
279 trans_class->get_unit_size = gst_vaapiupload_get_unit_size;
280 trans_class->prepare_output_buffer = gst_vaapiupload_prepare_output_buffer;
282 gst_element_class_set_details_simple(
284 gst_vaapiupload_details.longname,
285 gst_vaapiupload_details.klass,
286 gst_vaapiupload_details.description,
287 gst_vaapiupload_details.author
291 pad_template = gst_static_pad_template_get(&gst_vaapiupload_sink_factory);
292 gst_element_class_add_pad_template(element_class, pad_template);
293 gst_object_unref(pad_template);
296 pad_template = gst_static_pad_template_get(&gst_vaapiupload_src_factory);
297 gst_element_class_add_pad_template(element_class, pad_template);
298 gst_object_unref(pad_template);
301 * GstVaapiUpload:direct-rendering:
303 * Selects the direct rendering level.
305 * <listitem override="0">
306 * Disables direct rendering.
309 * Enables direct rendering to the output buffer. i.e. this
310 * tries to use a single buffer for both sink and src pads.
313 * Enables direct rendering to the underlying surface. i.e. with
314 * drivers supporting vaDeriveImage(), the output surface pixels
315 * will be modified directly.
319 g_object_class_install_property
321 PROP_DIRECT_RENDERING,
322 g_param_spec_uint("direct-rendering",
324 "Direct rendering level",
326 DIRECT_RENDERING_DEFAULT,
331 gst_vaapiupload_init(GstVaapiUpload *upload)
333 GstPad *sinkpad, *srcpad;
335 upload->display = NULL;
336 upload->images = NULL;
337 upload->images_reset = FALSE;
338 upload->image_width = 0;
339 upload->image_height = 0;
340 upload->surfaces = NULL;
341 upload->surfaces_reset = FALSE;
342 upload->surface_width = 0;
343 upload->surface_height = 0;
344 upload->direct_rendering_caps = 0;
345 upload->direct_rendering = G_MAXUINT32;
346 upload->need_manual_upload = FALSE;
348 /* Override buffer allocator on sink pad */
349 sinkpad = gst_element_get_static_pad(GST_ELEMENT(upload), "sink");
350 gst_pad_set_bufferalloc_function(
352 gst_vaapiupload_sinkpad_buffer_alloc
354 gst_pad_set_query_function(sinkpad, gst_vaapiupload_query);
355 g_object_unref(sinkpad);
357 /* Override query on src pad */
358 srcpad = gst_element_get_static_pad(GST_ELEMENT(upload), "src");
359 gst_pad_set_query_function(srcpad, gst_vaapiupload_query);
360 g_object_unref(srcpad);
363 static inline gboolean
364 gst_vaapiupload_ensure_display(GstVaapiUpload *upload)
366 return gst_vaapi_ensure_display(upload, GST_VAAPI_DISPLAY_TYPE_ANY,
371 gst_vaapiupload_start(GstBaseTransform *trans)
373 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
375 if (!gst_vaapiupload_ensure_display(upload))
381 gst_vaapiupload_stop(GstBaseTransform *trans)
383 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
385 g_clear_object(&upload->display);
391 gst_vaapiupload_transform(
392 GstBaseTransform *trans,
397 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
398 GstVaapiVideoBuffer *vbuffer;
399 GstVaapiSurface *surface;
400 GstVaapiImage *image;
403 vbuffer = GST_VAAPI_VIDEO_BUFFER(outbuf);
404 surface = gst_vaapi_video_buffer_get_surface(vbuffer);
406 return GST_FLOW_UNEXPECTED;
408 if (upload->direct_rendering) {
409 if (!GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) {
410 GST_DEBUG("GstVaapiVideoBuffer was expected");
411 return GST_FLOW_UNEXPECTED;
414 vbuffer = GST_VAAPI_VIDEO_BUFFER(inbuf);
415 image = gst_vaapi_video_buffer_get_image(vbuffer);
417 return GST_FLOW_UNEXPECTED;
418 if (!gst_vaapi_image_unmap(image))
419 return GST_FLOW_UNEXPECTED;
421 if (upload->direct_rendering < 2) {
422 if (!gst_vaapi_surface_put_image(surface, image))
423 goto error_put_image;
428 image = gst_vaapi_video_pool_get_object(upload->images);
430 goto error_put_image;
432 if (!upload->need_manual_upload) {
433 gst_vaapi_image_update_from_buffer(image, inbuf, NULL);
434 } else { /* manually copy data to image*/
435 success = gst_vaapi_convert_buffer_to_image(image, inbuf);
437 goto error_put_image;
440 success = gst_vaapi_surface_put_image(surface, image);
441 gst_vaapi_video_pool_put_object(upload->images, image);
443 goto error_put_image;
446 FPS_CALCULATION(vaapiupload);
451 GST_WARNING("failed to upload %" GST_FOURCC_FORMAT " image "
453 GST_FOURCC_ARGS(gst_vaapi_image_get_format(image)),
454 gst_vaapi_surface_get_id(surface));
460 gst_vaapi_get_other_support_caps(GstVaapiUpload *upload)
463 caps = gst_caps_from_string(GST_VIDEO_CAPS_YUV("YUY2"));
468 gst_vaapiupload_transform_caps(
469 GstBaseTransform *trans,
470 GstPadDirection direction,
474 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
475 GstCaps *out_caps = NULL;
476 GstStructure *structure;
478 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
480 structure = gst_caps_get_structure(caps, 0);
482 if (direction == GST_PAD_SINK) {
483 if (!gst_structure_has_name(structure, "video/x-raw-yuv"))
485 out_caps = gst_caps_from_string(gst_vaapiupload_vaapi_caps_str);
487 structure = gst_caps_get_structure(out_caps, 0);
490 "type", G_TYPE_STRING, "vaapi",
491 "opengl", G_TYPE_BOOLEAN, USE_GLX,
496 if (!gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME))
498 out_caps = gst_caps_from_string(gst_vaapiupload_yuv_caps_str);
499 if (upload->display) {
500 GstCaps *allowed_caps, *inter_caps, *other_caps;
501 allowed_caps = gst_vaapi_display_get_image_caps(upload->display);
504 /* can direct copy other YUV to va surface */
505 other_caps = gst_vaapi_get_other_support_caps(upload);
506 gst_caps_merge(allowed_caps, other_caps);
508 inter_caps = gst_caps_intersect(out_caps, allowed_caps);
509 gst_caps_unref(allowed_caps);
510 gst_caps_unref(out_caps);
511 out_caps = inter_caps;
515 if (!gst_vaapi_append_surface_caps(out_caps, caps)) {
516 gst_caps_unref(out_caps);
523 gst_vaapiupload_ensure_image_pool(GstVaapiUpload *upload, GstCaps *caps)
525 GstStructure * const structure = gst_caps_get_structure(caps, 0);
528 gst_structure_get_int(structure, "width", &width);
529 gst_structure_get_int(structure, "height", &height);
531 if (width != upload->image_width || height != upload->image_height) {
532 upload->image_width = width;
533 upload->image_height = height;
534 g_clear_object(&upload->images);
535 upload->images = gst_vaapi_image_pool_new(upload->display, caps);
538 upload->images_reset = TRUE;
544 gst_vaapiupload_ensure_surface_pool(GstVaapiUpload *upload, GstCaps *caps)
546 GstStructure * const structure = gst_caps_get_structure(caps, 0);
549 gst_structure_get_int(structure, "width", &width);
550 gst_structure_get_int(structure, "height", &height);
552 if (width != upload->surface_width || height != upload->surface_height) {
553 upload->surface_width = width;
554 upload->surface_height = height;
555 g_clear_object(&upload->surfaces);
556 upload->surfaces = gst_vaapi_surface_pool_new(upload->display, caps);
557 if (!upload->surfaces)
559 upload->surfaces_reset = TRUE;
565 gst_vaapiupload_ensure_direct_rendering_caps(
566 GstVaapiUpload *upload,
570 GstVaapiSurface *surface;
571 GstVaapiImage *image;
572 GstVaapiImageFormat vaformat;
573 GstVideoFormat vformat;
574 GstStructure *structure;
577 if (!upload->images_reset && !upload->surfaces_reset)
580 upload->images_reset = FALSE;
581 upload->surfaces_reset = FALSE;
582 upload->direct_rendering_caps = 0;
584 structure = gst_caps_get_structure(caps, 0);
587 gst_structure_get_int(structure, "width", &width);
588 gst_structure_get_int(structure, "height", &height);
590 /* Translate from Gst video format to VA image format */
591 if (!gst_video_format_parse_caps(caps, &vformat, NULL, NULL))
593 if (!gst_video_format_is_yuv(vformat))
595 vaformat = gst_vaapi_image_format_from_video(vformat);
599 /* Check if we can alias sink & output buffers (same data_size) */
600 image = gst_vaapi_video_pool_get_object(upload->images);
602 if (upload->direct_rendering_caps == 0 &&
603 (gst_vaapi_image_get_format(image) == vaformat &&
604 gst_vaapi_image_is_linear(image) &&
605 (gst_vaapi_image_get_data_size(image) ==
606 gst_video_format_get_size(vformat, width, height))))
607 upload->direct_rendering_caps = 1;
608 gst_vaapi_video_pool_put_object(upload->images, image);
611 /* Check if we can access to the surface pixels directly */
612 surface = gst_vaapi_video_pool_get_object(upload->surfaces);
614 image = gst_vaapi_surface_derive_image(surface);
616 if (gst_vaapi_image_map(image)) {
617 if (upload->direct_rendering_caps == 1 &&
618 (gst_vaapi_image_get_format(image) == vaformat &&
619 gst_vaapi_image_is_linear(image) &&
620 (gst_vaapi_image_get_data_size(image) ==
621 gst_video_format_get_size(vformat, width, height))))
622 upload->direct_rendering_caps = 2;
623 gst_vaapi_image_unmap(image);
625 g_object_unref(image);
627 gst_vaapi_video_pool_put_object(upload->surfaces, surface);
631 typedef enum YUV_TYPE {
639 _image_format_to_yuv_type(guint32 fourcc)
642 case GST_MAKE_FOURCC('N','V','1','2'):
643 case GST_MAKE_FOURCC('Y','V','1','2'):
644 case GST_MAKE_FOURCC('I','4','2','0'):
645 case GST_MAKE_FOURCC('N','V','2','1'):
648 case GST_MAKE_FOURCC('Y','U','Y','2'):
649 case GST_MAKE_FOURCC('Y','V','Y','U'):
652 case GST_MAKE_FOURCC('A','Y','U','V'):
661 _get_nearest_caps(GstCaps *caps_list, GstCaps *src_caps)
664 GstStructure *cur_struct, *tmp_struct;
665 guint32 cur_format, dest_format, tmp_format;
666 YUV_TYPE cur_type, tmp_type;
667 const GValue*tmp_val;
670 guint min_diff, tmp_diff;
672 cur_struct = gst_caps_get_structure(src_caps, 0);
673 tmp_val = gst_structure_get_value (cur_struct, "format");
677 cur_format = gst_value_get_fourcc(tmp_val);
678 if((cur_type = _image_format_to_yuv_type(cur_format)) == YUV_UNKOWN)
681 n_caps = gst_caps_get_size(caps_list);
684 for (i = 0; i < n_caps; ++i) {
685 tmp_struct = gst_caps_get_structure(caps_list, i);
686 tmp_val = gst_structure_get_value (tmp_struct, "format");
689 tmp_format = gst_value_get_fourcc(tmp_val);
690 if ((tmp_type = _image_format_to_yuv_type(tmp_format)) == YUV_UNKOWN)
692 tmp_diff = abs(tmp_type - cur_type);
693 if (tmp_diff < min_diff) {
695 dest_format = tmp_format;
699 if (dest_format == 0)
702 ret = gst_caps_copy(src_caps);
703 tmp_struct = gst_caps_get_structure(ret, 0);
704 gst_structure_set(tmp_struct, "format", GST_TYPE_FOURCC, dest_format, NULL);
709 gst_vaapiupload_negotiate_buffers(
710 GstVaapiUpload *upload,
717 GstCaps *image_allowed_caps = NULL;
718 GstCaps *image_caps = NULL;
720 image_allowed_caps = gst_vaapi_display_get_image_caps(upload->display);
721 if (gst_caps_can_intersect(incaps, image_allowed_caps)) {
722 image_caps = gst_caps_ref(incaps);
723 upload->need_manual_upload = FALSE;
725 image_caps = _get_nearest_caps(image_allowed_caps, incaps);
726 upload->need_manual_upload = TRUE;
729 if (!gst_vaapiupload_ensure_image_pool(upload, image_caps))
732 if (!gst_vaapiupload_ensure_surface_pool(upload, outcaps))
735 if (upload->direct_rendering && !upload->need_manual_upload)
736 gst_vaapiupload_ensure_direct_rendering_caps(upload, incaps);
737 dr = MIN(upload->direct_rendering, upload->direct_rendering_caps);
738 if (upload->direct_rendering != dr) {
739 upload->direct_rendering = dr;
740 GST_DEBUG("direct-rendering level: %d", dr);
749 gst_caps_unref(image_caps);
750 gst_caps_unref(image_allowed_caps);
755 gst_vaapiupload_set_caps(
756 GstBaseTransform *trans,
761 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
763 if (!gst_vaapiupload_negotiate_buffers(upload, incaps, outcaps))
766 GST_INFO("set caps\nIN caps:\n%" GST_PTR_FORMAT "\nOUT caps:\n%" GST_PTR_FORMAT,
772 gst_vaapiupload_get_unit_size(
773 GstBaseTransform *trans,
778 GstStructure * const structure = gst_caps_get_structure(caps, 0);
779 GstVideoFormat format;
782 if (gst_structure_has_name(structure, GST_VAAPI_SURFACE_CAPS_NAME))
785 if (!gst_video_format_parse_caps(caps, &format, &width, &height))
787 *size = gst_video_format_get_size(format, width, height);
793 gst_vaapiupload_buffer_alloc(
794 GstBaseTransform *trans,
800 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
801 GstBuffer *buffer = NULL;
802 GstVaapiImage *image = NULL;
803 GstVaapiSurface *surface = NULL;
804 GstVaapiVideoBuffer *vbuffer;
806 /* already checked */
807 if (!upload->direct_rendering)
810 /* Check if we can use direct-rendering */
811 if (!gst_vaapiupload_negotiate_buffers(upload, caps, caps))
813 if (!upload->direct_rendering)
816 switch (upload->direct_rendering) {
818 buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces);
821 vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);
823 surface = gst_vaapi_video_buffer_get_surface(vbuffer);
824 image = gst_vaapi_surface_derive_image(surface);
825 if (image && gst_vaapi_image_get_data_size(image) == size) {
826 gst_vaapi_video_buffer_set_image(vbuffer, image);
827 g_object_unref(image); /* video buffer owns an extra reference */
831 /* We can't use the derive-image optimization. Disable it. */
832 upload->direct_rendering = 1;
833 gst_buffer_unref(buffer);
837 buffer = gst_vaapi_video_buffer_new_from_pool(upload->images);
840 vbuffer = GST_VAAPI_VIDEO_BUFFER(buffer);
842 image = gst_vaapi_video_buffer_get_image(vbuffer);
847 if (!gst_vaapi_image_map(image))
850 GST_BUFFER_DATA(buffer) = gst_vaapi_image_get_plane(image, 0);
851 GST_BUFFER_SIZE(buffer) = gst_vaapi_image_get_data_size(image);
853 gst_buffer_set_caps(buffer, caps);
858 /* We can't use the inout-buffers optimization. Disable it. */
859 GST_DEBUG("disable in/out buffer optimization");
861 gst_buffer_unref(buffer);
862 upload->direct_rendering = 0;
867 gst_vaapiupload_sinkpad_buffer_alloc(
875 GstBaseTransform *trans;
878 trans = GST_BASE_TRANSFORM(gst_pad_get_parent_element(pad));
880 return GST_FLOW_UNEXPECTED;
882 ret = gst_vaapiupload_buffer_alloc(trans, size, caps, pbuf);
883 g_object_unref(trans);
888 gst_vaapiupload_prepare_output_buffer(
889 GstBaseTransform *trans,
896 GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
897 GstBuffer *buffer = NULL;
899 if (upload->direct_rendering == 2) {
900 if (GST_VAAPI_IS_VIDEO_BUFFER(inbuf)) {
901 buffer = gst_vaapi_video_buffer_new_from_buffer(inbuf);
902 GST_BUFFER_SIZE(buffer) = size;
905 GST_DEBUG("upstream element destroyed our in/out buffer");
906 upload->direct_rendering = 1;
911 buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces);
913 return GST_FLOW_UNEXPECTED;
914 gst_buffer_set_caps(buffer, caps);
922 gst_vaapiupload_query(GstPad *pad, GstQuery *query)
924 GstVaapiUpload *upload = GST_VAAPIUPLOAD (gst_pad_get_parent_element (pad));
927 GST_DEBUG ("sharing display %p", upload->display);
929 if (gst_vaapi_reply_to_query (query, upload->display))
932 res = gst_pad_query_default (pad, query);
934 g_object_unref (upload);