Index: source/libvpx/test/dct16x16_test.cc |
=================================================================== |
--- source/libvpx/test/dct16x16_test.cc (revision 278778) |
+++ source/libvpx/test/dct16x16_test.cc (working copy) |
@@ -272,10 +272,18 @@ |
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() {} |
@@ -358,12 +366,13 @@ |
input_block[j] = rnd.Rand8() - rnd.Rand8(); |
input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255; |
} |
- if (i == 0) |
+ if (i == 0) { |
for (int j = 0; j < kNumCoeffs; ++j) |
input_extreme_block[j] = 255; |
- if (i == 1) |
+ } else 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_); |
REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block, |
@@ -378,6 +387,47 @@ |
} |
} |
+ 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 +464,7 @@ |
int pitch_; |
int tx_type_; |
fht_t fwd_txfm_ref; |
+ iht_t inv_txfm_ref; |
}; |
class Trans16x16DCT |
@@ -428,6 +479,7 @@ |
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 +507,12 @@ |
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 +529,7 @@ |
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 +557,12 @@ |
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( |
@@ -534,4 +599,36 @@ |
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2), |
make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3))); |
#endif |
+ |
+#if HAVE_SSSE3 |
+INSTANTIATE_TEST_CASE_P( |
+ SSSE3, Trans16x16DCT, |
+ ::testing::Values( |
+ make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0))); |
+#endif |
+ |
+#if HAVE_AVX2 |
+// TODO(jzern): these prototypes can be removed after the avx2 versions are |
+// reenabled in vp9_rtcd_defs.pl. |
+extern "C" { |
+void vp9_fdct16x16_avx2(const int16_t *input, int16_t *output, int stride); |
+void vp9_fht16x16_avx2(const int16_t *input, int16_t *output, int stride, |
+ int tx_type); |
+} |
+INSTANTIATE_TEST_CASE_P( |
+ DISABLED_AVX2, Trans16x16DCT, |
+ ::testing::Values( |
+ make_tuple(&vp9_fdct16x16_avx2, |
+ &vp9_idct16x16_256_add_c, 0))); |
+INSTANTIATE_TEST_CASE_P( |
+ AVX2, Trans16x16HT, |
+ ::testing::Values( |
+ make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 3))); |
+INSTANTIATE_TEST_CASE_P( |
+ DISABLED_AVX2, Trans16x16HT, |
+ ::testing::Values( |
+ make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 0), |
+ make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 1), |
+ make_tuple(&vp9_fht16x16_avx2, &vp9_iht16x16_256_add_c, 2))); |
+#endif |
} // namespace |