va: basedec: fallback to system memory if downstream caps is any.
authorHe Junyan <junyan.he@intel.com>
Mon, 16 Nov 2020 15:53:39 +0000 (23:53 +0800)
committerHe Junyan <junyan.he@intel.com>
Mon, 16 Nov 2020 17:21:45 +0000 (01:21 +0800)
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>

sys/va/gstvabasedec.c

index b33e854..3e9dcbd 100644 (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;