diff options
Diffstat (limited to 'test/partial_idct_test.cc')
-rw-r--r-- | test/partial_idct_test.cc | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/test/partial_idct_test.cc b/test/partial_idct_test.cc index 0c704c5c8..3539591bb 100644 --- a/test/partial_idct_test.cc +++ b/test/partial_idct_test.cc @@ -32,6 +32,38 @@ typedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride); typedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, InvTxfmFunc, TX_SIZE, int> PartialInvTxfmParam; const int kMaxNumCoeffs = 1024; + +// https://bugs.chromium.org/p/webm/issues/detail?id=1332 +// The functions specified do not pass with INT16_MIN/MAX. They fail at the +// value specified, but pass when 1 is added/subtracted. +int16_t MaxSupportedCoeff(InvTxfmFunc a) { +#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH && \ + !CONFIG_EMULATE_HARDWARE + if (a == vpx_idct8x8_64_add_ssse3 || a == vpx_idct8x8_12_add_ssse3) { + return 23625 - 1; + } +#else + (void)a; +#endif + return INT16_MAX; +} + +int16_t MinSupportedCoeff(InvTxfmFunc a) { + (void)a; +#if !CONFIG_EMULATE_HARDWARE +#if HAVE_SSSE3 && ARCH_X86_64 && !CONFIG_VP9_HIGHBITDEPTH + if (a == vpx_idct8x8_64_add_ssse3 || a == vpx_idct8x8_12_add_ssse3) { + return -23625 + 1; + } +#elif HAVE_NEON + if (a == vpx_idct4x4_16_add_neon) { + return INT16_MIN + 1; + } +#endif +#endif // !CONFIG_EMULATE_HARDWARE + return INT16_MIN; +} + class PartialIDctTest : public ::testing::TestWithParam<PartialInvTxfmParam> { public: virtual ~PartialIDctTest() {} @@ -142,14 +174,14 @@ TEST_P(PartialIDctTest, ResultsMatch) { memset(output_block_ref_, 0, sizeof(*output_block_ref_) * block_size_); int max_energy_leftover = max_coeff * max_coeff; for (int j = 0; j < last_nonzero_; ++j) { - int16_t coef = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) * - (rnd.Rand16() - 32768) / 65536); - max_energy_leftover -= coef * coef; + int16_t coeff = static_cast<int16_t>(sqrt(1.0 * max_energy_leftover) * + (rnd.Rand16() - 32768) / 65536); + max_energy_leftover -= coeff * coeff; if (max_energy_leftover < 0) { max_energy_leftover = 0; - coef = 0; + coeff = 0; } - input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = coef; + input_block_[vp9_default_scan_orders[tx_size_].scan[j]] = coeff; } ASM_REGISTER_STATE_CHECK( @@ -186,6 +218,33 @@ TEST_P(PartialIDctTest, AddOutputBlock) { << "Error: Transform results are not correctly added to output."; } } + +TEST_P(PartialIDctTest, SingleLargeCoeff) { + ACMRandom rnd(ACMRandom::DeterministicSeed()); + const int16_t max_coeff = MaxSupportedCoeff(partial_itxfm_); + const int16_t min_coeff = MinSupportedCoeff(partial_itxfm_); + for (int i = 0; i < last_nonzero_; ++i) { + memset(input_block_, 0, sizeof(*input_block_) * block_size_); + // Run once for min and once for max. + for (int j = 0; j < 2; ++j) { + const int coeff = j ? min_coeff : max_coeff; + + memset(output_block_, 0, sizeof(*output_block_) * block_size_); + memset(output_block_ref_, 0, sizeof(*output_block_ref_) * block_size_); + input_block_[vp9_default_scan_orders[tx_size_].scan[i]] = coeff; + + ASM_REGISTER_STATE_CHECK( + full_itxfm_(input_block_, output_block_ref_, size_)); + ASM_REGISTER_STATE_CHECK( + partial_itxfm_(input_block_, output_block_, size_)); + + ASSERT_EQ(0, memcmp(output_block_ref_, output_block_, + sizeof(*output_block_) * block_size_)) + << "Error: Fails with single coeff of " << coeff << " at " << i + << "."; + } + } +} using std::tr1::make_tuple; INSTANTIATE_TEST_CASE_P( |