From 4ce0f8cc403d2d4c242442906fe694408ea41b5b Mon Sep 17 00:00:00 2001 From: Cheng Chen Date: Tue, 26 Dec 2017 11:03:45 -0800 Subject: [PATCH] Unit tests for convolve_2d copy and x, y functions Copy and x, y only convolve functions should be identical to the original 2d function. Change-Id: I2b84a1eed775e8d7cba9bc3baa6352227a0326c8 --- av1/common/convolve.c | 8 +++--- test/av1_convolve_2d_test.cc | 43 +++++++++++++++++++++++++++---- test/av1_convolve_2d_test_util.cc | 34 +++++++++++++++++------- test/av1_convolve_2d_test_util.h | 5 ++-- 4 files changed, 68 insertions(+), 22 deletions(-) diff --git a/av1/common/convolve.c b/av1/common/convolve.c index 42d8f34da..3a8b3c06c 100644 --- a/av1/common/convolve.c +++ b/av1/common/convolve.c @@ -735,17 +735,15 @@ void av1_jnt_convolve_2d_copy_c(const uint8_t *src, int src_stride, for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { - CONV_BUF_TYPE res = (1 << bits) * src[y * src_stride + x]; + CONV_BUF_TYPE res = src[y * src_stride + x] << bits; if (conv_params->use_jnt_comp_avg) { if (conv_params->do_average) { - dst[y * dst_stride + x] += - (src[y * src_stride + x] * conv_params->bck_offset) << bits; + dst[y * dst_stride + x] += res * conv_params->bck_offset; dst[y * dst_stride + x] = ROUND_POWER_OF_TWO(dst[y * dst_stride + x], DIST_PRECISION_BITS - 1); } else { - dst[y * dst_stride + x] = - (src[y * src_stride + x] * conv_params->fwd_offset) << bits; + dst[y * dst_stride + x] = res * conv_params->fwd_offset; } } else { if (conv_params->do_average) diff --git a/test/av1_convolve_2d_test.cc b/test/av1_convolve_2d_test.cc index ceb473031..1416f04f7 100644 --- a/test/av1_convolve_2d_test.cc +++ b/test/av1_convolve_2d_test.cc @@ -30,21 +30,54 @@ namespace { TEST_P(AV1Convolve2DTest, CheckOutput) { RunCheckOutput(GET_PARAM(2)); } +INSTANTIATE_TEST_CASE_P( + C_COPY, AV1Convolve2DTest, + libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_copy_c, 0, 0, 1)); + +INSTANTIATE_TEST_CASE_P(SSE2_COPY, AV1Convolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_convolve_2d_copy_sse2, 0, 0, 1)); + +INSTANTIATE_TEST_CASE_P( + C_X, AV1Convolve2DTest, + libaom_test::AV1Convolve2D::BuildParams(av1_convolve_x_c, 1, 0, 1)); + +INSTANTIATE_TEST_CASE_P( + SSE2_X, AV1Convolve2DTest, + libaom_test::AV1Convolve2D::BuildParams(av1_convolve_x_sse2, 1, 0, 1)); + +INSTANTIATE_TEST_CASE_P( + C_Y, AV1Convolve2DTest, + libaom_test::AV1Convolve2D::BuildParams(av1_convolve_y_c, 0, 1, 1)); + +INSTANTIATE_TEST_CASE_P( + SSE2_Y, AV1Convolve2DTest, + libaom_test::AV1Convolve2D::BuildParams(av1_convolve_y_sse2, 0, 1, 1)); + INSTANTIATE_TEST_CASE_P( SSE2, AV1Convolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_sse2)); + libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_sse2, 1, 1, 1)); + #if HAVE_AVX2 INSTANTIATE_TEST_CASE_P( AVX2, AV1Convolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_avx2)); + libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_avx2, 1, 1, 1)); #endif #if CONFIG_JNT_COMP && HAVE_SSE4_1 TEST_P(AV1JntConvolve2DTest, CheckOutput) { RunCheckOutput(GET_PARAM(2)); } -INSTANTIATE_TEST_CASE_P( - SSE4_1, AV1JntConvolve2DTest, - libaom_test::AV1Convolve2D::BuildParams(av1_jnt_convolve_2d_sse4_1)); +INSTANTIATE_TEST_CASE_P(C_COPY, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_jnt_convolve_2d_copy_c, 0, 0, 1)); + +INSTANTIATE_TEST_CASE_P(SSE2_COPY, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_jnt_convolve_2d_copy_sse2, 0, 0, 1)); + +INSTANTIATE_TEST_CASE_P(SSE4_1, AV1JntConvolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_jnt_convolve_2d_sse4_1, 1, 1, 1)); #endif #if CONFIG_HIGHBITDEPTH && HAVE_SSSE3 diff --git a/test/av1_convolve_2d_test_util.cc b/test/av1_convolve_2d_test_util.cc index b10670b7f..dca373c42 100644 --- a/test/av1_convolve_2d_test_util.cc +++ b/test/av1_convolve_2d_test_util.cc @@ -22,11 +22,13 @@ namespace libaom_test { namespace AV1Convolve2D { ::testing::internal::ParamGenerator BuildParams( - convolve_2d_func filter) { + convolve_2d_func filter, int has_subx, int has_suby, int is_compound) { const Convolve2DParam params[] = { - make_tuple(4, 4, filter), make_tuple(8, 8, filter), - make_tuple(64, 64, filter), make_tuple(4, 16, filter), - make_tuple(32, 8, filter), + make_tuple(4, 4, filter, has_subx, has_suby, is_compound), + make_tuple(8, 8, filter, has_subx, has_suby, is_compound), + make_tuple(64, 64, filter, has_subx, has_suby, is_compound), + make_tuple(4, 16, filter, has_subx, has_suby, is_compound), + make_tuple(32, 8, filter, has_subx, has_suby, is_compound), }; return ::testing::ValuesIn(params); } @@ -40,6 +42,10 @@ void AV1Convolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { const int w = 128, h = 128; const int out_w = GET_PARAM(0), out_h = GET_PARAM(1); int i, j, k; + const int has_subx = GET_PARAM(3); + const int has_suby = GET_PARAM(4); + const int is_compound = GET_PARAM(5); + (void)is_compound; uint8_t *input = new uint8_t[h * w]; @@ -63,8 +69,10 @@ void AV1Convolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { ConvolveParams conv_params2 = get_conv_params_no_round(0, do_average, 0, output2, MAX_SB_SIZE, 1); - for (subx = 0; subx < 16; ++subx) - for (suby = 0; suby < 16; ++suby) { + const int subx_range = has_subx ? 16 : 1; + const int suby_range = has_suby ? 16 : 1; + for (subx = 0; subx < subx_range; ++subx) + for (suby = 0; suby < suby_range; ++suby) { // av1_convolve_2d is designed for accumulate two predicted blocks for // compound mode, so we set num_iter to two here. // A larger number may introduce overflow @@ -111,6 +119,10 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { const int w = 128, h = 128; const int out_w = GET_PARAM(0), out_h = GET_PARAM(1); int i, j, k, l, m; + const int has_subx = GET_PARAM(3); + const int has_suby = GET_PARAM(4); + const int is_compound = GET_PARAM(5); + (void)is_compound; uint8_t *input = new uint8_t[h * w]; @@ -138,8 +150,10 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { conv_params1.use_jnt_comp_avg = 0; conv_params2.use_jnt_comp_avg = 0; - for (subx = 0; subx < 16; ++subx) - for (suby = 0; suby < 16; ++suby) { + const int subx_range = has_subx ? 16 : 1; + const int suby_range = has_suby ? 16 : 1; + for (subx = 0; subx < subx_range; ++subx) + for (suby = 0; suby < suby_range; ++suby) { // av1_convolve_2d is designed for accumulate two predicted blocks // for compound mode, so we set num_iter to two here. // A larger number may introduce overflow @@ -179,8 +193,8 @@ void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) { conv_params2.fwd_offset = quant_dist_lookup_table[l][m][0]; conv_params2.bck_offset = quant_dist_lookup_table[l][m][1]; - for (subx = 0; subx < 16; ++subx) - for (suby = 0; suby < 16; ++suby) { + for (subx = 0; subx < subx_range; ++subx) + for (suby = 0; suby < suby_range; ++suby) { // av1_convolve_2d is designed for accumulate two predicted blocks // for compound mode, so we set num_iter to two here. // A larger number may introduce overflow diff --git a/test/av1_convolve_2d_test_util.h b/test/av1_convolve_2d_test_util.h index 4847ee7d7..7eea6ef7f 100644 --- a/test/av1_convolve_2d_test_util.h +++ b/test/av1_convolve_2d_test_util.h @@ -31,10 +31,11 @@ typedef void (*convolve_2d_func)(const uint8_t *src, int src_stride, const int subpel_x_q4, const int subpel_y_q4, ConvolveParams *conv_params); -typedef std::tr1::tuple Convolve2DParam; +typedef std::tr1::tuple + Convolve2DParam; ::testing::internal::ParamGenerator BuildParams( - convolve_2d_func filter); + convolve_2d_func filter, int subx_exist, int suby_exist, int is_compound); class AV1Convolve2DTest : public ::testing::TestWithParam { public: -- GitLab