msdkdec: Enable SFC csc for AVC and HEVC
authorMengkejiergeli Ba <mengkejiergeli.ba@intel.com>
Wed, 15 Dec 2021 03:49:40 +0000 (11:49 +0800)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Wed, 16 Feb 2022 08:26:46 +0000 (08:26 +0000)
Decoder SFC will be triggered when default output format is not accept at
downstream. One use case below can work without using msdkvpp:
"! msdkh265dec ! "video/x-raw,format=BGRA" ! glimagesink",

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

subprojects/gst-plugins-bad/sys/msdk/gstmsdkdec.c
subprojects/gst-plugins-bad/sys/msdk/gstmsdkh264dec.c
subprojects/gst-plugins-bad/sys/msdk/gstmsdkh265dec.c

index 098ddcfd39212569808f3b588b7b658576e1cb28..11ae8467d73ff598ffec2c8dead01604ebfc3a0d 100644 (file)
@@ -581,10 +581,15 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
   GstVideoInfo *vinfo;
   GstVideoAlignment align;
   GstCaps *allocation_caps = NULL;
+  GstCaps *allowed_caps, *temp_caps;
   GstVideoFormat format;
   guint width, height;
   guint alloc_w, alloc_h;
   const gchar *format_str;
+  GstStructure *outs;
+  const gchar *out_format;
+  GValue v_format = G_VALUE_INIT;
+
 
   /* use display width and display height in output state, which
    * will be used for caps negotiation */
@@ -603,6 +608,37 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
     GST_WARNING_OBJECT (thiz, "Failed to find a valid video format");
     return FALSE;
   }
+#if (MFX_VERSION >= 1022)
+  /* SFC is triggered (for AVC and HEVC) when default output format is not
+   * accepted by downstream.
+   * For SFC csc, need to do the query twice: the first time uses default
+   * color format to query peer pad, empty caps means default format is
+   * not accepted by downstream; then we need the second query to decide
+   * src caps color format and let SFC work. */
+  if (thiz->param.mfx.CodecId == MFX_CODEC_AVC ||
+      thiz->param.mfx.CodecId == MFX_CODEC_HEVC) {
+    temp_caps = gst_pad_query_caps (GST_VIDEO_DECODER (thiz)->srcpad, NULL);
+    temp_caps = gst_caps_make_writable (temp_caps);
+
+    g_value_init (&v_format, G_TYPE_STRING);
+    g_value_set_string (&v_format, gst_video_format_to_string (format));
+    gst_caps_set_value (temp_caps, "format", &v_format);
+
+    if (gst_caps_is_empty (gst_pad_peer_query_caps (GST_VIDEO_DECODER
+                (thiz)->srcpad, temp_caps))) {
+      allowed_caps =
+          gst_pad_get_allowed_caps (GST_VIDEO_DECODER (thiz)->srcpad);
+      outs = gst_caps_get_structure (allowed_caps, 0);
+      out_format = gst_structure_get_string (outs, "format");
+      if (out_format) {
+        format = gst_video_format_from_string (out_format);
+        thiz->sfc = TRUE;
+      }
+      gst_caps_unref (allowed_caps);
+    }
+    gst_caps_unref (temp_caps);
+  }
+#endif
 
   output_state =
       gst_video_decoder_set_output_state (GST_VIDEO_DECODER (thiz),
index 4710e1ab4238013d645d3510bb3974b3800650dd..1fcc9437d746e4d634d732fbb4666149bfc9f527 100644 (file)
@@ -54,6 +54,8 @@
 GST_DEBUG_CATEGORY_EXTERN (gst_msdkh264dec_debug);
 #define GST_CAT_DEFAULT gst_msdkh264dec_debug
 
+#define COMMON_FORMAT "{ NV12, BGRA, BGRx }"
+
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
@@ -63,6 +65,12 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
         "profile = (string) { high, progressive-high, constrained-high, main, baseline, constrained-baseline }")
     );
 
+static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
+    GST_PAD_SRC,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS (GST_MSDK_CAPS_STR (COMMON_FORMAT, COMMON_FORMAT))
+    );
+
 #define gst_msdkh264dec_parent_class parent_class
 G_DEFINE_TYPE (GstMsdkH264Dec, gst_msdkh264dec, GST_TYPE_MSDKDEC);
 
@@ -181,6 +189,7 @@ gst_msdkh264dec_class_init (GstMsdkH264DecClass * klass)
 #endif
 
   gst_element_class_add_static_pad_template (element_class, &sink_factory);
+  gst_element_class_add_static_pad_template (element_class, &src_factory);
 }
 
 static void
index fe41c09f048443fef47d188ae2ab7395c3b552f1..6b0e4d440b8507fd3fc83b77bff380c33f236bc6 100644 (file)
@@ -56,7 +56,7 @@ GST_DEBUG_CATEGORY_EXTERN (gst_msdkh265dec_debug);
 #define GST_CAT_DEFAULT gst_msdkh265dec_debug
 
 #define COMMON_FORMAT \
-  "{ NV12, P010_10LE, YUY2, Y210, VUYA, Y410, P012_LE, Y212_LE, Y412_LE }"
+  "{ NV12, P010_10LE, YUY2, Y210, VUYA, Y410, P012_LE, Y212_LE, Y412_LE, BGRA, BGRx }"
 
 /* TODO: update both sink and src dynamically */
 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",