1d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org/* 2d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 3d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * 4d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * Use of this source code is governed by a BSD-style license 5d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * that can be found in the LICENSE file in the root of the source 6d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * tree. An additional intellectual property rights grant can be found 7d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * in the file PATENTS. All contributing project authors may 8d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org * be found in the AUTHORS file in the root of the source tree. 9d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org */ 10d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 11d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include <math.h> 12d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include <stdlib.h> 13d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include <string.h> 14d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 15d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "third_party/googletest/src/include/gtest/gtest.h" 16f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include "test/acm_random.h" 17f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include "test/clear_system_state.h" 18f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include "test/register_state_check.h" 19f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include "test/util.h" 20d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 21f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include "./vpx_config.h" 22d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "./vp9_rtcd.h" 23dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "vp9/common/vp9_entropy.h" 2487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#include "vpx/vpx_codec.h" 25d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#include "vpx/vpx_integer.h" 26d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 27d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgusing libvpx_test::ACMRandom; 28d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 29d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgnamespace { 30d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#ifdef _MSC_VER 31d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.orgstatic int round(double x) { 32d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org if (x < 0) 33f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org return static_cast<int>(ceil(x - 0.5)); 34d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org else 35f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org return static_cast<int>(floor(x + 0.5)); 36d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} 37d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org#endif 38d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 39f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgconst int kNumCoeffs = 1024; 40f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgconst double kPi = 3.141592653589793238462643383279502884; 41d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.orgvoid reference_32x32_dct_1d(const double in[32], double out[32]) { 42d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org const double kInvSqrt2 = 0.707106781186547524400844362104; 43d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int k = 0; k < 32; k++) { 44d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org out[k] = 0.0; 45d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int n = 0; n < 32; n++) 46d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org out[k] += in[n] * cos(kPi * (2 * n + 1) * k / 64.0); 47d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org if (k == 0) 48d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org out[k] = out[k] * kInvSqrt2; 49d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 50d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} 51d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 52f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgvoid reference_32x32_dct_2d(const int16_t input[kNumCoeffs], 53f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org double output[kNumCoeffs]) { 54d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org // First transform columns 55d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int i = 0; i < 32; ++i) { 56d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org double temp_in[32], temp_out[32]; 57d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int j = 0; j < 32; ++j) 58d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org temp_in[j] = input[j*32 + i]; 59d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org reference_32x32_dct_1d(temp_in, temp_out); 60d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int j = 0; j < 32; ++j) 61d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org output[j * 32 + i] = temp_out[j]; 62d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 63d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org // Then transform rows 64d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int i = 0; i < 32; ++i) { 65d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org double temp_in[32], temp_out[32]; 66d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int j = 0; j < 32; ++j) 67d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org temp_in[j] = output[j + i*32]; 68d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org reference_32x32_dct_1d(temp_in, temp_out); 69d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org // Scale by some magic number 70d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int j = 0; j < 32; ++j) 71d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org output[j + i * 32] = temp_out[j] / 4; 72d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 73d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} 74d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 7587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgtypedef void (*FwdTxfmFunc)(const int16_t *in, tran_low_t *out, int stride); 7687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgtypedef void (*InvTxfmFunc)(const tran_low_t *in, uint8_t *out, int stride); 77d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 7887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgtypedef std::tr1::tuple<FwdTxfmFunc, InvTxfmFunc, int, vpx_bit_depth_t> 7987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org Trans32x32Param; 8087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 8187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 8287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid idct32x32_10(const tran_low_t *in, uint8_t *out, int stride) { 8387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vp9_high_idct32x32_1024_add_c(in, out, stride, 10); 8487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org} 8587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 8687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgvoid idct32x32_12(const tran_low_t *in, uint8_t *out, int stride) { 8787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vp9_high_idct32x32_1024_add_c(in, out, stride, 12); 8887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org} 8987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 90d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 91ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.orgclass Trans32x32Test : public ::testing::TestWithParam<Trans32x32Param> { 92f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org public: 93f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org virtual ~Trans32x32Test() {} 94f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org virtual void SetUp() { 95f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org fwd_txfm_ = GET_PARAM(0); 96f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org inv_txfm_ = GET_PARAM(1); 97f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org version_ = GET_PARAM(2); // 0: high precision forward transform 98f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org // 1: low precision version for rd loop 9987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org bit_depth_ = GET_PARAM(3); 10087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org mask_ = (1 << bit_depth_) - 1; 101d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 102923acb6a717b7f2719ed21184c1bc533b0a14888johannkoenig@chromium.org 103f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org virtual void TearDown() { libvpx_test::ClearSystemState(); } 104f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 105f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org protected: 106f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org int version_; 10787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org vpx_bit_depth_t bit_depth_; 10887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int mask_; 109ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org FwdTxfmFunc fwd_txfm_; 110ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org InvTxfmFunc inv_txfm_; 111f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org}; 112f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 113f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgTEST_P(Trans32x32Test, AccuracyCheck) { 114d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org ACMRandom rnd(ACMRandom::DeterministicSeed()); 115f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org uint32_t max_error = 0; 116d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org int64_t total_error = 0; 117d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org const int count_test_block = 1000; 118f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs); 11987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, tran_low_t, test_temp_block, kNumCoeffs); 120f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); 121f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); 12287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 12387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs); 12487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs); 12587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 126d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 127f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int i = 0; i < count_test_block; ++i) { 12887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org // Initialize a test block with input range [-mask_, mask_]. 129f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) { 13087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (bit_depth_ == 8) { 13187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org src[j] = rnd.Rand8(); 13287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org dst[j] = rnd.Rand8(); 13387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org test_input_block[j] = src[j] - dst[j]; 13487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 13587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else { 13687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org src16[j] = rnd.Rand16() & mask_; 13787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org dst16[j] = rnd.Rand16() & mask_; 13887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org test_input_block[j] = src16[j] - dst16[j]; 13987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 14087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 141f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 142d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 14395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com ASM_REGISTER_STATE_CHECK(fwd_txfm_(test_input_block, test_temp_block, 32)); 14487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (bit_depth_ == VPX_BITS_8) { 14587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, dst, 32)); 14687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 14787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else { 14887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org ASM_REGISTER_STATE_CHECK(inv_txfm_(test_temp_block, 14987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org CONVERT_TO_BYTEPTR(dst16), 32)); 15087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 15187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 152d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 153f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) { 15487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 15587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org const uint32_t diff = 15687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; 15787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else 158f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const uint32_t diff = dst[j] - src[j]; 15987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 160f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const uint32_t error = diff * diff; 161d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org if (max_error < error) 162d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org max_error = error; 163d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org total_error += error; 164d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 165d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 166d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 167f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org if (version_ == 1) { 168f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org max_error /= 2; 169f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org total_error /= 45; 170f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 171f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 17287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org EXPECT_GE(1u << 2 * (bit_depth_ - 8), max_error) 173f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT/IDCT has an individual round-trip error > 1"; 174d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 17587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org EXPECT_GE(count_test_block << 2 * (bit_depth_ - 8), total_error) 176f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT/IDCT has average round-trip error > 1 per block"; 177d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} 178d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 179f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgTEST_P(Trans32x32Test, CoeffCheck) { 180d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org ACMRandom rnd(ACMRandom::DeterministicSeed()); 181d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org const int count_test_block = 1000; 182f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 183f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); 18487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs); 18587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs); 186f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 187d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org for (int i = 0; i < count_test_block; ++i) { 188f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) 18987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); 190f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 1910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org const int stride = 32; 1920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org vp9_fdct32x32_c(input_block, output_ref_block, stride); 19395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com ASM_REGISTER_STATE_CHECK(fwd_txfm_(input_block, output_block, stride)); 194f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 195f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org if (version_ == 0) { 196f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) 197f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org EXPECT_EQ(output_block[j], output_ref_block[j]) 198f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT versions have mismatched coefficients"; 199f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } else { 200f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) 201f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org EXPECT_GE(6, abs(output_block[j] - output_ref_block[j])) 202f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT rd has mismatched coefficients"; 203f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 204f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 205f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org} 206f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 207f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgTEST_P(Trans32x32Test, MemCheck) { 208f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org ACMRandom rnd(ACMRandom::DeterministicSeed()); 209f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int count_test_block = 2000; 210f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 211f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs); 212f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs); 21387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_ref_block, kNumCoeffs); 21487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, tran_low_t, output_block, kNumCoeffs); 215d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 216f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int i = 0; i < count_test_block; ++i) { 21787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org // Initialize a test block with input range [-mask_, mask_]. 218f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) { 21987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_); 22087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org input_extreme_block[j] = rnd.Rand8() & 1 ? mask_ : -mask_; 221d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 22288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org if (i == 0) { 223f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) 22487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org input_extreme_block[j] = mask_; 22588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } else if (i == 1) { 226f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) 22787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org input_extreme_block[j] = -mask_; 22888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org } 229d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 2300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org const int stride = 32; 2310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org vp9_fdct32x32_c(input_extreme_block, output_ref_block, stride); 23295aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com ASM_REGISTER_STATE_CHECK( 23395aa45d73048f952dcaad0037429cc6751b34f2fjohannkoenig@google.com fwd_txfm_(input_extreme_block, output_block, stride)); 234d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org 235d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org // The minimum quant value is 4. 236f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) { 237f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org if (version_ == 0) { 238f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org EXPECT_EQ(output_block[j], output_ref_block[j]) 239f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT versions have mismatched coefficients"; 240f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } else { 241f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org EXPECT_GE(6, abs(output_block[j] - output_ref_block[j])) 242f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT rd has mismatched coefficients"; 243f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 24487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_ref_block[j])) 245f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT C has coefficient larger than 4*DCT_MAX_VALUE"; 24687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j])) 247f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 FDCT has coefficient larger than " 248f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "4*DCT_MAX_VALUE"; 249d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 250d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org } 251d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} 252f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 253f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgTEST_P(Trans32x32Test, InverseAccuracy) { 254f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org ACMRandom rnd(ACMRandom::DeterministicSeed()); 255f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int count_test_block = 1000; 256f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs); 25787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff, kNumCoeffs); 258f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs); 259f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs); 26087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 26187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, uint16_t, dst16, kNumCoeffs); 26287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org DECLARE_ALIGNED_ARRAY(16, uint16_t, src16, kNumCoeffs); 26387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 264f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 265f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int i = 0; i < count_test_block; ++i) { 266f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org double out_r[kNumCoeffs]; 267f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 268f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org // Initialize a test block with input range [-255, 255] 269f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) { 27087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (bit_depth_ == VPX_BITS_8) { 27187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org src[j] = rnd.Rand8(); 27287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org dst[j] = rnd.Rand8(); 27387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org in[j] = src[j] - dst[j]; 27487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 27587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else { 27687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org src16[j] = rnd.Rand16() & mask_; 27787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org dst16[j] = rnd.Rand16() & mask_; 27887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org in[j] = src16[j] - dst16[j]; 27987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 28087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 281f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 282f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 283f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org reference_32x32_dct_2d(in, out_r); 284f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) 285f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org coeff[j] = round(out_r[j]); 28687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (bit_depth_ == VPX_BITS_8) { 28787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, dst, 32)); 28887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 28987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } else { 29087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org ASM_REGISTER_STATE_CHECK(inv_txfm_(coeff, CONVERT_TO_BYTEPTR(dst16), 32)); 29187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 29287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org } 293f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org for (int j = 0; j < kNumCoeffs; ++j) { 29487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 29587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org const int diff = 29687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j]; 29787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else 298f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int diff = dst[j] - src[j]; 29987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 300f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org const int error = diff * diff; 301f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org EXPECT_GE(1, error) 302f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << "Error: 32x32 IDCT has error " << error 303f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org << " at index " << j; 304f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 305f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org } 306f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org} 307f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 308f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgusing std::tr1::make_tuple; 309f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 31087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if CONFIG_VP9_HIGHBITDEPTH 31187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgINSTANTIATE_TEST_CASE_P( 31287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org C, Trans32x32Test, 31387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org ::testing::Values( 31487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_high_fdct32x32_c, 31587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &idct32x32_10, 0, VPX_BITS_10), 31687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_high_fdct32x32_rd_c, 31787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &idct32x32_10, 1, VPX_BITS_10), 31887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_high_fdct32x32_c, 31987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &idct32x32_12, 0, VPX_BITS_12), 32087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_high_fdct32x32_rd_c, 32187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &idct32x32_12, 1, VPX_BITS_12), 32287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_fdct32x32_c, 32387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_c, 0, VPX_BITS_8), 32487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_fdct32x32_rd_c, 32587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_c, 1, VPX_BITS_8))); 32687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#else 327f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgINSTANTIATE_TEST_CASE_P( 328f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org C, Trans32x32Test, 329f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org ::testing::Values( 33087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_fdct32x32_c, 33187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_c, 0, VPX_BITS_8), 33287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org make_tuple(&vp9_fdct32x32_rd_c, 33387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_c, 1, VPX_BITS_8))); 33487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#endif 335f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org 33687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH 337411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgINSTANTIATE_TEST_CASE_P( 338411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org NEON, Trans32x32Test, 339411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org ::testing::Values( 340411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org make_tuple(&vp9_fdct32x32_c, 34187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_neon, 0, VPX_BITS_8), 342411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org make_tuple(&vp9_fdct32x32_rd_c, 34387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_neon, 1, VPX_BITS_8))); 344411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#endif 345411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org 34687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH 347f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.orgINSTANTIATE_TEST_CASE_P( 348f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org SSE2, Trans32x32Test, 349f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org ::testing::Values( 3500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org make_tuple(&vp9_fdct32x32_sse2, 35187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8), 3520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org make_tuple(&vp9_fdct32x32_rd_sse2, 35387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8))); 354f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#endif 355d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org 35687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org#if HAVE_AVX2 && !CONFIG_VP9_HIGHBITDEPTH 357d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgINSTANTIATE_TEST_CASE_P( 358d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org AVX2, Trans32x32Test, 359d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org ::testing::Values( 360d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org make_tuple(&vp9_fdct32x32_avx2, 36187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_sse2, 0, VPX_BITS_8), 362d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org make_tuple(&vp9_fdct32x32_rd_avx2, 36387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &vp9_idct32x32_1024_add_sse2, 1, VPX_BITS_8))); 364d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org#endif 365d348b8d765c019ee7250075d663a83db00c65c08tomfinegan@chromium.org} // namespace 366