dct16x16_test.cc 31.8 KB
Newer Older
Daniel Kang's avatar
Daniel Kang committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 *  Copyright (c) 2012 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"
16

Yaowu Xu's avatar
Yaowu Xu committed
17
#include "./vp10_rtcd.h"
18
#include "./vpx_dsp_rtcd.h"
19
20
21
22
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
Yaowu Xu's avatar
Yaowu Xu committed
23
24
#include "vp10/common/entropy.h"
#include "vp10/common/scan.h"
25
#include "vpx/vpx_codec.h"
26
#include "vpx/vpx_integer.h"
27
#include "vpx_ports/mem.h"
28
#include "vpx_ports/msvc.h"  // for round()
29

Daniel Kang's avatar
Daniel Kang committed
30
31
32
using libvpx_test::ACMRandom;

namespace {
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const int kNumCoeffs = 256;
const double C1 = 0.995184726672197;
const double C2 = 0.98078528040323;
const double C3 = 0.956940335732209;
const double C4 = 0.923879532511287;
const double C5 = 0.881921264348355;
const double C6 = 0.831469612302545;
const double C7 = 0.773010453362737;
const double C8 = 0.707106781186548;
const double C9 = 0.634393284163646;
const double C10 = 0.555570233019602;
const double C11 = 0.471396736825998;
const double C12 = 0.38268343236509;
const double C13 = 0.290284677254462;
const double C14 = 0.195090322016128;
const double C15 = 0.098017140329561;
50

Jingning Han's avatar
Jingning Han committed
51
void butterfly_16x16_dct_1d(double input[16], double output[16]) {
Daniel Kang's avatar
Daniel Kang committed
52
53
54
55
56
  double step[16];
  double intermediate[16];
  double temp1, temp2;

  // step 1
clang-format's avatar
clang-format committed
57
58
59
60
61
62
63
64
65
66
  step[0] = input[0] + input[15];
  step[1] = input[1] + input[14];
  step[2] = input[2] + input[13];
  step[3] = input[3] + input[12];
  step[4] = input[4] + input[11];
  step[5] = input[5] + input[10];
  step[6] = input[6] + input[9];
  step[7] = input[7] + input[8];
  step[8] = input[7] - input[8];
  step[9] = input[6] - input[9];
Daniel Kang's avatar
Daniel Kang committed
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
  step[10] = input[5] - input[10];
  step[11] = input[4] - input[11];
  step[12] = input[3] - input[12];
  step[13] = input[2] - input[13];
  step[14] = input[1] - input[14];
  step[15] = input[0] - input[15];

  // step 2
  output[0] = step[0] + step[7];
  output[1] = step[1] + step[6];
  output[2] = step[2] + step[5];
  output[3] = step[3] + step[4];
  output[4] = step[3] - step[4];
  output[5] = step[2] - step[5];
  output[6] = step[1] - step[6];
  output[7] = step[0] - step[7];

clang-format's avatar
clang-format committed
84
  temp1 = step[8] * C7;
85
  temp2 = step[15] * C9;
clang-format's avatar
clang-format committed
86
  output[8] = temp1 + temp2;
Daniel Kang's avatar
Daniel Kang committed
87

clang-format's avatar
clang-format committed
88
  temp1 = step[9] * C11;
89
  temp2 = step[14] * C5;
clang-format's avatar
clang-format committed
90
  output[9] = temp1 - temp2;
Daniel Kang's avatar
Daniel Kang committed
91

92
93
  temp1 = step[10] * C3;
  temp2 = step[13] * C13;
Daniel Kang's avatar
Daniel Kang committed
94
95
  output[10] = temp1 + temp2;

96
97
  temp1 = step[11] * C15;
  temp2 = step[12] * C1;
Daniel Kang's avatar
Daniel Kang committed
98
99
  output[11] = temp1 - temp2;

100
101
  temp1 = step[11] * C1;
  temp2 = step[12] * C15;
Daniel Kang's avatar
Daniel Kang committed
102
103
  output[12] = temp2 + temp1;

104
105
  temp1 = step[10] * C13;
  temp2 = step[13] * C3;
Daniel Kang's avatar
Daniel Kang committed
106
107
  output[13] = temp2 - temp1;

clang-format's avatar
clang-format committed
108
  temp1 = step[9] * C5;
109
  temp2 = step[14] * C11;
Daniel Kang's avatar
Daniel Kang committed
110
111
  output[14] = temp2 + temp1;

clang-format's avatar
clang-format committed
112
  temp1 = step[8] * C9;
113
  temp2 = step[15] * C7;
Daniel Kang's avatar
Daniel Kang committed
114
115
116
  output[15] = temp2 - temp1;

  // step 3
clang-format's avatar
clang-format committed
117
118
119
120
  step[0] = output[0] + output[3];
  step[1] = output[1] + output[2];
  step[2] = output[1] - output[2];
  step[3] = output[0] - output[3];
Daniel Kang's avatar
Daniel Kang committed
121

122
123
  temp1 = output[4] * C14;
  temp2 = output[7] * C2;
clang-format's avatar
clang-format committed
124
  step[4] = temp1 + temp2;
Daniel Kang's avatar
Daniel Kang committed
125

126
127
  temp1 = output[5] * C10;
  temp2 = output[6] * C6;
clang-format's avatar
clang-format committed
128
  step[5] = temp1 + temp2;
Daniel Kang's avatar
Daniel Kang committed
129

130
131
  temp1 = output[5] * C6;
  temp2 = output[6] * C10;
clang-format's avatar
clang-format committed
132
  step[6] = temp2 - temp1;
Daniel Kang's avatar
Daniel Kang committed
133

134
135
  temp1 = output[4] * C2;
  temp2 = output[7] * C14;
clang-format's avatar
clang-format committed
136
  step[7] = temp2 - temp1;
Daniel Kang's avatar
Daniel Kang committed
137

clang-format's avatar
clang-format committed
138
139
140
141
  step[8] = output[8] + output[11];
  step[9] = output[9] + output[10];
  step[10] = output[9] - output[10];
  step[11] = output[8] - output[11];
Daniel Kang's avatar
Daniel Kang committed
142
143
144
145
146
147
148

  step[12] = output[12] + output[15];
  step[13] = output[13] + output[14];
  step[14] = output[13] - output[14];
  step[15] = output[12] - output[15];

  // step 4
clang-format's avatar
clang-format committed
149
150
  output[0] = (step[0] + step[1]);
  output[8] = (step[0] - step[1]);
Daniel Kang's avatar
Daniel Kang committed
151

152
153
  temp1 = step[2] * C12;
  temp2 = step[3] * C4;
Daniel Kang's avatar
Daniel Kang committed
154
  temp1 = temp1 + temp2;
clang-format's avatar
clang-format committed
155
  output[4] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
156

157
158
  temp1 = step[2] * C4;
  temp2 = step[3] * C12;
Daniel Kang's avatar
Daniel Kang committed
159
  temp1 = temp2 - temp1;
160
  output[12] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
161

clang-format's avatar
clang-format committed
162
163
  output[2] = 2 * ((step[4] + step[5]) * C8);
  output[14] = 2 * ((step[7] - step[6]) * C8);
Daniel Kang's avatar
Daniel Kang committed
164
165
166

  temp1 = step[4] - step[5];
  temp2 = step[6] + step[7];
clang-format's avatar
clang-format committed
167
  output[6] = (temp1 + temp2);
Daniel Kang's avatar
Daniel Kang committed
168
169
170
171
172
  output[10] = (temp1 - temp2);

  intermediate[8] = step[8] + step[14];
  intermediate[9] = step[9] + step[15];

173
174
  temp1 = intermediate[8] * C12;
  temp2 = intermediate[9] * C4;
Daniel Kang's avatar
Daniel Kang committed
175
  temp1 = temp1 - temp2;
176
  output[3] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
177

178
179
  temp1 = intermediate[8] * C4;
  temp2 = intermediate[9] * C12;
Daniel Kang's avatar
Daniel Kang committed
180
  temp1 = temp2 + temp1;
181
  output[13] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
182

clang-format's avatar
clang-format committed
183
  output[9] = 2 * ((step[10] + step[11]) * C8);
Daniel Kang's avatar
Daniel Kang committed
184
185
186
187

  intermediate[11] = step[10] - step[11];
  intermediate[12] = step[12] + step[13];
  intermediate[13] = step[12] - step[13];
clang-format's avatar
clang-format committed
188
189
  intermediate[14] = step[8] - step[14];
  intermediate[15] = step[9] - step[15];
Daniel Kang's avatar
Daniel Kang committed
190
191

  output[15] = (intermediate[11] + intermediate[12]);
clang-format's avatar
clang-format committed
192
  output[1] = -(intermediate[11] - intermediate[12]);
Daniel Kang's avatar
Daniel Kang committed
193

clang-format's avatar
clang-format committed
194
  output[7] = 2 * (intermediate[13] * C8);
Daniel Kang's avatar
Daniel Kang committed
195

196
197
  temp1 = intermediate[14] * C12;
  temp2 = intermediate[15] * C4;
Daniel Kang's avatar
Daniel Kang committed
198
  temp1 = temp1 - temp2;
199
  output[11] = -2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
200

201
202
  temp1 = intermediate[14] * C4;
  temp2 = intermediate[15] * C12;
Daniel Kang's avatar
Daniel Kang committed
203
  temp1 = temp2 + temp1;
clang-format's avatar
clang-format committed
204
  output[5] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
205
206
}

207
void reference_16x16_dct_2d(int16_t input[256], double output[256]) {
Daniel Kang's avatar
Daniel Kang committed
208
209
210
  // First transform columns
  for (int i = 0; i < 16; ++i) {
    double temp_in[16], temp_out[16];
clang-format's avatar
clang-format committed
211
    for (int j = 0; j < 16; ++j) temp_in[j] = input[j * 16 + i];
Daniel Kang's avatar
Daniel Kang committed
212
    butterfly_16x16_dct_1d(temp_in, temp_out);
clang-format's avatar
clang-format committed
213
    for (int j = 0; j < 16; ++j) output[j * 16 + i] = temp_out[j];
Daniel Kang's avatar
Daniel Kang committed
214
215
216
217
  }
  // Then transform rows
  for (int i = 0; i < 16; ++i) {
    double temp_in[16], temp_out[16];
clang-format's avatar
clang-format committed
218
    for (int j = 0; j < 16; ++j) temp_in[j] = output[j + i * 16];
Daniel Kang's avatar
Daniel Kang committed
219
220
    butterfly_16x16_dct_1d(temp_in, temp_out);
    // Scale by some magic number
clang-format's avatar
clang-format committed
221
    for (int j = 0; j < 16; ++j) output[j + i * 16] = temp_out[j] / 2;
Daniel Kang's avatar
Daniel Kang committed
222
223
224
  }
}

225
226
227
typedef void (*FdctFunc)(const int16_t *in, tran_low_t *out, int stride);
typedef void (*IdctFunc)(const tran_low_t *in, uint8_t *out, int stride);
typedef void (*FhtFunc)(const int16_t *in, tran_low_t *out, int stride,
228
                        int tx_type);
229
typedef void (*IhtFunc)(const tran_low_t *in, uint8_t *out, int stride,
230
                        int tx_type);
Daniel Kang's avatar
Daniel Kang committed
231

232
233
typedef std::tr1::tuple<FdctFunc, IdctFunc, int, vpx_bit_depth_t> Dct16x16Param;
typedef std::tr1::tuple<FhtFunc, IhtFunc, int, vpx_bit_depth_t> Ht16x16Param;
234
235
typedef std::tr1::tuple<IdctFunc, IdctFunc, int, vpx_bit_depth_t>
    Idct16x16Param;
236

237
void fdct16x16_ref(const int16_t *in, tran_low_t *out, int stride,
238
                   int /*tx_type*/) {
239
  vpx_fdct16x16_c(in, out, stride);
240
241
}

242
void idct16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
243
                   int /*tx_type*/) {
244
  vpx_idct16x16_256_add_c(in, dest, stride);
245
246
}

clang-format's avatar
clang-format committed
247
void fht16x16_ref(const int16_t *in, tran_low_t *out, int stride, int tx_type) {
Yaowu Xu's avatar
Yaowu Xu committed
248
  vp10_fht16x16_c(in, out, stride, tx_type);
249
250
}

251
252
void iht16x16_ref(const tran_low_t *in, uint8_t *dest, int stride,
                  int tx_type) {
Yaowu Xu's avatar
Yaowu Xu committed
253
  vp10_iht16x16_256_add_c(in, dest, stride, tx_type);
254
255
}

256
257
#if CONFIG_VP9_HIGHBITDEPTH
void idct16x16_10(const tran_low_t *in, uint8_t *out, int stride) {
258
  vpx_highbd_idct16x16_256_add_c(in, out, stride, 10);
259
260
261
}

void idct16x16_12(const tran_low_t *in, uint8_t *out, int stride) {
262
  vpx_highbd_idct16x16_256_add_c(in, out, stride, 12);
263
264
265
}

void idct16x16_10_ref(const tran_low_t *in, uint8_t *out, int stride,
Yaowu Xu's avatar
Yaowu Xu committed
266
                      int tx_type) {
267
268
269
270
  idct16x16_10(in, out, stride);
}

void idct16x16_12_ref(const tran_low_t *in, uint8_t *out, int stride,
Yaowu Xu's avatar
Yaowu Xu committed
271
                      int tx_type) {
272
273
274
275
  idct16x16_12(in, out, stride);
}

void iht16x16_10(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
Yaowu Xu's avatar
Yaowu Xu committed
276
  vp10_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 10);
277
278
279
}

void iht16x16_12(const tran_low_t *in, uint8_t *out, int stride, int tx_type) {
Yaowu Xu's avatar
Yaowu Xu committed
280
  vp10_highbd_iht16x16_256_add_c(in, out, stride, tx_type, 12);
281
}
282

283
#if HAVE_SSE2
284
void idct16x16_10_add_10_c(const tran_low_t *in, uint8_t *out, int stride) {
285
  vpx_highbd_idct16x16_10_add_c(in, out, stride, 10);
286
287
288
}

void idct16x16_10_add_12_c(const tran_low_t *in, uint8_t *out, int stride) {
289
  vpx_highbd_idct16x16_10_add_c(in, out, stride, 12);
290
291
292
}

void idct16x16_256_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
293
  vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 10);
294
295
296
}

void idct16x16_256_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
297
  vpx_highbd_idct16x16_256_add_sse2(in, out, stride, 12);
298
299
300
}

void idct16x16_10_add_10_sse2(const tran_low_t *in, uint8_t *out, int stride) {
301
  vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 10);
302
303
304
}

void idct16x16_10_add_12_sse2(const tran_low_t *in, uint8_t *out, int stride) {
305
  vpx_highbd_idct16x16_10_add_sse2(in, out, stride, 12);
306
307
308
}
#endif  // HAVE_SSE2
#endif  // CONFIG_VP9_HIGHBITDEPTH
309

310
class Trans16x16TestBase {
311
 public:
312
  virtual ~Trans16x16TestBase() {}
313

314
 protected:
315
  virtual void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) = 0;
316

317
  virtual void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) = 0;
318
319
320

  void RunAccuracyCheck() {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
321
322
    uint32_t max_error = 0;
    int64_t total_error = 0;
323
324
    const int count_test_block = 10000;
    for (int i = 0; i < count_test_block; ++i) {
325
326
327
328
      DECLARE_ALIGNED(16, int16_t, test_input_block[kNumCoeffs]);
      DECLARE_ALIGNED(16, tran_low_t, test_temp_block[kNumCoeffs]);
      DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
      DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
329
#if CONFIG_VP9_HIGHBITDEPTH
330
331
      DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
      DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
332
#endif
333

334
      // Initialize a test block with input range [-mask_, mask_].
335
      for (int j = 0; j < kNumCoeffs; ++j) {
336
337
338
339
340
341
342
343
344
345
346
        if (bit_depth_ == VPX_BITS_8) {
          src[j] = rnd.Rand8();
          dst[j] = rnd.Rand8();
          test_input_block[j] = src[j] - dst[j];
#if CONFIG_VP9_HIGHBITDEPTH
        } else {
          src16[j] = rnd.Rand16() & mask_;
          dst16[j] = rnd.Rand16() & mask_;
          test_input_block[j] = src16[j] - dst16[j];
#endif
        }
347
348
      }

clang-format's avatar
clang-format committed
349
350
      ASM_REGISTER_STATE_CHECK(
          RunFwdTxfm(test_input_block, test_temp_block, pitch_));
351
      if (bit_depth_ == VPX_BITS_8) {
clang-format's avatar
clang-format committed
352
        ASM_REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
353
354
355
356
357
358
#if CONFIG_VP9_HIGHBITDEPTH
      } else {
        ASM_REGISTER_STATE_CHECK(
            RunInvTxfm(test_temp_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
#endif
      }
359
360

      for (int j = 0; j < kNumCoeffs; ++j) {
361
#if CONFIG_VP9_HIGHBITDEPTH
Yaowu Xu's avatar
Yaowu Xu committed
362
        const int32_t diff =
clang-format's avatar
clang-format committed
363
            bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
364
#else
Yaowu Xu's avatar
Yaowu Xu committed
365
        const int32_t diff = dst[j] - src[j];
366
#endif
367
        const uint32_t error = diff * diff;
clang-format's avatar
clang-format committed
368
        if (max_error < error) max_error = error;
369
370
        total_error += error;
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
371
    }
Daniel Kang's avatar
Daniel Kang committed
372

clang-format's avatar
clang-format committed
373
    EXPECT_GE(1u << 2 * (bit_depth_ - 8), max_error)
374
375
        << "Error: 16x16 FHT/IHT has an individual round trip error > 1";

376
    EXPECT_GE(count_test_block << 2 * (bit_depth_ - 8), total_error)
377
        << "Error: 16x16 FHT/IHT has average round trip error > 1 per block";
378
379
  }

380
  void RunCoeffCheck() {
381
382
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 1000;
383
384
385
    DECLARE_ALIGNED(16, int16_t, input_block[kNumCoeffs]);
    DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
    DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
386

387
    for (int i = 0; i < count_test_block; ++i) {
388
      // Initialize a test block with input range [-mask_, mask_].
389
      for (int j = 0; j < kNumCoeffs; ++j)
390
        input_block[j] = (rnd.Rand16() & mask_) - (rnd.Rand16() & mask_);
391
392

      fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
393
      ASM_REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));
394
395
396
397
398
399
400
401
402
403

      // The minimum quant value is 4.
      for (int j = 0; j < kNumCoeffs; ++j)
        EXPECT_EQ(output_block[j], output_ref_block[j]);
    }
  }

  void RunMemCheck() {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 1000;
404
405
406
    DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
    DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
    DECLARE_ALIGNED(16, tran_low_t, output_block[kNumCoeffs]);
Scott LaVarnway's avatar
Scott LaVarnway committed
407

408
    for (int i = 0; i < count_test_block; ++i) {
409
      // Initialize a test block with input range [-mask_, mask_].
410
      for (int j = 0; j < kNumCoeffs; ++j) {
411
        input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
412
      }
413
      if (i == 0) {
clang-format's avatar
clang-format committed
414
        for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
415
      } else if (i == 1) {
clang-format's avatar
clang-format committed
416
        for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
417
      }
418

419
      fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
clang-format's avatar
clang-format committed
420
421
      ASM_REGISTER_STATE_CHECK(
          RunFwdTxfm(input_extreme_block, output_block, pitch_));
422
423
424

      // The minimum quant value is 4.
      for (int j = 0; j < kNumCoeffs; ++j) {
425
        EXPECT_EQ(output_block[j], output_ref_block[j]);
426
        EXPECT_GE(4 * DCT_MAX_VALUE << (bit_depth_ - 8), abs(output_block[j]))
427
428
            << "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE";
      }
429
    }
430
431
  }

432
433
  void RunQuantCheck(int dc_thred, int ac_thred) {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
434
    const int count_test_block = 100000;
435
436
    DECLARE_ALIGNED(16, int16_t, input_extreme_block[kNumCoeffs]);
    DECLARE_ALIGNED(16, tran_low_t, output_ref_block[kNumCoeffs]);
437

438
439
    DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
440
#if CONFIG_VP9_HIGHBITDEPTH
441
442
    DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
443
#endif
444
445

    for (int i = 0; i < count_test_block; ++i) {
446
      // Initialize a test block with input range [-mask_, mask_].
447
      for (int j = 0; j < kNumCoeffs; ++j) {
448
        input_extreme_block[j] = rnd.Rand8() % 2 ? mask_ : -mask_;
449
450
      }
      if (i == 0)
clang-format's avatar
clang-format committed
451
        for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = mask_;
452
      if (i == 1)
clang-format's avatar
clang-format committed
453
        for (int j = 0; j < kNumCoeffs; ++j) input_extreme_block[j] = -mask_;
454
455
456
457

      fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);

      // clear reconstructed pixel buffers
James Zern's avatar
James Zern committed
458
459
      memset(dst, 0, kNumCoeffs * sizeof(uint8_t));
      memset(ref, 0, kNumCoeffs * sizeof(uint8_t));
460
#if CONFIG_VP9_HIGHBITDEPTH
James Zern's avatar
James Zern committed
461
462
      memset(dst16, 0, kNumCoeffs * sizeof(uint16_t));
      memset(ref16, 0, kNumCoeffs * sizeof(uint16_t));
463
#endif
464
465
466
467
468

      // quantization with maximum allowed step sizes
      output_ref_block[0] = (output_ref_block[0] / dc_thred) * dc_thred;
      for (int j = 1; j < kNumCoeffs; ++j)
        output_ref_block[j] = (output_ref_block[j] / ac_thred) * ac_thred;
469
470
471
472
473
474
475
      if (bit_depth_ == VPX_BITS_8) {
        inv_txfm_ref(output_ref_block, ref, pitch_, tx_type_);
        ASM_REGISTER_STATE_CHECK(RunInvTxfm(output_ref_block, dst, pitch_));
#if CONFIG_VP9_HIGHBITDEPTH
      } else {
        inv_txfm_ref(output_ref_block, CONVERT_TO_BYTEPTR(ref16), pitch_,
                     tx_type_);
clang-format's avatar
clang-format committed
476
477
        ASM_REGISTER_STATE_CHECK(
            RunInvTxfm(output_ref_block, CONVERT_TO_BYTEPTR(dst16), pitch_));
478
479
480
#endif
      }
      if (bit_depth_ == VPX_BITS_8) {
clang-format's avatar
clang-format committed
481
        for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref[j], dst[j]);
482
483
#if CONFIG_VP9_HIGHBITDEPTH
      } else {
clang-format's avatar
clang-format committed
484
        for (int j = 0; j < kNumCoeffs; ++j) EXPECT_EQ(ref16[j], dst16[j]);
485
486
#endif
      }
487
488
489
    }
  }

490
491
492
  void RunInvAccuracyCheck() {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 1000;
493
494
495
496
    DECLARE_ALIGNED(16, int16_t, in[kNumCoeffs]);
    DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint8_t, src[kNumCoeffs]);
497
#if CONFIG_VP9_HIGHBITDEPTH
498
499
    DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint16_t, src16[kNumCoeffs]);
500
#endif  // CONFIG_VP9_HIGHBITDEPTH
Daniel Kang's avatar
Daniel Kang committed
501

502
503
    for (int i = 0; i < count_test_block; ++i) {
      double out_r[kNumCoeffs];
Daniel Kang's avatar
Daniel Kang committed
504

505
506
      // Initialize a test block with input range [-255, 255].
      for (int j = 0; j < kNumCoeffs; ++j) {
507
508
509
510
511
512
513
514
515
        if (bit_depth_ == VPX_BITS_8) {
          src[j] = rnd.Rand8();
          dst[j] = rnd.Rand8();
          in[j] = src[j] - dst[j];
#if CONFIG_VP9_HIGHBITDEPTH
        } else {
          src16[j] = rnd.Rand16() & mask_;
          dst16[j] = rnd.Rand16() & mask_;
          in[j] = src16[j] - dst16[j];
516
#endif  // CONFIG_VP9_HIGHBITDEPTH
517
        }
518
519
520
521
      }

      reference_16x16_dct_2d(in, out_r);
      for (int j = 0; j < kNumCoeffs; ++j)
522
        coeff[j] = static_cast<tran_low_t>(round(out_r[j]));
523

524
525
526
527
      if (bit_depth_ == VPX_BITS_8) {
        ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
#if CONFIG_VP9_HIGHBITDEPTH
      } else {
clang-format's avatar
clang-format committed
528
529
        ASM_REGISTER_STATE_CHECK(
            RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), 16));
530
#endif  // CONFIG_VP9_HIGHBITDEPTH
531
      }
532
533

      for (int j = 0; j < kNumCoeffs; ++j) {
534
535
536
537
#if CONFIG_VP9_HIGHBITDEPTH
        const uint32_t diff =
            bit_depth_ == VPX_BITS_8 ? dst[j] - src[j] : dst16[j] - src16[j];
#else
538
        const uint32_t diff = dst[j] - src[j];
539
#endif  // CONFIG_VP9_HIGHBITDEPTH
540
        const uint32_t error = diff * diff;
clang-format's avatar
clang-format committed
541
542
        EXPECT_GE(1u, error) << "Error: 16x16 IDCT has error " << error
                             << " at index " << j;
543
      }
Daniel Kang's avatar
Daniel Kang committed
544
545
    }
  }
546
547
548
549
550

  void CompareInvReference(IdctFunc ref_txfm, int thresh) {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 10000;
    const int eob = 10;
Yaowu Xu's avatar
Yaowu Xu committed
551
    const int16_t *scan = vp10_default_scan_orders[TX_16X16].scan;
552
553
554
    DECLARE_ALIGNED(16, tran_low_t, coeff[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint8_t, dst[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint8_t, ref[kNumCoeffs]);
555
#if CONFIG_VP9_HIGHBITDEPTH
556
557
    DECLARE_ALIGNED(16, uint16_t, dst16[kNumCoeffs]);
    DECLARE_ALIGNED(16, uint16_t, ref16[kNumCoeffs]);
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
#endif  // CONFIG_VP9_HIGHBITDEPTH

    for (int i = 0; i < count_test_block; ++i) {
      for (int j = 0; j < kNumCoeffs; ++j) {
        if (j < eob) {
          // Random values less than the threshold, either positive or negative
          coeff[scan[j]] = rnd(thresh) * (1 - 2 * (i % 2));
        } else {
          coeff[scan[j]] = 0;
        }
        if (bit_depth_ == VPX_BITS_8) {
          dst[j] = 0;
          ref[j] = 0;
#if CONFIG_VP9_HIGHBITDEPTH
        } else {
          dst16[j] = 0;
          ref16[j] = 0;
#endif  // CONFIG_VP9_HIGHBITDEPTH
        }
      }
      if (bit_depth_ == VPX_BITS_8) {
        ref_txfm(coeff, ref, pitch_);
        ASM_REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, pitch_));
      } else {
#if CONFIG_VP9_HIGHBITDEPTH
        ref_txfm(coeff, CONVERT_TO_BYTEPTR(ref16), pitch_);
clang-format's avatar
clang-format committed
584
585
        ASM_REGISTER_STATE_CHECK(
            RunInvTxfm(coeff, CONVERT_TO_BYTEPTR(dst16), pitch_));
586
587
588
589
590
591
592
593
594
595
596
#endif  // CONFIG_VP9_HIGHBITDEPTH
      }

      for (int j = 0; j < kNumCoeffs; ++j) {
#if CONFIG_VP9_HIGHBITDEPTH
        const uint32_t diff =
            bit_depth_ == VPX_BITS_8 ? dst[j] - ref[j] : dst16[j] - ref16[j];
#else
        const uint32_t diff = dst[j] - ref[j];
#endif  // CONFIG_VP9_HIGHBITDEPTH
        const uint32_t error = diff * diff;
clang-format's avatar
clang-format committed
597
598
        EXPECT_EQ(0u, error) << "Error: 16x16 IDCT Comparison has error "
                             << error << " at index " << j;
599
600
601
602
      }
    }
  }

603
604
  int pitch_;
  int tx_type_;
605
606
  vpx_bit_depth_t bit_depth_;
  int mask_;
607
608
  FhtFunc fwd_txfm_ref;
  IhtFunc inv_txfm_ref;
609
};
Daniel Kang's avatar
Daniel Kang committed
610

clang-format's avatar
clang-format committed
611
612
class Trans16x16DCT : public Trans16x16TestBase,
                      public ::testing::TestWithParam<Dct16x16Param> {
613
614
 public:
  virtual ~Trans16x16DCT() {}
Daniel Kang's avatar
Daniel Kang committed
615

616
617
618
  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    inv_txfm_ = GET_PARAM(1);
clang-format's avatar
clang-format committed
619
    tx_type_ = GET_PARAM(2);
620
    bit_depth_ = GET_PARAM(3);
clang-format's avatar
clang-format committed
621
    pitch_ = 16;
622
    fwd_txfm_ref = fdct16x16_ref;
623
    inv_txfm_ref = idct16x16_ref;
624
625
626
    mask_ = (1 << bit_depth_) - 1;
#if CONFIG_VP9_HIGHBITDEPTH
    switch (bit_depth_) {
clang-format's avatar
clang-format committed
627
628
629
      case VPX_BITS_10: inv_txfm_ref = idct16x16_10_ref; break;
      case VPX_BITS_12: inv_txfm_ref = idct16x16_12_ref; break;
      default: inv_txfm_ref = idct16x16_ref; break;
630
631
632
633
    }
#else
    inv_txfm_ref = idct16x16_ref;
#endif
634
635
  }
  virtual void TearDown() { libvpx_test::ClearSystemState(); }
Daniel Kang's avatar
Daniel Kang committed
636

637
 protected:
638
  void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {
639
640
    fwd_txfm_(in, out, stride);
  }
641
  void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
642
    inv_txfm_(out, dst, stride);
Daniel Kang's avatar
Daniel Kang committed
643
  }
644

645
646
  FdctFunc fwd_txfm_;
  IdctFunc inv_txfm_;
647
648
};

clang-format's avatar
clang-format committed
649
TEST_P(Trans16x16DCT, AccuracyCheck) { RunAccuracyCheck(); }
650

clang-format's avatar
clang-format committed
651
TEST_P(Trans16x16DCT, CoeffCheck) { RunCoeffCheck(); }
652

clang-format's avatar
clang-format committed
653
TEST_P(Trans16x16DCT, MemCheck) { RunMemCheck(); }
654

655
656
657
658
659
660
TEST_P(Trans16x16DCT, QuantCheck) {
  // Use maximally allowed quantization step sizes for DC and AC
  // coefficients respectively.
  RunQuantCheck(1336, 1828);
}

clang-format's avatar
clang-format committed
661
TEST_P(Trans16x16DCT, InvAccuracyCheck) { RunInvAccuracyCheck(); }
662

clang-format's avatar
clang-format committed
663
664
class Trans16x16HT : public Trans16x16TestBase,
                     public ::testing::TestWithParam<Ht16x16Param> {
665
666
667
668
669
670
 public:
  virtual ~Trans16x16HT() {}

  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    inv_txfm_ = GET_PARAM(1);
clang-format's avatar
clang-format committed
671
    tx_type_ = GET_PARAM(2);
672
    bit_depth_ = GET_PARAM(3);
clang-format's avatar
clang-format committed
673
    pitch_ = 16;
674
    fwd_txfm_ref = fht16x16_ref;
675
    inv_txfm_ref = iht16x16_ref;
676
677
678
    mask_ = (1 << bit_depth_) - 1;
#if CONFIG_VP9_HIGHBITDEPTH
    switch (bit_depth_) {
clang-format's avatar
clang-format committed
679
680
681
      case VPX_BITS_10: inv_txfm_ref = iht16x16_10; break;
      case VPX_BITS_12: inv_txfm_ref = iht16x16_12; break;
      default: inv_txfm_ref = iht16x16_ref; break;
682
683
684
685
    }
#else
    inv_txfm_ref = iht16x16_ref;
#endif
686
  }
687
688
689
  virtual void TearDown() { libvpx_test::ClearSystemState(); }

 protected:
690
  void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {
691
    fwd_txfm_(in, out, stride, tx_type_);
692
  }
693
  void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
694
    inv_txfm_(out, dst, stride, tx_type_);
695
696
  }

697
698
  FhtFunc fwd_txfm_;
  IhtFunc inv_txfm_;
699
700
};

clang-format's avatar
clang-format committed
701
TEST_P(Trans16x16HT, AccuracyCheck) { RunAccuracyCheck(); }
702

clang-format's avatar
clang-format committed
703
TEST_P(Trans16x16HT, CoeffCheck) { RunCoeffCheck(); }
704

clang-format's avatar
clang-format committed
705
TEST_P(Trans16x16HT, MemCheck) { RunMemCheck(); }
706

707
708
709
TEST_P(Trans16x16HT, QuantCheck) {
  // The encoder skips any non-DC intra prediction modes,
  // when the quantization step size goes beyond 988.
710
  RunQuantCheck(429, 729);
711
712
}

clang-format's avatar
clang-format committed
713
714
class InvTrans16x16DCT : public Trans16x16TestBase,
                         public ::testing::TestWithParam<Idct16x16Param> {
715
716
717
718
719
720
721
722
723
724
 public:
  virtual ~InvTrans16x16DCT() {}

  virtual void SetUp() {
    ref_txfm_ = GET_PARAM(0);
    inv_txfm_ = GET_PARAM(1);
    thresh_ = GET_PARAM(2);
    bit_depth_ = GET_PARAM(3);
    pitch_ = 16;
    mask_ = (1 << bit_depth_) - 1;
clang-format's avatar
clang-format committed
725
  }
726
727
728
  virtual void TearDown() { libvpx_test::ClearSystemState(); }

 protected:
Yaowu Xu's avatar
Yaowu Xu committed
729
  void RunFwdTxfm(int16_t *in, tran_low_t *out, int stride) {}
730
731
732
733
734
735
736
737
738
739
740
741
742
  void RunInvTxfm(tran_low_t *out, uint8_t *dst, int stride) {
    inv_txfm_(out, dst, stride);
  }

  IdctFunc ref_txfm_;
  IdctFunc inv_txfm_;
  int thresh_;
};

TEST_P(InvTrans16x16DCT, CompareReference) {
  CompareInvReference(ref_txfm_, thresh_);
}

clang-format's avatar
clang-format committed
743
744
class PartialTrans16x16Test : public ::testing::TestWithParam<
                                  std::tr1::tuple<FdctFunc, vpx_bit_depth_t> > {
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
 public:
  virtual ~PartialTrans16x16Test() {}
  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    bit_depth_ = GET_PARAM(1);
  }

  virtual void TearDown() { libvpx_test::ClearSystemState(); }

 protected:
  vpx_bit_depth_t bit_depth_;
  FdctFunc fwd_txfm_;
};

TEST_P(PartialTrans16x16Test, Extremes) {
#if CONFIG_VP9_HIGHBITDEPTH
  const int16_t maxval =
      static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
#else
  const int16_t maxval = 255;
#endif
  const int minval = -maxval;
  DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);

  for (int i = 0; i < kNumCoeffs; ++i) input[i] = maxval;
  output[0] = 0;
  ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
  EXPECT_EQ((maxval * kNumCoeffs) >> 1, output[0]);

  for (int i = 0; i < kNumCoeffs; ++i) input[i] = minval;
  output[0] = 0;
  ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
  EXPECT_EQ((minval * kNumCoeffs) >> 1, output[0]);
}

TEST_P(PartialTrans16x16Test, Random) {
#if CONFIG_VP9_HIGHBITDEPTH
  const int16_t maxval =
      static_cast<int16_t>(clip_pixel_highbd(1 << 30, bit_depth_));
#else
  const int16_t maxval = 255;
#endif
  DECLARE_ALIGNED(16, int16_t, input[kNumCoeffs]);
  DECLARE_ALIGNED(16, tran_low_t, output[kNumCoeffs]);
  ACMRandom rnd(ACMRandom::DeterministicSeed());

  int sum = 0;
  for (int i = 0; i < kNumCoeffs; ++i) {
    const int val = (i & 1) ? -rnd(maxval + 1) : rnd(maxval + 1);
    input[i] = val;
    sum += val;
  }
  output[0] = 0;
  ASM_REGISTER_STATE_CHECK(fwd_txfm_(input, output, 16));
  EXPECT_EQ(sum >> 1, output[0]);
}

803
804
using std::tr1::make_tuple;

805
806
807
808
#if CONFIG_VP9_HIGHBITDEPTH
INSTANTIATE_TEST_CASE_P(
    C, Trans16x16DCT,
    ::testing::Values(
809
810
        make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_10, 0, VPX_BITS_10),
        make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_12, 0, VPX_BITS_12),
811
        make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_c, 0, VPX_BITS_8)));
812
#else
clang-format's avatar
clang-format committed
813
814
815
816
INSTANTIATE_TEST_CASE_P(C, Trans16x16DCT,
                        ::testing::Values(make_tuple(&vpx_fdct16x16_c,
                                                     &vpx_idct16x16_256_add_c,
                                                     0, VPX_BITS_8)));
817
#endif  // CONFIG_VP9_HIGHBITDEPTH
818
819

#if CONFIG_VP9_HIGHBITDEPTH
820
821
822
INSTANTIATE_TEST_CASE_P(
    C, Trans16x16HT,
    ::testing::Values(
Yaowu Xu's avatar
Yaowu Xu committed
823
824
825
826
827
828
829
830
831
832
833
834
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 0, VPX_BITS_10),
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 1, VPX_BITS_10),
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 2, VPX_BITS_10),
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_10, 3, VPX_BITS_10),
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 0, VPX_BITS_12),
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 1, VPX_BITS_12),
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 2, VPX_BITS_12),
        make_tuple(&vp10_highbd_fht16x16_c, &iht16x16_12, 3, VPX_BITS_12),
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 3, VPX_BITS_8)));
835
836
837
838
839
INSTANTIATE_TEST_CASE_P(
    C, PartialTrans16x16Test,
    ::testing::Values(make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_8),
                      make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_10),
                      make_tuple(&vpx_highbd_fdct16x16_1_c, VPX_BITS_12)));
840
841
842
843
#else
INSTANTIATE_TEST_CASE_P(
    C, Trans16x16HT,
    ::testing::Values(
Yaowu Xu's avatar
Yaowu Xu committed
844
845
846
847
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 0, VPX_BITS_8),
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 1, VPX_BITS_8),
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 2, VPX_BITS_8),
        make_tuple(&vp10_fht16x16_c, &vp10_iht16x16_256_add_c, 3, VPX_BITS_8)));
848
849
850
INSTANTIATE_TEST_CASE_P(C, PartialTrans16x16Test,
                        ::testing::Values(make_tuple(&vpx_fdct16x16_1_c,
                                                     VPX_BITS_8)));
851
#endif  // CONFIG_VP9_HIGHBITDEPTH
852

853
#if HAVE_NEON_ASM && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
James Zern's avatar
James Zern committed
854
855
INSTANTIATE_TEST_CASE_P(
    NEON, Trans16x16DCT,
clang-format's avatar
clang-format committed
856
857
    ::testing::Values(make_tuple(&vpx_fdct16x16_c, &vpx_idct16x16_256_add_neon,
                                 0, VPX_BITS_8)));
James Zern's avatar
James Zern committed
858
859
#endif

860
#if HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
861
862
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16DCT,
clang-format's avatar
clang-format committed
863
864
    ::testing::Values(make_tuple(&vpx_fdct16x16_sse2,
                                 &vpx_idct16x16_256_add_sse2, 0, VPX_BITS_8)));
865
866
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16HT,
clang-format's avatar
clang-format committed
867
868
869
870
871
872
873
874
    ::testing::Values(make_tuple(&vp10_fht16x16_sse2,
                                 &vp10_iht16x16_256_add_sse2, 0, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_sse2,
                                 &vp10_iht16x16_256_add_sse2, 1, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_sse2,
                                 &vp10_iht16x16_256_add_sse2, 2, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_sse2,
                                 &vp10_iht16x16_256_add_sse2, 3, VPX_BITS_8)));
875
876
877
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
                        ::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
                                                     VPX_BITS_8)));
878
879
880
881
882
883
#endif  // HAVE_SSE2 && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE

#if HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16DCT,
    ::testing::Values(
clang-format's avatar
clang-format committed
884
885
886
887
888
889
890
891
        make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_10, 0, VPX_BITS_10),
        make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_10_sse2, 0,
                   VPX_BITS_10),
        make_tuple(&vpx_highbd_fdct16x16_sse2, &idct16x16_12, 0, VPX_BITS_12),
        make_tuple(&vpx_highbd_fdct16x16_c, &idct16x16_256_add_12_sse2, 0,
                   VPX_BITS_12),
        make_tuple(&vpx_fdct16x16_sse2, &vpx_idct16x16_256_add_c, 0,
                   VPX_BITS_8)));
892
893
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16HT,
clang-format's avatar
clang-format committed
894
895
896
897
898
899
900
901
    ::testing::Values(make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_c,
                                 0, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_c,
                                 1, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_c,
                                 2, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_sse2, &vp10_iht16x16_256_add_c,
                                 3, VPX_BITS_8)));
902
903
904
905
// Optimizations take effect at a threshold of 3155, so we use a value close to
// that to test both branches.
INSTANTIATE_TEST_CASE_P(
    SSE2, InvTrans16x16DCT,
clang-format's avatar
clang-format committed
906
907
908
909
910
911
912
913
    ::testing::Values(make_tuple(&idct16x16_10_add_10_c,
                                 &idct16x16_10_add_10_sse2, 3167, VPX_BITS_10),
                      make_tuple(&idct16x16_10, &idct16x16_256_add_10_sse2,
                                 3167, VPX_BITS_10),
                      make_tuple(&idct16x16_10_add_12_c,
                                 &idct16x16_10_add_12_sse2, 3167, VPX_BITS_12),
                      make_tuple(&idct16x16_12, &idct16x16_256_add_12_sse2,
                                 3167, VPX_BITS_12)));
914
915
916
INSTANTIATE_TEST_CASE_P(SSE2, PartialTrans16x16Test,
                        ::testing::Values(make_tuple(&vpx_fdct16x16_1_sse2,
                                                     VPX_BITS_8)));
917
#endif  // HAVE_SSE2 && CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
918

919
#if HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
clang-format's avatar
clang-format committed
920
921
922
923
INSTANTIATE_TEST_CASE_P(MSA, Trans16x16DCT,
                        ::testing::Values(make_tuple(&vpx_fdct16x16_msa,
                                                     &vpx_idct16x16_256_add_msa,
                                                     0, VPX_BITS_8)));
924
#if !CONFIG_EXT_TX
925
926
INSTANTIATE_TEST_CASE_P(
    MSA, Trans16x16HT,
clang-format's avatar
clang-format committed
927
928
929
930
931
932
933
934
    ::testing::Values(make_tuple(&vp10_fht16x16_msa, &vp10_iht16x16_256_add_msa,
                                 0, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_msa, &vp10_iht16x16_256_add_msa,
                                 1, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_msa, &vp10_iht16x16_256_add_msa,
                                 2, VPX_BITS_8),
                      make_tuple(&vp10_fht16x16_msa, &vp10_iht16x16_256_add_msa,
                                 3, VPX_BITS_8)));
935
#endif  // !CONFIG_EXT_TX
936
937
938
INSTANTIATE_TEST_CASE_P(MSA, PartialTrans16x16Test,
                        ::testing::Values(make_tuple(&vpx_fdct16x16_1_msa,
                                                     VPX_BITS_8)));
939
#endif  // HAVE_MSA && !CONFIG_VP9_HIGHBITDEPTH && !CONFIG_EMULATE_HARDWARE
Daniel Kang's avatar
Daniel Kang committed
940
}  // namespace