16fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org/*
26fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Copyright (c) 2012 The WebM project authors. All Rights Reserved.
36fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *
46fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  Use of this source code is governed by a BSD-style license
56fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  that can be found in the LICENSE file in the root of the source
66fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  tree. An additional intellectual property rights grant can be found
76fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  in the file PATENTS.  All contributing project authors may
86fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org *  be found in the AUTHORS file in the root of the source tree.
96fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org */
106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <math.h>
126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <stdlib.h>
136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include <string.h>
146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org#include "third_party/googletest/src/include/gtest/gtest.h"
160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@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"
190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#include "test/util.h"
206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
21f9586bb54d74c97d07b09eb2512f8569c9c1c025fgalligan@chromium.org#include "./vp9_rtcd.h"
22dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "vp9/common/vp9_entropy.h"
23dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org#include "vpx/vpx_integer.h"
24dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.org
25dddee1ec7cedf276305b107429f684539b105276johannkoenig@chromium.orgextern "C" {
260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid vp9_idct8x8_64_add_c(const int16_t *input, uint8_t *output, int pitch);
276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}
286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgusing libvpx_test::ACMRandom;
306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgnamespace {
320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtypedef void (*fdct_t)(const int16_t *in, int16_t *out, int stride);
330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtypedef void (*idct_t)(const int16_t *in, uint8_t *out, int stride);
340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtypedef void (*fht_t) (const int16_t *in, int16_t *out, int stride,
350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       int tx_type);
360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgtypedef void (*iht_t) (const int16_t *in, uint8_t *out, int stride,
370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org                       int tx_type);
380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
39d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgtypedef std::tr1::tuple<fdct_t, idct_t, int> dct_8x8_param_t;
40d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgtypedef std::tr1::tuple<fht_t, iht_t, int> ht_8x8_param_t;
41d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org
420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid fdct8x8_ref(const int16_t *in, int16_t *out, int stride, int tx_type) {
430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  vp9_fdct8x8_c(in, out, stride);
44ee2f97e8e0aed42dc736a058a7e8b580eef36d8djohannkoenig@chromium.org}
450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgvoid fht8x8_ref(const int16_t *in, int16_t *out, int stride, int tx_type) {
4776e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org  vp9_fht8x8_c(in, out, stride, tx_type);
4847265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org}
4947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgclass FwdTrans8x8TestBase {
5147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org public:
520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual ~FwdTrans8x8TestBase() {}
5347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
5447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org protected:
550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void RunFwdTxfm(int16_t *in, int16_t *out, int stride) = 0;
560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) = 0;
5747265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org
580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RunSignBiasCheck() {
590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ACMRandom rnd(ACMRandom::DeterministicSeed());
600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, int16_t, test_output_block, 64);
620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int count_sign_block[64][2];
630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int count_test_block = 100000;
646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    memset(count_sign_block, 0, sizeof(count_sign_block));
666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = 0; i < count_test_block; ++i) {
680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Initialize a test block with input range [-255, 255].
690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j)
700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        test_input_block[j] = rnd.Rand8() - rnd.Rand8();
710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      REGISTER_STATE_CHECK(
720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          RunFwdTxfm(test_input_block, test_output_block, pitch_));
736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j) {
750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (test_output_block[j] < 0)
760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ++count_sign_block[j][0];
770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        else if (test_output_block[j] > 0)
780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ++count_sign_block[j][1];
790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    for (int j = 0; j < 64; ++j) {
830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const int max_diff = 1125;
850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      EXPECT_LT(diff, max_diff)
860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "Error: 8x8 FDCT/FHT has a sign bias > "
870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << 1. * max_diff / count_test_block * 100 << "%"
880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " for input range [-255, 255] at index " << j
890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " count0: " << count_sign_block[j][0]
900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " count1: " << count_sign_block[j][1]
910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " diff: " << diff;
926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    memset(count_sign_block, 0, sizeof(count_sign_block));
956fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = 0; i < count_test_block; ++i) {
970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Initialize a test block with input range [-15, 15].
980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j)
990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        test_input_block[j] = (rnd.Rand8() >> 4) - (rnd.Rand8() >> 4);
1000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      REGISTER_STATE_CHECK(
1010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          RunFwdTxfm(test_input_block, test_output_block, pitch_));
1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j) {
1040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (test_output_block[j] < 0)
1050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ++count_sign_block[j][0];
1060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        else if (test_output_block[j] > 0)
1070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          ++count_sign_block[j][1];
1080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
1090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    }
1106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    for (int j = 0; j < 64; ++j) {
1120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const int diff = abs(count_sign_block[j][0] - count_sign_block[j][1]);
1130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      const int max_diff = 10000;
1140d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      EXPECT_LT(diff, max_diff)
1150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "Error: 4x4 FDCT/FHT has a sign bias > "
1160d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << 1. * max_diff / count_test_block * 100 << "%"
1170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " for input range [-15, 15] at index " << j
1180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " count0: " << count_sign_block[j][0]
1190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " count1: " << count_sign_block[j][1]
1200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " diff: " << diff;
1216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
1226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
1236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1240d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RunRoundTripErrorCheck() {
1250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ACMRandom rnd(ACMRandom::DeterministicSeed());
1260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int max_error = 0;
1270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int total_error = 0;
1280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int count_test_block = 100000;
12947265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
13047265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, int16_t, test_temp_block, 64);
13147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
13247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
1336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = 0; i < count_test_block; ++i) {
1350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Initialize a test block with input range [-255, 255].
1360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j) {
1370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        src[j] = rnd.Rand8();
1380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        dst[j] = rnd.Rand8();
1390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        test_input_block[j] = src[j] - dst[j];
1400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
1413c315c7cf74983e7cc6a5290265081bb64ddfeb3fgalligan@chromium.org
1420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      REGISTER_STATE_CHECK(
1430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          RunFwdTxfm(test_input_block, test_temp_block, pitch_));
1440d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j) {
1450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          if (test_temp_block[j] > 0) {
1460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            test_temp_block[j] += 2;
1470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            test_temp_block[j] /= 4;
1480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            test_temp_block[j] *= 4;
1490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          } else {
1500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            test_temp_block[j] -= 2;
1510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            test_temp_block[j] /= 4;
1520d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org            test_temp_block[j] *= 4;
1530d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          }
1540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
1550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      REGISTER_STATE_CHECK(
1560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          RunInvTxfm(test_temp_block, dst, pitch_));
1570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j) {
1590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        const int diff = dst[j] - src[j];
1600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        const int error = diff * diff;
1610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (max_error < error)
1620d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          max_error = error;
1630d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        total_error += error;
1640d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
1656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    }
1666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    EXPECT_GE(1, max_error)
1680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Error: 8x8 FDCT/IDCT or FHT/IHT has an individual"
1690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << " roundtrip error > 1";
1706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    EXPECT_GE(count_test_block/5, total_error)
1720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "Error: 8x8 FDCT/IDCT or FHT/IHT has average roundtrip "
1730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      << "error > 1/5 per block";
1740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
1756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RunExtremalCheck() {
1770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ACMRandom rnd(ACMRandom::DeterministicSeed());
1780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int max_error = 0;
1790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    int total_error = 0;
1800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    const int count_test_block = 100000;
18147265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, 64);
18247265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, int16_t, test_temp_block, 64);
18347265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, 64);
18447265f8fe3a36a426773454ad90d20c9aa616c24johannkoenig@chromium.org    DECLARE_ALIGNED_ARRAY(16, uint8_t, src, 64);
1856fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    for (int i = 0; i < count_test_block; ++i) {
1870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      // Initialize a test block with input range [-255, 255].
1880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j) {
1890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        src[j] = rnd.Rand8() % 2 ? 255 : 0;
1900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        dst[j] = src[j] > 0 ? 0 : 255;
1910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        test_input_block[j] = src[j] - dst[j];
1920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
1936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      REGISTER_STATE_CHECK(
1950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          RunFwdTxfm(test_input_block, test_temp_block, pitch_));
1960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      REGISTER_STATE_CHECK(
1970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          RunInvTxfm(test_temp_block, dst, pitch_));
1980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
1990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      for (int j = 0; j < 64; ++j) {
2000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        const int diff = dst[j] - src[j];
2010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        const int error = diff * diff;
2020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        if (max_error < error)
2030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          max_error = error;
2040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        total_error += error;
2050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      }
2060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      EXPECT_GE(1, max_error)
2080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has"
2090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "an individual roundtrip error > 1";
2100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2110d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org      EXPECT_GE(count_test_block/5, total_error)
2120d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << "Error: Extremal 8x8 FDCT/IDCT or FHT/IHT has average"
2130d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org          << " roundtrip error > 1/5 per block";
214ee2f97e8e0aed42dc736a058a7e8b580eef36d8djohannkoenig@chromium.org    }
2150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
2163c315c7cf74983e7cc6a5290265081bb64ddfeb3fgalligan@chromium.org
2170d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int pitch_;
2180d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  int tx_type_;
2190d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fht_t fwd_txfm_ref;
2200d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
2213c315c7cf74983e7cc6a5290265081bb64ddfeb3fgalligan@chromium.org
222d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgclass FwdTrans8x8DCT
223d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    : public FwdTrans8x8TestBase,
224d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      public ::testing::TestWithParam<dct_8x8_param_t> {
2250d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
2260d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual ~FwdTrans8x8DCT() {}
2270d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2280d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void SetUp() {
2290d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fwd_txfm_ = GET_PARAM(0);
2300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    inv_txfm_ = GET_PARAM(1);
2310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    tx_type_  = GET_PARAM(2);
2320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    pitch_    = 8;
2330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fwd_txfm_ref = fdct8x8_ref;
2340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
2350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void TearDown() { libvpx_test::ClearSystemState(); }
2370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2380d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org protected:
2390d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RunFwdTxfm(int16_t *in, int16_t *out, int stride) {
2400d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fwd_txfm_(in, out, stride);
2410d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
2420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) {
2430d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    inv_txfm_(out, dst, stride);
2443c315c7cf74983e7cc6a5290265081bb64ddfeb3fgalligan@chromium.org  }
2450d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2460d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fdct_t fwd_txfm_;
2470d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  idct_t inv_txfm_;
2480d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
2490d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2500d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTEST_P(FwdTrans8x8DCT, SignBiasCheck) {
2510d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  RunSignBiasCheck();
2523c315c7cf74983e7cc6a5290265081bb64ddfeb3fgalligan@chromium.org}
2533c315c7cf74983e7cc6a5290265081bb64ddfeb3fgalligan@chromium.org
2540d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTEST_P(FwdTrans8x8DCT, RoundTripErrorCheck) {
2550d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  RunRoundTripErrorCheck();
2560d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
2570d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2580d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTEST_P(FwdTrans8x8DCT, ExtremalCheck) {
2590d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  RunExtremalCheck();
2600d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
2610d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
262d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.orgclass FwdTrans8x8HT
263d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org    : public FwdTrans8x8TestBase,
264d851b91d14ef0bd71acdce7b90c9a8f1af1181adjohannkoenig@chromium.org      public ::testing::TestWithParam<ht_8x8_param_t> {
2650d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org public:
2660d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual ~FwdTrans8x8HT() {}
2670d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2680d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void SetUp() {
2690d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fwd_txfm_ = GET_PARAM(0);
2700d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    inv_txfm_ = GET_PARAM(1);
2710d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    tx_type_  = GET_PARAM(2);
2720d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    pitch_    = 8;
2730d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fwd_txfm_ref = fht8x8_ref;
2740d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
2750d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2760d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  virtual void TearDown() { libvpx_test::ClearSystemState(); }
2770d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2780d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org protected:
2790d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RunFwdTxfm(int16_t *in, int16_t *out, int stride) {
2800d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    fwd_txfm_(in, out, stride, tx_type_);
2810d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
2820d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) {
2830d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    inv_txfm_(out, dst, stride, tx_type_);
2840d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  }
2850d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2860d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  fht_t fwd_txfm_;
2870d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  iht_t inv_txfm_;
2880d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org};
2890d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2900d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTEST_P(FwdTrans8x8HT, SignBiasCheck) {
2910d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  RunSignBiasCheck();
2920d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
2930d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2940d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTEST_P(FwdTrans8x8HT, RoundTripErrorCheck) {
2950d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  RunRoundTripErrorCheck();
2960d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
2970d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
2980d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgTEST_P(FwdTrans8x8HT, ExtremalCheck) {
2990d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org  RunExtremalCheck();
3000d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org}
3010d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3020d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgusing std::tr1::make_tuple;
3030d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3040d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgINSTANTIATE_TEST_CASE_P(
3050d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    C, FwdTrans8x8DCT,
3060d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::Values(
3070d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_c, 0)));
3080d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgINSTANTIATE_TEST_CASE_P(
3090d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    C, FwdTrans8x8HT,
3100d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::Values(
31176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 0),
31276e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 1),
31376e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 2),
31476e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_c, 3)));
3150d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org
3167765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#if HAVE_NEON_ASM
317411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgINSTANTIATE_TEST_CASE_P(
318411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    NEON, FwdTrans8x8DCT,
319411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    ::testing::Values(
320411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        make_tuple(&vp9_fdct8x8_c, &vp9_idct8x8_64_add_neon, 0)));
321411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.orgINSTANTIATE_TEST_CASE_P(
322411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    DISABLED_NEON, FwdTrans8x8HT,
323411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org    ::testing::Values(
324411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 0),
325411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 1),
326411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 2),
327411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org        make_tuple(&vp9_fht8x8_c, &vp9_iht8x8_64_add_neon, 3)));
328411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org#endif
329411971f94253c85e1866c281860d6344f6aa0c78fgalligan@chromium.org
3300d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#if HAVE_SSE2
3310d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgINSTANTIATE_TEST_CASE_P(
3320d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SSE2, FwdTrans8x8DCT,
3330d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::Values(
3340d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org        make_tuple(&vp9_fdct8x8_sse2, &vp9_idct8x8_64_add_sse2, 0)));
3350d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.orgINSTANTIATE_TEST_CASE_P(
3360d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    SSE2, FwdTrans8x8HT,
3370d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org    ::testing::Values(
33876e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 0),
33976e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 1),
34076e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 2),
34176e516e2154f353aa02c504bac88afb0f95fefa7johannkoenig@chromium.org        make_tuple(&vp9_fht8x8_sse2, &vp9_iht8x8_64_add_sse2, 3)));
3420d106b34dc08439a7c6887d1316a3e1a35f8f0cajohannkoenig@chromium.org#endif
3437765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org
3447765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#if HAVE_SSSE3 && ARCH_X86_64
3457765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.orgINSTANTIATE_TEST_CASE_P(
3467765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org    SSSE3, FwdTrans8x8DCT,
3477765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org    ::testing::Values(
3487765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org        make_tuple(&vp9_fdct8x8_ssse3, &vp9_idct8x8_64_add_ssse3, 0)));
3497765c078fa920ba6c949c15f16b6cc979d8bb95bjohannkoenig@chromium.org#endif
3506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org}  // namespace
351