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: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/2081>
This commit is contained in:
He Junyan 2021-03-15 00:04:21 +08:00 committed by Víctor Manuel Jáquez Leal
parent 8a0224a198
commit 805ff6346a

View file

@ -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;
}
gst_caps_append_structure_full (ret, structure,
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_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) {