[FFmpeg-cvslog] swscale/unscaled: correctly round yuv2yuv when not dithering

Niklas Haas git at videolan.org
Mon Dec 23 12:33:41 EET 2024


ffmpeg | branch: master | Niklas Haas <git at haasn.dev> | Tue Dec 17 15:20:14 2024 +0100| [c6bf7f664527842fa3b89e49dc2a43f639430c33] | committer: Niklas Haas

swscale/unscaled: correctly round yuv2yuv when not dithering

We should at least bias towards the nearest integer, instead of always
rounding down, when not dithering. This is a bit more correct.

The FATE changes are only in the cases where sws_dither was explicitly set
to "none", which is exactly as expected.

Signed-off-by: Niklas Haas <git at haasn.dev>
Sponsored-by: Sovereign Tech Fund

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

 libswscale/swscale_unscaled.c          | 22 ++++++++++++----------
 tests/ref/pixfmt/yuv444p10-yuv444p     |  2 +-
 tests/ref/pixfmt/yuv444p12-yuv444p     |  2 +-
 tests/ref/pixfmt/yuv444p12-yuv444p10be |  2 +-
 tests/ref/pixfmt/yuv444p12-yuv444p10le |  2 +-
 5 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index c7ad6b014a..f0fe8304f5 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -2075,20 +2075,21 @@ static int packedCopyWrapper(SwsInternal *c, const uint8_t *const src[],
 
 #define DITHER_COPY(dst, dstStride, src, srcStride, bswap, dbswap)\
     unsigned shift= src_depth-dst_depth, tmp;\
+    unsigned bias = 1 << (shift - 1);\
     if (c->opts.dither == SWS_DITHER_NONE) {\
         for (i = 0; i < height; i++) {\
             for (j = 0; j < length-7; j+=8) {\
-                dst[j+0] = dbswap(bswap(src[j+0])>>shift);\
-                dst[j+1] = dbswap(bswap(src[j+1])>>shift);\
-                dst[j+2] = dbswap(bswap(src[j+2])>>shift);\
-                dst[j+3] = dbswap(bswap(src[j+3])>>shift);\
-                dst[j+4] = dbswap(bswap(src[j+4])>>shift);\
-                dst[j+5] = dbswap(bswap(src[j+5])>>shift);\
-                dst[j+6] = dbswap(bswap(src[j+6])>>shift);\
-                dst[j+7] = dbswap(bswap(src[j+7])>>shift);\
+                tmp = (bswap(src[j+0]) + bias)>>shift; dst[j+0] = dbswap(tmp - (tmp>>dst_depth));\
+                tmp = (bswap(src[j+1]) + bias)>>shift; dst[j+1] = dbswap(tmp - (tmp>>dst_depth));\
+                tmp = (bswap(src[j+2]) + bias)>>shift; dst[j+2] = dbswap(tmp - (tmp>>dst_depth));\
+                tmp = (bswap(src[j+3]) + bias)>>shift; dst[j+3] = dbswap(tmp - (tmp>>dst_depth));\
+                tmp = (bswap(src[j+4]) + bias)>>shift; dst[j+4] = dbswap(tmp - (tmp>>dst_depth));\
+                tmp = (bswap(src[j+5]) + bias)>>shift; dst[j+5] = dbswap(tmp - (tmp>>dst_depth));\
+                tmp = (bswap(src[j+6]) + bias)>>shift; dst[j+6] = dbswap(tmp - (tmp>>dst_depth));\
+                tmp = (bswap(src[j+7]) + bias)>>shift; dst[j+7] = dbswap(tmp - (tmp>>dst_depth));\
             }\
             for (; j < length; j++) {\
-                dst[j] = dbswap(bswap(src[j])>>shift);\
+                tmp = (bswap(src[j]) + bias)>>shift; dst[j] = dbswap(tmp - (tmp>>dst_depth));\
             }\
             dst += dstStride;\
             src += srcStride;\
@@ -2169,6 +2170,7 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                 uint16_t *dstPtr2 = (uint16_t*)dstPtr;
 
                 if (dst_depth == 8) {
+                    av_assert1(src_depth > 8);
                     if(isBE(c->opts.src_format) == HAVE_BIGENDIAN){
                         DITHER_COPY(dstPtr, dstStride[plane], srcPtr2, srcStride[plane]/2, , )
                     } else {
@@ -2248,7 +2250,7 @@ static int planarCopyWrapper(SwsInternal *c, const uint8_t *const src[],
                         dstPtr2 += dstStride[plane]/2;
                         srcPtr2 += srcStride[plane]/2;
                     }
-                } else {
+                } else { /* src_depth > dst_depth */
                     if(isBE(c->opts.src_format) == HAVE_BIGENDIAN){
                         if(isBE(c->opts.dst_format) == HAVE_BIGENDIAN){
                             DITHER_COPY(dstPtr2, dstStride[plane]/2, srcPtr2, srcStride[plane]/2, , )
diff --git a/tests/ref/pixfmt/yuv444p10-yuv444p b/tests/ref/pixfmt/yuv444p10-yuv444p
index 44cd8a40a6..fc676f2874 100644
--- a/tests/ref/pixfmt/yuv444p10-yuv444p
+++ b/tests/ref/pixfmt/yuv444p10-yuv444p
@@ -1,2 +1,2 @@
-1b783c5b90f43945b91b0b5be254aded *tests/data/pixfmt/yuv444p10-yuv444p.yuv
+51b33e13d1f9f7f5da849f780262200c *tests/data/pixfmt/yuv444p10-yuv444p.yuv
 15206400 tests/data/pixfmt/yuv444p10-yuv444p.yuv
diff --git a/tests/ref/pixfmt/yuv444p12-yuv444p b/tests/ref/pixfmt/yuv444p12-yuv444p
index fc5e8e53ad..db5034a25c 100644
--- a/tests/ref/pixfmt/yuv444p12-yuv444p
+++ b/tests/ref/pixfmt/yuv444p12-yuv444p
@@ -1,2 +1,2 @@
-9339fb7fd327f4131639c3b718eeccce *tests/data/pixfmt/yuv444p12-yuv444p.yuv
+6b16abfcc822202064351794f08b6db8 *tests/data/pixfmt/yuv444p12-yuv444p.yuv
 15206400 tests/data/pixfmt/yuv444p12-yuv444p.yuv
diff --git a/tests/ref/pixfmt/yuv444p12-yuv444p10be b/tests/ref/pixfmt/yuv444p12-yuv444p10be
index 9785443799..2aaadbcf56 100644
--- a/tests/ref/pixfmt/yuv444p12-yuv444p10be
+++ b/tests/ref/pixfmt/yuv444p12-yuv444p10be
@@ -1,2 +1,2 @@
-6f9fb7022d197765457c7a39645d8a3f *tests/data/pixfmt/yuv444p12-yuv444p10be.yuv
+d885def826d77206e10cd7f9bc2ce72a *tests/data/pixfmt/yuv444p12-yuv444p10be.yuv
 15206400 tests/data/pixfmt/yuv444p12-yuv444p10be.yuv
diff --git a/tests/ref/pixfmt/yuv444p12-yuv444p10le b/tests/ref/pixfmt/yuv444p12-yuv444p10le
index 829a350417..af44101b09 100644
--- a/tests/ref/pixfmt/yuv444p12-yuv444p10le
+++ b/tests/ref/pixfmt/yuv444p12-yuv444p10le
@@ -1,2 +1,2 @@
-6f9fb7022d197765457c7a39645d8a3f *tests/data/pixfmt/yuv444p12-yuv444p10le.yuv
+d885def826d77206e10cd7f9bc2ce72a *tests/data/pixfmt/yuv444p12-yuv444p10le.yuv
 15206400 tests/data/pixfmt/yuv444p12-yuv444p10le.yuv



More information about the ffmpeg-cvslog mailing list