diff mbox series

[FFmpeg-devel,1/4] swscale/output: add support for P012

Message ID 20220906195822.83664-2-philipl@overt.org
State New
Headers show
Series swscale/output: Add support for new VAAPI formats | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Philip Langdale Sept. 6, 2022, 7:58 p.m. UTC
This generalises the existing P010 support.

Signed-off-by: Philip Langdale <philipl@overt.org>
---
 libswscale/output.c                     | 140 ++++++++++++++----------
 libswscale/utils.c                      |   4 +-
 tests/ref/fate/filter-pixdesc-p012be    |   1 +
 tests/ref/fate/filter-pixdesc-p012le    |   1 +
 tests/ref/fate/filter-pixfmts-copy      |   2 +
 tests/ref/fate/filter-pixfmts-crop      |   2 +
 tests/ref/fate/filter-pixfmts-field     |   2 +
 tests/ref/fate/filter-pixfmts-hflip     |   2 +
 tests/ref/fate/filter-pixfmts-il        |   2 +
 tests/ref/fate/filter-pixfmts-null      |   2 +
 tests/ref/fate/filter-pixfmts-pad       |   1 +
 tests/ref/fate/filter-pixfmts-scale     |   2 +
 tests/ref/fate/filter-pixfmts-transpose |   2 +
 tests/ref/fate/filter-pixfmts-vflip     |   2 +
 14 files changed, 104 insertions(+), 61 deletions(-)
 create mode 100644 tests/ref/fate/filter-pixdesc-p012be
 create mode 100644 tests/ref/fate/filter-pixdesc-p012le
diff mbox series

Patch

diff --git a/libswscale/output.c b/libswscale/output.c
index 40a4476c6d..5cbc7ab748 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -460,17 +460,18 @@  static void yuv2nv12cX_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
 
 #define output_pixel(pos, val) \
     if (big_endian) { \
-        AV_WB16(pos, av_clip_uintp2(val >> shift, 10) << 6); \
+        AV_WB16(pos, av_clip_uintp2(val >> shift, output_bits) << output_shift); \
     } else { \
-        AV_WL16(pos, av_clip_uintp2(val >> shift, 10) << 6); \
+        AV_WL16(pos, av_clip_uintp2(val >> shift, output_bits) << output_shift); \
     }
 
-static void yuv2p010l1_c(const int16_t *src,
+static void yuv2p01xl1_c(const int16_t *src,
                          uint16_t *dest, int dstW,
-                         int big_endian)
+                         int big_endian, int output_bits)
 {
     int i;
-    int shift = 5;
+    int shift = 15 - output_bits;
+    int output_shift = 16 - output_bits;
 
     for (i = 0; i < dstW; i++) {
         int val = src[i] + (1 << (shift - 1));
@@ -478,12 +479,13 @@  static void yuv2p010l1_c(const int16_t *src,
     }
 }
 
-static void yuv2p010lX_c(const int16_t *filter, int filterSize,
+static void yuv2p01xlX_c(const int16_t *filter, int filterSize,
                          const int16_t **src, uint16_t *dest, int dstW,
-                         int big_endian)
+                         int big_endian, int output_bits)
 {
     int i, j;
-    int shift = 17;
+    int shift = 11 + 16 - output_bits;
+    int output_shift = 16 - output_bits;
 
     for (i = 0; i < dstW; i++) {
         int val = 1 << (shift - 1);
@@ -495,14 +497,15 @@  static void yuv2p010lX_c(const int16_t *filter, int filterSize,
     }
 }
 
-static void yuv2p010cX_c(int big_endian, const uint8_t *chrDither,
+static void yuv2p01xcX_c(int big_endian, const uint8_t *chrDither,
                          const int16_t *chrFilter, int chrFilterSize,
                          const int16_t **chrUSrc, const int16_t **chrVSrc,
-                         uint8_t *dest8, int chrDstW)
+                         uint8_t *dest8, int chrDstW, int output_bits)
 {
     uint16_t *dest = (uint16_t*)dest8;
-    int shift = 17;
     int i, j;
+    int shift = 11 + 16 - output_bits;
+    int output_shift = 16 - output_bits;
 
     for (i = 0; i < chrDstW; i++) {
         int u = 1 << (shift - 1);
@@ -518,52 +521,65 @@  static void yuv2p010cX_c(int big_endian, const uint8_t *chrDither,
     }
 }
 
-static void yuv2p010l1_LE_c(const int16_t *src,
-                            uint8_t *dest, int dstW,
-                            const uint8_t *dither, int offset)
-{
-    yuv2p010l1_c(src, (uint16_t*)dest, dstW, 0);
-}
-
-static void yuv2p010l1_BE_c(const int16_t *src,
-                            uint8_t *dest, int dstW,
-                            const uint8_t *dither, int offset)
-{
-    yuv2p010l1_c(src, (uint16_t*)dest, dstW, 1);
-}
-
-static void yuv2p010lX_LE_c(const int16_t *filter, int filterSize,
-                            const int16_t **src, uint8_t *dest, int dstW,
-                            const uint8_t *dither, int offset)
-{
-    yuv2p010lX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 0);
-}
-
-static void yuv2p010lX_BE_c(const int16_t *filter, int filterSize,
-                            const int16_t **src, uint8_t *dest, int dstW,
-                            const uint8_t *dither, int offset)
-{
-    yuv2p010lX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 1);
-}
-
-static void yuv2p010cX_LE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
-                            const int16_t *chrFilter, int chrFilterSize,
-                            const int16_t **chrUSrc, const int16_t **chrVSrc,
-                            uint8_t *dest8, int chrDstW)
-{
-    yuv2p010cX_c(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW);
-}
-
-static void yuv2p010cX_BE_c(enum AVPixelFormat dstFormat, const uint8_t *chrDither,
-                            const int16_t *chrFilter, int chrFilterSize,
-                            const int16_t **chrUSrc, const int16_t **chrVSrc,
-                            uint8_t *dest8, int chrDstW)
-{
-    yuv2p010cX_c(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, dest8, chrDstW);
-}
-
 #undef output_pixel
 
+#define yuv2p01x_wrapper(bits)                                                 \
+    static void yuv2p0 ## bits ## l1_LE_c(const int16_t *src,                  \
+                                          uint8_t *dest, int dstW,             \
+                                          const uint8_t *dither, int offset)   \
+    {                                                                          \
+        yuv2p01xl1_c(src, (uint16_t*)dest, dstW, 0, bits);                     \
+    }                                                                          \
+                                                                               \
+    static void yuv2p0 ## bits ## l1_BE_c(const int16_t *src,                  \
+                                          uint8_t *dest, int dstW,             \
+                                          const uint8_t *dither, int offset)   \
+    {                                                                          \
+        yuv2p01xl1_c(src, (uint16_t*)dest, dstW, 1, bits);                     \
+    }                                                                          \
+                                                                               \
+    static void yuv2p0 ## bits ## lX_LE_c(const int16_t *filter,               \
+                                          int filterSize, const int16_t **src, \
+                                          uint8_t *dest, int dstW,             \
+                                          const uint8_t *dither, int offset)   \
+    {                                                                          \
+        yuv2p01xlX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 0, bits); \
+    }                                                                          \
+                                                                               \
+    static void yuv2p0 ## bits ## lX_BE_c(const int16_t *filter,               \
+                                          int filterSize, const int16_t **src, \
+                                          uint8_t *dest, int dstW,             \
+                                          const uint8_t *dither, int offset)   \
+    {                                                                          \
+        yuv2p01xlX_c(filter, filterSize, src, (uint16_t*)dest, dstW, 1, bits); \
+    }                                                                          \
+                                                                               \
+    static void yuv2p0 ## bits ## cX_LE_c(enum AVPixelFormat dstFormat,        \
+                                          const uint8_t *chrDither,            \
+                                          const int16_t *chrFilter,            \
+                                          int chrFilterSize,                   \
+                                          const int16_t **chrUSrc,             \
+                                          const int16_t **chrVSrc,             \
+                                          uint8_t *dest8, int chrDstW)         \
+    {                                                                          \
+        yuv2p01xcX_c(0, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, \
+                     dest8, chrDstW, bits);                                    \
+    }                                                                          \
+                                                                               \
+    static void yuv2p0 ## bits ## cX_BE_c(enum AVPixelFormat dstFormat,        \
+                                          const uint8_t *chrDither,            \
+                                          const int16_t *chrFilter,            \
+                                          int chrFilterSize,                   \
+                                          const int16_t **chrUSrc,             \
+                                          const int16_t **chrVSrc,             \
+                                          uint8_t *dest8, int chrDstW)         \
+    {                                                                          \
+        yuv2p01xcX_c(1, chrDither, chrFilter, chrFilterSize, chrUSrc, chrVSrc, \
+                     dest8, chrDstW, bits);                                    \
+    }
+
+yuv2p01x_wrapper(10);
+yuv2p01x_wrapper(12);
 
 #define accumulate_bit(acc, val) \
     acc <<= 1; \
@@ -2675,10 +2691,16 @@  av_cold void ff_sws_init_output_funcs(SwsContext *c,
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(dstFormat);
 
     if (isSemiPlanarYUV(dstFormat) && isDataInHighBits(dstFormat)) {
-        av_assert0(desc->comp[0].depth == 10);
-        *yuv2plane1 = isBE(dstFormat) ? yuv2p010l1_BE_c : yuv2p010l1_LE_c;
-        *yuv2planeX = isBE(dstFormat) ? yuv2p010lX_BE_c : yuv2p010lX_LE_c;
-        *yuv2nv12cX = isBE(dstFormat) ? yuv2p010cX_BE_c : yuv2p010cX_LE_c;
+        if (desc->comp[0].depth == 10) {
+            *yuv2plane1 = isBE(dstFormat) ? yuv2p010l1_BE_c : yuv2p010l1_LE_c;
+            *yuv2planeX = isBE(dstFormat) ? yuv2p010lX_BE_c : yuv2p010lX_LE_c;
+            *yuv2nv12cX = isBE(dstFormat) ? yuv2p010cX_BE_c : yuv2p010cX_LE_c;
+        } else if (desc->comp[0].depth == 12) {
+            *yuv2plane1 = isBE(dstFormat) ? yuv2p012l1_BE_c : yuv2p012l1_LE_c;
+            *yuv2planeX = isBE(dstFormat) ? yuv2p012lX_BE_c : yuv2p012lX_LE_c;
+            *yuv2nv12cX = isBE(dstFormat) ? yuv2p012cX_BE_c : yuv2p012cX_LE_c;
+        } else
+            av_assert0(0);
     } else if (is16BPS(dstFormat)) {
         *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c  : yuv2planeX_16LE_c;
         *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c  : yuv2plane1_16LE_c;
diff --git a/libswscale/utils.c b/libswscale/utils.c
index a5a9bc589a..599c326754 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -236,8 +236,8 @@  static const FormatEntry format_entries[] = {
     [AV_PIX_FMT_AYUV64LE]    = { 1, 1},
     [AV_PIX_FMT_P010LE]      = { 1, 1 },
     [AV_PIX_FMT_P010BE]      = { 1, 1 },
-    [AV_PIX_FMT_P012LE]      = { 1, 0 },
-    [AV_PIX_FMT_P012BE]      = { 1, 0 },
+    [AV_PIX_FMT_P012LE]      = { 1, 1 },
+    [AV_PIX_FMT_P012BE]      = { 1, 1 },
     [AV_PIX_FMT_P016LE]      = { 1, 1 },
     [AV_PIX_FMT_P016BE]      = { 1, 1 },
     [AV_PIX_FMT_GRAYF32LE]   = { 1, 1 },
diff --git a/tests/ref/fate/filter-pixdesc-p012be b/tests/ref/fate/filter-pixdesc-p012be
new file mode 100644
index 0000000000..217ca49157
--- /dev/null
+++ b/tests/ref/fate/filter-pixdesc-p012be
@@ -0,0 +1 @@ 
+pixdesc-p012be      784a49bf554861da9d0809a615bcf813
diff --git a/tests/ref/fate/filter-pixdesc-p012le b/tests/ref/fate/filter-pixdesc-p012le
new file mode 100644
index 0000000000..681cd48b4b
--- /dev/null
+++ b/tests/ref/fate/filter-pixdesc-p012le
@@ -0,0 +1 @@ 
+pixdesc-p012le      0268fd44f63022e21ada69704534fc85
diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy
index 371b94c62e..d92dd169dc 100644
--- a/tests/ref/fate/filter-pixfmts-copy
+++ b/tests/ref/fate/filter-pixfmts-copy
@@ -62,6 +62,8 @@  nv24                f30fc8d0ac40af69e119ea919a314572
 nv42                29a212f70f8780fe0eb99abcae81894d
 p010be              7f9842d6015026136bad60d03c035cc3
 p010le              c453421b9f726bdaf2bacf59a492c43b
+p012be              7f9842d6015026136bad60d03c035cc3
+p012le              1929db89609c4b8c6d9c9030a9e7843d
 p016be              7f9842d6015026136bad60d03c035cc3
 p016le              c453421b9f726bdaf2bacf59a492c43b
 p210be              847e9c6e292b17349e69570829252b3e
diff --git a/tests/ref/fate/filter-pixfmts-crop b/tests/ref/fate/filter-pixfmts-crop
index 364e881aef..f7103a5906 100644
--- a/tests/ref/fate/filter-pixfmts-crop
+++ b/tests/ref/fate/filter-pixfmts-crop
@@ -60,6 +60,8 @@  nv24                514c8f12082f0737e558778cbe7de258
 nv42                ece9baae1c5de579dac2c66a89e08ef3
 p010be              8b2de2eb6b099bbf355bfc55a0694ddc
 p010le              373b50c766dfd0a8e79c9a73246d803a
+p012be              8b2de2eb6b099bbf355bfc55a0694ddc
+p012le              a1e4f713e145dfc465bfe0cc77096a03
 p016be              8b2de2eb6b099bbf355bfc55a0694ddc
 p016le              373b50c766dfd0a8e79c9a73246d803a
 p210be              2947f43774352ef61f9e83777548c7c5
diff --git a/tests/ref/fate/filter-pixfmts-field b/tests/ref/fate/filter-pixfmts-field
index 768b3f474a..910728e512 100644
--- a/tests/ref/fate/filter-pixfmts-field
+++ b/tests/ref/fate/filter-pixfmts-field
@@ -62,6 +62,8 @@  nv24                3b100fb527b64ee2b2d7120da573faf5
 nv42                1841ce853152d86b27c130f319ea0db2
 p010be              a0311a09bba7383553267d2b3b9c075e
 p010le              ee09a18aefa3ebe97715b3a7312cb8ff
+p012be              a0311a09bba7383553267d2b3b9c075e
+p012le              f1cc90d292046109a626db2da9f0f9b6
 p016be              a0311a09bba7383553267d2b3b9c075e
 p016le              ee09a18aefa3ebe97715b3a7312cb8ff
 p210be              58d46f566ab28e3bcfb715c7aa53cf58
diff --git a/tests/ref/fate/filter-pixfmts-hflip b/tests/ref/fate/filter-pixfmts-hflip
index 6fbc472a4e..1e37027ec2 100644
--- a/tests/ref/fate/filter-pixfmts-hflip
+++ b/tests/ref/fate/filter-pixfmts-hflip
@@ -60,6 +60,8 @@  nv24                f0c5b2f42970f8d4003621d8857a872f
 nv42                4dcf9aec82b110712b396a8b365dcb13
 p010be              744b13e44d39e1ff7588983fa03e0101
 p010le              a50b160346ab94f55a425065b57006f0
+p012be              744b13e44d39e1ff7588983fa03e0101
+p012le              aeb31f50c66f376b0530c7bb6287212b
 p016be              744b13e44d39e1ff7588983fa03e0101
 p016le              a50b160346ab94f55a425065b57006f0
 p210be              6f5a76d6467b86d55fe5589d3af8a7ea
diff --git a/tests/ref/fate/filter-pixfmts-il b/tests/ref/fate/filter-pixfmts-il
index 09748c2d08..9efbf5d8e1 100644
--- a/tests/ref/fate/filter-pixfmts-il
+++ b/tests/ref/fate/filter-pixfmts-il
@@ -62,6 +62,8 @@  nv24                554153c71d142e3fd8e40b7dcaaec229
 nv42                d699724c8deaeb4f87faf2766512eec3
 p010be              3df51286ef66b53e3e283dbbab582263
 p010le              eadcd8241e97e35b2b47d5eb2eaea6cd
+p012be              3df51286ef66b53e3e283dbbab582263
+p012le              38945445b360fa737e9e37257393e823
 p016be              3df51286ef66b53e3e283dbbab582263
 p016le              eadcd8241e97e35b2b47d5eb2eaea6cd
 p210be              29ec4e8912d456cd15203a96487c42e8
diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null
index 371b94c62e..d92dd169dc 100644
--- a/tests/ref/fate/filter-pixfmts-null
+++ b/tests/ref/fate/filter-pixfmts-null
@@ -62,6 +62,8 @@  nv24                f30fc8d0ac40af69e119ea919a314572
 nv42                29a212f70f8780fe0eb99abcae81894d
 p010be              7f9842d6015026136bad60d03c035cc3
 p010le              c453421b9f726bdaf2bacf59a492c43b
+p012be              7f9842d6015026136bad60d03c035cc3
+p012le              1929db89609c4b8c6d9c9030a9e7843d
 p016be              7f9842d6015026136bad60d03c035cc3
 p016le              c453421b9f726bdaf2bacf59a492c43b
 p210be              847e9c6e292b17349e69570829252b3e
diff --git a/tests/ref/fate/filter-pixfmts-pad b/tests/ref/fate/filter-pixfmts-pad
index 07aaea6b06..d659ef6121 100644
--- a/tests/ref/fate/filter-pixfmts-pad
+++ b/tests/ref/fate/filter-pixfmts-pad
@@ -27,6 +27,7 @@  nv21                0fdeb2cdd56cf5a7147dc273456fa217
 nv24                193b9eadcc06ad5081609f76249b3e47
 nv42                1738ad3c31c6c16e17679f5b09ce4677
 p010le              fbbc23cc1d764a5e6fb71883d985f3ed
+p012le              3a92c1bd3e9de050bf6abcc3fd911ab7
 p016le              fbbc23cc1d764a5e6fb71883d985f3ed
 p210le              680912c059de39c3401cac856bd1b0c1
 p216le              8718662e226a4581561e7bb532af2d83
diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale
index e1bbe961e1..017eeee84f 100644
--- a/tests/ref/fate/filter-pixfmts-scale
+++ b/tests/ref/fate/filter-pixfmts-scale
@@ -62,6 +62,8 @@  nv24                2aa6e805bf6d4179ed8d7dea37d75db3
 nv42                80714d1eb2d8bcaeab3abc3124df1abd
 p010be              1d6726d94bf1385996a9a9840dd0e878
 p010le              4b316f2b9e18972299beb73511278fa8
+p012be              e4dc7ccd654c2d74fde9c7b2711d960b
+p012le              cd4b6bdcd8967fc0e869ce3b8a014133
 p016be              31e204018cbb53f8988c4e1174ea8ce9
 p016le              d5afe557f492a09317e525d7cb782f5b
 p210be              2cc6dfcf5e006c8ed5238988a06fd45e
diff --git a/tests/ref/fate/filter-pixfmts-transpose b/tests/ref/fate/filter-pixfmts-transpose
index 0c2993d5b0..f1b16ca528 100644
--- a/tests/ref/fate/filter-pixfmts-transpose
+++ b/tests/ref/fate/filter-pixfmts-transpose
@@ -59,6 +59,8 @@  nv24                ea9de8b47faed722ee40182f89489beb
 nv42                636af6cd6a4f3ac5edc0fc3ce3c56d63
 p010be              ad0de2cc9bff81688b182a870fcf7000
 p010le              e7ff5143595021246733ce6bd0a769e8
+p012be              ad0de2cc9bff81688b182a870fcf7000
+p012le              024ef1cf56a4872f202b96a6a4bbf10a
 p016be              ad0de2cc9bff81688b182a870fcf7000
 p016le              e7ff5143595021246733ce6bd0a769e8
 p410be              8b3e0ccb31b6a20ff00a29253fb2dec3
diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip
index 5cac61a9d2..814008cefd 100644
--- a/tests/ref/fate/filter-pixfmts-vflip
+++ b/tests/ref/fate/filter-pixfmts-vflip
@@ -62,6 +62,8 @@  nv24                334420b9d3df84499d2ca16bb66eed2b
 nv42                ba4063e2795c17fea3c8a646b01fd1f5
 p010be              06e9354b6e0e38ba41736352cedc0bd5
 p010le              fd18d322bffbf5816902c13102872e22
+p012be              06e9354b6e0e38ba41736352cedc0bd5
+p012le              cdf6a3c38d9d4e3f079fa369e1dda662
 p016be              06e9354b6e0e38ba41736352cedc0bd5
 p016le              fd18d322bffbf5816902c13102872e22
 p210be              ca886ab2b3ea5c153f1954b3709f7249