[FFmpeg-devel,1/5] avutil: Add YUV444P10_LSB and YUV444P12_LSB pixel formats

Submitted by Philip Langdale on Oct. 7, 2018, 5:50 p.m.

Details

Message ID 20181007175057.31070-2-philipl@overt.org
State New
Headers show

Commit Message

Philip Langdale Oct. 7, 2018, 5:50 p.m.
Currently, ffmpeg defines a set of YUV444P formats for use where
the bits-per-pixel are between 8 and 16 bits. In these formats,
the bits are packed in the MSBs of the 16 bits of available storage.

On the other hand, all the hardware vendors have defined their
equivalent formats with the bits packed in the LSBs, which has the
virtue of making the memory layouts compatible with being treated
as full 16 bit values (which is also why P010 is defined this way).

So, to be able to use these hardware compatible formats, we need
definitions for them in ffmpeg. Right now, I need this for nvdec,
but Vulkan also uses the same format definitions.

Signed-off-by: Philip Langdale <philipl@overt.org>
---
 libavutil/pixdesc.c | 48 +++++++++++++++++++++++++++++++++++++++++++++
 libavutil/pixfmt.h  |  8 ++++++++
 libavutil/version.h |  4 ++--
 3 files changed, 58 insertions(+), 2 deletions(-)

Comments

Carl Eugen Hoyos Oct. 9, 2018, 12:32 a.m.
2018-10-08 21:59 GMT+02:00, Timo Rothenpieler <timo@rothenpieler.org>:
>>> So, to be able to use these hardware compatible formats, we need
>>> definitions for them in ffmpeg. Right now, I need this for nvdec,
>>> but Vulkan also uses the same format definitions.
>>
>> Sorry if this was already done and I forgot but please explain why
>> you cannot use YUV444P16 for this use-case.
>>
>> If the only thing missing is libavfilter understanding
>> bits_per_raw_sample
>> we should add it there: It is needed in any case and would save us a few
>> pix_fmts and could speed up many use cases compared to your solution.
>
> It's pretty much all of ffmpeg and all client applications understanding
> it.
> First of all, bits_per_raw_sample, or an equivalent bit depth field, is
> missing from AVFrame.
> "In" avfilter it's primarily swscale I guess, but it also affects each
> and every filter supporting YUV444P16.
> Also, for encoders, it would mean they need a way to indicate what bit
> depths they can take, and that also has to be per pix_fmt they support.
> Then all of avcodec, ffmpeg.c, ... needs support for that.
> It's quite a deep rabit hole of changes with quite a good chance of
> something going horribly wrong in the process. Probably even in more
> places than just the ones mentioned here.

This may or may not be true, unfortunately my question was not
how difficult it would be to fix this mess (I don't think it is), but
why you want to add more to the mess.

What would happen if you just use YUV444P16?

Carl Eugen

Patch hide | download patch | download mbox

diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 970a83214c..c48a100907 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -1629,6 +1629,54 @@  static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         },
         .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
     },
+    [AV_PIX_FMT_YUV444P10LE_LSB] = {
+        .name = "yuv444p10lelsb",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 2, 0, 6, 10, 1, 9, 1 },        /* Y */
+            { 1, 2, 0, 6, 10, 1, 9, 1 },        /* U */
+            { 2, 2, 0, 6, 10, 1, 9, 1 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
+    },
+    [AV_PIX_FMT_YUV444P10BE_LSB] = {
+        .name = "yuv444p10belsb",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 2, 0, 6, 10, 1, 9, 1 },        /* Y */
+            { 1, 2, 0, 6, 10, 1, 9, 1 },        /* U */
+            { 2, 2, 0, 6, 10, 1, 9, 1 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
+    },
+    [AV_PIX_FMT_YUV444P12LE_LSB] = {
+        .name = "yuv444p12lelsb",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 2, 0, 4, 12, 1, 11, 1 },        /* Y */
+            { 1, 2, 0, 4, 12, 1, 11, 1 },        /* U */
+            { 2, 2, 0, 4, 12, 1, 11, 1 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_PLANAR,
+    },
+    [AV_PIX_FMT_YUV444P12BE_LSB] = {
+        .name = "yuv444p12belsb",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 2, 0, 4, 12, 1, 11, 1 },        /* Y */
+            { 1, 2, 0, 4, 12, 1, 11, 1 },        /* U */
+            { 2, 2, 0, 4, 12, 1, 11, 1 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
+    },
     [AV_PIX_FMT_D3D11VA_VLD] = {
         .name = "d3d11va_vld",
         .log2_chroma_w = 1,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 6815f8dc7b..910cb0a995 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -340,6 +340,11 @@  enum AVPixelFormat {
     AV_PIX_FMT_GRAYF32BE,  ///< IEEE-754 single precision Y, 32bpp, big-endian
     AV_PIX_FMT_GRAYF32LE,  ///< IEEE-754 single precision Y, 32bpp, little-endian
 
+    AV_PIX_FMT_YUV444P10LE_LSB,  ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, little-endian
+    AV_PIX_FMT_YUV444P10BE_LSB,  ///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, big-endian
+    AV_PIX_FMT_YUV444P12LE_LSB,  ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, little-endian
+    AV_PIX_FMT_YUV444P12BE_LSB,  ///< planar YUV 4:4:4, 36bpp, (1 Cr & Cb sample per 1x1 Y samples), LSB packed, big-endian
+
     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
 };
 
@@ -391,6 +396,9 @@  enum AVPixelFormat {
 #define AV_PIX_FMT_YUV422P16 AV_PIX_FMT_NE(YUV422P16BE, YUV422P16LE)
 #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE)
 
+#define AV_PIX_FMT_YUV444P10_LSB AV_PIX_FMT_NE(YUV444P10BE_LSB, YUV444P10LE_LSB)
+#define AV_PIX_FMT_YUV444P12_LSB AV_PIX_FMT_NE(YUV444P12BE_LSB, YUV444P12LE_LSB)
+
 #define AV_PIX_FMT_GBRP9     AV_PIX_FMT_NE(GBRP9BE ,    GBRP9LE)
 #define AV_PIX_FMT_GBRP10    AV_PIX_FMT_NE(GBRP10BE,    GBRP10LE)
 #define AV_PIX_FMT_GBRP12    AV_PIX_FMT_NE(GBRP12BE,    GBRP12LE)
diff --git a/libavutil/version.h b/libavutil/version.h
index f84ec89154..377714a91e 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,8 +79,8 @@ 
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  56
-#define LIBAVUTIL_VERSION_MINOR  19
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MINOR  20
+#define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                LIBAVUTIL_VERSION_MINOR, \