diff mbox series

[FFmpeg-devel,1/3] lavu/pixfmt: Add P012, Y212, XV30, and XV36 formats

Message ID 20220826021736.355903-2-philipl@overt.org
State New
Headers show
Series V5: VAAPI: Add high bit depth encode/decode support | expand

Commit Message

Philip Langdale Aug. 26, 2022, 2:17 a.m. UTC
These are the formats we want/need to use when dealing with the Intel
VAAPI decoder for 12bit 4:2:0, 12bit 4:2:2, 10bit 4:4:4 and 12bit 4:4:4
respectively.

As with the already supported Y210 and YUVX (XVUY) formats, they are
based on formats Microsoft picked as their preferred 4:2:2 and 4:4:4
video formats, and Intel ran with it.

P12 and Y212 are simply an extension of 10 bit formats to say 12 bits
will be used, with 4 unused bits instead of 6.

XV30, and XV36, as exotic as they sound, are variants of Y410 and Y412
where the alpha channel is left formally undefined. We prefer these
over the alpha versions because the hardware cannot actually do
anything with the alpha channel and respecting it is just overhead.

Y412/XV46 is a normal looking packed 4 channel format where each
channel is 16bits wide but only the 12msb are used (like P012).

Y410/XV30 packs three 10bit channels in 32bits with 2bits of alpha,
like A/X2RGB10 style formats. This annoying layout forced me to define
the BE version as a bitstream format. It seems like our pixdesc
infrastructure can handle the LE version being byte-defined, but not
when it's reversed. If there's a better way to handle this, please
let me know. Our existing X2 formats all have the 2 bits at the MSB
end, but this format places them at the LSB end and that seems to be
the root of the problem.

Signed-off-by: Philip Langdale <philipl@overt.org>
---
 libavutil/pixdesc.c              | 95 +++++++++++++++++++++++++++++++-
 libavutil/pixfmt.h               | 16 ++++++
 tests/ref/fate/imgutils          |  8 +++
 tests/ref/fate/sws-pixdesc-query | 38 +++++++++++++
 4 files changed, 156 insertions(+), 1 deletion(-)

Comments

James Almer Sept. 5, 2022, 2:51 p.m. UTC | #1
On 8/25/2022 11:17 PM, Philip Langdale wrote:
>   static const char * const color_range_names[] = {
> @@ -2778,7 +2871,7 @@ void ff_check_pixfmt_descriptors(void){
>   
>           if (!d->name && !d->nb_components && !d->log2_chroma_w && !d->log2_chroma_h && !d->flags)
>               continue;
> -//         av_log(NULL, AV_LOG_DEBUG, "Checking: %s\n", d->name);
> +        av_log(NULL, AV_LOG_INFO, "Checking: %s\n", d->name);
>           av_assert0(d->log2_chroma_w <= 3);
>           av_assert0(d->log2_chroma_h <= 3);
>           av_assert0(d->nb_components <= 4);

Unintended change?
Philip Langdale Sept. 5, 2022, 6:09 p.m. UTC | #2
On Mon, 5 Sep 2022 11:51:56 -0300
James Almer <jamrial@gmail.com> wrote:

> On 8/25/2022 11:17 PM, Philip Langdale wrote:
> >   static const char * const color_range_names[] = {
> > @@ -2778,7 +2871,7 @@ void ff_check_pixfmt_descriptors(void){
> >   
> >           if (!d->name && !d->nb_components && !d->log2_chroma_w &&
> > !d->log2_chroma_h && !d->flags) continue;
> > -//         av_log(NULL, AV_LOG_DEBUG, "Checking: %s\n", d->name);
> > +        av_log(NULL, AV_LOG_INFO, "Checking: %s\n", d->name);
> >           av_assert0(d->log2_chroma_w <= 3);
> >           av_assert0(d->log2_chroma_h <= 3);
> >           av_assert0(d->nb_components <= 4);  
> 
> Unintended change?

Actually intended. Because if there is a problem and the assert fails,
you can't tell what format was being tested. It seems you want it on
all the time, otherwise the test isn't helpful out-of-the-box.

--phil
diff mbox series

Patch

diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 79ebfd3f16..d7c6ebfdc4 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -2147,6 +2147,30 @@  static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         },
         .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE,
     },
+    [AV_PIX_FMT_P012LE] = {
+        .name = "p012le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .comp = {
+            { 0, 2, 0, 4, 12 },        /* Y */
+            { 1, 4, 0, 4, 12 },        /* U */
+            { 1, 4, 2, 4, 12 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
+    },
+    [AV_PIX_FMT_P012BE] = {
+        .name = "p012be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 1,
+        .comp = {
+            { 0, 2, 0, 4, 12 },        /* Y */
+            { 1, 4, 0, 4, 12 },        /* U */
+            { 1, 4, 2, 4, 12 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_BE,
+    },
     [AV_PIX_FMT_P016LE] = {
         .name = "p016le",
         .nb_components = 3,
@@ -2543,6 +2567,75 @@  static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         .flags = AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA |
                  AV_PIX_FMT_FLAG_FLOAT,
     },
+    [AV_PIX_FMT_Y212LE] = {
+        .name = "y212le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 4, 0, 4, 12 },        /* Y */
+            { 0, 8, 2, 4, 12 },        /* U */
+            { 0, 8, 6, 4, 12 },        /* V */
+        },
+    },
+    [AV_PIX_FMT_Y212BE] = {
+        .name = "y212be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 4, 0, 4, 12 },        /* Y */
+            { 0, 8, 2, 4, 12 },        /* U */
+            { 0, 8, 6, 4, 12 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE,
+    },
+    [AV_PIX_FMT_XV30LE] = {
+        .name = "xv30le",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 4, 1, 2, 10 },       /* Y */
+            { 0, 4, 0, 0, 10 },       /* U */
+            { 0, 4, 2, 4, 10 },       /* V */
+        },
+    },
+    [AV_PIX_FMT_XV30BE] = {
+        .name = "xv30be",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 32, 10, 0, 10 },       /* Y */
+            { 0, 32,  0, 0, 10 },       /* U */
+            { 0, 32, 20, 0, 10 },       /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_BITSTREAM,
+    },
+    [AV_PIX_FMT_XV36LE] = {
+        .name = "xv36le",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 8, 2, 4, 12 },       /* Y */
+            { 0, 8, 0, 4, 12 },       /* U */
+            { 0, 8, 4, 4, 12 },       /* V */
+        },
+    },
+    [AV_PIX_FMT_XV36BE] = {
+        .name = "xv36be",
+        .nb_components= 3,
+        .log2_chroma_w= 0,
+        .log2_chroma_h= 0,
+        .comp = {
+            { 0, 8, 2, 4, 12 },       /* Y */
+            { 0, 8, 0, 4, 12 },       /* U */
+            { 0, 8, 4, 4, 12 },       /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE,
+    },
 };
 
 static const char * const color_range_names[] = {
@@ -2778,7 +2871,7 @@  void ff_check_pixfmt_descriptors(void){
 
         if (!d->name && !d->nb_components && !d->log2_chroma_w && !d->log2_chroma_h && !d->flags)
             continue;
-//         av_log(NULL, AV_LOG_DEBUG, "Checking: %s\n", d->name);
+        av_log(NULL, AV_LOG_INFO, "Checking: %s\n", d->name);
         av_assert0(d->log2_chroma_w <= 3);
         av_assert0(d->log2_chroma_h <= 3);
         av_assert0(d->nb_components <= 4);
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 7d45561395..a1c4c9fb75 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -374,6 +374,18 @@  enum AVPixelFormat {
 
     AV_PIX_FMT_VUYX,        ///< packed VUYX 4:4:4, 32bpp, Variant of VUYA where alpha channel is left undefined
 
+    AV_PIX_FMT_P012LE,      ///< like NV12, with 12bpp per component, data in the high bits, zeros in the low bits, little-endian
+    AV_PIX_FMT_P012BE,      ///< like NV12, with 12bpp per component, data in the high bits, zeros in the low bits, big-endian
+
+    AV_PIX_FMT_Y212BE,      ///< packed YUV 4:2:2 like YUYV422, 24bpp, data in the high bits, zeros in the low bits, big-endian
+    AV_PIX_FMT_Y212LE,      ///< packed YUV 4:2:2 like YUYV422, 24bpp, data in the high bits, zeros in the low bits, little-endian
+
+    AV_PIX_FMT_XV30BE,      ///< packed XVYU 4:4:4, 32bpp, (msb)2X 10V 10Y 10U(lsb), big-endian, variant of Y410 where alpha channel is left undefined
+    AV_PIX_FMT_XV30LE,      ///< packed XVYU 4:4:4, 32bpp, (msb)2X 10V 10Y 10U(lsb), little-endian, variant of Y410 where alpha channel is left undefined
+
+    AV_PIX_FMT_XV36BE,      ///< packed XVYU 4:4:4, 48bpp, data in the high bits, zeros in the low bits, big-endian, variant of Y412 where alpha channel is left undefined
+    AV_PIX_FMT_XV36LE,      ///< packed XVYU 4:4:4, 48bpp, data in the high bits, zeros in the low bits, little-endian, variant of Y412 where alpha channel is left undefined
+
     AV_PIX_FMT_NB         ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
 };
 
@@ -460,9 +472,13 @@  enum AVPixelFormat {
 #define AV_PIX_FMT_NV20       AV_PIX_FMT_NE(NV20BE,  NV20LE)
 #define AV_PIX_FMT_AYUV64     AV_PIX_FMT_NE(AYUV64BE, AYUV64LE)
 #define AV_PIX_FMT_P010       AV_PIX_FMT_NE(P010BE,  P010LE)
+#define AV_PIX_FMT_P012       AV_PIX_FMT_NE(P012BE,  P012LE)
 #define AV_PIX_FMT_P016       AV_PIX_FMT_NE(P016BE,  P016LE)
 
 #define AV_PIX_FMT_Y210       AV_PIX_FMT_NE(Y210BE,  Y210LE)
+#define AV_PIX_FMT_Y212       AV_PIX_FMT_NE(Y212BE,  Y212LE)
+#define AV_PIX_FMT_XV30       AV_PIX_FMT_NE(XV30BE,  XV30LE)
+#define AV_PIX_FMT_XV36       AV_PIX_FMT_NE(XV36BE,  XV36LE)
 #define AV_PIX_FMT_X2RGB10    AV_PIX_FMT_NE(X2RGB10BE, X2RGB10LE)
 #define AV_PIX_FMT_X2BGR10    AV_PIX_FMT_NE(X2BGR10BE, X2BGR10LE)
 
diff --git a/tests/ref/fate/imgutils b/tests/ref/fate/imgutils
index 47b73b1b64..de73513e7c 100644
--- a/tests/ref/fate/imgutils
+++ b/tests/ref/fate/imgutils
@@ -250,3 +250,11 @@  vuya            planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0
 rgbaf16be       planes: 1, linesizes: 512   0   0   0, plane_sizes: 24576     0     0     0, plane_offsets:     0     0     0, total_size: 24576
 rgbaf16le       planes: 1, linesizes: 512   0   0   0, plane_sizes: 24576     0     0     0, plane_offsets:     0     0     0, total_size: 24576
 vuyx            planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
+p012le          planes: 2, linesizes: 128 128   0   0, plane_sizes:  6144  3072     0     0, plane_offsets:  6144     0     0, total_size: 9216
+p012be          planes: 2, linesizes: 128 128   0   0, plane_sizes:  6144  3072     0     0, plane_offsets:  6144     0     0, total_size: 9216
+y212be          planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
+y212le          planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
+xv30be          planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
+xv30le          planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
+xv36be          planes: 1, linesizes: 512   0   0   0, plane_sizes: 24576     0     0     0, plane_offsets:     0     0     0, total_size: 24576
+xv36le          planes: 1, linesizes: 512   0   0   0, plane_sizes: 24576     0     0     0, plane_offsets:     0     0     0, total_size: 24576
diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query
index f54372d364..20fc596ce9 100644
--- a/tests/ref/fate/sws-pixdesc-query
+++ b/tests/ref/fate/sws-pixdesc-query
@@ -63,6 +63,8 @@  isNBPS:
   nv20le
   p010be
   p010le
+  p012be
+  p012le
   p210be
   p210le
   p410be
@@ -71,10 +73,16 @@  isNBPS:
   x2bgr10le
   x2rgb10be
   x2rgb10le
+  xv30be
+  xv30le
+  xv36be
+  xv36le
   xyz12be
   xyz12le
   y210be
   y210le
+  y212be
+  y212le
   yuv420p10be
   yuv420p10le
   yuv420p12be
@@ -149,6 +157,7 @@  isBE:
   grayf32be
   nv20be
   p010be
+  p012be
   p016be
   p210be
   p216be
@@ -162,8 +171,11 @@  isBE:
   rgbaf16be
   x2bgr10be
   x2rgb10be
+  xv30be
+  xv36be
   xyz12be
   y210be
+  y212be
   ya16be
   yuv420p10be
   yuv420p12be
@@ -206,6 +218,8 @@  isYUV:
   nv42
   p010be
   p010le
+  p012be
+  p012le
   p016be
   p016le
   p210be
@@ -220,10 +234,16 @@  isYUV:
   uyyvyy411
   vuya
   vuyx
+  xv30be
+  xv30le
+  xv36be
+  xv36le
   xyz12be
   xyz12le
   y210be
   y210le
+  y212be
+  y212le
   ya16be
   ya16le
   ya8
@@ -310,6 +330,8 @@  isPlanarYUV:
   nv42
   p010be
   p010le
+  p012be
+  p012le
   p016be
   p016le
   p210be
@@ -401,6 +423,8 @@  isSemiPlanarYUV:
   nv42
   p010be
   p010le
+  p012be
+  p012le
   p016be
   p016le
   p210be
@@ -759,10 +783,16 @@  Packed:
   x2bgr10le
   x2rgb10be
   x2rgb10le
+  xv30be
+  xv30le
+  xv36be
+  xv36le
   xyz12be
   xyz12le
   y210be
   y210le
+  y212be
+  y212le
   ya16be
   ya16le
   ya8
@@ -801,6 +831,8 @@  Planar:
   nv42
   p010be
   p010le
+  p012be
+  p012le
   p016be
   p016le
   p210be
@@ -973,14 +1005,20 @@  usePal:
 DataInHighBits:
   p010be
   p010le
+  p012be
+  p012le
   p210be
   p210le
   p410be
   p410le
+  xv36be
+  xv36le
   xyz12be
   xyz12le
   y210be
   y210le
+  y212be
+  y212le
 
 SwappedChroma:
   nv21