[PR] checkasm/h264: add weight tests (PR #24255)

zuxy via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <[email protected]>
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]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.