PR #24255 opened by zuxy
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24255
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24255.patch

Also fixed a bug in handling negative weights in 10-bit asm
implementation.

Signed-off-by: Zuxy Meng <[email protected]>


>From 56cba6021b87fdf778290649549bb540530c34c1 Mon Sep 17 00:00:00 2001
From: Zuxy Meng <[email protected]>
Date: Fri, 21 Aug 2026 22:04:42 -0700
Subject: [PATCH] checkasm/h264: add weight tests

Also fixed a bug in handling negative weights in 10-bit asm
implementation.

Signed-off-by: Zuxy Meng <[email protected]>
---
 libavcodec/x86/h264_weight_10bit.asm |   9 ++-
 tests/checkasm/h264dsp.c             | 103 +++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 3 deletions(-)

diff --git a/libavcodec/x86/h264_weight_10bit.asm 
b/libavcodec/x86/h264_weight_10bit.asm
index 356871bc62..7b7e367c9d 100644
--- a/libavcodec/x86/h264_weight_10bit.asm
+++ b/libavcodec/x86/h264_weight_10bit.asm
@@ -54,8 +54,10 @@ SECTION .text
     movd       m2, r3m
     pslld      m0, m2       ; 1<<log2_denom
     SPLATW     m0, m0
+    add        r4w, r4w
+    movzx      r4d, r4w
     shl        r5, 19       ; *8, move to upper half of dword
-    lea        r5, [r5+r4*2+0x10000]
+    lea        r5, [r5+r4+0x10000]
     movd       m3, r5d      ; weight<<1 | 1+(offset<<(3))
     pshufd     m3, m3, 0
     mova       m4, [pw_pixel_max]
@@ -82,7 +84,7 @@ SECTION .text
     psrad       m6, m2
 %if cpuflag(sse4)
     packusdw    m5, m6
-    pminsw      m5, m4
+    pminuw      m5, m4
 %else
     packssdw    m5, m6
     CLIPW       m5, m7, m4
@@ -176,6 +178,7 @@ DECLARE_REG_TMP 7
 %macro BIWEIGHT_SETUP 0
     lea        t0, [t0*4+1] ; (offset<<2)+1
     or         t0, 1
+    and       r5d, 0xFFFF
     shl        r6, 16
     or         r5, r6
     movd       m4, r5d      ; weightd | weights
@@ -214,7 +217,7 @@ DECLARE_REG_TMP 7
     psrad      m2, m6
 %if cpuflag(sse4)
     packusdw   m0, m2
-    pminsw     m0, m3
+    pminuw     m0, m3
 %else
     packssdw   m0, m2
     CLIPW      m0, m7, m3
diff --git a/tests/checkasm/h264dsp.c b/tests/checkasm/h264dsp.c
index 680fd91576..6d0649ebb4 100644
--- a/tests/checkasm/h264dsp.c
+++ b/tests/checkasm/h264dsp.c
@@ -500,6 +500,103 @@ static void check_loop_filter_intra(void)
     }
 }
 
+static void check_weight(void)
+{
+    LOCAL_ALIGNED_16(uint8_t, dst, [32 * 32 * 2]);
+    LOCAL_ALIGNED_16(uint8_t, dst0, [32 * 32 * 2]);
+    LOCAL_ALIGNED_16(uint8_t, dst1, [32 * 32 * 2]);
+    H264DSPContext h;
+    declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, ptrdiff_t stride,
+                      int height, int log2_denom, int weight, int offset);
+
+    for (int bit_depth = 8; bit_depth <= 10; bit_depth += 2) {
+        ff_h264dsp_init(&h, bit_depth, 1);
+        uint32_t mask = pixel_mask[bit_depth - 8];
+        for (int w = 16; w >= 2; w >>= 1) {
+            int idx = 4 - av_log2(w);
+
+            if (check_func(h.weight_pixels_tab[idx], "weight_%dx%d_%d",
+                           w, 16, bit_depth)) {
+                for (int hgt = 16; hgt >= 2; hgt >>= 1) {
+                    for (int i = 0; i < 32; i++) {
+                        int stride = 32 * SIZEOF_PIXEL;
+                        int log2_denom = rnd() % 8;
+                        int weight = (rnd() % 256) - 128;
+                        int offset = (rnd() % (1 << bit_depth)) -
+                                     (1 << (bit_depth - 1));
+                        for (int y = 0; y < hgt; y++) {
+                            for (int x = 0; x < w * SIZEOF_PIXEL; x += 4) {
+                                AV_WN32A(dst + y * stride + x, rnd() & mask);
+                            }
+                        }
+                        memcpy(dst0, dst, 32 * 32 * 2);
+                        memcpy(dst1, dst, 32 * 32 * 2);
+                        call_ref(dst0, stride, hgt, log2_denom, weight, 
offset);
+                        call_new(dst1, stride, hgt, log2_denom, weight, 
offset);
+                        if (memcmp(dst0, dst1, 32 * 32 * 2))
+                            fail();
+                        bench_new(dst, stride, hgt, log2_denom, weight, 
offset);
+                    }
+                }
+            }
+        }
+    }
+}
+
+static void check_biweight(void)
+{
+    LOCAL_ALIGNED_16(uint8_t, dst, [32 * 32 * 2]);
+    LOCAL_ALIGNED_16(uint8_t, dst0, [32 * 32 * 2]);
+    LOCAL_ALIGNED_16(uint8_t, dst1, [32 * 32 * 2]);
+    LOCAL_ALIGNED_16(uint8_t, src, [32 * 32 * 2]);
+    LOCAL_ALIGNED_16(uint8_t, src0, [32 * 32 * 2]);
+    LOCAL_ALIGNED_16(uint8_t, src1, [32 * 32 * 2]);
+    H264DSPContext h;
+    declare_func_emms(AV_CPU_FLAG_MMX, void, uint8_t *dst, uint8_t *src,
+                      ptrdiff_t stride, int height, int log2_denom,
+                      int weightd, int weights, int offset);
+
+    for (int bit_depth = 8; bit_depth <= 10; bit_depth += 2) {
+        uint32_t mask = pixel_mask[bit_depth - 8];
+        ff_h264dsp_init(&h, bit_depth, 1);
+        for (int w = 16; w >= 2; w >>= 1) {
+            int idx = 4 - av_log2(w);
+
+            if (check_func(h.biweight_pixels_tab[idx], "biweight_%dx%d_%d",
+                           w, 16, bit_depth)) {
+                for (int hgt = 16; hgt >= 4; hgt >>= 1) {
+                    for (int i = 0; i < 32; i++) {
+                        int stride = 32 * SIZEOF_PIXEL;
+                        int log2_denom = rnd() % 4; // 8-bit fails if > 3
+                        int weightd = rnd() % 256 - 128;
+                        int weights = rnd() % 256 - 128;
+                        int offset = (rnd() % (1 << bit_depth)) -
+                                     (1 << (bit_depth - 1));
+                        for (int y = 0; y < hgt; y++) {
+                            for (int x = 0; x < w * SIZEOF_PIXEL; x += 4) {
+                                AV_WN32A(dst + y * stride + x, rnd() & mask);
+                                AV_WN32A(src + y * stride + x, rnd() & mask);
+                            }
+                        }
+                        memcpy(dst0, dst, 32 * 32 * 2);
+                        memcpy(dst1, dst, 32 * 32 * 2);
+                        memcpy(src0, src, 32 * 32 * 2);
+                        memcpy(src1, src, 32 * 32 * 2);
+                        call_ref(dst0, src0, stride, hgt, log2_denom, weightd,
+                                 weights, offset);
+                        call_new(dst1, src1, stride, hgt, log2_denom, weightd,
+                                 weights, offset);
+                        if (memcmp(dst0, dst1, 32 * 32 * 2))
+                            fail();
+                        bench_new(dst, src, stride, hgt, log2_denom, weightd,
+                                  weights, offset);
+                    }
+                }
+            }
+        }
+    }
+}
+
 void checkasm_check_h264dsp(void)
 {
     check_idct();
@@ -512,4 +609,10 @@ void checkasm_check_h264dsp(void)
 
     check_loop_filter_intra();
     report("loop_filter_intra");
+
+    check_weight();
+    report("weight");
+
+    check_biweight();
+    report("biweight");
 }
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to