diff --git a/test/dct16x16_test.cc b/test/dct16x16_test.cc index 20b1c8fbd..92976e14c 100644 --- a/test/dct16x16_test.cc +++ b/test/dct16x16_test.cc @@ -272,10 +272,18 @@ void fdct16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) { vp9_fdct16x16_c(in, out, stride); } +void idct16x16_ref(const int16_t *in, uint8_t *dest, int stride, int tx_type) { + vp9_idct16x16_256_add_c(in, dest, stride); +} + void fht16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) { vp9_fht16x16_c(in, out, stride, tx_type); } +void iht16x16_ref(const int16_t *in, uint8_t *dest, int stride, int tx_type) { + vp9_iht16x16_256_add_c(in, dest, stride, tx_type); +} + class Trans16x16TestBase { public: virtual ~Trans16x16TestBase() {} @@ -378,6 +386,47 @@ class Trans16x16TestBase { } } + void RunQuantCheck(int dc_thred, int ac_thred) { + ACMRandom rnd(ACMRandom::DeterministicSeed()); + const int count_test_block = 1000; + DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); + DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); + DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs); + + DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); + DECLARE_ALIGNED_ARRAY(16, uint8_t, ref, kNumCoeffs); + + for (int i = 0; i < count_test_block; ++i) { + // Initialize a test block with input range [-255, 255]. + for (int j = 0; j < kNumCoeffs; ++j) { + input_block[j] = rnd.Rand8() - rnd.Rand8(); + input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255; + } + if (i == 0) + for (int j = 0; j < kNumCoeffs; ++j) + input_extreme_block[j] = 255; + if (i == 1) + for (int j = 0; j < kNumCoeffs; ++j) + input_extreme_block[j] = -255; + + fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_); + + // clear reconstructed pixel buffers + vpx_memset(dst, 0, kNumCoeffs * sizeof(uint8_t)); + vpx_memset(ref, 0, kNumCoeffs * sizeof(uint8_t)); + + // quantization with maximum allowed step sizes + output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred; + for (int j = 1; j < kNumCoeffs; ++j) + output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred; + inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_); + REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_)); + + for (int j = 0; j < kNumCoeffs; ++j) + EXPECT_EQ(ref[j], dst[j]); + } + } + void RunInvAccuracyCheck() { ACMRandom rnd(ACMRandom::DeterministicSeed()); const int count_test_block = 1000; @@ -414,6 +463,7 @@ class Trans16x16TestBase { int pitch_; int tx_type_; fht_t fwd_txfm_ref; + iht_t inv_txfm_ref; }; class Trans16x16DCT @@ -428,6 +478,7 @@ class Trans16x16DCT tx_type_ = GET_PARAM(2); pitch_ = 16; fwd_txfm_ref = fdct16x16_ref; + inv_txfm_ref = idct16x16_ref; } virtual void TearDown() { libvpx_test::ClearSystemState(); } @@ -455,6 +506,12 @@ TEST_P(Trans16x16DCT, MemCheck) { RunMemCheck(); } +TEST_P(Trans16x16DCT, QuantCheck) { + // Use maximally allowed quantization step sizes for DC and AC + // coefficients respectively. + RunQuantCheck(1336, 1828); +} + TEST_P(Trans16x16DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); } @@ -471,6 +528,7 @@ class Trans16x16HT tx_type_ = GET_PARAM(2); pitch_ = 16; fwd_txfm_ref = fht16x16_ref; + inv_txfm_ref = iht16x16_ref; } virtual void TearDown() { libvpx_test::ClearSystemState(); } @@ -498,6 +556,12 @@ TEST_P(Trans16x16HT, MemCheck) { RunMemCheck(); } +TEST_P(Trans16x16HT, QuantCheck) { + // The encoder skips any non-DC intra prediction modes, + // when the quantization step size goes beyond 988. + RunQuantCheck(549, 988); +} + using std::tr1::make_tuple; INSTANTIATE_TEST_CASE_P(