JNT_COMP: Add unit tests for low bit-depth Unit tests for jnt_comp low bit-depth added. Change-Id: Ib070a67c125c5fa9a034e2b368aa109f9a256a45
diff --git a/av1/common/common_data.h b/av1/common/common_data.h index 525547c..ab3fc4e 100644 --- a/av1/common/common_data.h +++ b/av1/common/common_data.h
@@ -1802,6 +1802,8 @@ #endif #if CONFIG_JNT_COMP +// Note: this is also used in unit tests. So whenever one changes the table, +// the unit tests need to be changed accordingly. static const double quant_dist_category[4] = { 1.5, 2.5, 3.5, 255 }; static const int quant_dist_lookup_table[2][4][2] = { { { 8, 8 }, { 11, 5 }, { 12, 4 }, { 13, 3 } },
diff --git a/test/av1_convolve_2d_test.cc b/test/av1_convolve_2d_test.cc index 002ede4..23e2700 100644 --- a/test/av1_convolve_2d_test.cc +++ b/test/av1_convolve_2d_test.cc
@@ -22,11 +22,22 @@ namespace { +#if CONFIG_JNT_COMP +TEST_P(AV1Convolve2DTest, CheckOutput) { RunCheckOutput(GET_PARAM(2)); } +#if HAVE_SSE4_1 +TEST_P(AV1Convolve2DTest, CheckOutput2) { RunCheckOutput2(GET_PARAM(3)); } +#endif + +INSTANTIATE_TEST_CASE_P(SSE4_1, AV1Convolve2DTest, + libaom_test::AV1Convolve2D::BuildParams( + av1_convolve_2d_sse2, av1_jnt_convolve_2d_sse4_1)); +#else TEST_P(AV1Convolve2DTest, CheckOutput) { RunCheckOutput(GET_PARAM(2)); } INSTANTIATE_TEST_CASE_P( SSE2, AV1Convolve2DTest, libaom_test::AV1Convolve2D::BuildParams(av1_convolve_2d_sse2)); +#endif // CONFIG_JNT_COMP #if CONFIG_HIGHBITDEPTH && HAVE_SSSE3 TEST_P(AV1HighbdConvolve2DTest, CheckOutput) { RunCheckOutput(GET_PARAM(3)); }
diff --git a/test/av1_convolve_2d_test_util.cc b/test/av1_convolve_2d_test_util.cc index 3b61f6b..a173a53 100644 --- a/test/av1_convolve_2d_test_util.cc +++ b/test/av1_convolve_2d_test_util.cc
@@ -12,6 +12,7 @@ #include "test/av1_convolve_2d_test_util.h" #include "av1/common/convolve.h" +#include "av1/common/common_data.h" using std::tr1::tuple; using std::tr1::make_tuple; @@ -20,6 +21,17 @@ namespace AV1Convolve2D { +#if CONFIG_JNT_COMP +::testing::internal::ParamGenerator<Convolve2DParam> BuildParams( + convolve_2d_func filter, convolve_2d_func filter2) { + const Convolve2DParam params[] = { + make_tuple(4, 4, filter, filter2), make_tuple(8, 8, filter, filter2), + make_tuple(64, 64, filter, filter2), make_tuple(4, 16, filter, filter2), + make_tuple(32, 8, filter, filter2), + }; + return ::testing::ValuesIn(params); +} +#else ::testing::internal::ParamGenerator<Convolve2DParam> BuildParams( convolve_2d_func filter) { const Convolve2DParam params[] = { @@ -29,6 +41,7 @@ }; return ::testing::ValuesIn(params); } +#endif // CONFIG_JNT_COMP AV1Convolve2DTest::~AV1Convolve2DTest() {} void AV1Convolve2DTest::SetUp() { rnd_.Reset(ACMRandom::DeterministicSeed()); } @@ -97,6 +110,120 @@ delete[] output; delete[] output2; } + +#if CONFIG_JNT_COMP +void AV1Convolve2DTest::RunCheckOutput2(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; + + uint8_t *input = new uint8_t[h * w]; + + int output_n = out_h * MAX_SB_SIZE; + CONV_BUF_TYPE *output = new CONV_BUF_TYPE[output_n]; + CONV_BUF_TYPE *output2 = new CONV_BUF_TYPE[output_n]; + + for (i = 0; i < h; ++i) + for (j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand8(); + + int hfilter, vfilter, subx, suby; + for (hfilter = EIGHTTAP_REGULAR; hfilter < INTERP_FILTERS_ALL; ++hfilter) { + for (vfilter = EIGHTTAP_REGULAR; vfilter < INTERP_FILTERS_ALL; ++vfilter) { + InterpFilterParams filter_params_x = + av1_get_interp_filter_params((InterpFilter)hfilter); + InterpFilterParams filter_params_y = + av1_get_interp_filter_params((InterpFilter)vfilter); + const int do_average = rnd_.Rand8() & 1; + ConvolveParams conv_params1 = + get_conv_params_no_round(0, do_average, 0, output, MAX_SB_SIZE); + ConvolveParams conv_params2 = + get_conv_params_no_round(0, do_average, 0, output2, MAX_SB_SIZE); + + // Test special case where fwd and bck offsets are -1 + conv_params1.fwd_offset = -1; + conv_params1.bck_offset = -1; + conv_params2.fwd_offset = -1; + conv_params2.bck_offset = -1; + + for (subx = 0; subx < 16; ++subx) + for (suby = 0; suby < 16; ++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 + const int num_iters = 2; + memset(output, 0, output_n * sizeof(*output)); + memset(output2, 0, output_n * sizeof(*output2)); + for (i = 0; i < num_iters; ++i) { + // Choose random locations within the source block + int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); + int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); + av1_jnt_convolve_2d_c(input + offset_r * w + offset_c, w, output, + MAX_SB_SIZE, out_w, out_h, &filter_params_x, + &filter_params_y, subx, suby, &conv_params1); + test_impl(input + offset_r * w + offset_c, w, output2, MAX_SB_SIZE, + out_w, out_h, &filter_params_x, &filter_params_y, subx, + suby, &conv_params2); + + for (j = 0; j < out_h; ++j) + for (k = 0; k < out_w; ++k) { + int idx = j * MAX_SB_SIZE + k; + ASSERT_EQ(output[idx], output2[idx]) + << "Mismatch at unit tests for av1_jnt_convolve_2d\n" + << "Pixel mismatch at index " << idx << " = (" << j << ", " + << k << "), sub pixel offset = (" << suby << ", " << subx + << ")"; + } + } + } + + // Test different combination of fwd and bck offset weights + for (l = 0; l < 2; ++l) { + for (m = 0; m < 4; ++m) { + conv_params1.fwd_offset = quant_dist_lookup_table[l][m][0]; + conv_params1.bck_offset = quant_dist_lookup_table[l][m][1]; + 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) { + // 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 + const int num_iters = 2; + memset(output, 0, output_n * sizeof(*output)); + memset(output2, 0, output_n * sizeof(*output2)); + for (i = 0; i < num_iters; ++i) { + // Choose random locations within the source block + int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7); + int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7); + av1_jnt_convolve_2d_c(input + offset_r * w + offset_c, w, + output, MAX_SB_SIZE, out_w, out_h, + &filter_params_x, &filter_params_y, subx, + suby, &conv_params1); + test_impl(input + offset_r * w + offset_c, w, output2, + MAX_SB_SIZE, out_w, out_h, &filter_params_x, + &filter_params_y, subx, suby, &conv_params2); + + for (j = 0; j < out_h; ++j) + for (k = 0; k < out_w; ++k) { + int idx = j * MAX_SB_SIZE + k; + ASSERT_EQ(output[idx], output2[idx]) + << "Mismatch at unit tests for av1_jnt_convolve_2d\n" + << "Pixel mismatch at index " << idx << " = (" << j + << ", " << k << "), sub pixel offset = (" << suby + << ", " << subx << ")"; + } + } + } + } + } + } + } + delete[] input; + delete[] output; + delete[] output2; +} +#endif // CONFIG_JNT_COMP } // namespace AV1Convolve2D #if CONFIG_HIGHBITDEPTH
diff --git a/test/av1_convolve_2d_test_util.h b/test/av1_convolve_2d_test_util.h index 013126b..974169c 100644 --- a/test/av1_convolve_2d_test_util.h +++ b/test/av1_convolve_2d_test_util.h
@@ -31,10 +31,18 @@ const int subpel_x_q4, const int subpel_y_q4, ConvolveParams *conv_params); +#if CONFIG_JNT_COMP +typedef std::tr1::tuple<int, int, convolve_2d_func, convolve_2d_func> + Convolve2DParam; + +::testing::internal::ParamGenerator<Convolve2DParam> BuildParams( + convolve_2d_func filter, convolve_2d_func filter2); +#else typedef std::tr1::tuple<int, int, convolve_2d_func> Convolve2DParam; ::testing::internal::ParamGenerator<Convolve2DParam> BuildParams( convolve_2d_func filter); +#endif // CONFIG_JNT_COMP class AV1Convolve2DTest : public ::testing::TestWithParam<Convolve2DParam> { public: @@ -45,6 +53,9 @@ protected: void RunCheckOutput(convolve_2d_func test_impl); +#if CONFIG_JNT_COMP + void RunCheckOutput2(convolve_2d_func test_impl); +#endif libaom_test::ACMRandom rnd_; };
diff --git a/test/av1_convolve_scale_test.cc b/test/av1_convolve_scale_test.cc index 9d8be88..0cc5206 100644 --- a/test/av1_convolve_scale_test.cc +++ b/test/av1_convolve_scale_test.cc
@@ -20,6 +20,10 @@ #include "test/register_state_check.h" #include "test/util.h" +#if CONFIG_JNT_COMP +#include "av1/common/common_data.h" +#endif + namespace { const int kTestIters = 10; const int kPerfIters = 1000; @@ -257,13 +261,43 @@ image_ = new TestImage<SrcPixel>(width_, height_, bd_); } +#if CONFIG_JNT_COMP + void SetConvParamOffset(int i, int j) { + if (i == -1 && j == -1) { + convolve_params_.fwd_offset = -1; + convolve_params_.bck_offset = -1; + } else { + convolve_params_.fwd_offset = quant_dist_lookup_table[i][j][0]; + convolve_params_.bck_offset = quant_dist_lookup_table[i][j][1]; + } + } +#endif // CONFIG_JNT_COMP + void Run() { ACMRandom rnd(ACMRandom::DeterministicSeed()); for (int i = 0; i < kTestIters; ++i) { +#if CONFIG_JNT_COMP + SetConvParamOffset(-1, -1); Prep(&rnd); RunOne(true); RunOne(false); image_->Check(); + + for (int j = 0; j < 2; ++j) { + for (int k = 0; k < 4; ++k) { + SetConvParamOffset(j, k); + Prep(&rnd); + RunOne(true); + RunOne(false); + image_->Check(); + } + } +#else + Prep(&rnd); + RunOne(true); + RunOne(false); + image_->Check(); +#endif // CONFIG_JNT_COMP } }