va: basedec: Select format from template or negotiated caps.
authorVíctor Manuel Jáquez Leal <vjaquez@igalia.com>
Wed, 30 Mar 2022 15:19:54 +0000 (17:19 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 9 May 2022 08:50:58 +0000 (08:50 +0000)
Instead of using a hard-coded list of preferred formats according the
chroma type, now if now caps are pre-negotiated, from template caps
will choose the first format with the same chroma type. If
pre-negotiated, then it will choose the first format, with same chroma
type, from the first caps structure.

Also all the decoders will check if GST_VIDEO_FORMAT_UNKNOWN is
returned, failing the negotiation.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2351>

subprojects/gst-plugins-bad/sys/va/gstvaav1dec.c
subprojects/gst-plugins-bad/sys/va/gstvabasedec.c
subprojects/gst-plugins-bad/sys/va/gstvah264dec.c
subprojects/gst-plugins-bad/sys/va/gstvah265dec.c
subprojects/gst-plugins-bad/sys/va/gstvampeg2dec.c
subprojects/gst-plugins-bad/sys/va/gstvavp8dec.c
subprojects/gst-plugins-bad/sys/va/gstvavp9dec.c

index 266e6c493f3454f4088286f8f010954da85db7b3..8bbaa114b71fb49f2538e91ba55e34a7e467cd7f 100644 (file)
@@ -124,6 +124,8 @@ gst_va_av1_dec_negotiate (GstVideoDecoder * decoder)
 
   gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
       &capsfeatures);
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return FALSE;
 
   base->output_state = gst_video_decoder_set_output_state (decoder, format,
       base->width, base->height, av1dec->input_state);
index a05cd4747cf12d0b152eb8f0b7917b01a3c58ba5..e7eee2c30c57da27c2dacbc409acdc905e646a4b 100644 (file)
@@ -696,33 +696,67 @@ gst_va_base_dec_class_init (GstVaBaseDecClass * klass, GstVaCodecs codec,
 }
 
 static GstVideoFormat
-_default_video_format_from_chroma (guint chroma_type)
+_find_video_format_from_chroma (const GValue * formats, guint chroma_type)
 {
-  switch (chroma_type) {
-      /* 4:2:0 */
-    case VA_RT_FORMAT_YUV420:
-      return GST_VIDEO_FORMAT_NV12;
-    case VA_RT_FORMAT_YUV420_10:
-      return GST_VIDEO_FORMAT_P010_10LE;
-    case VA_RT_FORMAT_YUV420_12:
-      return GST_VIDEO_FORMAT_P012_LE;
-      /* 4:2:2 */
-    case VA_RT_FORMAT_YUV422:
-      return GST_VIDEO_FORMAT_UYVY;
-    case VA_RT_FORMAT_YUV422_10:
-      return GST_VIDEO_FORMAT_Y210;
-    case VA_RT_FORMAT_YUV422_12:
-      return GST_VIDEO_FORMAT_Y212_LE;
-      /* 4:4:4 */
-    case VA_RT_FORMAT_YUV444:
-      return GST_VIDEO_FORMAT_VUYA;
-    case VA_RT_FORMAT_YUV444_10:
-      return GST_VIDEO_FORMAT_Y410;
-    case VA_RT_FORMAT_YUV444_12:
-      return GST_VIDEO_FORMAT_Y412_LE;
-    default:
-      return GST_VIDEO_FORMAT_UNKNOWN;
+  GstVideoFormat fmt;
+  guint i, num_values;
+
+  if (!formats)
+    return GST_VIDEO_FORMAT_UNKNOWN;
+
+  if (G_VALUE_HOLDS_STRING (formats)) {
+    fmt = gst_video_format_from_string (g_value_get_string (formats));
+    if (gst_va_chroma_from_video_format (fmt) == chroma_type)
+      return fmt;
+  } else if (GST_VALUE_HOLDS_LIST (formats)) {
+    num_values = gst_value_list_get_size (formats);
+    for (i = 0; i < num_values; i++) {
+      const GValue *val = gst_value_list_get_value (formats, i);
+      if (!val)
+        continue;
+      fmt = gst_video_format_from_string (g_value_get_string (val));
+      if (gst_va_chroma_from_video_format (fmt) == chroma_type)
+        return fmt;
+    }
   }
+
+  return GST_VIDEO_FORMAT_UNKNOWN;
+}
+
+static GstVideoFormat
+_caps_video_format_from_chroma (GstCaps * caps, GstCapsFeatures * features,
+    guint chroma_type)
+{
+  guint i, num_structures;
+  GstCapsFeatures *feats;
+  GstStructure *structure;
+  const GValue *format;
+
+  num_structures = gst_caps_get_size (caps);
+  for (i = 0; i < num_structures; i++) {
+    feats = gst_caps_get_features (caps, i);
+    if (!gst_caps_features_is_equal (feats, features))
+      continue;
+    structure = gst_caps_get_structure (caps, i);
+    format = gst_structure_get_value (structure, "format");
+    return _find_video_format_from_chroma (format, chroma_type);
+  }
+
+  return GST_VIDEO_FORMAT_UNKNOWN;
+}
+
+static GstVideoFormat
+_default_video_format_from_chroma (GstVaBaseDec * base,
+    GstCapsFeatures * features, guint chroma_type)
+{
+  GstCaps *tmpl_caps;
+  GstVideoFormat ret = GST_VIDEO_FORMAT_UNKNOWN;
+
+  tmpl_caps = gst_pad_get_pad_template_caps (GST_VIDEO_DECODER_SRC_PAD (base));
+  ret = _caps_video_format_from_chroma (tmpl_caps, features, chroma_type);
+  gst_caps_unref (tmpl_caps);
+
+  return ret;
 }
 
 /* Check whether the downstream supports VideoMeta; if not, we need to
@@ -790,11 +824,15 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
   if (gst_caps_is_empty (preferred_caps)) {
     if (capsfeatures)
       *capsfeatures = NULL;     /* system memory */
-    if (format)
-      *format = _default_video_format_from_chroma (base->rt_format);
+    if (format) {
+      *format = _default_video_format_from_chroma (base,
+          GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, base->rt_format);
+    }
     goto bail;
   }
 
+  /* Use the first structure/feature is caps because is the
+   * "preferred" one */
   if (capsfeatures) {
     features = gst_caps_get_features (preferred_caps, 0);
     if (features) {
@@ -812,33 +850,22 @@ gst_va_base_dec_get_preferred_format_and_caps_features (GstVaBaseDec * base,
     } else {
       *capsfeatures = NULL;
     }
+
+    if (!*capsfeatures && format) {
+      *format = _default_video_format_from_chroma (base,
+          GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, base->rt_format);
+
+      goto bail;
+    }
   }
 
   if (!format)
     goto bail;
 
+
   structure = gst_caps_get_structure (preferred_caps, 0);
   v_format = gst_structure_get_value (structure, "format");
-  if (!v_format)
-    *format = _default_video_format_from_chroma (base->rt_format);
-  else if (G_VALUE_HOLDS_STRING (v_format))
-    *format = gst_video_format_from_string (g_value_get_string (v_format));
-  else if (GST_VALUE_HOLDS_LIST (v_format)) {
-    guint num_values = gst_value_list_get_size (v_format);
-    for (i = 0; i < num_values; i++) {
-      GstVideoFormat fmt;
-      const GValue *v_fmt = gst_value_list_get_value (v_format, i);
-      if (!v_fmt)
-        continue;
-      fmt = gst_video_format_from_string (g_value_get_string (v_fmt));
-      if (gst_va_chroma_from_video_format (fmt) == base->rt_format) {
-        *format = fmt;
-        break;
-      }
-    }
-    if (i == num_values)
-      *format = _default_video_format_from_chroma (base->rt_format);
-  }
+  *format = _find_video_format_from_chroma (v_format, base->rt_format);
 
 bail:
   gst_clear_caps (&preferred_caps);
index e47c86f7bc2a45165d0c5ddc330cac8b1ee9e168..cf7d55c4b143755440b94dd7bdfebaac1679e233 100644 (file)
@@ -845,6 +845,8 @@ gst_va_h264_dec_negotiate (GstVideoDecoder * decoder)
 
   gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
       &capsfeatures);
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return FALSE;
 
   base->output_state =
       gst_video_decoder_set_output_state (decoder, format,
index 4494446930c37be7d6cdae330f8c4e08415e4b47..275a209335d48e04b0e97cf10aafe225736b45e5 100644 (file)
@@ -1231,6 +1231,8 @@ gst_va_h265_dec_negotiate (GstVideoDecoder * decoder)
 
   gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
       &capsfeatures);
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return FALSE;
 
   base->output_state =
       gst_video_decoder_set_output_state (decoder, format,
index 641eba852235a329ba71e6b743a062bc8f1de351..4cfc929c0159bd74795cd12401065257c93d08fd 100644 (file)
@@ -115,6 +115,8 @@ gst_va_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
 
   gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
       &capsfeatures);
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return FALSE;
 
   base->output_state =
       gst_video_decoder_set_output_state (decoder, format,
index 8863426d3a6d9e794b7fffbb1dc6a50eef4b8ba4..e4d91513850d523ac4ee7fb0741854eba8f00663 100644 (file)
@@ -114,6 +114,8 @@ gst_va_vp8_dec_negotiate (GstVideoDecoder * decoder)
 
   gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
       &capsfeatures);
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return FALSE;
 
   base->output_state =
       gst_video_decoder_set_output_state (decoder, format,
index ae9e47bf570faad74c09138dcdb1071c166b2a7b..86af8ceba5ceaac79380c118457a98084c55861e 100644 (file)
@@ -601,6 +601,8 @@ gst_va_vp9_dec_negotiate (GstVideoDecoder * decoder)
 
   gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
       &capsfeatures);
+  if (format == GST_VIDEO_FORMAT_UNKNOWN)
+    return FALSE;
 
   base->output_state =
       gst_video_decoder_set_output_state (decoder, format,