From ef6e186801fe664e5c22281f0a5d6f98176b3607 Mon Sep 17 00:00:00 2001 From: Sreerenj Balachandran Date: Mon, 30 Apr 2018 12:39:52 -0800 Subject: [PATCH] msdk: vpp: Add dmabuf-export support Currenly, the dmabuf buffer pool can be negotiated only through DMABuf capsfeatures. This will not allow to negotiate dmabuf support with v4l2src (v4l2src ! msdkvpp) where v4l2src always export the dmabuf based memory with out using the DMABuf capsfeatures. So it requires fix based on: https://bugzilla.gnome.org/show_bug.cgi?id=794817 https://bugzilla.gnome.org/show_bug.cgi?id=794946 --- sys/msdk/gstmsdkvpp.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++---- sys/msdk/gstmsdkvpp.h | 2 + 2 files changed, 108 insertions(+), 8 deletions(-) diff --git a/sys/msdk/gstmsdkvpp.c b/sys/msdk/gstmsdkvpp.c index 774c265..61405bf 100644 --- a/sys/msdk/gstmsdkvpp.c +++ b/sys/msdk/gstmsdkvpp.c @@ -48,19 +48,23 @@ GST_DEBUG_CATEGORY_EXTERN (gst_msdkvpp_debug); #define GST_CAT_DEFAULT gst_msdkvpp_debug static GstStaticPadTemplate gst_msdkvpp_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ NV12, YV12, I420, YUY2, UYVY, BGRA, BGRx }") - ", " "interlace-mode = (string){ progressive, interleaved, mixed }")); + ", " "interlace-mode = (string){ progressive, interleaved, mixed }" ";" + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF, + "{ NV12, BGRA, YUY2}"))); static GstStaticPadTemplate gst_msdkvpp_src_factory = -GST_STATIC_PAD_TEMPLATE ("src", + GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ NV12, YUY2, BGRA, BGRx }") ", " - "interlace-mode = (string){ progressive, interleaved, mixed }")); + "interlace-mode = (string){ progressive, interleaved, mixed }" ";" + GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF, + "{ NV12, BGRA, YUY2}"))); enum { @@ -220,13 +224,16 @@ gst_msdkvpp_create_buffer_pool (GstMsdkVPP * thiz, GstPadDirection direction, GstVideoAlignment align; GstAllocationParams params = { 0, 31, 0, 0, }; mfxFrameAllocResponse *alloc_resp = NULL; + gboolean use_dmabuf = FALSE; if (direction == GST_PAD_SINK) { alloc_resp = &thiz->in_alloc_resp; pool_info = &thiz->sinkpad_buffer_pool_info; + use_dmabuf = thiz->use_sinkpad_dmabuf; } else if (direction == GST_PAD_SRC) { alloc_resp = &thiz->out_alloc_resp; pool_info = &thiz->srcpad_buffer_pool_info; + use_dmabuf = thiz->use_srcpad_dmabuf; } pool = gst_msdk_buffer_pool_new (thiz->context, alloc_resp); @@ -239,7 +246,10 @@ gst_msdkvpp_create_buffer_pool (GstMsdkVPP * thiz, GstPadDirection direction, gst_msdk_set_video_alignment (&info, &align); gst_video_info_align (&info, &align); - if (thiz->use_video_memory) + if (use_dmabuf) + allocator = + gst_msdk_dmabuf_allocator_new (thiz->context, &info, alloc_resp); + else if (thiz->use_video_memory) allocator = gst_msdk_video_allocator_new (thiz->context, &info, alloc_resp); else allocator = gst_msdk_system_allocator_new (&info); @@ -254,9 +264,13 @@ gst_msdkvpp_create_buffer_pool (GstMsdkVPP * thiz, GstPadDirection direction, gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); - if (thiz->use_video_memory) + if (thiz->use_video_memory) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY); + if (use_dmabuf) + gst_buffer_pool_config_add_option (config, + GST_BUFFER_POOL_OPTION_MSDK_USE_DMABUF); + } gst_buffer_pool_config_set_video_alignment (config, &align); gst_buffer_pool_config_set_allocator (config, allocator, ¶ms); @@ -299,6 +313,22 @@ error_pool_config: } static gboolean +_gst_caps_has_feature (const GstCaps * caps, const gchar * feature) +{ + guint i; + + for (i = 0; i < gst_caps_get_size (caps); i++) { + GstCapsFeatures *const features = gst_caps_get_features (caps, i); + /* Skip ANY features, we need an exact match for correct evaluation */ + if (gst_caps_features_is_any (features)) + continue; + if (gst_caps_features_contains (features, feature)) + return TRUE; + } + return FALSE; +} + +static gboolean gst_msdkvpp_decide_allocation (GstBaseTransform * trans, GstQuery * query) { GstMsdkVPP *thiz = GST_MSDKVPP (trans); @@ -320,6 +350,12 @@ gst_msdkvpp_decide_allocation (GstBaseTransform * trans, GstQuery * query) GST_ERROR_OBJECT (thiz, "Failed to get video info"); return FALSE; } + /* if downstream allocation query supports dmabuf-capsfeatures, + * we do allocate dmabuf backed memory */ + if (_gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_DMABUF)) { + GST_INFO_OBJECT (thiz, "MSDK VPP srcpad uses DMABuf memory"); + thiz->use_srcpad_dmabuf = TRUE; + } if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) thiz->add_video_meta = TRUE; @@ -397,6 +433,13 @@ gst_msdkvpp_propose_allocation (GstBaseTransform * trans, return FALSE; } + /* if upstream allocation query supports dmabuf-capsfeatures, + * we do allocate dmabuf backed memory */ + if (_gst_caps_has_feature (caps, GST_CAPS_FEATURE_MEMORY_DMABUF)) { + GST_INFO_OBJECT (thiz, "MSDK VPP srcpad uses DMABuf memory"); + thiz->use_sinkpad_dmabuf = TRUE; + } + if (need_pool) { /* alwys provide a new pool for upstream to help re-negotiation * more info here: https://bugzilla.gnome.org/show_bug.cgi?id=748344 */ @@ -859,8 +902,15 @@ gst_msdkvpp_initialize (GstMsdkVPP * thiz) if (thiz->use_video_memory) { /* Input surface pool pre-allocation */ + request[0].Type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + if (thiz->use_sinkpad_dmabuf) + request[0].Type |= MFX_MEMTYPE_EXPORT_FRAME; gst_msdk_frame_alloc (thiz->context, &(request[0]), &thiz->in_alloc_resp); + /* Output surface pool pre-allocation */ + request[1].Type |= MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET; + if (thiz->use_srcpad_dmabuf) + request[1].Type |= MFX_MEMTYPE_EXPORT_FRAME; gst_msdk_frame_alloc (thiz->context, &(request[1]), &thiz->out_alloc_resp); } @@ -948,21 +998,69 @@ gst_msdkvpp_set_caps (GstBaseTransform * trans, GstCaps * caps, return TRUE; } +static gboolean +pad_can_dmabuf (GstMsdkVPP * thiz, GstPadDirection direction, GstCaps * filter) +{ + gboolean ret = FALSE; + GstCaps *caps, *out_caps; + GstPad *pad; + GstBaseTransform *trans = GST_BASE_TRANSFORM (thiz); + + if (direction == GST_PAD_SRC) + pad = GST_BASE_TRANSFORM_SRC_PAD (trans); + else + pad = GST_BASE_TRANSFORM_SINK_PAD (trans); + + /* make a copy of filter caps since we need to alter the structure + * by adding dmabuf-capsfeatures */ + caps = gst_caps_copy (filter); + gst_caps_set_features (caps, 0, + gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF)); + + out_caps = gst_pad_peer_query_caps (pad, caps); + if (!out_caps) + goto done; + + if (gst_caps_is_any (out_caps) || gst_caps_is_empty (out_caps) + || out_caps == caps) + goto done; + + if (_gst_caps_has_feature (out_caps, GST_CAPS_FEATURE_MEMORY_DMABUF)) + ret = TRUE; +done: + if (caps) + gst_caps_unref (caps); + if (out_caps) + gst_caps_unref (out_caps); + return ret; +} + static GstCaps * gst_msdkvpp_fixate_caps (GstBaseTransform * trans, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps) { GstMsdkVPP *thiz = GST_MSDKVPP (trans); GstCaps *result = NULL; + gboolean *use_dmabuf; - if (direction == GST_PAD_SRC) + if (direction == GST_PAD_SRC) { result = gst_caps_fixate (result); - else { + use_dmabuf = &thiz->use_sinkpad_dmabuf; + } else { result = gst_msdkvpp_fixate_srccaps (thiz, caps, othercaps); + use_dmabuf = &thiz->use_srcpad_dmabuf; } GST_DEBUG_OBJECT (trans, "fixated to %" GST_PTR_FORMAT, result); gst_caps_unref (othercaps); + + if (pad_can_dmabuf (thiz, + direction == GST_PAD_SRC ? GST_PAD_SINK : GST_PAD_SRC, result)) { + gst_caps_set_features (result, 0, + gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_DMABUF, NULL)); + *use_dmabuf = TRUE; + } + return result; } diff --git a/sys/msdk/gstmsdkvpp.h b/sys/msdk/gstmsdkvpp.h index 57cf829..3e0e8d7 100644 --- a/sys/msdk/gstmsdkvpp.h +++ b/sys/msdk/gstmsdkvpp.h @@ -96,6 +96,8 @@ struct _GstMsdkVPP mfxFrameAllocResponse out_alloc_resp; gboolean use_video_memory; + gboolean use_sinkpad_dmabuf; + gboolean use_srcpad_dmabuf; gboolean shared_context; gboolean add_video_meta; guint flags; -- 2.7.4