Commit c80bfd962f for ffmpeg
commit c80bfd962f246f53a6768b16ffe2c504ea5cb83b
Author: Zuxy Meng <zuxy.meng@gmail.com>
Date: Fri Sep 4 21:09:51 2026 -0700
avcodec/arm|aarch64/h264dsp: Fix edge cases for weight
Add/sub with saturation is used only on log2_denom > 1 path, but with
log2_denom == 1 (block[x]*weight + offset << 1) can fall below S16_MIN.
Use saturation in all paths for safety.
This fixes the weight checkasm test for arm and aarch64
Signed-off-by: Zuxy Meng <zuxy.meng@gmail.com>
diff --git a/libavcodec/aarch64/h264dsp_neon.S b/libavcodec/aarch64/h264dsp_neon.S
index 723b692019..c09db164b6 100644
--- a/libavcodec/aarch64/h264dsp_neon.S
+++ b/libavcodec/aarch64/h264dsp_neon.S
@@ -810,9 +810,9 @@ function ff_weight_h264_pixels_\w\()_neon, export=1
dup v18.8h, w6
cmp w4, #0
b.lt 10f
- weight_\w add
+ weight_\w sqadd
10: neg w4, w4
- weight_\w sub
+ weight_\w sqsub
endfunc
.endm
diff --git a/libavcodec/arm/h264dsp_neon.S b/libavcodec/arm/h264dsp_neon.S
index 5fed6848d8..975b61c8c0 100644
--- a/libavcodec/arm/h264dsp_neon.S
+++ b/libavcodec/arm/h264dsp_neon.S
@@ -549,9 +549,9 @@ function ff_weight_h264_pixels_\w\()_neon, export=1
vdup.16 q9, lr
cmp r12, #0
blt 10f
- weight_\w vadd.s16
+ weight_\w vqadd.s16
10: rsb r12, r12, #0
- weight_\w vsub.s16
+ weight_\w vqsub.s16
endfunc
.endm
diff --git a/tests/checkasm/h264dsp.c b/tests/checkasm/h264dsp.c
index 30478f2956..a38ee32d9c 100644
--- a/tests/checkasm/h264dsp.c
+++ b/tests/checkasm/h264dsp.c
@@ -500,10 +500,6 @@ 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]);
@@ -547,7 +543,6 @@ static void check_weight(void)
}
}
}
-#endif
// only arch that can pass test
#define H264_CHECK_BIWEIGHT ARCH_X86
@@ -634,10 +629,8 @@ 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();