Skip to content
Snippets Groups Projects
Commit ed7e3d24 authored by Yaowu Xu's avatar Yaowu Xu
Browse files

Add test for partial inverse transforms

To make sure the results they produce to match their full versions

Change-Id: Ib00b036fecf43fe20af716acfc580af18ef87757
parent d62af81f
No related branches found
No related tags found
No related merge requests found
......@@ -26,6 +26,11 @@ class ACMRandom {
void Reset(int seed) {
random_.Reseed(seed);
}
uint16_t Rand16(void) {
const uint32_t value =
random_.Generate(testing::internal::Random::kMaxRange);
return (value >> 16) & 0xffff;
}
uint8_t Rand8(void) {
const uint32_t value =
......
/*
* Copyright (c) 2013 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 <math.h>
#include <stdlib.h>
#include <string.h>
#include "third_party/googletest/src/include/gtest/gtest.h"
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
extern "C" {
#include "./vp9_rtcd.h"
#include "vp9/common/vp9_blockd.h"
#include "vp9/common/vp9_scan.h"
}
#include "vpx/vpx_integer.h"
using libvpx_test::ACMRandom;
namespace {
typedef void (*fwd_txfm_t)(const int16_t *in, int16_t *out, int stride);
typedef void (*inv_txfm_t)(const int16_t *in, uint8_t *out, int stride);
typedef std::tr1::tuple<inv_txfm_t,
inv_txfm_t,
TX_SIZE, int> partial_itxfm_param_t;
const int kMaxNumCoeffs = 1024;
class PartialIDctTest : public ::testing::TestWithParam<partial_itxfm_param_t> {
public:
virtual ~PartialIDctTest() {}
virtual void SetUp() {
full_itxfm_ = GET_PARAM(0);
partial_itxfm_ = GET_PARAM(1);
tx_size_ = GET_PARAM(2);
last_nonzero_ = GET_PARAM(3);
}
virtual void TearDown() { libvpx_test::ClearSystemState(); }
protected:
int last_nonzero_;
TX_SIZE tx_size_;
inv_txfm_t full_itxfm_;
inv_txfm_t partial_itxfm_;
};
TEST_P(PartialIDctTest, ResultsMatch) {
ACMRandom rnd(ACMRandom::DeterministicSeed());
int size;
switch (tx_size_) {
case TX_4X4:
size = 4;
break;
case TX_8X8:
size = 8;
break;
case TX_16X16:
size = 16;
break;
case TX_32X32:
size = 32;
break;
default:
ASSERT_TRUE(0) << "Wrong Size!";
break;
}
DECLARE_ALIGNED_ARRAY(16, int16_t, test_coef_block1, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, int16_t, test_coef_block2, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst1, kMaxNumCoeffs);
DECLARE_ALIGNED_ARRAY(16, uint8_t, dst2, kMaxNumCoeffs);
const int count_test_block = 1000;
const int max_coeff = 32766 / 4;
const int block_size = size * size;
int max_error = 0;
for (int i = 0; i < count_test_block; ++i) {
// clear out destination buffer
memset(dst1, 0, sizeof(*dst1) * block_size);
memset(dst2, 0, sizeof(*dst2) * block_size);
memset(test_coef_block1, 0, sizeof(*test_coef_block1) * block_size);
memset(test_coef_block2, 0, sizeof(*test_coef_block2) * 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(max_energy_leftover) *
(rnd.Rand16() - 32768) / 65536);
max_energy_leftover -= coef * coef;
if (max_energy_leftover < 0) {
max_energy_leftover = 0;
coef = 0;
}
test_coef_block1[vp9_default_scan_orders[tx_size_].scan[j]] = coef;
}
memcpy(test_coef_block2, test_coef_block1,
sizeof(*test_coef_block2) * block_size);
REGISTER_STATE_CHECK(full_itxfm_(test_coef_block1, dst1, size));
REGISTER_STATE_CHECK(partial_itxfm_(test_coef_block2, dst2, size));
for (int j = 0; j < block_size; ++j) {
const int diff = dst1[j] - dst2[j];
const int error = diff * diff;
if (max_error < error)
max_error = error;
}
}
EXPECT_EQ(0, max_error)
<< "Error: partial inverse transform produces different results";
}
using std::tr1::make_tuple;
INSTANTIATE_TEST_CASE_P(
C, PartialIDctTest,
::testing::Values(
make_tuple(vp9_idct32x32_1024_add_c,
vp9_idct32x32_34_add_c,
TX_32X32, 34),
make_tuple(vp9_idct32x32_1024_add_c,
vp9_idct32x32_1_add_c,
TX_32X32, 1),
make_tuple(vp9_idct16x16_256_add_c,
vp9_idct16x16_10_add_c,
TX_16X16, 10),
make_tuple(vp9_idct16x16_256_add_c,
vp9_idct16x16_1_add_c,
TX_16X16, 1),
make_tuple(vp9_idct8x8_64_add_c,
vp9_idct8x8_10_add_c,
TX_8X8, 10),
make_tuple(vp9_idct8x8_64_add_c,
vp9_idct8x8_1_add_c,
TX_8X8, 1),
make_tuple(vp9_idct4x4_16_add_c,
vp9_idct4x4_1_add_c,
TX_4X4, 1)));
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
SSE2, PartialIDctTest,
::testing::Values(
make_tuple(vp9_idct32x32_1024_add_c,
vp9_idct32x32_34_add_sse2,
TX_32X32, 34),
make_tuple(vp9_idct32x32_1024_add_c,
vp9_idct32x32_1_add_sse2,
TX_32X32, 1),
make_tuple(vp9_idct16x16_256_add_c,
vp9_idct16x16_10_add_sse2,
TX_16X16, 10),
make_tuple(vp9_idct16x16_256_add_c,
vp9_idct16x16_1_add_sse2,
TX_16X16, 1),
make_tuple(vp9_idct8x8_64_add_c,
vp9_idct8x8_10_add_sse2,
TX_8X8, 10),
make_tuple(vp9_idct8x8_64_add_c,
vp9_idct8x8_1_add_sse2,
TX_8X8, 1),
make_tuple(vp9_idct4x4_16_add_c,
vp9_idct4x4_1_add_sse2,
TX_4X4, 1)));
#endif
} // namespace
......@@ -88,6 +88,7 @@ LIBVPX_TEST_SRCS-yes += vp9_boolcoder_test.cc
# IDCT test currently depends on FDCT function
LIBVPX_TEST_SRCS-yes += idct8x8_test.cc
LIBVPX_TEST_SRCS-yes += partial_idct_test.cc
LIBVPX_TEST_SRCS-yes += superframe_test.cc
LIBVPX_TEST_SRCS-yes += tile_independence_test.cc
endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment