Commit 49b4a274 authored by Jingning Han's avatar Jingning Han

Add overflow check unit test for 16x16 inverse DCT/ADST transform

This commit applies quantization process with coarse quantization
step size to the forward transform coefficients and tests all the
inverse 16x16 DCT and ADST implementation versions with the
dequantized coefficients as input, to verify that the outcomes
match the prototype.

Change-Id: I68034a6126b45192c87d8c642155290e89bff8fa
parent 2c1cdf69
......@@ -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(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment