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 e6d06ee..256c070 100644 --- a/av1/common/x86/convolve_2d_avx2.c +++ b/av1/common/x86/convolve_2d_avx2.c
@@ -273,17 +273,6 @@ 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 7697285..bbc8015 100644 --- a/test/av1_convolve_test.cc +++ b/test/av1_convolve_test.cc
@@ -1365,10 +1365,82 @@ 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 @@ 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,