From: Daniel Kang Date: Wed, 27 Jun 2012 01:11:33 +0000 (-0700) Subject: Port Yaowu's 4x4 fDCT test. X-Git-Tag: v1.3.0~1217^2~379^2~5^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=58156f182657b567ba4dd03a892017e4ef50f7a9;p=platform%2Fupstream%2Flibvpx.git Port Yaowu's 4x4 fDCT test. Also fix unit testing. Change-Id: Iacdc6f1ec53388e093cda1c13e4379e83d4a6535 --- diff --git a/test/fdct4x4_test.cc b/test/fdct4x4_test.cc new file mode 100644 index 0000000..c4ecbdf --- /dev/null +++ b/test/fdct4x4_test.cc @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2012 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include + +#include "third_party/googletest/src/include/gtest/gtest.h" + +extern "C" { +#include "vp8/common/idct.h" +#include "vp8/encoder/dct.h" +} + +#include "vpx/vpx_integer.h" + +namespace { + +class ACMRandom { + public: + explicit ACMRandom(int seed) { Reset(seed); } + + void Reset(int seed) { srand(seed); } + + uint8_t Rand8(void) { return (rand() >> 8) & 0xff; } + + int PseudoUniform(int range) { return (rand() >> 8) % range; } + + int operator()(int n) { return PseudoUniform(n); } + + static int DeterministicSeed(void) { return 0xbaba; } +}; + +TEST(Vp8FdctTest, SignBiasCheck) { + ACMRandom rnd(ACMRandom::DeterministicSeed()); + int16_t test_input_block[16]; + int16_t test_output_block[16]; + const int pitch = 8; + int count_sign_block[16][2]; + 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. + vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch); + + for (int j = 0; j < 16; ++j) { + if (test_output_block[j] < 0) + ++count_sign_block[j][0]; + else if (test_output_block[j] > 0) + ++count_sign_block[j][1]; + } + } + + for (int j = 0; j < 16; ++j) { + 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; + } + + 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. + vp8_short_fdct4x4_c(test_input_block, test_output_block, pitch); + + for (int j = 0; j < 16; ++j) { + if (test_output_block[j] < 0) + ++count_sign_block[j][0]; + else if (test_output_block[j] > 0) + ++count_sign_block[j][1]; + } + } + + for (int j = 0; j < 16; ++j) { + 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%" + << " for input range [-15, 15] at index " << j; + } +}; + +TEST(Vp8FdctTest, RoundTripErrorCheck) { + ACMRandom rnd(ACMRandom::DeterministicSeed()); + int max_error = 0; + double total_error = 0; + const int count_test_block = 1000000; + for (int i = 0; i < count_test_block; ++i) { + int16_t test_input_block[16]; + int16_t test_temp_block[16]; + int16_t test_output_block[16]; + + // 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. + const int pitch = 8; + vp8_short_fdct4x4_c(test_input_block, test_temp_block, pitch); + // Because the bitstream is not frozen yet, use the idct in the codebase. + vp8_short_idct4x4llm_c(test_temp_block, test_output_block, pitch); + + for (int j = 0; j < 16; ++j) { + const int diff = test_input_block[j] - test_output_block[j]; + const int error = diff * diff; + if (max_error < error) + max_error = error; + total_error += error; + } + } + + EXPECT_GE(1, max_error) + << "Error: FDCT/IDCT has an individual roundtrip error > 1"; + + EXPECT_GE(count_test_block, total_error) + << "Error: FDCT/IDCT has average roundtrip error > 1 per block"; +}; + +} // namespace diff --git a/test/test-data.sha1 b/test/test-data.sha1 new file mode 100644 index 0000000..8d40242 --- /dev/null +++ b/test/test-data.sha1 @@ -0,0 +1 @@ +d5dfb0151c9051f8c85999255645d7a23916d3c0 hantro_collage_w352h288.yuv diff --git a/test/test.mk b/test/test.mk index bfef823..a9ccaf2 100644 --- a/test/test.mk +++ b/test/test.mk @@ -1,3 +1,6 @@ LIBVPX_TEST_SRCS-yes += test.mk LIBVPX_TEST_SRCS-yes += boolcoder_test.cc +LIBVPX_TEST_SRCS-yes += fdct4x4_test.cc LIBVPX_TEST_SRCS-yes += test_libvpx.cc + +LIBVPX_TEST_DATA-yes += hantro_collage_w352h288.yuv