vp9: check if libvpx supports high bit depth
authorJakub Adam <jakub.adam@collabora.com>
Thu, 22 Sep 2022 17:02:10 +0000 (19:02 +0200)
committerJakub Adam <jakub.adam@collabora.com>
Fri, 23 Sep 2022 11:55:12 +0000 (13:55 +0200)
Detect at runtime if libvpx is compiled with --enable-vp9-highbitdepth
and enable 10bit video formats in element caps accordingly.

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

subprojects/gst-plugins-good/ext/vpx/gstvp9dec.c
subprojects/gst-plugins-good/ext/vpx/gstvp9enc.c

index 1aa45a2..dea6655 100644 (file)
@@ -71,30 +71,40 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     GST_STATIC_CAPS ("video/x-vp9")
     );
 
-static GstStaticPadTemplate gst_vp9_dec_src_template =
-GST_STATIC_PAD_TEMPLATE ("src",
-    GST_PAD_SRC,
-    GST_PAD_ALWAYS,
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
-        ("{ I420, YV12, Y42B, Y444, GBR, I420_10LE, I422_10LE }"))
-    );
+#define GST_VP9_DEC_VIDEO_FORMATS_8BIT "I420, YV12, Y42B, Y444, GBR"
+#define GST_VP9_DEC_VIDEO_FORMATS_10BIT "I420_10LE, I422_10LE"
 
 #define parent_class gst_vp9_dec_parent_class
 G_DEFINE_TYPE (GstVP9Dec, gst_vp9_dec, GST_TYPE_VPX_DEC);
 GST_ELEMENT_REGISTER_DEFINE_WITH_CODE (vp9dec, "vp9dec", GST_RANK_PRIMARY,
     gst_vp9_dec_get_type (), vpx_element_init (plugin));
 
+static GstCaps *
+gst_vp9_dec_get_src_caps (void)
+{
+#define CAPS_8BIT GST_VIDEO_CAPS_MAKE ("{ " GST_VP9_DEC_VIDEO_FORMATS_8BIT " }")
+#define CAPS_10BIT GST_VIDEO_CAPS_MAKE ( "{ " GST_VP9_DEC_VIDEO_FORMATS_8BIT ", " \
+    GST_VP9_DEC_VIDEO_FORMATS_10BIT "}")
+
+  return gst_caps_from_string ((vpx_codec_get_caps (&vpx_codec_vp9_dx_algo)
+          & VPX_CODEC_CAP_HIGHBITDEPTH) ? CAPS_10BIT : CAPS_8BIT);
+}
+
 static void
 gst_vp9_dec_class_init (GstVP9DecClass * klass)
 {
   GstElementClass *element_class;
   GstVPXDecClass *vpx_class;
+  GstCaps *caps;
 
   element_class = GST_ELEMENT_CLASS (klass);
   vpx_class = GST_VPX_DEC_CLASS (klass);
 
-  gst_element_class_add_static_pad_template (element_class,
-      &gst_vp9_dec_src_template);
+  caps = gst_vp9_dec_get_src_caps ();
+  gst_element_class_add_pad_template (element_class,
+      gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS, caps));
+  gst_clear_caps (&caps);
+
   gst_element_class_add_static_pad_template (element_class,
       &gst_vp9_dec_sink_template);
 
index a913837..2145996 100644 (file)
@@ -87,15 +87,8 @@ enum
   PROP_FRAME_PARALLEL_DECODING,
 };
 
-/* FIXME: Y42B do not work yet it seems */
-static GstStaticPadTemplate gst_vp9_enc_sink_template =
-GST_STATIC_PAD_TEMPLATE ("sink",
-    GST_PAD_SINK,
-    GST_PAD_ALWAYS,
-    /*GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ I420, YV12, Y42B, Y444 }")) */
-    GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
-        ("{ I420, YV12, Y444, I420_10LE, I422_10LE }"))
-    );
+#define GST_VP9_ENC_VIDEO_FORMATS_8BIT "I420, YV12, Y444"
+#define GST_VP9_ENC_VIDEO_FORMATS_10BIT "I420_10LE, I422_10LE"
 
 static GstStaticPadTemplate gst_vp9_enc_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
@@ -130,12 +123,24 @@ static gboolean gst_vp9_enc_configure_encoder (GstVPXEnc * encoder,
 
 #define DEFAULT_BITS_PER_PIXEL 0.0289
 
+static GstCaps *
+gst_vp9_enc_get_sink_caps (void)
+{
+#define CAPS_8BIT GST_VIDEO_CAPS_MAKE ("{ " GST_VP9_ENC_VIDEO_FORMATS_8BIT " }")
+#define CAPS_10BIT GST_VIDEO_CAPS_MAKE ( "{ " GST_VP9_ENC_VIDEO_FORMATS_8BIT ", " \
+    GST_VP9_ENC_VIDEO_FORMATS_10BIT "}")
+
+  return gst_caps_from_string ((vpx_codec_get_caps (gst_vp9_enc_get_algo (NULL))
+          & VPX_CODEC_CAP_HIGHBITDEPTH) ? CAPS_10BIT : CAPS_8BIT);
+}
+
 static void
 gst_vp9_enc_class_init (GstVP9EncClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *element_class;
   GstVPXEncClass *vpx_encoder_class;
+  GstCaps *caps;
 
   gobject_class = G_OBJECT_CLASS (klass);
   element_class = GST_ELEMENT_CLASS (klass);
@@ -213,8 +218,11 @@ gst_vp9_enc_class_init (GstVP9EncClass * klass)
 
   gst_element_class_add_static_pad_template (element_class,
       &gst_vp9_enc_src_template);
-  gst_element_class_add_static_pad_template (element_class,
-      &gst_vp9_enc_sink_template);
+
+  caps = gst_vp9_enc_get_sink_caps ();
+  gst_element_class_add_pad_template (element_class,
+      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps));
+  gst_clear_caps (&caps);
 
   gst_element_class_set_static_metadata (element_class,
       "On2 VP9 Encoder",