This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new 3bec079933 checkasm/h264: add weight tests
3bec079933 is described below

commit 3bec079933ca6d5e50e9e307a597b27cab47e288
Author:     Zuxy Meng <[email protected]>
AuthorDate: Fri Aug 21 22:04:42 2026 -0700
Commit:     Zuxy Meng <[email protected]>
CommitDate: Tue Sep 1 19:47:55 2026 -0700

    checkasm/h264: add weight tests
    
    Also fixed a bug in handling negative weights in x86 10-bit asm
    implementation found by the newly added tests.
    
    Weight isn't enabled for neon as it can fail at certain edge cases.
    
    Bi-weight test is only enabled on x86 as other archs cannot pass it
    yet.
    
    Signed-off-by: Zuxy Meng <[email protected]>
---
 libavcodec/x86/h264_weight_10bit.asm |   9 ++-
 tests/checkasm/h264dsp.c             | 132 +++++++++++++++++++++++++++++++++++
 2 files changed, 138 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 bc036301dd..cc2d7524da 100644
--- a/tests/checkasm/h264dsp.c
+++ b/tests/checkasm/h264dsp.c
@@ -500,6 +500,128 @@ static void check_loop_filter_intra(void)
     }
 }
 
+// neon fails at edge cases
+#define H264_CHECK_WEIGHT (!ARCH_ARM && !ARCH_AARCH64)
+
+#if H264_CHECK_WEIGHT
+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() % 256) - 128;
+
+                        memset(dst, 0, 32 * 32 * 2);
+                        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);
+                    }
+                }
+            }
+        }
+    }
+}
+#endif
+
+// only arch that can pass test
+#define H264_CHECK_BIWEIGHT ARCH_X86
+
+#if H264_CHECK_BIWEIGHT
+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 >= 2; hgt >>= 1) {
+                    for (int i = 0; i < 32; i++) {
+                        int stride = 32 * SIZEOF_PIXEL;
+                        // Spec allows for 0 <= log2_denom <= 7 regardless
+                        // of bit depth, but x86 asm impl. is bit accurate
+                        // only up to 6 for 8bpp.
+                        //
+                        // In practice, log2_denom > 3 is rarely used.
+                        int max_log2_denom_8b = 6;
+                        int log2_denom = rnd() %
+                            (bit_depth == 8 ? (max_log2_denom_8b + 1) : 8);
+
+                        int weightd, weights;
+                        do {
+                            weightd = rnd() % 256 - 128;
+                            weights = rnd() % 256 - 128;
+                        } while (weightd + weights < -128 ||
+                                 weightd + weights > (log2_denom == 7 ? 127 : 
128));
+                        int offset = (rnd() % 256 - 128) + (rnd() % 256 - 128);
+
+                        memset(dst, 0, 32 * 32 * 2);
+                        memset(src, 0, 32 * 32 * 2);
+                        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);
+                    }
+                }
+            }
+        }
+    }
+}
+#endif
+
 void checkasm_check_h264dsp(void)
 {
     check_idct();
@@ -512,4 +634,14 @@ void checkasm_check_h264dsp(void)
 
     check_loop_filter_intra();
     report("loop_filter_intra");
+
+#if H264_CHECK_WEIGHT
+    check_weight();
+    report("weight");
+#endif
+
+#if H264_CHECK_BIWEIGHT
+    check_biweight();
+    report("biweight");
+#endif
 }

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to