Commit 362809df authored by Jingning Han's avatar Jingning Han

Add unit tests for 4x4 ADST

Enable sign bias check and round-trip error unit tests for 4x4 hybrid
transform modules.

Change-Id: Icd3d839f098d4b92b00ff76eac146765b039d0d3
parent a41a4860
......@@ -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<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(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
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