diff mbox series

[FFmpeg-devel,v12,4/9] avutil/swscale: add YUV444F32 and UYVYF32 pixel format and input support

Message ID 20241021195721.892544-6-ms+git@mur.at
State New
Headers show
Series DNxUncompressed decoder | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished

Commit Message

martin schitter Oct. 21, 2024, 7:57 p.m. UTC
---
 libavutil/pixdesc.c              |  48 +++++++++++++++
 libavutil/pixfmt.h               |   6 ++
 libswscale/input.c               | 100 +++++++++++++++++++++++++++++++
 libswscale/utils.c               |   6 +-
 tests/ref/fate/imgutils          |   8 +++
 tests/ref/fate/sws-pixdesc-query |  10 ++++
 6 files changed, 177 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 609f07a..f69c9b2 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -539,6 +539,30 @@  static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         },
         .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT,
     },
+    [AV_PIX_FMT_UYVY422F32LE] = {
+        .name = "uyvy422f32le",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 8,  4, 0, 32 },        /* Y */
+            { 0, 16, 0, 0, 32 },        /* U */
+            { 0, 16, 8, 0, 32 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_FLOAT,
+    },
+    [AV_PIX_FMT_UYVY422F32BE] = {
+        .name = "uyvy422f32be",
+        .nb_components = 3,
+        .log2_chroma_w = 1,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 8,  4, 0, 32 },        /* Y */
+            { 0, 16, 0, 0, 32 },        /* U */
+            { 0, 16, 8, 0, 32 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT,
+    },
     [AV_PIX_FMT_UYYVYY411] = {
         .name = "uyyvyy411",
         .nb_components = 3,
@@ -1761,6 +1785,30 @@  static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
         },
         .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT,
     },
+    [AV_PIX_FMT_YUV444F32LE] = {
+        .name = "yuv444f32le",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 12, 0, 0, 32 },        /* Y */
+            { 0, 12, 4, 0, 32 },        /* U */
+            { 0, 12, 8, 0, 32 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_FLOAT,
+    },
+    [AV_PIX_FMT_YUV444F32BE] = {
+        .name = "yuv444f32be",
+        .nb_components = 3,
+        .log2_chroma_w = 0,
+        .log2_chroma_h = 0,
+        .comp = {
+            { 0, 12, 0, 0, 32 },        /* Y */
+            { 0, 12, 4, 0, 32 },        /* U */
+            { 0, 12, 8, 0, 32 },        /* V */
+        },
+        .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_FLOAT,
+    },
     [AV_PIX_FMT_YUV444P10LE] = {
         .name = "yuv444p10le",
         .nb_components = 3,
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 67f568f..b946b8d 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -462,11 +462,15 @@  enum AVPixelFormat {
     AV_PIX_FMT_YUV444_16LE,  ///< packed YUV 4:4:4, 48bpp (1 Cr & Cb sample per 1x1 Y), YUVYUV..., little-endian
     AV_PIX_FMT_YUV444F16BE,  ///< IEEE-754 half precision packed YUV 4:4:4, 48bpp (1 Cr & Cb sample per 1x1 Y), YUVYUV..., big-endian
     AV_PIX_FMT_YUV444F16LE,  ///< IEEE-754 half precision packed YUV 4:4:4, 48bpp (1 Cr & Cb sample per 1x1 Y), YUVYUV..., little-endian
+    AV_PIX_FMT_YUV444F32BE,  ///< IEEE-754 single precision packed YUV 4:4:4, 96bpp (1 Cr & Cb sample per 1x1 Y), YUVYUV..., big-endian
+    AV_PIX_FMT_YUV444F32LE,  ///< IEEE-754 single precision packed YUV 4:4:4, 96bpp (1 Cr & Cb sample per 1x1 Y), YUVYUV..., little-endian
 
     AV_PIX_FMT_UYVY422_16BE, ///< packed UYVU 4:2:2, 32bpp, Cb Y0 Cr Y1, big-endian
     AV_PIX_FMT_UYVY422_16LE, ///< packed UYVU 4:2:2, 32bpp, Cb Y0 Cr Y1, little-endian
     AV_PIX_FMT_UYVY422F16BE, ///< IEEE-754 half precision packed UYVU 4:2:2, 32bpp, Cb Y0 Cr Y1, big-endian
     AV_PIX_FMT_UYVY422F16LE, ///< IEEE-754 half precision packed UYVU 4:2:2, 32bpp, Cb Y0 Cr Y1, little-endian
+    AV_PIX_FMT_UYVY422F32BE, ///< IEEE-754 single precision packed UYVU 4:2:2, 64bpp, Cb Y0 Cr Y1, big-endian
+    AV_PIX_FMT_UYVY422F32LE, ///< IEEE-754 single precision packed UYVU 4:2:2, 64bpp, Cb Y0 Cr Y1, little-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
 };
@@ -520,6 +524,7 @@  enum AVPixelFormat {
 #define AV_PIX_FMT_YUV444P16 AV_PIX_FMT_NE(YUV444P16BE, YUV444P16LE)
 #define AV_PIX_FMT_YUV444_16 AV_PIX_FMT_NE(YUV444_16BE, YUV444_16LE)
 #define AV_PIX_FMT_YUV444F16 AV_PIX_FMT_NE(YUV444F16BE, YUV444F16LE)
+#define AV_PIX_FMT_YUV444F32 AV_PIX_FMT_NE(YUV444F32BE, YUV444F32LE)
 
 #define AV_PIX_FMT_GBRP9     AV_PIX_FMT_NE(GBRP9BE ,    GBRP9LE)
 #define AV_PIX_FMT_GBRP10    AV_PIX_FMT_NE(GBRP10BE,    GBRP10LE)
@@ -555,6 +560,7 @@  enum AVPixelFormat {
 
 #define AV_PIX_FMT_UYVY422_16 AV_PIX_FMT_NE(UYVY422_16BE, UYVY422_16LE)
 #define AV_PIX_FMT_UYVY422F16 AV_PIX_FMT_NE(UYVY422F16BE, UYVY422F16LE)
+#define AV_PIX_FMT_UYVY422F32 AV_PIX_FMT_NE(UYVY422F32BE, UYVY422F32LE)
 
 #define AV_PIX_FMT_XYZ12      AV_PIX_FMT_NE(XYZ12BE, XYZ12LE)
 #define AV_PIX_FMT_NV20       AV_PIX_FMT_NE(NV20BE,  NV20LE)
diff --git a/libswscale/input.c b/libswscale/input.c
index 685b2ea..f9d7c39 100644
--- a/libswscale/input.c
+++ b/libswscale/input.c
@@ -876,6 +876,44 @@  static void read_yuv444f16be_UV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *u
     }
 }
 
+static void read_yuv444f32le_Y_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused0,
+                                 const uint8_t *unused1, int width, uint32_t *unused2, void *opq)
+{
+    uint16_t *dst = (uint16_t *) _dst;
+    for (int i = 0; i < width; i++)
+        dst[i] = lrintf(av_clipf(65535.0f * av_int2float(AV_RL32(src + i * 12)), 0.0f, 65535.0f));
+}
+
+static void read_yuv444f32le_UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src,
+                                  const uint8_t *unused1, int width, uint32_t *unused2, void *opq)
+{
+    uint16_t *dstU = (uint16_t *) _dstU;
+    uint16_t *dstV = (uint16_t *) _dstV;
+    for (int i = 0; i < width; i++) {
+        dstU[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RL32(src + i * 12 + 4)) + 0.5f), 0.0f, 65535.0f));
+        dstV[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RL32(src + i * 12 + 8)) + 0.5f), 0.0f, 65535.0f));
+    }
+}
+
+static void read_yuv444f32be_Y_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused0,
+                                 const uint8_t *unused1, int width, uint32_t *unused2, void *opq)
+{
+    uint16_t *dst = (uint16_t *) _dst;
+    for (int i = 0; i < width; i++)
+        dst[i] = lrintf(av_clipf(65535.0f * av_int2float(AV_RB32(src + i * 12)), 0.0f, 65535.0f));
+}
+
+static void read_yuv444f32be_UV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src,
+                                  const uint8_t *unused1, int width, uint32_t *unused2, void *opq)
+{
+    uint16_t *dstU = (uint16_t *) _dstU;
+    uint16_t *dstV = (uint16_t *) _dstV;
+    for (int i = 0; i < width; i++) {
+        dstU[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RB32(src + i * 12 + 4)) + 0.5f), 0.0f, 65535.0f));
+        dstV[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RB32(src + i * 12 + 8)) + 0.5f), 0.0f, 65535.0f));
+    }
+}
+
 static void read_v30xle_Y_c(uint8_t *dst, const uint8_t *src, const uint8_t *unused0, const uint8_t *unused1, int width,
                                uint32_t *unused2, void *opq)
 {
@@ -1044,6 +1082,44 @@  static void uyvyf16be_ToUV_c(uint8_t *dstU, uint8_t *dstV, const uint8_t *unused
     }
 }
 
+static void uyvyf32le_ToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width,
+                            uint32_t *unused, void *obl)
+{
+    uint16_t *dst    = (uint16_t *) _dst;
+    for (int i = 0; i < width; i++)
+        dst[i] = lrintf(av_clipf(65535.0f * av_int2float(AV_RL32(src + i * 8 + 4)), 0.0f, 65535.0f));
+}
+
+static void uyvyf32le_ToUV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
+                       const uint8_t *src2, int width, uint32_t *unused, void *obl)
+{
+    uint16_t *dstU    = (uint16_t *) _dstU;
+    uint16_t *dstV    = (uint16_t *) _dstV;
+    for (int i = 0; i < width; i++) {
+        dstU[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RL32(src1 + i * 16)) + 0.5f), 0.0f, 65535.0f));
+        dstV[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RL32(src1 + i * 16 + 8)) + 0.5f), 0.0f, 65535.0f));
+    }
+}
+
+static void uyvyf32be_ToY_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2,  int width,
+                            uint32_t *unused, void *obl)
+{
+    uint16_t *dst    = (uint16_t *) _dst;
+    for (int i = 0; i < width; i++)
+        dst[i] = lrintf(av_clipf(65535.0f * av_int2float(AV_RB32(src + i * 8 + 4)), 0.0f, 65535.0f));
+}
+
+static void uyvyf32be_ToUV_c(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *unused0, const uint8_t *src1,
+                       const uint8_t *src2, int width, uint32_t *unused, void *obl)
+{
+    uint16_t *dstU    = (uint16_t *) _dstU;
+    uint16_t *dstV    = (uint16_t *) _dstV;
+    for (int i = 0; i < width; i++) {
+        dstU[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RB32(src1 + i * 16)) + 0.5f), 0.0f, 65535.0f));
+        dstV[i] = lrintf(av_clipf(65535.0f * (av_int2float(AV_RB32(src1 + i * 16 + 8)) + 0.5f), 0.0f, 65535.0f));
+    }
+}
+
 static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
                                         const uint8_t *src, int width)
 {
@@ -1728,6 +1804,12 @@  av_cold void ff_sws_init_input_funcs(SwsContext *c,
     case AV_PIX_FMT_UYVY422F16BE:
         *chrToYV12 = uyvyf16be_ToUV_c;
         break;
+    case AV_PIX_FMT_UYVY422F32LE:
+        *chrToYV12 = uyvyf32le_ToUV_c;
+        break;
+    case AV_PIX_FMT_UYVY422F32BE:
+        *chrToYV12 = uyvyf32be_ToUV_c;
+        break;
     case AV_PIX_FMT_VYU444:
         *chrToYV12 = vyuToUV_c;
         break;
@@ -1746,6 +1828,12 @@  av_cold void ff_sws_init_input_funcs(SwsContext *c,
     case AV_PIX_FMT_YUV444F16BE:
         *chrToYV12 = read_yuv444f16be_UV_c;
         break;
+    case AV_PIX_FMT_YUV444F32LE:
+        *chrToYV12 = read_yuv444f32le_UV_c;
+        break;
+    case AV_PIX_FMT_YUV444F32BE:
+        *chrToYV12 = read_yuv444f32be_UV_c;
+        break;
     case AV_PIX_FMT_NV12:
     case AV_PIX_FMT_NV16:
     case AV_PIX_FMT_NV24:
@@ -2357,6 +2445,12 @@  av_cold void ff_sws_init_input_funcs(SwsContext *c,
     case AV_PIX_FMT_UYVY422F16BE:
         *lumToYV12 = uyvyf16be_ToY_c;
         break;
+    case AV_PIX_FMT_UYVY422F32LE:
+        *lumToYV12 = uyvyf32le_ToY_c;
+        break;
+    case AV_PIX_FMT_UYVY422F32BE:
+        *lumToYV12 = uyvyf32be_ToY_c;
+        break;
     case AV_PIX_FMT_VYU444:
         *lumToYV12 = vyuToY_c;
         break;
@@ -2375,6 +2469,12 @@  av_cold void ff_sws_init_input_funcs(SwsContext *c,
     case AV_PIX_FMT_YUV444F16BE:
         *lumToYV12 = read_yuv444f16be_Y_c;
         break;
+    case AV_PIX_FMT_YUV444F32LE:
+        *lumToYV12 = read_yuv444f32le_Y_c;
+        break;
+    case AV_PIX_FMT_YUV444F32BE:
+        *lumToYV12 = read_yuv444f32be_Y_c;
+        break;
     case AV_PIX_FMT_BGR24:
         *lumToYV12 = bgr24ToY_c;
         break;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 4573355..5318ae8 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -78,6 +78,8 @@  static const FormatEntry format_entries[] = {
     [AV_PIX_FMT_YUV444_16LE] = { 1, 0 },
     [AV_PIX_FMT_YUV444F16BE] = { 1, 0 },
     [AV_PIX_FMT_YUV444F16LE] = { 1, 0 },
+    [AV_PIX_FMT_YUV444F32BE] = { 1, 0 },
+    [AV_PIX_FMT_YUV444F32LE] = { 1, 0 },
     [AV_PIX_FMT_YUV410P]     = { 1, 1 },
     [AV_PIX_FMT_YUV411P]     = { 1, 1 },
     [AV_PIX_FMT_GRAY8]       = { 1, 1 },
@@ -94,6 +96,8 @@  static const FormatEntry format_entries[] = {
     [AV_PIX_FMT_UYVY422_16LE]= { 1, 0 },
     [AV_PIX_FMT_UYVY422F16BE]= { 1, 0 },
     [AV_PIX_FMT_UYVY422F16LE]= { 1, 0 },
+    [AV_PIX_FMT_UYVY422F32BE]= { 1, 0 },
+    [AV_PIX_FMT_UYVY422F32LE]= { 1, 0 },
     [AV_PIX_FMT_UYYVYY411]   = { 0, 0 },
     [AV_PIX_FMT_BGR8]        = { 1, 1 },
     [AV_PIX_FMT_BGR4]        = { 0, 1 },
@@ -1717,7 +1721,7 @@  static av_cold int sws_init_single_context(SwsContext *c, SwsFilter *srcFilter,
     }
 
     // float will be converted to uint16_t
-    if ((srcFormat == AV_PIX_FMT_GRAYF32BE || srcFormat == AV_PIX_FMT_GRAYF32LE) &&
+    if (isFloat(srcFormat) &&
         (!unscaled || unscaled && dstFormat != srcFormat && (srcFormat != AV_PIX_FMT_GRAYF32 ||
         dstFormat != AV_PIX_FMT_GRAY8))){
         c->srcBpc = 16;
diff --git a/tests/ref/fate/imgutils b/tests/ref/fate/imgutils
index bebd540..f0ac9d2 100644
--- a/tests/ref/fate/imgutils
+++ b/tests/ref/fate/imgutils
@@ -285,10 +285,14 @@  yuv444_16be     planes: 1, linesizes: 384   0   0   0, plane_sizes: 18432     0
 yuv444_16le     planes: 1, linesizes: 384   0   0   0, plane_sizes: 18432     0     0     0, plane_offsets:     0     0     0, total_size: 18432
 yuv444f16be     planes: 1, linesizes: 384   0   0   0, plane_sizes: 18432     0     0     0, plane_offsets:     0     0     0, total_size: 18432
 yuv444f16le     planes: 1, linesizes: 384   0   0   0, plane_sizes: 18432     0     0     0, plane_offsets:     0     0     0, total_size: 18432
+yuv444f32be     planes: 1, linesizes: 768   0   0   0, plane_sizes: 36864     0     0     0, plane_offsets:     0     0     0, total_size: 36864
+yuv444f32le     planes: 1, linesizes: 768   0   0   0, plane_sizes: 36864     0     0     0, plane_offsets:     0     0     0, total_size: 36864
 uyvy422_16be    planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
 uyvy422_16le    planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
 uyvy422f16be    planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
 uyvy422f16le    planes: 1, linesizes: 256   0   0   0, plane_sizes: 12288     0     0     0, plane_offsets:     0     0     0, total_size: 12288
+uyvy422f32be    planes: 1, linesizes: 512   0   0   0, plane_sizes: 24576     0     0     0, plane_offsets:     0     0     0, total_size: 24576
+uyvy422f32le    planes: 1, linesizes: 512   0   0   0, plane_sizes: 24576     0     0     0, plane_offsets:     0     0     0, total_size: 24576
 
 image_fill_black tests
 yuv420p         total_size:   4608,  black_unknown_crc: 0xd00f6cc6,  black_tv_crc: 0xd00f6cc6,  black_pc_crc: 0x234969af
@@ -521,7 +525,11 @@  yuv444_16be     total_size:  18432,  black_unknown_crc: 0xac983d03,  black_tv_cr
 yuv444_16le     total_size:  18432,  black_unknown_crc: 0x24c4432b,  black_tv_crc: 0x24c4432b,  black_pc_crc: 0xfe5a7889
 yuv444f16be     total_size:  18432,  black_unknown_crc: 0x5cf972e1,  black_tv_crc: 0x5cf972e1,  black_pc_crc: 0x482033cf
 yuv444f16le     total_size:  18432,  black_unknown_crc: 0x4a18e5bb,  black_tv_crc: 0x4a18e5bb,  black_pc_crc: 0x920584a7
+yuv444f32be     total_size:  36864,  black_unknown_crc: 0x1ea7a984,  black_tv_crc: 0x1ea7a984,  black_pc_crc: 0x63cf67b9
+yuv444f32le     total_size:  36864,  black_unknown_crc: 0x63d60c2d,  black_tv_crc: 0x63d60c2d,  black_pc_crc: 0x2d5f6a04
 uyvy422_16be    total_size:  12288,  black_unknown_crc: 0xb53352d5,  black_tv_crc: 0xb53352d5,  black_pc_crc: 0xf8461cf3
 uyvy422_16le    total_size:  12288,  black_unknown_crc: 0xe39de4bd,  black_tv_crc: 0xe39de4bd,  black_pc_crc: 0x24b29add
 uyvy422f16be    total_size:  12288,  black_unknown_crc: 0x9c275ddf,  black_tv_crc: 0x9c275ddf,  black_pc_crc: 0xde92b629
 uyvy422f16le    total_size:  12288,  black_unknown_crc: 0x2e5b76c4,  black_tv_crc: 0x2e5b76c4,  black_pc_crc: 0x2928eced
+uyvy422f32be    total_size:  24576,  black_unknown_crc: 0x04614e4a,  black_tv_crc: 0x04614e4a,  black_pc_crc: 0xaa67a8ce
+uyvy422f32le    total_size:  24576,  black_unknown_crc: 0x3bf0427e,  black_tv_crc: 0x3bf0427e,  black_pc_crc: 0x7636d7e3
diff --git a/tests/ref/fate/sws-pixdesc-query b/tests/ref/fate/sws-pixdesc-query
index 0d564c8..d19007f 100644
--- a/tests/ref/fate/sws-pixdesc-query
+++ b/tests/ref/fate/sws-pixdesc-query
@@ -197,6 +197,7 @@  isBE:
   rgbf32be
   uyvy422_16be
   uyvy422f16be
+  uyvy422f32be
   v30xbe
   x2bgr10be
   x2rgb10be
@@ -220,6 +221,7 @@  isBE:
   yuv440p12be
   yuv444_16be
   yuv444f16be
+  yuv444f32be
   yuv444p10be
   yuv444p12be
   yuv444p14be
@@ -272,6 +274,8 @@  isYUV:
   uyvy422_16le
   uyvy422f16be
   uyvy422f16le
+  uyvy422f32be
+  uyvy422f32le
   uyyvyy411
   v30xbe
   v30xle
@@ -325,6 +329,8 @@  isYUV:
   yuv444_16le
   yuv444f16be
   yuv444f16le
+  yuv444f32be
+  yuv444f32le
   yuv444p
   yuv444p10be
   yuv444p10le
@@ -881,6 +887,8 @@  Packed:
   uyvy422_16le
   uyvy422f16be
   uyvy422f16le
+  uyvy422f32be
+  uyvy422f32le
   uyyvyy411
   v30xbe
   v30xle
@@ -909,6 +917,8 @@  Packed:
   yuv444_16le
   yuv444f16be
   yuv444f16le
+  yuv444f32be
+  yuv444f32le
   yuyv422
   yvyu422