Commit 8e7b6a567d for aom
commit 8e7b6a567df174d795479b92b4ac766d271add73
Author: Lin Zheng <linzhen@google.com>
Date: Tue Sep 8 14:43:13 2026 +0000
Fix the tune vmaf mode performance regression
Bug: 558679217
Change-Id: I77669167e79cf8390d0fffc9a8f1edb834262d6a
diff --git a/av1/common/x86/convolve_2d_avx2.c b/av1/common/x86/convolve_2d_avx2.c
index e6d06ee91a..256c070f1a 100644
--- a/av1/common/x86/convolve_2d_avx2.c
+++ b/av1/common/x86/convolve_2d_avx2.c
@@ -273,17 +273,6 @@ static void convolve_2d_sr_avx2(const uint8_t *src, int src_stride,
filt[2] = _mm256_load_si256((__m256i const *)filt3_global_avx2);
filt[3] = _mm256_load_si256((__m256i const *)filt4_global_avx2);
- if (subpel_x_qn == 0 && subpel_y_qn == 0) {
- for (i = 0; i < h; ++i) {
- for (int j = 0; j < w; j += 8) {
- _mm_storel_epi64(
- (__m128i *)&dst[i * dst_stride + j],
- _mm_loadl_epi64((const __m128i *)&src[i * src_stride + j]));
- }
- }
- return;
- }
-
for (i = 0; i < (im_h - 1); i += 2) {
const uint8_t *src_row0 = &src_ptr[i * src_stride];
const uint8_t *src_row1 = &src_ptr[(i + 1) * src_stride];
diff --git a/test/av1_convolve_test.cc b/test/av1_convolve_test.cc
index 7697285773..bbc80152c7 100644
--- a/test/av1_convolve_test.cc
+++ b/test/av1_convolve_test.cc
@@ -1365,10 +1365,82 @@ class AV1Convolve2DTest : public AV1ConvolveTest<convolve_2d_func> {
printf("%d - %d %3dx%-3d:%7.2f/%7.2fus (%3.2f)\n", h_f, v_f, width, height,
time1, time2, time1 / time2);
}
+
+ public:
+ void VmafTest() {
+ if (GetParam().Block().Width() < 8 || GetParam().Block().Height() < 8) {
+ return;
+ }
+ TestConvolveVmaf();
+ }
+
+ private:
+ void TestConvolveVmaf() {
+ // 8-tap Gaussian blur filter used by tune=vmaf_with_preprocessing
+ // in av1/encoder/tune_vmaf.c.
+ static const int16_t kGaussFilter[8] = { 2, 8, 24, 60, 24, 8, 2, 0 };
+ const InterpFilterParams filter_params = { kGaussFilter, 8,
+ EIGHTTAP_REGULAR };
+ const int width = GetParam().Block().Width();
+ const int height = GetParam().Block().Height();
+ const uint8_t *input = FirstRandomInput8(GetParam());
+ const int input_stride = width;
+ const int im_h = height + filter_params.taps - 1;
+ const int fo_vert = filter_params.taps / 2 - 1;
+ const int fo_horiz = filter_params.taps / 2 - 1;
+ const int kOverread = 8;
+ const int max_input_offset = -fo_vert * input_stride +
+ (im_h - 1) * input_stride + width - 1 -
+ fo_horiz + filter_params.taps - 1 + kOverread;
+ ASAN_POISON_MEMORY_REGION(input + max_input_offset + 1, 16);
+ const int min_input_offset = -fo_vert * input_stride - fo_horiz;
+ ASAN_POISON_MEMORY_REGION(input + min_input_offset - 16, 16);
+
+ DECLARE_ALIGNED(32, uint8_t, reference[MAX_SB_SQUARE]);
+ ConvolveParams conv_params1 =
+ get_conv_params_no_round(0, 0, nullptr, 0, 0, 8);
+ av1_convolve_2d_sr_c(input, input_stride, reference, kOutputStride, width,
+ height, &filter_params, &filter_params, 0, 0,
+ &conv_params1);
+
+ DECLARE_ALIGNED(32, uint8_t, test[MAX_SB_SQUARE]);
+ const int max_dst_offset = height * kOutputStride;
+ ASAN_POISON_MEMORY_REGION(test + max_dst_offset,
+ sizeof(test) - max_dst_offset);
+ ConvolveParams conv_params2 =
+ get_conv_params_no_round(0, 0, nullptr, 0, 0, 8);
+ GetParam().TestFunction()(input, input_stride, test, kOutputStride, width,
+ height, &filter_params, &filter_params, 0, 0,
+ &conv_params2);
+ ASAN_UNPOISON_MEMORY_REGION(test + max_dst_offset,
+ sizeof(test) - max_dst_offset);
+ ASAN_UNPOISON_MEMORY_REGION(input + max_input_offset + 1, 16);
+ ASAN_UNPOISON_MEMORY_REGION(input + min_input_offset - 16, 16);
+
+ // 1. Verify optimized implementation matches reference C implementation.
+ AssertOutputBufferEq(reference, test, width, height);
+
+ // 2. Verify that the output was actually convolved/blurred and is not
+ // merely an unmodified copy of the input. In commit 3d57983, a bug returned
+ // early with a pixel copy whenever subpel_x_qn == 0 && subpel_y_qn == 0,
+ // causing the Gaussian blur in VMAF mode to be skipped and
+ // best_frame_unsharp_amount to collapse from 1.0 to 0.05.
+ int diff_count = 0;
+ for (int r = 0; r < height; ++r) {
+ for (int c = 0; c < width; ++c) {
+ if (test[r * kOutputStride + c] != input[r * input_stride + c]) {
+ ++diff_count;
+ }
+ }
+ }
+ EXPECT_GT(diff_count, 0);
+ }
};
TEST_P(AV1Convolve2DTest, RunTest) { RunTest(); }
+TEST_P(AV1Convolve2DTest, VmafPreprocessing) { VmafTest(); }
+
TEST_P(AV1Convolve2DTest, DISABLED_SpeedTest) { SpeedTest(); }
INSTANTIATE_TEST_SUITE_P(C, AV1Convolve2DTest,
@@ -1613,10 +1685,59 @@ class AV1Convolve2DHighbdTest
printf("%d - %d %3dx%-3d:%7.2f/%7.2fus (%3.2f)\n", h_f, v_f, width, height,
time1, time2, time1 / time2);
}
+
+ public:
+ void VmafTest() {
+ if (GetParam().Block().Width() < 8 || GetParam().Block().Height() < 8) {
+ return;
+ }
+ TestConvolveVmaf();
+ }
+
+ private:
+ void TestConvolveVmaf() {
+ static const int16_t kGaussFilter[8] = { 2, 8, 24, 60, 24, 8, 2, 0 };
+ const InterpFilterParams filter_params = { kGaussFilter, 8,
+ EIGHTTAP_REGULAR };
+ const int width = GetParam().Block().Width();
+ const int height = GetParam().Block().Height();
+ const int bit_depth = GetParam().BitDepth();
+ const uint16_t *input = FirstRandomInput16(GetParam());
+ DECLARE_ALIGNED(32, uint16_t, reference[MAX_SB_SQUARE]);
+ ConvolveParams conv_params1 =
+ get_conv_params_no_round(0, 0, nullptr, 0, 0, bit_depth);
+ av1_highbd_convolve_2d_sr_c(input, width, reference, kOutputStride, width,
+ height, &filter_params, &filter_params, 0, 0,
+ &conv_params1, bit_depth);
+
+ DECLARE_ALIGNED(32, uint16_t, test[MAX_SB_SQUARE]);
+ ConvolveParams conv_params2 =
+ get_conv_params_no_round(0, 0, nullptr, 0, 0, bit_depth);
+ GetParam().TestFunction()(input, width, test, kOutputStride, width, height,
+ &filter_params, &filter_params, 0, 0,
+ &conv_params2, bit_depth);
+
+ // 1. Verify optimized implementation matches reference C implementation.
+ AssertOutputBufferEq(reference, test, width, height);
+
+ // 2. Verify that the output was actually convolved/blurred and is not
+ // merely an unmodified copy of the input.
+ int diff_count = 0;
+ for (int r = 0; r < height; ++r) {
+ for (int c = 0; c < width; ++c) {
+ if (test[r * kOutputStride + c] != input[r * width + c]) {
+ ++diff_count;
+ }
+ }
+ }
+ EXPECT_GT(diff_count, 0);
+ }
};
TEST_P(AV1Convolve2DHighbdTest, RunTest) { RunTest(); }
+TEST_P(AV1Convolve2DHighbdTest, VmafPreprocessing) { VmafTest(); }
+
TEST_P(AV1Convolve2DHighbdTest, DISABLED_SpeedTest) { SpeedTest(); }
INSTANTIATE_TEST_SUITE_P(C, AV1Convolve2DHighbdTest,