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]