summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorHe Junyan <junyan.he@intel.com>2020-11-16 23:53:39 +0800
committerHe Junyan <junyan.he@intel.com>2020-11-17 01:21:45 +0800
commit672a30d0def1f02b6911892ddd4dfc854e1727d3 (patch)
tree72268e4c87c313201c4d25644e3be0dcf187c7c2 /sys
parentd3d2af6c84446cffcd041f76baa8781b1a560eca (diff)
downloadgstreamer-plugins-bad-672a30d0def1f02b6911892ddd4dfc854e1727d3.tar.gz
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>
Diffstat (limited to 'sys')
-rw-r--r--sys/va/gstvabasedec.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/sys/va/gstvabasedec.c b/sys/va/gstvabasedec.c
index b33e85432..3e9dcbdea 100644
--- a/sys/va/gstvabasedec.c
+++ b/sys/va/gstvabasedec.c
@@ -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;