vpx: Complete high bitdepth vp9 en/decoding support
authorSeungha Yang <seungha@centricular.com>
Sun, 30 Oct 2022 11:28:25 +0000 (20:28 +0900)
committerSeungha Yang <seungha@centricular.com>
Thu, 3 Nov 2022 20:37:58 +0000 (05:37 +0900)
Adding 12bits variant formats to en/decoder, and high bitdepth
4:4:4 (except for GBR) encoding support

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

subprojects/gst-plugins-good/docs/gst_plugins_cache.json
subprojects/gst-plugins-good/ext/vpx/gstvp9dec.c
subprojects/gst-plugins-good/ext/vpx/gstvp9enc.c
subprojects/gst-plugins-good/ext/vpx/gstvpxenc.c

index 550568f..2879352 100644 (file)
                         "presence": "always"
                     },
                     "src": {
-                        "caps": "video/x-raw:\n         format: { I420, YV12, Y42B, Y444, GBR, I420_10LE, I422_10LE }\n          width: [ 1, 2147483647 ]\n         height: [ 1, 2147483647 ]\n      framerate: [ 0/1, 2147483647/1 ]\n",
+                        "caps": "video/x-raw:\n         format: { I420, YV12, Y42B, Y444, GBR, I420_10LE, I420_12LE, I422_10LE, I422_12LE, Y444_10LE, Y444_12LE, GBR_10LE, GBR_12LE }\n          width: [ 1, 2147483647 ]\n         height: [ 1, 2147483647 ]\n      framerate: [ 0/1, 2147483647/1 ]\n",
                         "direction": "src",
                         "presence": "always"
                     }
                 "long-name": "On2 VP9 Encoder",
                 "pad-templates": {
                     "sink": {
-                        "caps": "video/x-raw:\n         format: { I420, YV12, Y444, I420_10LE, I422_10LE }\n          width: [ 1, 2147483647 ]\n         height: [ 1, 2147483647 ]\n      framerate: [ 0/1, 2147483647/1 ]\n",
+                        "caps": "video/x-raw:\n         format: { I420, YV12, Y444, I420_10LE, I420_12LE, I422_10LE, I422_12LE, Y444_10LE, Y444_12LE }\n          width: [ 1, 2147483647 ]\n         height: [ 1, 2147483647 ]\n      framerate: [ 0/1, 2147483647/1 ]\n",
                         "direction": "sink",
                         "presence": "always"
                     },
index ae9833f..3819e60 100644 (file)
@@ -72,7 +72,8 @@ GST_STATIC_PAD_TEMPLATE ("sink",
     );
 
 #define GST_VP9_DEC_VIDEO_FORMATS_8BIT "I420, YV12, Y42B, Y444, GBR"
-#define GST_VP9_DEC_VIDEO_FORMATS_10BIT "I420_10LE, I422_10LE"
+#define GST_VP9_DEC_VIDEO_FORMATS_HIGHBIT \
+    "I420_10LE, I420_12LE, I422_10LE, I422_12LE, Y444_10LE, Y444_12LE, GBR_10LE, GBR_12LE"
 
 #define parent_class gst_vp9_dec_parent_class
 G_DEFINE_TYPE (GstVP9Dec, gst_vp9_dec, GST_TYPE_VPX_DEC);
@@ -83,11 +84,11 @@ 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 "}")
+#define CAPS_HIGHBIT GST_VIDEO_CAPS_MAKE ( "{ " GST_VP9_DEC_VIDEO_FORMATS_8BIT ", " \
+    GST_VP9_DEC_VIDEO_FORMATS_HIGHBIT "}")
 
   return gst_caps_from_string ((vpx_codec_get_caps (&vpx_codec_vp9_dx_algo)
-          & VPX_CODEC_CAP_HIGHBITDEPTH) ? CAPS_10BIT : CAPS_8BIT);
+          & VPX_CODEC_CAP_HIGHBITDEPTH) ? CAPS_HIGHBIT : CAPS_8BIT);
 }
 
 static void
@@ -147,7 +148,7 @@ static gboolean
 gst_vp9_dec_get_valid_format (GstVPXDec * dec, vpx_image_t * img,
     GstVideoFormat * fmt)
 {
-  switch (img->fmt) {
+  switch ((gst_vpx_img_fmt_t) img->fmt) {
     case GST_VPX_IMG_FMT_I420:
       *fmt = GST_VIDEO_FORMAT_I420;
       return TRUE;
@@ -176,24 +177,47 @@ gst_vp9_dec_get_valid_format (GstVPXDec * dec, vpx_image_t * img,
       if (img->bit_depth == 10) {
         *fmt = GST_VIDEO_FORMAT_I420_10LE;
         return TRUE;
+      } else if (img->bit_depth == 12) {
+        *fmt = GST_VIDEO_FORMAT_I420_12LE;
+        return TRUE;
       }
-      GST_FIXME_OBJECT (dec, "Please add 16-bit I420 format");
       GST_ELEMENT_WARNING (dec, STREAM, NOT_IMPLEMENTED,
-          (NULL), ("Unsupported frame format - 16-bit 4:2:0 planar"));
+          (NULL), ("Unsupported frame format - %d-bit 4:2:0 planar",
+              img->bit_depth));
       return FALSE;
     case GST_VPX_IMG_FMT_I42216:
       if (img->bit_depth == 10) {
         *fmt = GST_VIDEO_FORMAT_I422_10LE;
         return TRUE;
+      } else if (img->bit_depth == 12) {
+        *fmt = GST_VIDEO_FORMAT_I422_12LE;
+        return TRUE;
       }
-      GST_FIXME_OBJECT (dec, "Please add 16-bit Y42B format");
       GST_ELEMENT_WARNING (dec, STREAM, NOT_IMPLEMENTED,
-          (NULL), ("Unsupported frame format - 16-bit 4:2:2 planar"));
+          (NULL), ("Unsupported frame format - %d-bit 4:2:2 planar",
+              img->bit_depth));
       return FALSE;
     case GST_VPX_IMG_FMT_I44416:
-      GST_FIXME_OBJECT (dec, "Please add 16-bit Y444 format");
+      if (img->cs == VPX_CS_SRGB) {
+        if (img->bit_depth == 10) {
+          *fmt = GST_VIDEO_FORMAT_GBR_10LE;
+          return TRUE;
+        } else if (img->bit_depth == 12) {
+          *fmt = GST_VIDEO_FORMAT_GBR_12LE;
+          return TRUE;
+        }
+      } else {
+        if (img->bit_depth == 10) {
+          *fmt = GST_VIDEO_FORMAT_Y444_10LE;
+          return TRUE;
+        } else if (img->bit_depth == 12) {
+          *fmt = GST_VIDEO_FORMAT_Y444_12LE;
+          return TRUE;
+        }
+      }
       GST_ELEMENT_WARNING (dec, STREAM, NOT_IMPLEMENTED,
-          (NULL), ("Unsupported frame format - 16-bit 4:4:4 planar"));
+          (NULL), ("Unsupported frame format - %d-bit 4:4:4 planar",
+              img->bit_depth));
       return FALSE;
     case GST_VPX_IMG_FMT_I44016:
       GST_FIXME_OBJECT (dec, "Please add 16-bit 4:4:0 planar frame format");
index e79ae2b..eb75fa1 100644 (file)
@@ -88,7 +88,8 @@ enum
 };
 
 #define GST_VP9_ENC_VIDEO_FORMATS_8BIT "I420, YV12, Y444"
-#define GST_VP9_ENC_VIDEO_FORMATS_10BIT "I420_10LE, I422_10LE"
+#define GST_VP9_ENC_VIDEO_FORMATS_HIGHBIT \
+    "I420_10LE, I420_12LE, I422_10LE, I422_12LE, Y444_10LE, Y444_12LE"
 
 static GstStaticPadTemplate gst_vp9_enc_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
@@ -127,11 +128,11 @@ 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 "}")
+#define CAPS_HIGHBIT GST_VIDEO_CAPS_MAKE ( "{ " GST_VP9_ENC_VIDEO_FORMATS_8BIT ", " \
+    GST_VP9_ENC_VIDEO_FORMATS_HIGHBIT "}")
 
   return gst_caps_from_string ((vpx_codec_get_caps (gst_vp9_enc_get_algo (NULL))
-          & VPX_CODEC_CAP_HIGHBITDEPTH) ? CAPS_10BIT : CAPS_8BIT);
+          & VPX_CODEC_CAP_HIGHBITDEPTH) ? CAPS_HIGHBIT : CAPS_8BIT);
 }
 
 static void
@@ -535,37 +536,68 @@ gst_vp9_enc_set_image_format (GstVPXEnc * enc, vpx_image_t * image)
 {
   switch (enc->input_state->info.finfo->format) {
     case GST_VIDEO_FORMAT_I420:
-      image->fmt = GST_VPX_IMG_FMT_I420;
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I420;
       image->bps = 12;
+      image->bit_depth = 8;
       image->x_chroma_shift = image->y_chroma_shift = 1;
       break;
     case GST_VIDEO_FORMAT_YV12:
-      image->fmt = GST_VPX_IMG_FMT_YV12;
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_YV12;
       image->bps = 12;
+      image->bit_depth = 8;
       image->x_chroma_shift = image->y_chroma_shift = 1;
       break;
     case GST_VIDEO_FORMAT_Y42B:
-      image->fmt = GST_VPX_IMG_FMT_I422;
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I422;
       image->bps = 16;
+      image->bit_depth = 8;
       image->x_chroma_shift = 1;
       image->y_chroma_shift = 0;
       break;
     case GST_VIDEO_FORMAT_Y444:
-      image->fmt = GST_VPX_IMG_FMT_I444;
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I444;
       image->bps = 24;
+      image->bit_depth = 8;
       image->x_chroma_shift = image->y_chroma_shift = 0;
       break;
     case GST_VIDEO_FORMAT_I420_10LE:
-      image->fmt = GST_VPX_IMG_FMT_I42016;
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I42016;
       image->bps = 15;
+      image->bit_depth = 10;
+      image->x_chroma_shift = image->y_chroma_shift = 1;
+      break;
+    case GST_VIDEO_FORMAT_I420_12LE:
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I42016;
+      image->bps = 18;
+      image->bit_depth = 12;
       image->x_chroma_shift = image->y_chroma_shift = 1;
       break;
     case GST_VIDEO_FORMAT_I422_10LE:
-      image->fmt = GST_VPX_IMG_FMT_I42216;
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I42216;
       image->bps = 20;
+      image->bit_depth = 10;
+      image->x_chroma_shift = 1;
+      image->y_chroma_shift = 0;
+      break;
+    case GST_VIDEO_FORMAT_I422_12LE:
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I42216;
+      image->bps = 24;
+      image->bit_depth = 12;
       image->x_chroma_shift = 1;
       image->y_chroma_shift = 0;
       break;
+    case GST_VIDEO_FORMAT_Y444_10LE:
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I44416;
+      image->bps = 30;
+      image->bit_depth = 10;
+      image->x_chroma_shift = image->y_chroma_shift = 0;
+      break;
+    case GST_VIDEO_FORMAT_Y444_12LE:
+      image->fmt = (vpx_img_fmt_t) GST_VPX_IMG_FMT_I44416;
+      image->bps = 36;
+      image->bit_depth = 12;
+      image->x_chroma_shift = image->y_chroma_shift = 0;
+      break;
     default:
       g_assert_not_reached ();
       break;
index 569a9f0..612a7a5 100644 (file)
@@ -1666,9 +1666,13 @@ gst_vpx_enc_get_downstream_profile (GstVPXEnc * encoder, GstVideoInfo * info)
       min_profile = 1;
       break;
     case GST_VIDEO_FORMAT_I420_10LE:
+    case GST_VIDEO_FORMAT_I420_12LE:
       min_profile = 2;
       break;
     case GST_VIDEO_FORMAT_I422_10LE:
+    case GST_VIDEO_FORMAT_I422_12LE:
+    case GST_VIDEO_FORMAT_Y444_10LE:
+    case GST_VIDEO_FORMAT_Y444_12LE:
       min_profile = 3;
       break;
     default: