Index: source/libvpx/test/fdct4x4_test.cc |
=================================================================== |
--- source/libvpx/test/fdct4x4_test.cc (revision 207479) |
+++ source/libvpx/test/fdct4x4_test.cc (working copy) |
@@ -24,8 +24,56 @@ |
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); |
+} |
-TEST(Vp9Fdct4x4Test, SignBiasCheck) { |
+class FwdTrans4x4Test : public ::testing::TestWithParam<int> { |
+ 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_P(FwdTrans4x4Test, SignBiasCheck) { |
ACMRandom rnd(ACMRandom::DeterministicSeed()); |
int16_t test_input_block[16]; |
int16_t test_output_block[16]; |
@@ -34,15 +82,12 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
} |
} |
- // 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 @@ |
} |
} |
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 |