[FFmpeg-devel] [PATCH 1/2] avutil: Add MSB packed YUV444P10 format

Philip Langdale philipl at overt.org
Thu Feb 2 00:54:18 EET 2017


nvenc supports a YUV444P10 format with the same bit layout as P010,
with the data bits at the MSB end.

Unfortunately, the current YUV444P10 format we have defined puts
the data bits at the LSB end.

This mismatch led to us introducing a fudge in nvenc where we
mapped their 444P10 format to the ffmpeg 444P16 format. This
ensured that the data ends up in the right place if you are
starting with 10bit content, but it leads to other problems.

Specifically:

* >10bit content will be preferrentially converted to 444P16
  to pass to nvenc to 'preserve' the additional bits. However, they
  aren't actually preserved, but are discarded, so we're worse off
  because no dithering took place in swscale.
* On top of that, the input data is almost certainly 4:2:0 and so
  the conversion to 4:4:4 is pointless, while also leading to an
  output file that's incompatible with many playback scenarios
  (no hardware decoder supports 4:4:4 content).

So, for the sake of accuracy, introduce an explicit pixfmt for this
situation. There's no conversion support because you'll basically
never have a use for it. If someone ever finds one, they can write
the swscale code.

In the mean time, common 12 bit content (YUV420P12 or P016) will be
correctly converted to P010 for nvenc.

Signed-off-by: Philip Langdale <philipl at overt.org>
---
 libavutil/pixdesc.c | 24 ++++++++++++++++++++++++
 libavutil/pixfmt.h  |  5 +++++
 libavutil/version.h |  2 +-
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 3b9c45d..fe9b59d 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -1565,6 +1565,30 @@ 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_YUV444P10MSBLE] = {
+        .name = "yuv444p10msble",
+        .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_YUV444P10MSBBE] = {
+        .name = "yuv444p10msbbe",
+        .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_YUV444P9LE] = {
         .name = "yuv444p9le",
         .nb_components = 3,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index dfb1b11..46bf9c0 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -314,6 +314,9 @@ enum AVPixelFormat {
     AV_PIX_FMT_P016LE, ///< like NV12, with 16bpp per component, little-endian
     AV_PIX_FMT_P016BE, ///< like NV12, with 16bpp per component, big-endian
 
+    AV_PIX_FMT_YUV444P10MSBLE, /// like YUV444P10 but with data in the high bits, zeros in the low bits, little-endian
+    AV_PIX_FMT_YUV444P10MSBBE, /// like YUV444P10 but with data in the high bits, zeros in the low bits, 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
 };
 
@@ -394,6 +397,8 @@ enum AVPixelFormat {
 #define AV_PIX_FMT_P010       AV_PIX_FMT_NE(P010BE,  P010LE)
 #define AV_PIX_FMT_P016       AV_PIX_FMT_NE(P016BE,  P016LE)
 
+#define AV_PIX_FMT_YUV444P10MSB AV_PIX_FMT_NE(YUV444P10MSBBE, YUV444P10MSBLE)
+
 /**
   * Chromaticity coordinates of the source primaries.
   */
diff --git a/libavutil/version.h b/libavutil/version.h
index 8866064..a8b00bf 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  55
-#define LIBAVUTIL_VERSION_MINOR  46
+#define LIBAVUTIL_VERSION_MINOR  47
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
2.9.3


More information about the ffmpeg-devel mailing list