From 805ff6346ac186eeef9b269711d034ba864b006d Mon Sep 17 00:00:00 2001 From: He Junyan Date: Mon, 15 Mar 2021 00:04:21 +0800 Subject: [PATCH] va: vpp: Fix features lost in transform_caps(). When we transform the caps from the sink to src, or vice versa, the "caps" passed to us may only contain parts of the features. Which makes our vpp lose some feature in caps and get a negotiation error. The correct way should be: Cleaning the format and resolution of that caps, but adding all VA, DMA features to it, making it a full feature caps. Then, clipping it with the pad template. fixes: #1551 Part-of: --- sys/va/gstvavpp.c | 95 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 24 deletions(-) diff --git a/sys/va/gstvavpp.c b/sys/va/gstvavpp.c index a81a233..a085ad8 100644 --- a/sys/va/gstvavpp.c +++ b/sys/va/gstvavpp.c @@ -1285,15 +1285,21 @@ gst_va_vpp_transform_meta (GstBaseTransform * trans, GstBuffer * inbuf, meta, inbuf); } +/* Remove all the info for the cases when we can actually convert: + * Delete all the video "format", rangify the resolution size, also + * remove "colorimetry", "chroma-site" and "pixel-aspect-ratio". All + * the missing caps features should be added based on the template, + * and the caps features' order in @caps is kept */ static GstCaps * -gst_va_vpp_caps_remove_format_and_rangify_size_info (GstCaps * caps) +gst_va_vpp_complete_caps_features (GstCaps * caps, GstCaps * tmpl_caps) { - GstCaps *ret; + GstCaps *ret, *full_caps; GstStructure *structure; GstCapsFeatures *features; + gboolean has_sys_mem = FALSE, has_dma = FALSE, has_va = FALSE; gint i, n; - ret = gst_caps_new_empty (); + full_caps = gst_caps_new_empty (); n = gst_caps_get_size (caps); for (i = 0; i < n; i++) { @@ -1302,31 +1308,73 @@ gst_va_vpp_caps_remove_format_and_rangify_size_info (GstCaps * caps) /* If this is already expressed by the existing caps * skip this structure */ - if (i > 0 && gst_caps_is_subset_structure_full (ret, structure, features)) + if (i > 0 + && gst_caps_is_subset_structure_full (full_caps, structure, features)) continue; - structure = gst_structure_copy (structure); - /* Only remove format info for the cases when we can actually convert */ - if (!gst_caps_features_is_any (features) - && (gst_caps_features_is_equal (features, - GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) - || gst_caps_features_contains (features, - GST_CAPS_FEATURE_MEMORY_DMABUF) - || gst_caps_features_contains (features, "memory:VAMemory"))) { - gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, - "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); - /* if pixel aspect ratio, make a range of it */ - if (gst_structure_has_field (structure, "pixel-aspect-ratio")) { - gst_structure_set (structure, "pixel-aspect-ratio", - GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1, NULL); + if (gst_caps_features_is_any (features)) + continue; + + if (gst_caps_features_is_equal (features, + GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) { + has_sys_mem = TRUE; + } else { + gboolean valid = FALSE; + + if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF)) { + has_dma = TRUE; + valid = TRUE; } - gst_structure_remove_fields (structure, "format", "colorimetry", - "chroma-site", NULL); + if (gst_caps_features_contains (features, "memory:VAMemory")) { + has_va = TRUE; + valid = TRUE; + } + /* Not contain our supported feature */ + if (!valid) + continue; + } + + structure = gst_structure_copy (structure); + + gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT, + "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL); + /* if pixel aspect ratio, make a range of it */ + if (gst_structure_has_field (structure, "pixel-aspect-ratio")) { + gst_structure_set (structure, "pixel-aspect-ratio", + GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1, NULL); } - gst_caps_append_structure_full (ret, structure, + gst_structure_remove_fields (structure, "format", "colorimetry", + "chroma-site", NULL); + + gst_caps_append_structure_full (full_caps, structure, gst_caps_features_copy (features)); } + /* Adding the missing features. */ + n = gst_caps_get_size (tmpl_caps); + for (i = 0; i < n; i++) { + structure = gst_caps_get_structure (tmpl_caps, i); + features = gst_caps_get_features (tmpl_caps, i); + + if (gst_caps_features_contains (features, "memory:VAMemory") && !has_va) + gst_caps_append_structure_full (full_caps, gst_structure_copy (structure), + gst_caps_features_copy (features)); + + if (gst_caps_features_contains (features, + GST_CAPS_FEATURE_MEMORY_DMABUF) && !has_dma) + gst_caps_append_structure_full (full_caps, gst_structure_copy (structure), + gst_caps_features_copy (features)); + + if (gst_caps_features_is_equal (features, + GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY) && !has_sys_mem) + gst_caps_append_structure_full (full_caps, gst_structure_copy (structure), + gst_caps_features_copy (features)); + } + + ret = gst_caps_intersect_full (full_caps, tmpl_caps, + GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (full_caps); + return ret; } @@ -1341,8 +1389,6 @@ gst_va_vpp_transform_caps (GstBaseTransform * trans, GstPadDirection direction, "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps, (direction == GST_PAD_SINK) ? "sink" : "src"); - caps = gst_va_vpp_caps_remove_format_and_rangify_size_info (caps); - if (direction == GST_PAD_SINK) { tmpl_caps = gst_pad_get_pad_template_caps (GST_BASE_TRANSFORM_SRC_PAD (trans)); @@ -1351,7 +1397,8 @@ gst_va_vpp_transform_caps (GstBaseTransform * trans, GstPadDirection direction, gst_pad_get_pad_template_caps (GST_BASE_TRANSFORM_SINK_PAD (trans)); } - ret = gst_caps_intersect_full (tmpl_caps, caps, GST_CAPS_INTERSECT_FIRST); + ret = gst_va_vpp_complete_caps_features (caps, tmpl_caps); + gst_caps_unref (tmpl_caps); if (filter) { -- 2.7.4