1/* 2 * Copyright (c) 2015 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include <math.h> 12#include <stdlib.h> 13#include <new> 14 15#include "third_party/googletest/src/include/gtest/gtest.h" 16#include "test/acm_random.h" 17#include "test/util.h" 18#include "./vpx_config.h" 19#include "vpx_ports/msvc.h" 20 21#undef CONFIG_COEFFICIENT_RANGE_CHECKING 22#define CONFIG_COEFFICIENT_RANGE_CHECKING 1 23#include "vp10/encoder/dct.c" 24 25using libvpx_test::ACMRandom; 26 27namespace { 28void reference_dct_1d(const double *in, double *out, int size) { 29 const double PI = 3.141592653589793238462643383279502884; 30 const double kInvSqrt2 = 0.707106781186547524400844362104; 31 for (int k = 0; k < size; ++k) { 32 out[k] = 0; 33 for (int n = 0; n < size; ++n) { 34 out[k] += in[n] * cos(PI * (2 * n + 1) * k / (2 * size)); 35 } 36 if (k == 0) 37 out[k] = out[k] * kInvSqrt2; 38 } 39} 40 41typedef void (*FdctFuncRef)(const double *in, double *out, int size); 42typedef void (*IdctFuncRef)(const double *in, double *out, int size); 43typedef void (*FdctFunc)(const tran_low_t *in, tran_low_t *out); 44typedef void (*IdctFunc)(const tran_low_t *in, tran_low_t *out); 45 46class TransTestBase { 47 public: 48 virtual ~TransTestBase() {} 49 50 protected: 51 void RunFwdAccuracyCheck() { 52 tran_low_t *input = new tran_low_t[txfm_size_]; 53 tran_low_t *output = new tran_low_t[txfm_size_]; 54 double *ref_input = new double[txfm_size_]; 55 double *ref_output = new double[txfm_size_]; 56 57 ACMRandom rnd(ACMRandom::DeterministicSeed()); 58 const int count_test_block = 5000; 59 for (int ti = 0; ti < count_test_block; ++ti) { 60 for (int ni = 0; ni < txfm_size_; ++ni) { 61 input[ni] = rnd.Rand8() - rnd.Rand8(); 62 ref_input[ni] = static_cast<double>(input[ni]); 63 } 64 65 fwd_txfm_(input, output); 66 fwd_txfm_ref_(ref_input, ref_output, txfm_size_); 67 68 for (int ni = 0; ni < txfm_size_; ++ni) { 69 EXPECT_LE( 70 abs(output[ni] - static_cast<tran_low_t>(round(ref_output[ni]))), 71 max_error_); 72 } 73 } 74 75 delete[] input; 76 delete[] output; 77 delete[] ref_input; 78 delete[] ref_output; 79 } 80 81 double max_error_; 82 int txfm_size_; 83 FdctFunc fwd_txfm_; 84 FdctFuncRef fwd_txfm_ref_; 85}; 86 87typedef std::tr1::tuple<FdctFunc, FdctFuncRef, int, int> FdctParam; 88class Vp10FwdTxfm 89 : public TransTestBase, 90 public ::testing::TestWithParam<FdctParam> { 91 public: 92 virtual void SetUp() { 93 fwd_txfm_ = GET_PARAM(0); 94 fwd_txfm_ref_ = GET_PARAM(1); 95 txfm_size_ = GET_PARAM(2); 96 max_error_ = GET_PARAM(3); 97 } 98 virtual void TearDown() {} 99}; 100 101TEST_P(Vp10FwdTxfm, RunFwdAccuracyCheck) { 102 RunFwdAccuracyCheck(); 103} 104 105INSTANTIATE_TEST_CASE_P( 106 C, Vp10FwdTxfm, 107 ::testing::Values( 108 FdctParam(&fdct4, &reference_dct_1d, 4, 1), 109 FdctParam(&fdct8, &reference_dct_1d, 8, 1), 110 FdctParam(&fdct16, &reference_dct_1d, 16, 2))); 111} // namespace 112