+#if USE_GLX
+ case GST_VAAPI_DISPLAY_TYPE_GLX:
+ if (!sink->use_glx)
+ goto put_surface_x11;
+ success = gst_vaapisink_show_frame_glx(sink, surface, surface_rect,
+ flags);
+ break;
+#endif
+#if USE_X11
+ case GST_VAAPI_DISPLAY_TYPE_X11:
+ put_surface_x11:
+ success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags);
+ break;
+#endif
+#if USE_WAYLAND
+ case GST_VAAPI_DISPLAY_TYPE_WAYLAND:
+ success = gst_vaapisink_put_surface(sink, surface, surface_rect, flags);
+ break;
+#endif
+ default:
+ GST_ERROR("unsupported display type %d", sink->display_type);
+ success = FALSE;
+ break;
+ }
+ if (!success)
+ goto error;
+
+ /* Retain VA surface until the next one is displayed */
+ if (sink->use_overlay)
+ gst_buffer_replace(&sink->video_buffer, buffer);
+ gst_buffer_unref(buffer);
+ return GST_FLOW_OK;
+
+error:
+ gst_buffer_unref(buffer);
+ return GST_FLOW_EOS;
+}
+
+#if GST_CHECK_VERSION(1,0,0)
+static gboolean
+gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
+ GstCaps *caps = NULL;
+ gboolean need_pool;
+
+ gst_query_parse_allocation(query, &caps, &need_pool);
+
+ if (need_pool) {
+ if (!caps)
+ goto error_no_caps;
+ if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps))
+ return FALSE;
+ gst_query_add_allocation_pool(query, sink->video_buffer_pool,
+ sink->video_buffer_size, 0, 0);
+ }
+
+ gst_query_add_allocation_meta(query,
+ GST_VAAPI_VIDEO_META_API_TYPE, NULL);
+ gst_query_add_allocation_meta(query,
+ GST_VIDEO_META_API_TYPE, NULL);
+ gst_query_add_allocation_meta(query,
+ GST_VIDEO_CROP_META_API_TYPE, NULL);
+ gst_query_add_allocation_meta(query,
+ GST_VIDEO_OVERLAY_COMPOSITION_META_API_TYPE, NULL);
+ return TRUE;
+
+ /* ERRORS */
+error_no_caps:
+ {
+ GST_ERROR("no caps specified");
+ return FALSE;
+ }
+}
+#else
+static GstFlowReturn
+gst_vaapisink_buffer_alloc(
+ GstBaseSink *base_sink,
+ guint64 offset,
+ guint size,
+ GstCaps *caps,
+ GstBuffer **pbuf
+)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
+ GstVideoInfo vi;
+ GstBuffer *buf;
+
+ *pbuf = NULL;
+
+ if (!sink->use_video_raw) {
+ /* Note: this code path is rarely used but for raw YUV formats
+ from custom pipeline. Otherwise, GstBaseSink::set_caps() is
+ called first, and GstBaseSink::buffer_alloc() is not called
+ in VA surface format mode */
+ if (!gst_video_info_from_caps(&vi, caps))
+ return GST_FLOW_NOT_SUPPORTED;
+ if (!GST_VIDEO_INFO_IS_YUV(&vi))
+ return GST_FLOW_OK;
+ }
+
+ if (!gst_vaapi_uploader_ensure_display(sink->uploader, sink->display))
+ return GST_FLOW_NOT_SUPPORTED;
+ if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL))
+ return GST_FLOW_NOT_SUPPORTED;
+
+ buf = gst_vaapi_uploader_get_buffer(sink->uploader);
+ if (!buf) {
+ GST_WARNING("failed to allocate resources for raw YUV buffer");
+ return GST_FLOW_NOT_SUPPORTED;
+ }
+
+ *pbuf = buf;
+ return GST_FLOW_OK;
+}
+#endif
+
+static gboolean
+gst_vaapisink_query(GstBaseSink *base_sink, GstQuery *query)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
+
+ if (gst_vaapi_reply_to_query(query, sink->display)) {
+ GST_DEBUG("sharing display %p", sink->display);
+ return TRUE;
+ }
+ return GST_BASE_SINK_CLASS(gst_vaapisink_parent_class)->query(base_sink,
+ query);