diff --git a/gst/vaapi/gstvaapiencode.c b/gst/vaapi/gstvaapiencode.c index 87fadc09f5..d1afc44247 100644 --- a/gst/vaapi/gstvaapiencode.c +++ b/gst/vaapi/gstvaapiencode.c @@ -61,33 +61,10 @@ ensure_display (GstVaapiEncode * encode) static gboolean ensure_uploader (GstVaapiEncode * encode) { -#if !GST_CHECK_VERSION(1,0,0) if (!ensure_display (encode)) return FALSE; - - if (!encode->uploader) { - encode->uploader = gst_vaapi_uploader_new ( - GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); - if (!encode->uploader) - return FALSE; - } - - if (!gst_vaapi_uploader_ensure_display (encode->uploader, - GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) + if (!gst_vaapi_plugin_base_ensure_uploader (GST_VAAPI_PLUGIN_BASE (encode))) return FALSE; -#endif - return TRUE; -} - -static gboolean -ensure_uploader_caps (GstVaapiEncode * encode) -{ -#if !GST_CHECK_VERSION(1,0,0) - if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info) && - !gst_vaapi_uploader_ensure_caps (encode->uploader, encode->sinkpad_caps, - NULL)) - return FALSE; -#endif return TRUE; } @@ -283,7 +260,7 @@ gst_vaapiencode_get_caps_impl (GstVideoEncoder * venc) caps = gst_caps_from_string (GST_VAAPI_SURFACE_CAPS); if (caps && ensure_uploader (encode)) { - GstCaps *const yuv_caps = gst_vaapi_uploader_get_caps (encode->uploader); + GstCaps *const yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS (encode); if (yuv_caps) { caps = gst_caps_make_writable (caps); gst_caps_append (caps, gst_caps_copy (yuv_caps)); @@ -316,10 +293,6 @@ static gboolean gst_vaapiencode_destroy (GstVaapiEncode * encode) { gst_vaapi_encoder_replace (&encode->encoder, NULL); -#if GST_CHECK_VERSION(1,0,0) - g_clear_object (&encode->video_buffer_pool); -#endif - g_clear_object (&encode->uploader); gst_caps_replace (&encode->sinkpad_caps, NULL); gst_caps_replace (&encode->srcpad_caps, NULL); return TRUE; @@ -332,12 +305,8 @@ ensure_encoder (GstVaapiEncode * encode) g_return_val_if_fail (klass->create_encoder, FALSE); - if (!ensure_display (encode)) - return FALSE; if (!ensure_uploader (encode)) return FALSE; - if (!ensure_uploader_caps (encode)) - return FALSE; encode->encoder = klass->create_encoder (encode, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); @@ -378,18 +347,6 @@ gst_vaapiencode_update_sink_caps (GstVaapiEncode * encode, GstVideoCodecState * state) { gst_caps_replace (&encode->sinkpad_caps, state->caps); - encode->sink_video_info = state->info; - -#if !GST_CHECK_VERSION(1,0,0) - if (GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) { - /* Ensure the uploader is set up for upstream allocated buffers */ - GstVaapiUploader *const uploader = encode->uploader; - if (!gst_vaapi_uploader_ensure_display (uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY (encode))) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps (uploader, state->caps, NULL)) - return FALSE; - } -#endif return TRUE; } @@ -450,72 +407,6 @@ gst_vaapiencode_update_src_caps (GstVaapiEncode * encode, return TRUE; } -static gboolean -gst_vaapiencode_ensure_video_buffer_pool (GstVaapiEncode * encode, - GstCaps * caps) -{ -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *pool; - GstCaps *pool_caps; - GstStructure *config; - GstVideoInfo vi; - gboolean need_pool; - - if (!ensure_display (encode)) - return FALSE; - - if (encode->video_buffer_pool) { - config = gst_buffer_pool_get_config (encode->video_buffer_pool); - gst_buffer_pool_config_get_params (config, &pool_caps, NULL, NULL, NULL); - need_pool = !gst_caps_is_equal (caps, pool_caps); - gst_structure_free (config); - if (!need_pool) - return TRUE; - g_clear_object (&encode->video_buffer_pool); - encode->video_buffer_size = 0; - } - - pool = gst_vaapi_video_buffer_pool_new (GST_VAAPI_PLUGIN_BASE_DISPLAY (encode)); - if (!pool) - goto error_create_pool; - - gst_video_info_init (&vi); - gst_video_info_from_caps (&vi, caps); - if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { - GST_DEBUG ("assume video buffer pool format is NV12"); - gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); - } - encode->video_buffer_size = vi.size; - - config = gst_buffer_pool_get_config (pool); - gst_buffer_pool_config_set_params (config, caps, encode->video_buffer_size, - 0, 0); - gst_buffer_pool_config_add_option (config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config (pool, config)) - goto error_pool_config; - encode->video_buffer_pool = pool; - return TRUE; - - /* ERRORS */ -error_create_pool: - { - GST_ERROR ("failed to create buffer pool"); - return FALSE; - } -error_pool_config: - { - GST_ERROR ("failed to reset buffer pool config"); - gst_object_unref (pool); - return FALSE; - } -#else - return TRUE; -#endif -} - static gboolean gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) { @@ -523,9 +414,6 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) g_return_val_if_fail (state->caps != NULL, FALSE); - if (!gst_vaapiencode_ensure_video_buffer_pool (encode, state->caps)) - return FALSE; - if (!ensure_encoder (encode)) return FALSE; if (!gst_vaapiencode_update_sink_caps (encode, state)) @@ -533,6 +421,10 @@ gst_vaapiencode_set_format (GstVideoEncoder * venc, GstVideoCodecState * state) if (!gst_vaapiencode_update_src_caps (encode, state)) return FALSE; + if (!gst_vaapi_plugin_base_set_caps (GST_VAAPI_PLUGIN_BASE (encode), + encode->sinkpad_caps, encode->srcpad_caps)) + return FALSE; + #if GST_CHECK_VERSION(1,0,0) if (encode->out_caps_done && !gst_video_encoder_negotiate (venc)) { GST_ERROR ("failed to negotiate with caps %" GST_PTR_FORMAT, @@ -557,114 +449,6 @@ gst_vaapiencode_reset (GstVideoEncoder * venc, gboolean hard) return TRUE; } -static GstFlowReturn -get_source_buffer (GstVaapiEncode * encode, GstBuffer * src_buffer, - GstBuffer ** out_buffer_ptr) -{ - GstVaapiVideoMeta *meta; - GstBuffer *out_buffer; -#if GST_CHECK_VERSION(1,0,0) - GstVideoFrame src_frame, out_frame; - gboolean success; -#endif - - meta = gst_buffer_get_vaapi_video_meta (src_buffer); - if (meta) { - *out_buffer_ptr = gst_buffer_ref (src_buffer); - return GST_FLOW_OK; - } - -#if GST_CHECK_VERSION(1,0,0) - if (!GST_VIDEO_INFO_IS_YUV (&encode->sink_video_info)) - goto error_invalid_buffer; - - if (!encode->video_buffer_pool) - goto error_no_pool; - - if (!gst_buffer_pool_set_active (encode->video_buffer_pool, TRUE)) - goto error_activate_pool; - - out_buffer = NULL; - success = gst_buffer_pool_acquire_buffer (encode->video_buffer_pool, - &out_buffer, NULL) == GST_FLOW_OK; - if (!success) - goto error_create_buffer; - - if (!gst_video_frame_map (&src_frame, &encode->sink_video_info, src_buffer, - GST_MAP_READ)) - goto error_map_src_buffer; - - if (!gst_video_frame_map (&out_frame, &encode->sink_video_info, out_buffer, - GST_MAP_WRITE)) - goto error_map_dst_buffer; - - success = gst_video_frame_copy (&out_frame, &src_frame); - gst_video_frame_unmap (&out_frame); - gst_video_frame_unmap (&src_frame); - if (!success) - goto error_copy_buffer; - - gst_buffer_copy_into (out_buffer, src_buffer, GST_BUFFER_COPY_TIMESTAMPS, 0, - -1); - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_invalid_buffer: - { - GST_ERROR ("unsupported video buffer"); - return GST_FLOW_EOS; - } -error_no_pool: - { - GST_ERROR ("no buffer pool was negotiated"); - return GST_FLOW_ERROR; - } -error_activate_pool: - { - GST_ERROR ("failed to activate buffer pool"); - return GST_FLOW_ERROR; - } -error_map_dst_buffer: - { - gst_video_frame_unmap (&src_frame); - // fall-through - } -error_map_src_buffer: - { - GST_WARNING ("failed to map buffer. Skipping this frame"); - gst_buffer_unref (out_buffer); - return GST_FLOW_OK; - } -#else - out_buffer = gst_vaapi_uploader_get_buffer (encode->uploader); - if (!out_buffer) - goto error_create_buffer; - if (!gst_vaapi_uploader_process (encode->uploader, src_buffer, out_buffer)) - goto error_copy_buffer; - - gst_buffer_copy_metadata (out_buffer, src_buffer, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; -#endif - - /* ERRORS */ -error_create_buffer: - { - GST_WARNING ("failed to create buffer. Skipping this frame"); - return GST_FLOW_OK; - } -error_copy_buffer: - { - GST_WARNING ("failed to upload buffer to VA surface. Skipping this frame"); - gst_buffer_unref (out_buffer); - return GST_FLOW_OK; - } -} - static GstFlowReturn gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstVideoCodecFrame * frame) @@ -677,7 +461,8 @@ gst_vaapiencode_handle_frame (GstVideoEncoder * venc, GstBuffer *buf; buf = NULL; - ret = get_source_buffer (encode, frame->input_buffer, &buf); + ret = gst_vaapi_plugin_base_get_input_buffer (GST_VAAPI_PLUGIN_BASE (encode), + frame->input_buffer, &buf); if (ret != GST_FLOW_OK) goto error_buffer_invalid; @@ -759,31 +544,11 @@ gst_vaapiencode_finish (GstVideoEncoder * venc) static gboolean gst_vaapiencode_propose_allocation (GstVideoEncoder * venc, GstQuery * query) { - GstVaapiEncode *const encode = GST_VAAPIENCODE_CAST (venc); - GstCaps *caps = NULL; - gboolean need_pool; + GstVaapiPluginBase *const plugin = GST_VAAPI_PLUGIN_BASE (venc); - gst_query_parse_allocation (query, &caps, &need_pool); - - if (need_pool) { - if (!caps) - goto error_no_caps; - if (!gst_vaapiencode_ensure_video_buffer_pool (encode, caps)) - return FALSE; - gst_query_add_allocation_pool (query, encode->video_buffer_pool, - encode->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); - return TRUE; - - /* ERRORS */ -error_no_caps: - { - GST_ERROR ("no caps specified"); + if (!gst_vaapi_plugin_base_propose_allocation (plugin, query)) return FALSE; - } + return TRUE; } #endif @@ -864,7 +629,6 @@ gst_vaapiencode_init (GstVaapiEncode * encode) encode->sinkpad = GST_VIDEO_ENCODER_SINK_PAD (encode); encode->sinkpad_query = GST_PAD_QUERYFUNC (encode->sinkpad); gst_pad_set_query_function (encode->sinkpad, gst_vaapiencode_query); - gst_video_info_init (&encode->sink_video_info); /* src pad */ encode->srcpad = GST_VIDEO_ENCODER_SRC_PAD (encode); diff --git a/gst/vaapi/gstvaapiencode.h b/gst/vaapi/gstvaapiencode.h index 1bf0dbc9cc..401913ffb5 100644 --- a/gst/vaapi/gstvaapiencode.h +++ b/gst/vaapi/gstvaapiencode.h @@ -24,7 +24,6 @@ #include "gstvaapipluginbase.h" #include -#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -54,19 +53,12 @@ struct _GstVaapiEncode GstPad *sinkpad; GstCaps *sinkpad_caps; GstPadQueryFunction sinkpad_query; - GstVideoInfo sink_video_info; GstPad *srcpad; GstCaps *srcpad_caps; GstPadQueryFunction srcpad_query; GstVaapiEncoder *encoder; - GstVaapiUploader *uploader; - -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *video_buffer_pool; -#endif - guint video_buffer_size; GstVaapiRateControl rate_control; guint32 bitrate; /* kbps */ diff --git a/gst/vaapi/gstvaapipluginbase.c b/gst/vaapi/gstvaapipluginbase.c index 733921037c..e1ff7400d2 100644 --- a/gst/vaapi/gstvaapipluginbase.c +++ b/gst/vaapi/gstvaapipluginbase.c @@ -26,6 +26,10 @@ #include "gstvaapipluginbase.h" #include "gstvaapipluginutil.h" #include "gstvaapivideocontext.h" +#include "gstvaapivideometa.h" +#if GST_CHECK_VERSION(1,0,0) +#include "gstvaapivideobufferpool.h" +#endif /* Default debug category is from the subclass */ #define GST_CAT_DEFAULT (plugin->debug_category) @@ -174,11 +178,18 @@ gst_vaapi_plugin_base_open (GstVaapiPluginBase * plugin) void gst_vaapi_plugin_base_close (GstVaapiPluginBase * plugin) { + g_clear_object (&plugin->uploader); gst_vaapi_display_replace (&plugin->display, NULL); gst_caps_replace (&plugin->sinkpad_caps, NULL); plugin->sinkpad_caps_changed = FALSE; gst_video_info_init (&plugin->sinkpad_info); +#if GST_CHECK_VERSION(1,0,0) + if (plugin->sinkpad_buffer_pool) { + gst_object_unref (plugin->sinkpad_buffer_pool); + plugin->sinkpad_buffer_pool = NULL; + } +#endif gst_caps_replace (&plugin->srcpad_caps, NULL); plugin->srcpad_caps_changed = FALSE; @@ -227,6 +238,104 @@ gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin) return TRUE; } +/** + * gst_vaapi_plugin_base_ensure_uploader: + * @plugin: a #GstVaapiPluginBase + * + * Makes sure the built-in #GstVaapiUploader object is created, or + * that it was successfully notified of any VA display change. + * + * Returns: %TRUE if the uploader was successfully created, %FALSE otherwise. + */ +gboolean +gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin) +{ + if (plugin->uploader) { + if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) + return FALSE; + } else { + plugin->uploader = gst_vaapi_uploader_new (plugin->display); + if (!plugin->uploader) + return FALSE; + } + return TRUE; +} + +/** + * ensure_sinkpad_buffer_pool: + * @plugin: a #GstVaapiPluginBase + * @caps: the initial #GstCaps for the resulting buffer pool + * + * Makes sure the sink pad video buffer pool is created with the + * appropriate @caps. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +static gboolean +ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) +{ +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *pool; + GstCaps *pool_caps; + GstStructure *config; + GstVideoInfo vi; + gboolean need_pool; + + if (!gst_vaapi_plugin_base_ensure_display (plugin)) + return FALSE; + + if (plugin->sinkpad_buffer_pool) { + config = gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool); + gst_buffer_pool_config_get_params (config, &pool_caps, NULL, NULL, NULL); + need_pool = !gst_caps_is_equal (caps, pool_caps); + gst_structure_free (config); + if (!need_pool) + return TRUE; + g_clear_object (&plugin->sinkpad_buffer_pool); + plugin->sinkpad_buffer_size = 0; + } + + pool = gst_vaapi_video_buffer_pool_new (plugin->display); + if (!pool) + goto error_create_pool; + + gst_video_info_init (&vi); + gst_video_info_from_caps (&vi, caps); + if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { + GST_DEBUG ("assume video buffer pool format is NV12"); + gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, + GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); + } + plugin->sinkpad_buffer_size = vi.size; + + config = gst_buffer_pool_get_config (pool); + gst_buffer_pool_config_set_params (config, caps, + plugin->sinkpad_buffer_size, 0, 0); + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); + gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); + if (!gst_buffer_pool_set_config (pool, config)) + goto error_pool_config; + plugin->sinkpad_buffer_pool = pool; + return TRUE; + + /* ERRORS */ +error_create_pool: + { + GST_ERROR ("failed to create buffer pool"); + return FALSE; + } +error_pool_config: + { + GST_ERROR ("failed to reset buffer pool config"); + gst_object_unref (pool); + return FALSE; + } +#else + return TRUE; +#endif +} + /** * gst_vaapi_plugin_base_set_caps: * @plugin: a #GstVaapiPluginBase @@ -255,5 +364,227 @@ gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, return FALSE; plugin->srcpad_caps_changed = TRUE; } + + if (plugin->uploader && GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) { + if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) + return FALSE; + if (!gst_vaapi_uploader_ensure_caps (plugin->uploader, + plugin->sinkpad_caps, plugin->srcpad_caps)) + return FALSE; + } + + if (!ensure_sinkpad_buffer_pool (plugin, plugin->sinkpad_caps)) + return FALSE; return TRUE; } + +/** + * gst_vaapi_plugin_base_propose_allocation: + * @plugin: a #GstVaapiPluginBase + * @query: the allocation query to configure + * + * Proposes allocation parameters to the upstream elements. + * + * Returns: %TRUE if successful, %FALSE otherwise. + */ +#if GST_CHECK_VERSION(1,0,0) +gboolean +gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, + GstQuery * query) +{ + GstCaps *caps = NULL; + gboolean need_pool; + + gst_query_parse_allocation (query, &caps, &need_pool); + + if (need_pool) { + if (!caps) + goto error_no_caps; + if (!ensure_sinkpad_buffer_pool (plugin, caps)) + return FALSE; + gst_query_add_allocation_pool (query, plugin->sinkpad_buffer_pool, + plugin->sinkpad_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); + return TRUE; + + /* ERRORS */ +error_no_caps: + { + GST_ERROR ("no caps specified"); + return FALSE; + } +} +#endif + +/** + * gst_vaapi_plugin_base_allocate_input_buffer: + * @plugin: a #GstVaapiPluginBase + * @caps: the buffer caps constraints to honour + * @outbuf_ptr: the pointer location to the newly allocated buffer + * + * Creates a buffer that holds a VA surface memory for the sink pad to + * use it as the result for buffer_alloc() impementations. + * + * Return: #GST_FLOW_OK if the buffer could be created. + */ +GstFlowReturn +gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, + GstCaps * caps, GstBuffer ** outbuf_ptr) +{ + GstBuffer *outbuf; + + *outbuf_ptr = NULL; + + if (!plugin->sinkpad_caps_changed) { + if (!gst_video_info_from_caps (&plugin->sinkpad_info, caps)) + return GST_FLOW_NOT_SUPPORTED; + plugin->sinkpad_caps_changed = TRUE; + } + + if (!GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) + return GST_FLOW_OK; + + if (!gst_vaapi_uploader_ensure_display (plugin->uploader, plugin->display)) + return GST_FLOW_NOT_SUPPORTED; + if (!gst_vaapi_uploader_ensure_caps (plugin->uploader, caps, NULL)) + return GST_FLOW_NOT_SUPPORTED; + + outbuf = gst_vaapi_uploader_get_buffer (plugin->uploader); + if (!outbuf) { + GST_WARNING ("failed to allocate resources for raw YUV buffer"); + return GST_FLOW_NOT_SUPPORTED; + } + + *outbuf_ptr = outbuf; + return GST_FLOW_OK; +} + +/** + * gst_vaapi_plugin_base_get_input_buffer: + * @plugin: a #GstVaapiPluginBase + * @incaps: the sink pad (input) buffer + * @outbuf_ptr: the pointer to location to the VA surface backed buffer + * + * Acquires the sink pad (input) buffer as a VA surface backed + * buffer. This is mostly useful for raw YUV buffers, as source + * buffers that are already backed as a VA surface are passed + * verbatim. + * + * Returns: #GST_FLOW_OK if the buffer could be acquired + */ +GstFlowReturn +gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer ** outbuf_ptr) +{ + GstVaapiVideoMeta *meta; + GstBuffer *outbuf; +#if GST_CHECK_VERSION(1,0,0) + GstVideoFrame src_frame, out_frame; + gboolean success; +#endif + + g_return_val_if_fail (inbuf != NULL, GST_FLOW_ERROR); + g_return_val_if_fail (outbuf_ptr != NULL, GST_FLOW_ERROR); + + meta = gst_buffer_get_vaapi_video_meta (inbuf); +#if GST_CHECK_VERSION(1,0,0) + if (meta) { + *outbuf_ptr = gst_buffer_ref (inbuf); + return GST_FLOW_OK; + } + + if (!GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) + goto error_invalid_buffer; + + if (!plugin->sinkpad_buffer_pool) + goto error_no_pool; + + if (!gst_buffer_pool_set_active (plugin->sinkpad_buffer_pool, TRUE)) + goto error_active_pool; + + outbuf = NULL; + if (gst_buffer_pool_acquire_buffer (plugin->sinkpad_buffer_pool, + &outbuf, NULL) != GST_FLOW_OK) + goto error_create_buffer; + + if (!gst_video_frame_map (&src_frame, &plugin->sinkpad_info, inbuf, + GST_MAP_READ)) + goto error_map_src_buffer; + + if (!gst_video_frame_map (&out_frame, &plugin->sinkpad_info, outbuf, + GST_MAP_WRITE)) + goto error_map_dst_buffer; + + success = gst_video_frame_copy (&out_frame, &src_frame); + gst_video_frame_unmap (&out_frame); + gst_video_frame_unmap (&src_frame); + if (!success) + goto error_copy_buffer; + + gst_buffer_copy_into (outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); + *outbuf_ptr = outbuf; + return GST_FLOW_OK; + + /* ERRORS */ +error_no_pool: + { + GST_ERROR ("no buffer pool was negotiated"); + return GST_FLOW_ERROR; + } +error_active_pool: + { + GST_ERROR ("failed to activate buffer pool"); + return GST_FLOW_ERROR; + } +error_map_dst_buffer: + { + gst_video_frame_unmap (&src_frame); + // fall-through + } +error_map_src_buffer: + { + GST_WARNING ("failed to map buffer"); + gst_buffer_unref (outbuf); + return GST_FLOW_NOT_SUPPORTED; + } +#else + if (meta) + outbuf = gst_buffer_ref (inbuf); + else if (GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info)) { + outbuf = gst_vaapi_uploader_get_buffer (plugin->uploader); + if (!outbuf) + goto error_create_buffer; + gst_buffer_copy_metadata (outbuf, inbuf, + GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); + } else + goto error_invalid_buffer; + + if (GST_VIDEO_INFO_IS_YUV (&plugin->sinkpad_info) && + !gst_vaapi_uploader_process (plugin->uploader, inbuf, outbuf)) + goto error_copy_buffer; + + *outbuf_ptr = outbuf; + return GST_FLOW_OK; +#endif + + /* ERRORS */ +error_invalid_buffer: + { + GST_ERROR ("failed to validate source buffer"); + return GST_FLOW_ERROR; + } +error_create_buffer: + { + GST_ERROR ("failed to create buffer"); + return GST_FLOW_ERROR; + } +error_copy_buffer: + { + GST_WARNING ("failed to upload buffer to VA surface"); + gst_buffer_unref (outbuf); + return GST_FLOW_NOT_SUPPORTED; + } +} diff --git a/gst/vaapi/gstvaapipluginbase.h b/gst/vaapi/gstvaapipluginbase.h index 68ed6c83f6..6c8abcf658 100644 --- a/gst/vaapi/gstvaapipluginbase.h +++ b/gst/vaapi/gstvaapipluginbase.h @@ -30,6 +30,7 @@ #include #include #include +#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -96,6 +97,13 @@ typedef struct _GstVaapiPluginBaseClass GstVaapiPluginBaseClass; (gst_vaapi_display_replace(&GST_VAAPI_PLUGIN_BASE_DISPLAY(plugin), \ (new_display))) +#define GST_VAAPI_PLUGIN_BASE_UPLOADER(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->uploader) +#define GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(plugin) \ + (gst_vaapi_uploader_get_caps(GST_VAAPI_PLUGIN_BASE_UPLOADER(plugin))) +#define GST_VAAPI_PLUGIN_BASE_UPLOADER_USED(plugin) \ + (GST_VAAPI_PLUGIN_BASE(plugin)->uploader_used) + struct _GstVaapiPluginBase { /*< private >*/ @@ -115,6 +123,10 @@ struct _GstVaapiPluginBase gboolean sinkpad_caps_changed; GstVideoInfo sinkpad_info; GstPadQueryFunction sinkpad_query; +#if GST_CHECK_VERSION(1,0,0) + GstBufferPool *sinkpad_buffer_pool; + guint sinkpad_buffer_size; +#endif GstPad *srcpad; GstCaps *srcpad_caps; @@ -125,6 +137,9 @@ struct _GstVaapiPluginBase GstVaapiDisplay *display; GstVaapiDisplayType display_type; GstVaapiDisplayType display_type_req; + + GstVaapiUploader *uploader; + gboolean uploader_used; }; struct _GstVaapiPluginBaseClass @@ -177,11 +192,30 @@ G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_ensure_display (GstVaapiPluginBase * plugin); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_ensure_uploader (GstVaapiPluginBase * plugin); + G_GNUC_INTERNAL gboolean gst_vaapi_plugin_base_set_caps (GstVaapiPluginBase * plugin, GstCaps * incaps, GstCaps * outcaps); +G_GNUC_INTERNAL +gboolean +gst_vaapi_plugin_base_propose_allocation (GstVaapiPluginBase * plugin, + GstQuery * query); + +G_GNUC_INTERNAL +GstFlowReturn +gst_vaapi_plugin_base_allocate_input_buffer (GstVaapiPluginBase * plugin, + GstCaps * caps, GstBuffer ** outbuf_ptr); + +G_GNUC_INTERNAL +GstFlowReturn +gst_vaapi_plugin_base_get_input_buffer (GstVaapiPluginBase * plugin, + GstBuffer * inbuf, GstBuffer ** outbuf_ptr); + G_END_DECLS #endif /* GST_VAAPI_PLUGIN_BASE_H */ diff --git a/gst/vaapi/gstvaapipostproc.c b/gst/vaapi/gstvaapipostproc.c index fb61a0c55a..58fff7a172 100755 --- a/gst/vaapi/gstvaapipostproc.c +++ b/gst/vaapi/gstvaapipostproc.c @@ -212,32 +212,11 @@ gst_vaapipostproc_ensure_uploader(GstVaapiPostproc *postproc) { if (!gst_vaapipostproc_ensure_display(postproc)) return FALSE; - - if (!postproc->uploader) { - postproc->uploader = gst_vaapi_uploader_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); - if (!postproc->uploader) - return FALSE; - } - - if (!gst_vaapi_uploader_ensure_display(postproc->uploader, - GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) + if (!gst_vaapi_plugin_base_ensure_uploader(GST_VAAPI_PLUGIN_BASE(postproc))) return FALSE; return TRUE; } -static gboolean -gst_vaapipostproc_ensure_uploader_caps(GstVaapiPostproc *postproc) -{ -#if !GST_CHECK_VERSION(1,0,0) - GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(postproc); - if (postproc->is_raw_yuv && !gst_vaapi_uploader_ensure_caps( - postproc->uploader, plugin->sinkpad_caps, NULL)) - return FALSE; -#endif - return TRUE; -} - static gboolean gst_vaapipostproc_ensure_filter(GstVaapiPostproc *postproc) { @@ -279,8 +258,6 @@ gst_vaapipostproc_create(GstVaapiPostproc *postproc) return FALSE; if (!gst_vaapipostproc_ensure_uploader(postproc)) return FALSE; - if (!gst_vaapipostproc_ensure_uploader_caps(postproc)) - return FALSE; if (gst_vaapipostproc_ensure_filter(postproc)) postproc->use_vpp = TRUE; return TRUE; @@ -306,10 +283,6 @@ static void gst_vaapipostproc_destroy(GstVaapiPostproc *postproc) { ds_reset(&postproc->deinterlace_state); -#if GST_CHECK_VERSION(1,0,0) - g_clear_object(&postproc->sinkpad_buffer_pool); -#endif - g_clear_object(&postproc->uploader); gst_vaapipostproc_destroy_filter(postproc); gst_caps_replace(&postproc->allowed_sinkpad_caps, NULL); @@ -791,16 +764,6 @@ gst_vaapipostproc_update_sink_caps(GstVaapiPostproc *postproc, GstCaps *caps, (1 + deinterlace) * GST_VIDEO_INFO_FPS_N(&vi)); postproc->is_raw_yuv = GST_VIDEO_INFO_IS_YUV(&vi); -#if !GST_CHECK_VERSION(1,0,0) - if (postproc->is_raw_yuv) { - /* Ensure the uploader is set up for upstream allocated buffers */ - GstVaapiUploader * const uploader = postproc->uploader; - if (!gst_vaapi_uploader_ensure_display(uploader, GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc))) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps(uploader, caps, NULL)) - return FALSE; - } -#endif return TRUE; } @@ -849,7 +812,7 @@ ensure_allowed_sinkpad_caps(GstVaapiPostproc *postproc) /* Append YUV caps */ if (gst_vaapipostproc_ensure_uploader(postproc)) { - yuv_caps = gst_vaapi_uploader_get_caps(postproc->uploader); + yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(postproc); if (yuv_caps) { out_caps = gst_caps_make_writable(out_caps); gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); @@ -1117,107 +1080,6 @@ gst_vaapipostproc_transform_size(GstBaseTransform *trans, return TRUE; } -static GstBuffer * -get_source_buffer(GstVaapiPostproc *postproc, GstBuffer *inbuf) -{ - GstVaapiVideoMeta *meta; - GstBuffer *outbuf; -#if GST_CHECK_VERSION(1,0,0) - GstVideoFrame src_frame, out_frame; -#endif - - meta = gst_buffer_get_vaapi_video_meta(inbuf); - if (meta) - return gst_buffer_ref(inbuf); - -#if GST_CHECK_VERSION(1,0,0) - if (!postproc->is_raw_yuv) - goto error_invalid_buffer; - - if (!postproc->sinkpad_buffer_pool) - goto error_no_pool; - - if (!gst_buffer_pool_set_active(postproc->sinkpad_buffer_pool, TRUE)) - goto error_active_pool; - - outbuf = NULL; - if (gst_buffer_pool_acquire_buffer(postproc->sinkpad_buffer_pool, - &outbuf, NULL) != GST_FLOW_OK) - goto error_create_buffer; - - if (!gst_video_frame_map(&src_frame, &postproc->sinkpad_info, inbuf, - GST_MAP_READ)) - goto error_map_src_buffer; - - if (!gst_video_frame_map(&out_frame, &postproc->sinkpad_info, outbuf, - GST_MAP_WRITE)) - goto error_map_dst_buffer; - - if (!gst_video_frame_copy(&out_frame, &src_frame)) - goto error_copy_buffer; - - gst_video_frame_unmap(&out_frame); - gst_video_frame_unmap(&src_frame); - gst_buffer_copy_into(outbuf, inbuf, GST_BUFFER_COPY_TIMESTAMPS, 0, -1); - return outbuf; - - /* ERRORS */ -error_invalid_buffer: - { - GST_ERROR("failed to validate source buffer"); - return NULL; - } -error_no_pool: - { - GST_ERROR("no buffer pool was negotiated"); - return NULL; - } -error_active_pool: - { - GST_ERROR("failed to activate buffer pool"); - return NULL; - } -error_map_dst_buffer: - { - gst_video_frame_unmap(&src_frame); - // fall-through - } -error_map_src_buffer: - { - GST_ERROR("failed to map buffer"); - gst_buffer_unref(outbuf); - return NULL; - } -#else - outbuf = gst_vaapi_uploader_get_buffer(postproc->uploader); - if (!outbuf) - goto error_create_buffer; - if (!gst_vaapi_uploader_process(postproc->uploader, inbuf, outbuf)) - goto error_copy_buffer; - - gst_buffer_copy_metadata(outbuf, inbuf, - GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS); - return outbuf; -#endif - - /* ERRORS */ -error_create_buffer: - { - GST_ERROR("failed to create buffer"); - return NULL; - } -error_copy_buffer: - { - GST_ERROR("failed to upload buffer to VA surface"); -#if GST_CHECK_VERSION(1,0,0) - gst_video_frame_unmap(&out_frame); - gst_video_frame_unmap(&src_frame); -#endif - gst_buffer_unref(outbuf); - return NULL; - } -} - static GstFlowReturn gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *outbuf) @@ -1226,8 +1088,9 @@ gst_vaapipostproc_transform(GstBaseTransform *trans, GstBuffer *inbuf, GstBuffer *buf; GstFlowReturn ret; - buf = get_source_buffer(postproc, inbuf); - if (!buf) + ret = gst_vaapi_plugin_base_get_input_buffer( + GST_VAAPI_PLUGIN_BASE(postproc), inbuf, &buf); + if (ret != GST_FLOW_OK) return GST_FLOW_ERROR; ret = GST_FLOW_NOT_SUPPORTED; @@ -1272,73 +1135,6 @@ gst_vaapipostproc_prepare_output_buffer(GstBaseTransform *trans, return *outbuf_ptr ? GST_FLOW_OK : GST_FLOW_ERROR; } -static gboolean -ensure_sinkpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) -{ -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *pool; - GstCaps *pool_caps; - GstStructure *config; - GstVideoInfo vi; - gboolean need_pool; - - if (!gst_vaapipostproc_ensure_display(postproc)) - return FALSE; - - if (postproc->sinkpad_buffer_pool) { - config = gst_buffer_pool_get_config(postproc->sinkpad_buffer_pool); - gst_buffer_pool_config_get_params(config, &pool_caps, NULL, NULL, NULL); - need_pool = !gst_caps_is_equal(caps, pool_caps); - gst_structure_free(config); - if (!need_pool) - return TRUE; - g_clear_object(&postproc->sinkpad_buffer_pool); - postproc->sinkpad_buffer_size = 0; - } - - pool = gst_vaapi_video_buffer_pool_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(postproc)); - if (!pool) - goto error_create_pool; - - gst_video_info_init(&vi); - gst_video_info_from_caps(&vi, caps); - if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) { - GST_DEBUG("assume sink pad buffer pool format is NV12"); - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - } - postproc->sinkpad_buffer_size = vi.size; - - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_set_params(config, caps, - postproc->sinkpad_buffer_size, 0, 0); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config(pool, config)) - goto error_pool_config; - postproc->sinkpad_buffer_pool = pool; - return TRUE; - - /* ERRORS */ -error_create_pool: - { - GST_ERROR("failed to create buffer pool"); - return FALSE; - } -error_pool_config: - { - GST_ERROR("failed to reset buffer pool config"); - gst_object_unref(pool); - return FALSE; - } -#else - return TRUE; -#endif -} - static gboolean ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps) { @@ -1378,15 +1174,13 @@ gst_vaapipostproc_set_caps(GstBaseTransform *trans, GstCaps *caps, if (caps_changed) { gst_vaapipostproc_destroy(postproc); + if (!gst_vaapipostproc_create(postproc)) + return FALSE; if (!gst_vaapi_plugin_base_set_caps(GST_VAAPI_PLUGIN_BASE(trans), caps, out_caps)) return FALSE; - if (!gst_vaapipostproc_create(postproc)) - return FALSE; } - if (!ensure_sinkpad_buffer_pool(postproc, caps)) - return FALSE; if (!ensure_srcpad_buffer_pool(postproc, out_caps)) return FALSE; return TRUE; @@ -1415,40 +1209,14 @@ gst_vaapipostproc_propose_allocation(GstBaseTransform *trans, GstQuery *decide_query, GstQuery *query) { GstVaapiPostproc * const postproc = GST_VAAPIPOSTPROC(trans); - GstCaps *caps = NULL; - gboolean need_pool; + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(trans); /* Let vaapidecode allocate the video buffers */ if (!postproc->is_raw_yuv) return FALSE; - - gst_query_parse_allocation(query, &caps, &need_pool); - - if (need_pool) { - if (!caps) - goto error_no_caps; - if (!ensure_sinkpad_buffer_pool(postproc, caps)) - return FALSE; - gst_query_add_allocation_pool(query, postproc->sinkpad_buffer_pool, - postproc->sinkpad_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"); + if (!gst_vaapi_plugin_base_propose_allocation(plugin, query)) return FALSE; - } + return TRUE; } #endif diff --git a/gst/vaapi/gstvaapipostproc.h b/gst/vaapi/gstvaapipostproc.h index fe04947852..93b4495d4d 100755 --- a/gst/vaapi/gstvaapipostproc.h +++ b/gst/vaapi/gstvaapipostproc.h @@ -27,7 +27,6 @@ #include #include #include -#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -136,7 +135,6 @@ struct _GstVaapiPostproc { /*< private >*/ GstVaapiPluginBase parent_instance; - GstVaapiUploader *uploader; GstVaapiFilter *filter; GPtrArray *filter_ops; GstVaapiVideoPool *filter_pool; @@ -149,10 +147,6 @@ struct _GstVaapiPostproc { GstCaps *allowed_sinkpad_caps; GstVideoInfo sinkpad_info; -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *sinkpad_buffer_pool; -#endif - guint sinkpad_buffer_size; GstCaps *allowed_srcpad_caps; GstVideoInfo srcpad_info; diff --git a/gst/vaapi/gstvaapisink.c b/gst/vaapi/gstvaapisink.c index e219753a27..3b7f8d7d25 100644 --- a/gst/vaapi/gstvaapisink.c +++ b/gst/vaapi/gstvaapisink.c @@ -239,10 +239,7 @@ gst_vaapisink_destroy(GstVaapiSink *sink) #if USE_GLX gst_vaapi_texture_replace(&sink->texture, NULL); #endif - g_clear_object(&sink->uploader); - gst_caps_replace(&sink->caps, NULL); - gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); } #if USE_X11 @@ -341,13 +338,8 @@ gst_vaapisink_ensure_uploader(GstVaapiSink *sink) { if (!gst_vaapisink_ensure_display(sink)) return FALSE; - - if (!sink->uploader) { - sink->uploader = gst_vaapi_uploader_new( - GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - if (!sink->uploader) - return FALSE; - } + if (!gst_vaapi_plugin_base_ensure_uploader(GST_VAAPI_PLUGIN_BASE(sink))) + return FALSE; return TRUE; } @@ -605,72 +597,6 @@ end: return success; } -static gboolean -gst_vaapisink_ensure_video_buffer_pool(GstVaapiSink *sink, GstCaps *caps) -{ -#if GST_CHECK_VERSION(1,0,0) - GstBufferPool *pool; - GstCaps *pool_caps; - GstStructure *config; - GstVideoInfo vi; - gboolean need_pool; - - if (!gst_vaapisink_ensure_display(sink)) - return FALSE; - - if (sink->video_buffer_pool) { - config = gst_buffer_pool_get_config(sink->video_buffer_pool); - gst_buffer_pool_config_get_params(config, &pool_caps, NULL, NULL, NULL); - need_pool = !gst_caps_is_equal(caps, pool_caps); - gst_structure_free(config); - if (!need_pool) - return TRUE; - g_clear_object(&sink->video_buffer_pool); - sink->video_buffer_size = 0; - } - - pool = gst_vaapi_video_buffer_pool_new(GST_VAAPI_PLUGIN_BASE_DISPLAY(sink)); - if (!pool) - goto error_create_pool; - - gst_video_info_init(&vi); - gst_video_info_from_caps(&vi, caps); - if (GST_VIDEO_INFO_FORMAT(&vi) == GST_VIDEO_FORMAT_ENCODED) { - GST_DEBUG("assume video buffer pool format is NV12"); - gst_video_info_set_format(&vi, GST_VIDEO_FORMAT_NV12, - GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); - } - sink->video_buffer_size = vi.size; - - config = gst_buffer_pool_get_config(pool); - gst_buffer_pool_config_set_params(config, caps, sink->video_buffer_size, - 0, 0); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); - gst_buffer_pool_config_add_option(config, - GST_BUFFER_POOL_OPTION_VIDEO_META); - if (!gst_buffer_pool_set_config(pool, config)) - goto error_pool_config; - sink->video_buffer_pool = pool; - return TRUE; - - /* ERRORS */ -error_create_pool: - { - GST_ERROR("failed to create buffer pool"); - return FALSE; - } -error_pool_config: - { - GST_ERROR("failed to reset buffer pool config"); - gst_object_unref(pool); - return FALSE; - } -#else - return TRUE; -#endif -} - static gboolean gst_vaapisink_start(GstBaseSink *base_sink) { @@ -691,7 +617,7 @@ gst_vaapisink_stop(GstBaseSink *base_sink) g_clear_object(&sink->video_buffer_pool); #endif gst_vaapi_window_replace(&sink->window, NULL); - g_clear_object(&sink->uploader); + gst_vaapi_plugin_base_close(GST_VAAPI_PLUGIN_BASE(sink)); return TRUE; } @@ -711,7 +637,7 @@ gst_vaapisink_get_caps_impl(GstBaseSink *base_sink) return NULL; if (gst_vaapisink_ensure_uploader(sink)) { - yuv_caps = gst_vaapi_uploader_get_caps(sink->uploader); + yuv_caps = GST_VAAPI_PLUGIN_BASE_UPLOADER_CAPS(sink); if (yuv_caps) { out_caps = gst_caps_make_writable(out_caps); gst_caps_append(out_caps, gst_caps_copy(yuv_caps)); @@ -745,7 +671,7 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) { GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstVideoInfo * const vip = &sink->video_info; + GstVideoInfo * const vip = GST_VAAPI_PLUGIN_BASE_SINK_PAD_INFO(sink); GstVaapiDisplay *display; guint win_width, win_height; @@ -761,12 +687,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) if (!gst_vaapi_plugin_base_set_caps(plugin, caps, NULL)) return FALSE; - if (!gst_vaapisink_ensure_video_buffer_pool(sink, caps)) - return FALSE; - - if (!gst_video_info_from_caps(vip, caps)) - return FALSE; - sink->use_video_raw = GST_VIDEO_INFO_IS_YUV(vip); sink->video_width = GST_VIDEO_INFO_WIDTH(vip); sink->video_height = GST_VIDEO_INFO_HEIGHT(vip); sink->video_par_n = GST_VIDEO_INFO_PAR_N(vip); @@ -776,16 +696,6 @@ gst_vaapisink_set_caps(GstBaseSink *base_sink, GstCaps *caps) gst_caps_replace(&sink->caps, caps); -#if !GST_CHECK_VERSION(1,0,0) - if (sink->use_video_raw) { - /* Ensure the uploader is set up for upstream allocated buffers */ - if (!gst_vaapi_uploader_ensure_display(sink->uploader, display)) - return FALSE; - if (!gst_vaapi_uploader_ensure_caps(sink->uploader, caps, NULL)) - return FALSE; - } -#endif - gst_vaapisink_ensure_rotation(sink, FALSE); gst_vaapisink_ensure_window_size(sink, &win_width, &win_height); @@ -1029,116 +939,6 @@ gst_vaapisink_put_surface( return TRUE; } -#if GST_CHECK_VERSION(1,0,0) -static GstFlowReturn -gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer, - GstBuffer **out_buffer_ptr) -{ - GstVaapiVideoMeta *meta; - GstBuffer *out_buffer; - GstBufferPoolAcquireParams params = { 0, }; - GstVideoFrame src_frame, out_frame; - GstFlowReturn ret; - - meta = gst_buffer_get_vaapi_video_meta(src_buffer); - if (meta) { - *out_buffer_ptr = gst_buffer_ref(src_buffer); - return GST_FLOW_OK; - } - - if (!sink->use_video_raw) { - GST_ERROR("unsupported video buffer"); - return GST_FLOW_EOS; - } - - GST_DEBUG("buffer %p not from our pool, copying", src_buffer); - - *out_buffer_ptr = NULL; - if (!sink->video_buffer_pool) - goto error_no_pool; - - if (!gst_buffer_pool_set_active(sink->video_buffer_pool, TRUE)) - goto error_activate_pool; - - params.flags = GST_BUFFER_POOL_ACQUIRE_FLAG_DONTWAIT; - ret = gst_buffer_pool_acquire_buffer(sink->video_buffer_pool, &out_buffer, - ¶ms); - if (ret != GST_FLOW_OK) - goto error_create_buffer; - - if (!gst_video_frame_map(&src_frame, &sink->video_info, src_buffer, - GST_MAP_READ)) - goto error_map_src_buffer; - - if (!gst_video_frame_map(&out_frame, &sink->video_info, out_buffer, - GST_MAP_WRITE)) - goto error_map_dst_buffer; - - gst_video_frame_copy(&out_frame, &src_frame); - gst_video_frame_unmap(&out_frame); - gst_video_frame_unmap(&src_frame); - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_no_pool: - GST_ERROR("no buffer pool was negotiated"); - return GST_FLOW_ERROR; -error_activate_pool: - GST_ERROR("failed to activate buffer pool"); - return GST_FLOW_ERROR; -error_create_buffer: - GST_WARNING("failed to create image. Skipping this frame"); - return GST_FLOW_OK; -error_map_dst_buffer: - gst_video_frame_unmap(&src_frame); - // fall-through -error_map_src_buffer: - GST_WARNING("failed to map buffer. Skipping this frame"); - gst_buffer_unref(out_buffer); - return GST_FLOW_OK; -} -#else -static GstFlowReturn -gst_vaapisink_get_render_buffer(GstVaapiSink *sink, GstBuffer *src_buffer, - GstBuffer **out_buffer_ptr) -{ - GstVaapiVideoMeta *meta; - GstBuffer *out_buffer; - - *out_buffer_ptr = NULL; - meta = gst_buffer_get_vaapi_video_meta(src_buffer); - if (meta) - out_buffer = gst_buffer_ref(src_buffer); - else if (sink->use_video_raw) { - out_buffer = gst_vaapi_uploader_get_buffer(sink->uploader); - if (!out_buffer) - goto error_create_buffer; - } - else { - GST_ERROR("unsupported video buffer"); - return GST_FLOW_EOS; - } - - if (sink->use_video_raw && - !gst_vaapi_uploader_process(sink->uploader, src_buffer, out_buffer)) - goto error_copy_buffer; - - *out_buffer_ptr = out_buffer; - return GST_FLOW_OK; - - /* ERRORS */ -error_create_buffer: - GST_WARNING("failed to create buffer. Skipping this frame"); - return GST_FLOW_OK; -error_copy_buffer: - GST_WARNING("failed to copy buffers. Skipping this frame"); - gst_buffer_unref(out_buffer); - return GST_FLOW_OK; -} -#endif - static GstFlowReturn gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) { @@ -1166,8 +966,9 @@ gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *src_buffer) } #endif - ret = gst_vaapisink_get_render_buffer(sink, src_buffer, &buffer); - if (ret != GST_FLOW_OK || !buffer) + ret = gst_vaapi_plugin_base_get_input_buffer(GST_VAAPI_PLUGIN_BASE(sink), + src_buffer, &buffer); + if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_SUPPORTED) return ret; meta = gst_buffer_get_vaapi_video_meta(buffer); @@ -1249,78 +1050,23 @@ error: static gboolean gst_vaapisink_propose_allocation(GstBaseSink *base_sink, GstQuery *query) { - GstVaapiSink * const sink = GST_VAAPISINK(base_sink); - GstCaps *caps = NULL; - gboolean need_pool; + GstVaapiPluginBase * const plugin = GST_VAAPI_PLUGIN_BASE(base_sink); - gst_query_parse_allocation(query, &caps, &need_pool); + if (!gst_vaapi_plugin_base_propose_allocation(plugin, query)) + return FALSE; - 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_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 -) +gst_vaapisink_buffer_alloc(GstBaseSink *base_sink, guint64 offset, guint size, + GstCaps *caps, GstBuffer **outbuf_ptr) { - 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, GST_VAAPI_PLUGIN_BASE_DISPLAY(sink))) - 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; + return gst_vaapi_plugin_base_allocate_input_buffer( + GST_VAAPI_PLUGIN_BASE(base_sink), caps, outbuf_ptr); } #endif diff --git a/gst/vaapi/gstvaapisink.h b/gst/vaapi/gstvaapisink.h index 8aae2ff3e6..bcabe089ec 100644 --- a/gst/vaapi/gstvaapisink.h +++ b/gst/vaapi/gstvaapisink.h @@ -31,7 +31,6 @@ #include #endif #include "gstvaapipluginutil.h" -#include "gstvaapiuploader.h" G_BEGIN_DECLS @@ -69,7 +68,6 @@ struct _GstVaapiSink { /*< private >*/ GstVaapiPluginBase parent_instance; - GstVaapiUploader *uploader; GstCaps *caps; GstVaapiWindow *window; guint window_width; @@ -96,7 +94,6 @@ struct _GstVaapiSink { guint use_overlay : 1; guint use_rotation : 1; guint keep_aspect : 1; - guint use_video_raw : 1; }; struct _GstVaapiSinkClass {