[FFmpeg-cvslog] swscale: Add p016 output support and generalise yuv420p1x to p010

Philip Langdale git at videolan.org
Sat Mar 3 01:39:20 EET 2018


ffmpeg | branch: master | Philip Langdale <philipl at overt.org> | Thu Mar  1 20:16:48 2018 -0800| [9d5aff09a7163b17ec98f8c712ddde7727372dbc] | committer: Philip Langdale

swscale: Add p016 output support and generalise yuv420p1x to p010

To make the best use of existing code, I generalised the wrapper
that currently does yuv420p10 to p010 to support any mixture of
input and output sizes between 10 and 16 bits. This had the side
effect of yielding a working code path for all yuv420p1x formats
to p01x.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9d5aff09a7163b17ec98f8c712ddde7727372dbc
---

 libswscale/output.c                     | 31 +++++++++++++++++++++++++++++
 libswscale/swscale_unscaled.c           | 35 +++++++++++++++++++++++----------
 libswscale/utils.c                      |  4 ++--
 libswscale/version.h                    |  2 +-
 tests/ref/fate/filter-pixdesc-p016be    |  1 +
 tests/ref/fate/filter-pixdesc-p016le    |  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 ++
 16 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/libswscale/output.c b/libswscale/output.c
index f30bce8dd3..0af2fffea4 100644
--- a/libswscale/output.c
+++ b/libswscale/output.c
@@ -180,6 +180,34 @@ yuv2planeX_16_c_template(const int16_t *filter, int filterSize,
     }
 }
 
+static void yuv2p016cX_c(SwsContext *c, const int16_t *chrFilter, int chrFilterSize,
+                         const int16_t **chrUSrc, const int16_t **chrVSrc,
+                         uint8_t *dest8, int chrDstW)
+{
+    uint16_t *dest = (uint16_t*)dest8;
+    const int32_t **uSrc = (const int32_t **)chrUSrc;
+    const int32_t **vSrc = (const int32_t **)chrVSrc;
+    int shift = 15;
+    int big_endian = c->dstFormat == AV_PIX_FMT_P016BE;
+    int i, j;
+
+    for (i = 0; i < chrDstW; i++) {
+        int u = 1 << (shift - 1);
+        int v = 1 << (shift - 1);
+
+        /* See yuv2planeX_16_c_template for details. */
+        u -= 0x40000000;
+        v -= 0x40000000;
+        for (j = 0; j < chrFilterSize; j++) {
+            u += uSrc[j][i] * (unsigned)chrFilter[j];
+            v += vSrc[j][i] * (unsigned)chrFilter[j];
+        }
+
+        output_pixel(&dest[2*i]  , u, 0x8000, int);
+        output_pixel(&dest[2*i+1], v, 0x8000, int);
+    }
+}
+
 #undef output_pixel
 
 #define output_pixel(pos, val) \
@@ -2257,6 +2285,9 @@ av_cold void ff_sws_init_output_funcs(SwsContext *c,
     } else if (is16BPS(dstFormat)) {
         *yuv2planeX = isBE(dstFormat) ? yuv2planeX_16BE_c  : yuv2planeX_16LE_c;
         *yuv2plane1 = isBE(dstFormat) ? yuv2plane1_16BE_c  : yuv2plane1_16LE_c;
+        if (dstFormat == AV_PIX_FMT_P016LE || dstFormat == AV_PIX_FMT_P016BE) {
+          *yuv2nv12cX = yuv2p016cX_c;
+        }
     } else if (isNBPS(dstFormat)) {
         if (desc->comp[0].depth == 9) {
             *yuv2planeX = isBE(dstFormat) ? yuv2planeX_9BE_c  : yuv2planeX_9LE_c;
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 5ec2116bcf..766c9b4872 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -180,16 +180,28 @@ static int nv12ToPlanarWrapper(SwsContext *c, const uint8_t *src[],
     return srcSliceH;
 }
 
-static int planarToP010Wrapper(SwsContext *c, const uint8_t *src8[],
+static int planarToP01xWrapper(SwsContext *c, const uint8_t *src8[],
                                int srcStride[], int srcSliceY,
                                int srcSliceH, uint8_t *dstParam8[],
                                int dstStride[])
 {
+    const AVPixFmtDescriptor *src_format = av_pix_fmt_desc_get(c->srcFormat);
+    const AVPixFmtDescriptor *dst_format = av_pix_fmt_desc_get(c->dstFormat);
     const uint16_t **src = (const uint16_t**)src8;
     uint16_t *dstY = (uint16_t*)(dstParam8[0] + dstStride[0] * srcSliceY);
     uint16_t *dstUV = (uint16_t*)(dstParam8[1] + dstStride[1] * srcSliceY / 2);
     int x, y;
 
+    /* Calculate net shift required for values. */
+    const int shift[3] = {
+        dst_format->comp[0].depth + dst_format->comp[0].shift -
+        src_format->comp[0].depth - src_format->comp[0].shift,
+        dst_format->comp[1].depth + dst_format->comp[1].shift -
+        src_format->comp[1].depth - src_format->comp[1].shift,
+        dst_format->comp[2].depth + dst_format->comp[2].shift -
+        src_format->comp[2].depth - src_format->comp[2].shift,
+    };
+
     av_assert0(!(srcStride[0] % 2 || srcStride[1] % 2 || srcStride[2] % 2 ||
                  dstStride[0] % 2 || dstStride[1] % 2));
 
@@ -197,7 +209,7 @@ static int planarToP010Wrapper(SwsContext *c, const uint8_t *src8[],
         uint16_t *tdstY = dstY;
         const uint16_t *tsrc0 = src[0];
         for (x = c->srcW; x > 0; x--) {
-            *tdstY++ = *tsrc0++ << 6;
+            *tdstY++ = *tsrc0++ << shift[0];
         }
         src[0] += srcStride[0] / 2;
         dstY += dstStride[0] / 2;
@@ -207,8 +219,8 @@ static int planarToP010Wrapper(SwsContext *c, const uint8_t *src8[],
             const uint16_t *tsrc1 = src[1];
             const uint16_t *tsrc2 = src[2];
             for (x = c->srcW / 2; x > 0; x--) {
-                *tdstUV++ = *tsrc1++ << 6;
-                *tdstUV++ = *tsrc2++ << 6;
+                *tdstUV++ = *tsrc1++ << shift[1];
+                *tdstUV++ = *tsrc2++ << shift[2];
             }
             src[1] += srcStride[1] / 2;
             src[2] += srcStride[2] / 2;
@@ -1738,14 +1750,17 @@ void ff_get_unscaled_swscale(SwsContext *c)
         !(flags & SWS_ACCURATE_RND) && (c->dither == SWS_DITHER_BAYER || c->dither == SWS_DITHER_AUTO) && !(dstH & 1)) {
         c->swscale = ff_yuv2rgb_get_func_ptr(c);
     }
-    /* yuv420p10_to_p010 */
-    if ((srcFormat == AV_PIX_FMT_YUV420P10 || srcFormat == AV_PIX_FMT_YUVA420P10) &&
-        dstFormat == AV_PIX_FMT_P010) {
-        c->swscale = planarToP010Wrapper;
+    /* yuv420p1x_to_p01x */
+    if ((srcFormat == AV_PIX_FMT_YUV420P10 || srcFormat == AV_PIX_FMT_YUVA420P10 ||
+         srcFormat == AV_PIX_FMT_YUV420P12 ||
+         srcFormat == AV_PIX_FMT_YUV420P14 ||
+         srcFormat == AV_PIX_FMT_YUV420P16 || srcFormat == AV_PIX_FMT_YUVA420P16) &&
+        (dstFormat == AV_PIX_FMT_P010 || dstFormat == AV_PIX_FMT_P016)) {
+        c->swscale = planarToP01xWrapper;
     }
-    /* yuv420p_to_p010le */
+    /* yuv420p_to_p01xle */
     if ((srcFormat == AV_PIX_FMT_YUV420P || srcFormat == AV_PIX_FMT_YUVA420P) &&
-        dstFormat == AV_PIX_FMT_P010LE) {
+        (dstFormat == AV_PIX_FMT_P010LE || dstFormat == AV_PIX_FMT_P016LE)) {
         c->swscale = planar8ToP01xleWrapper;
     }
 
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 4df09306d3..98a6b99476 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -254,8 +254,8 @@ static const FormatEntry format_entries[AV_PIX_FMT_NB] = {
     [AV_PIX_FMT_AYUV64LE]    = { 1, 1},
     [AV_PIX_FMT_P010LE]      = { 1, 1 },
     [AV_PIX_FMT_P010BE]      = { 1, 1 },
-    [AV_PIX_FMT_P016LE]      = { 1, 0 },
-    [AV_PIX_FMT_P016BE]      = { 1, 0 },
+    [AV_PIX_FMT_P016LE]      = { 1, 1 },
+    [AV_PIX_FMT_P016BE]      = { 1, 1 },
 };
 
 int sws_isSupportedInput(enum AVPixelFormat pix_fmt)
diff --git a/libswscale/version.h b/libswscale/version.h
index 0393a6fe4a..edc133b233 100644
--- a/libswscale/version.h
+++ b/libswscale/version.h
@@ -28,7 +28,7 @@
 
 #define LIBSWSCALE_VERSION_MAJOR   5
 #define LIBSWSCALE_VERSION_MINOR   0
-#define LIBSWSCALE_VERSION_MICRO 101
+#define LIBSWSCALE_VERSION_MICRO 102
 
 #define LIBSWSCALE_VERSION_INT  AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \
                                                LIBSWSCALE_VERSION_MINOR, \
diff --git a/tests/ref/fate/filter-pixdesc-p016be b/tests/ref/fate/filter-pixdesc-p016be
new file mode 100644
index 0000000000..7c934079c8
--- /dev/null
+++ b/tests/ref/fate/filter-pixdesc-p016be
@@ -0,0 +1 @@
+pixdesc-p016be      784a49bf554861da9d0809a615bcf813
diff --git a/tests/ref/fate/filter-pixdesc-p016le b/tests/ref/fate/filter-pixdesc-p016le
new file mode 100644
index 0000000000..c723a0f1fd
--- /dev/null
+++ b/tests/ref/fate/filter-pixdesc-p016le
@@ -0,0 +1 @@
+pixdesc-p016le      ed04897de0a6788bb3458e7365f10d36
diff --git a/tests/ref/fate/filter-pixfmts-copy b/tests/ref/fate/filter-pixfmts-copy
index 124dddeacb..c45ce937b3 100644
--- a/tests/ref/fate/filter-pixfmts-copy
+++ b/tests/ref/fate/filter-pixfmts-copy
@@ -51,6 +51,8 @@ nv12                8e24feb2c544dc26a20047a71e4c27aa
 nv21                335d85c9af6110f26ae9e187a82ed2cf
 p010be              7f9842d6015026136bad60d03c035cc3
 p010le              c453421b9f726bdaf2bacf59a492c43b
+p016be              7f9842d6015026136bad60d03c035cc3
+p016le              c453421b9f726bdaf2bacf59a492c43b
 pal8                ff5929f5b42075793b2c34cb441bede5
 rgb0                0de71e5a1f97f81fb51397a0435bfa72
 rgb24               f4438057d046e6d98ade4e45294b21be
diff --git a/tests/ref/fate/filter-pixfmts-crop b/tests/ref/fate/filter-pixfmts-crop
index e21479ceb0..c5bb8a4135 100644
--- a/tests/ref/fate/filter-pixfmts-crop
+++ b/tests/ref/fate/filter-pixfmts-crop
@@ -49,6 +49,8 @@ nv12                92cda427f794374731ec0321ee00caac
 nv21                1bcfc197f4fb95de85ba58182d8d2f69
 p010be              8b2de2eb6b099bbf355bfc55a0694ddc
 p010le              373b50c766dfd0a8e79c9a73246d803a
+p016be              8b2de2eb6b099bbf355bfc55a0694ddc
+p016le              373b50c766dfd0a8e79c9a73246d803a
 pal8                1f2cdc8e718f95c875dbc1034a688bfb
 rgb0                736646b70dd9a0be22b8da8041e35035
 rgb24               c5fbbf816bb2000f4d2914e335698ef5
diff --git a/tests/ref/fate/filter-pixfmts-field b/tests/ref/fate/filter-pixfmts-field
index ba2af6e76f..df43ce6931 100644
--- a/tests/ref/fate/filter-pixfmts-field
+++ b/tests/ref/fate/filter-pixfmts-field
@@ -51,6 +51,8 @@ nv12                16f7a46708ef25ebd0b72e47920cc11e
 nv21                7294574037cc7f9373ef5695d8ebe809
 p010be              a0311a09bba7383553267d2b3b9c075e
 p010le              ee09a18aefa3ebe97715b3a7312cb8ff
+p016be              a0311a09bba7383553267d2b3b9c075e
+p016le              ee09a18aefa3ebe97715b3a7312cb8ff
 pal8                0658c18dcd8d052d59dfbe23f5b368d9
 rgb0                ca3fa6e865b91b3511c7f2bf62830059
 rgb24               25ab271e26a5785be169578d99da5dd0
diff --git a/tests/ref/fate/filter-pixfmts-hflip b/tests/ref/fate/filter-pixfmts-hflip
index 875980d892..a98314b0b3 100644
--- a/tests/ref/fate/filter-pixfmts-hflip
+++ b/tests/ref/fate/filter-pixfmts-hflip
@@ -49,6 +49,8 @@ nv12                801e58f1be5fd0b5bc4bf007c604b0b4
 nv21                9f10dfff8963dc327d3395af21f0554f
 p010be              744b13e44d39e1ff7588983fa03e0101
 p010le              a50b160346ab94f55a425065b57006f0
+p016be              744b13e44d39e1ff7588983fa03e0101
+p016le              a50b160346ab94f55a425065b57006f0
 pal8                5b7c77d99817b4f52339742a47de7797
 rgb0                0092452f37d73da20193265ace0b7d57
 rgb24               21571104e6091a689feabb7867e513dd
diff --git a/tests/ref/fate/filter-pixfmts-il b/tests/ref/fate/filter-pixfmts-il
index c6885b970e..3ed6c46226 100644
--- a/tests/ref/fate/filter-pixfmts-il
+++ b/tests/ref/fate/filter-pixfmts-il
@@ -51,6 +51,8 @@ nv12                3c3ba9b1b4c4dfff09c26f71b51dd146
 nv21                ab586d8781246b5a32d8760a61db9797
 p010be              3df51286ef66b53e3e283dbbab582263
 p010le              eadcd8241e97e35b2b47d5eb2eaea6cd
+p016be              3df51286ef66b53e3e283dbbab582263
+p016le              eadcd8241e97e35b2b47d5eb2eaea6cd
 rgb0                cfaf68671e43248267d8cd50cae8c13f
 rgb24               88894f608cf33ba310f21996748d77a7
 rgb444be            99d36d814988fb388aacdef575dacfcf
diff --git a/tests/ref/fate/filter-pixfmts-null b/tests/ref/fate/filter-pixfmts-null
index 124dddeacb..c45ce937b3 100644
--- a/tests/ref/fate/filter-pixfmts-null
+++ b/tests/ref/fate/filter-pixfmts-null
@@ -51,6 +51,8 @@ nv12                8e24feb2c544dc26a20047a71e4c27aa
 nv21                335d85c9af6110f26ae9e187a82ed2cf
 p010be              7f9842d6015026136bad60d03c035cc3
 p010le              c453421b9f726bdaf2bacf59a492c43b
+p016be              7f9842d6015026136bad60d03c035cc3
+p016le              c453421b9f726bdaf2bacf59a492c43b
 pal8                ff5929f5b42075793b2c34cb441bede5
 rgb0                0de71e5a1f97f81fb51397a0435bfa72
 rgb24               f4438057d046e6d98ade4e45294b21be
diff --git a/tests/ref/fate/filter-pixfmts-pad b/tests/ref/fate/filter-pixfmts-pad
index e777211cd9..097bd58c86 100644
--- a/tests/ref/fate/filter-pixfmts-pad
+++ b/tests/ref/fate/filter-pixfmts-pad
@@ -22,6 +22,7 @@ gray16le            468bda6155bdc7a7a20c34d6e599fd16
 gray9le             f8f3dfe31ca5fcba828285bceefdab9a
 nv12                381574979cb04be10c9168540310afad
 nv21                0fdeb2cdd56cf5a7147dc273456fa217
+p016le              536a3b4c3b47d005f9ab033370cc1c3b
 rgb0                78d500c8361ab6423a4826a00268c908
 rgb24               17f9e2e0c609009acaf2175c42d4a2a5
 rgba                b157c90191463d34fb3ce77b36c96386
diff --git a/tests/ref/fate/filter-pixfmts-scale b/tests/ref/fate/filter-pixfmts-scale
index f43c519428..1611c60ea7 100644
--- a/tests/ref/fate/filter-pixfmts-scale
+++ b/tests/ref/fate/filter-pixfmts-scale
@@ -51,6 +51,8 @@ nv12                b118d24a3653fe66e5d9e079033aef79
 nv21                c74bb1c10dbbdee8a1f682b194486c4d
 p010be              1d6726d94bf1385996a9a9840dd0e878
 p010le              4b316f2b9e18972299beb73511278fa8
+p016be              31e204018cbb53f8988c4e1174ea8ce9
+p016le              d5afe557f492a09317e525d7cb782f5b
 pal8                29e10892009b2cfe431815ec3052ed3b
 rgb0                fbd27e98154efb7535826afed41e9bb0
 rgb24               e022e741451e81f2ecce1c7240b93e87
diff --git a/tests/ref/fate/filter-pixfmts-transpose b/tests/ref/fate/filter-pixfmts-transpose
index fcad28b9ff..49069d6e06 100644
--- a/tests/ref/fate/filter-pixfmts-transpose
+++ b/tests/ref/fate/filter-pixfmts-transpose
@@ -49,6 +49,8 @@ nv12                1965e3826144686748f2f6b516fca5ba
 nv21                292adaf5271c5c8516b71640458c01f4
 p010be              ad0de2cc9bff81688b182a870fcf7000
 p010le              e7ff5143595021246733ce6bd0a769e8
+p016be              ad0de2cc9bff81688b182a870fcf7000
+p016le              e7ff5143595021246733ce6bd0a769e8
 rgb0                31ea5da7fe779c6ea0a33f1d28aad918
 rgb24               47654cabaaad79170b90afd5a02161dd
 rgb444be            3cac1f0c43a74d2a95eb02e187070845
diff --git a/tests/ref/fate/filter-pixfmts-vflip b/tests/ref/fate/filter-pixfmts-vflip
index 84b9d56858..d49e50196e 100644
--- a/tests/ref/fate/filter-pixfmts-vflip
+++ b/tests/ref/fate/filter-pixfmts-vflip
@@ -51,6 +51,8 @@ nv12                261ebe585ae2aa4e70d39a10c1679294
 nv21                2909feacd27bebb080c8e0fa41795269
 p010be              06e9354b6e0e38ba41736352cedc0bd5
 p010le              fd18d322bffbf5816902c13102872e22
+p016be              06e9354b6e0e38ba41736352cedc0bd5
+p016le              fd18d322bffbf5816902c13102872e22
 pal8                450b0155d0f2d5628bf95a442db5f817
 rgb0                56a7ea69541bcd27bef6a5615784722b
 rgb24               195e6dae1c3a488b9d3ceb7560d25d85



More information about the ffmpeg-cvslog mailing list