va: basedec: fallback to system memory if downstream caps is any.

When the downstream element reports an ANY caps, and it also fails to
support VideoMeta, we should fallback to the system memory.
Note: the basetransform kind elements never return valid allocation
query before set_caps(). So, if a basetransform return an ANY sink
caps, we always fallback to system memory for it.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1711>
This commit is contained in:
He Junyan 2020-11-16 23:53:39 +08:00
parent d3d2af6c84
commit 672a30d0de

View file

@ -438,6 +438,22 @@ _default_video_format_from_chroma (guint chroma_type)
}
}
/* Check whether the downstream supports VideoMeta; if not, we need to
* fallback to the system memory. */
static gboolean
_downstream_has_video_meta (GstVaBaseDec * base, GstCaps * caps)
{
GstQuery *query;
gboolean ret = FALSE;
query = gst_query_new_allocation (caps, FALSE);
if (gst_pad_peer_query (GST_VIDEO_DECODER_SRC_PAD (base), query))
ret = gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
gst_query_unref (query);
return ret;
}
void
gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
GstVideoFormat * format, GstCapsFeatures ** capsfeatures)
@ -447,9 +463,18 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
GstStructure *structure;
const GValue *v_format;
guint num_structures, i;
gboolean is_any;
g_return_if_fail (base);
/* verify if peer caps is any */
{
peer_caps =
gst_pad_peer_query_caps (GST_VIDEO_DECODER_SRC_PAD (base), NULL);
is_any = gst_caps_is_any (peer_caps);
gst_clear_caps (&peer_caps);
}
peer_caps = gst_pad_get_allowed_caps (GST_VIDEO_DECODER_SRC_PAD (base));
GST_DEBUG_OBJECT (base, "Allowed caps %" GST_PTR_FORMAT, peer_caps);
@ -475,19 +500,32 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
else
gst_clear_caps (&peer_caps);
if (gst_caps_is_empty (preferred_caps)
|| gst_caps_is_any (preferred_caps)) {
/* if any or not linked yet then system memory and nv12 */
if (gst_caps_is_empty (preferred_caps)) {
if (capsfeatures)
*capsfeatures = NULL;
*capsfeatures = NULL; /* system memory */
if (format)
*format = _default_video_format_from_chroma (base->rt_format);
goto bail;
}
features = gst_caps_get_features (preferred_caps, 0);
if (features && capsfeatures)
*capsfeatures = gst_caps_features_copy (features);
if (capsfeatures) {
features = gst_caps_get_features (preferred_caps, 0);
if (features) {
*capsfeatures = gst_caps_features_copy (features);
if (is_any
&& !gst_caps_features_is_equal (features,
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
&& !_downstream_has_video_meta (base, preferred_caps)) {
GST_INFO_OBJECT (base, "Downstream reports ANY caps but without"
" VideoMeta support; fallback to system memory.");
gst_caps_features_free (*capsfeatures);
*capsfeatures = NULL;
}
} else {
*capsfeatures = NULL;
}
}
if (!format)
goto bail;