From 362809dfbfff8695c0a67f072edd0d971f22ffb4 Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Tue, 18 Jun 2013 10:46:33 -0700 Subject: [PATCH] Add unit tests for 4x4 ADST Enable sign bias check and round-trip error unit tests for 4x4 hybrid transform modules. Change-Id: Icd3d839f098d4b92b00ff76eac146765b039d0d3 --- test/fdct4x4_test.cc | 88 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 22 deletions(-) diff --git a/test/fdct4x4_test.cc b/test/fdct4x4_test.cc index 1c887bb..e246491 100644 --- a/test/fdct4x4_test.cc +++ b/test/fdct4x4_test.cc @@ -24,8 +24,56 @@ extern "C" { using libvpx_test::ACMRandom; namespace { +void fdct4x4(int16_t *in, int16_t *out, uint8_t *dst, int stride, int tx_type) { + vp9_short_fdct4x4_c(in, out, stride); +} +void idct4x4_add(int16_t *in, int16_t *out, uint8_t *dst, + int stride, int tx_type) { + vp9_short_idct4x4_add_c(out, dst, stride >> 1); +} +void fht4x4(int16_t *in, int16_t *out, uint8_t *dst, int stride, int tx_type) { + vp9_short_fht4x4_c(in, out, stride >> 1, tx_type); +} +void iht4x4_add(int16_t *in, int16_t *out, uint8_t *dst, + int stride, int tx_type) { + vp9_short_iht4x4_add_c(out, dst, stride >> 1, tx_type); +} + +class FwdTrans4x4Test : public ::testing::TestWithParam { + public: + FwdTrans4x4Test() {SetUpTestTxfm();} + ~FwdTrans4x4Test() {} + + void SetUpTestTxfm() { + tx_type = GetParam(); + if (tx_type == 0) { + fwd_txfm = fdct4x4; + inv_txfm = idct4x4_add; + } else { + fwd_txfm = fht4x4; + inv_txfm = iht4x4_add; + } + } + + protected: + void RunFwdTxfm(int16_t *in, int16_t *out, uint8_t *dst, + int stride, int tx_type) { + (*fwd_txfm)(in, out, dst, stride, tx_type); + } + + void RunInvTxfm(int16_t *in, int16_t *out, uint8_t *dst, + int stride, int tx_type) { + (*inv_txfm)(in, out, dst, stride, tx_type); + } + + int tx_type; + void (*fwd_txfm)(int16_t *in, int16_t *out, uint8_t *dst, + int stride, int tx_type); + void (*inv_txfm)(int16_t *in, int16_t *out, uint8_t *dst, + int stride, int tx_type); +}; -TEST(Vp9Fdct4x4Test, SignBiasCheck) { +TEST_P(FwdTrans4x4Test, SignBiasCheck) { ACMRandom rnd(ACMRandom::DeterministicSeed()); int16_t test_input_block[16]; int16_t test_output_block[16]; @@ -34,15 +82,12 @@ TEST(Vp9Fdct4x4Test, SignBiasCheck) { const int count_test_block = 1000000; memset(count_sign_block, 0, sizeof(count_sign_block)); - for (int i = 0; i < count_test_block; ++i) { // Initialize a test block with input range [-255, 255]. for (int j = 0; j < 16; ++j) test_input_block[j] = rnd.Rand8() - rnd.Rand8(); - // TODO(Yaowu): this should be converted to a parameterized test - // to test optimized versions of this function. - vp9_short_fdct4x4_c(test_input_block, test_output_block, pitch); + RunFwdTxfm(test_input_block, test_output_block, NULL, pitch, tx_type); for (int j = 0; j < 16; ++j) { if (test_output_block[j] < 0) @@ -56,20 +101,18 @@ TEST(Vp9Fdct4x4Test, SignBiasCheck) { const bool bias_acceptable = (abs(count_sign_block[j][0] - count_sign_block[j][1]) < 10000); EXPECT_TRUE(bias_acceptable) - << "Error: 4x4 FDCT has a sign bias > 1%" - << " for input range [-255, 255] at index " << j; + << "Error: 4x4 FDCT/FHT has a sign bias > 1%" + << " for input range [-255, 255] at index " << j + << " tx_type " << tx_type; } memset(count_sign_block, 0, sizeof(count_sign_block)); - for (int i = 0; i < count_test_block; ++i) { // Initialize a test block with input range [-15, 15]. for (int j = 0; j < 16; ++j) test_input_block[j] = (rnd.Rand8() >> 4) - (rnd.Rand8() >> 4); - // TODO(Yaowu): this should be converted to a parameterized test - // to test optimized versions of this function. - vp9_short_fdct4x4_c(test_input_block, test_output_block, pitch); + RunFwdTxfm(test_input_block, test_output_block, NULL, pitch, tx_type); for (int j = 0; j < 16; ++j) { if (test_output_block[j] < 0) @@ -83,13 +126,14 @@ TEST(Vp9Fdct4x4Test, SignBiasCheck) { const bool bias_acceptable = (abs(count_sign_block[j][0] - count_sign_block[j][1]) < 100000); EXPECT_TRUE(bias_acceptable) - << "Error: 4x4 FDCT has a sign bias > 10%" + << "Error: 4x4 FDCT/FHT has a sign bias > 10%" << " for input range [-15, 15] at index " << j; } -}; +} -TEST(Vp9Fdct4x4Test, RoundTripErrorCheck) { +TEST_P(FwdTrans4x4Test, RoundTripErrorCheck) { ACMRandom rnd(ACMRandom::DeterministicSeed()); + int max_error = 0; double total_error = 0; const int count_test_block = 1000000; @@ -106,10 +150,8 @@ TEST(Vp9Fdct4x4Test, RoundTripErrorCheck) { for (int j = 0; j < 16; ++j) test_input_block[j] = src[j] - dst[j]; - // TODO(Yaowu): this should be converted to a parameterized test - // to test optimized versions of this function. const int pitch = 8; - vp9_short_fdct4x4_c(test_input_block, test_temp_block, pitch); + RunFwdTxfm(test_input_block, test_temp_block, dst, pitch, tx_type); for (int j = 0; j < 16; ++j) { if(test_temp_block[j] > 0) { @@ -123,8 +165,8 @@ TEST(Vp9Fdct4x4Test, RoundTripErrorCheck) { } } - // Because the bitstream is not frozen yet, use the idct in the codebase. - vp9_short_idct4x4_add_c(test_temp_block, dst, 4); + // inverse transform and reconstruct the pixel block + RunInvTxfm(test_input_block, test_temp_block, dst, pitch, tx_type); for (int j = 0; j < 16; ++j) { const int diff = dst[j] - src[j]; @@ -135,10 +177,12 @@ TEST(Vp9Fdct4x4Test, RoundTripErrorCheck) { } } EXPECT_GE(1, max_error) - << "Error: FDCT/IDCT has an individual roundtrip error > 1"; + << "Error: FDCT/IDCT or FHT/IHT has an individual roundtrip error > 1"; EXPECT_GE(count_test_block, total_error) - << "Error: FDCT/IDCT has average roundtrip error > 1 per block"; -}; + << "Error: FDCT/IDCT or FHT/IHT has average " + "roundtrip error > 1 per block"; +} +INSTANTIATE_TEST_CASE_P(VP9, FwdTrans4x4Test, ::testing::Range(0, 4)); } // namespace -- 2.7.4