dct16x16_test.cc 15.3 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 17 18 19
#include "test/acm_random.h"
#include "test/clear_system_state.h"
#include "test/register_state_check.h"
#include "test/util.h"
Daniel Kang's avatar
Daniel Kang committed
20

Yaowu Xu's avatar
Yaowu Xu committed
21
#include "./vp9_rtcd.h"
22 23 24 25
#include "vp9/common/vp9_entropy.h"
#include "vpx/vpx_integer.h"

extern "C" {
26
void vp9_idct16x16_256_add_c(const int16_t *input, uint8_t *output, int pitch);
Daniel Kang's avatar
Daniel Kang committed
27 28 29 30 31
}

using libvpx_test::ACMRandom;

namespace {
32 33 34 35

#ifdef _MSC_VER
static int round(double x) {
  if (x < 0)
Yaowu Xu's avatar
Yaowu Xu committed
36
    return static_cast<int>(ceil(x - 0.5));
37
  else
Yaowu Xu's avatar
Yaowu Xu committed
38
    return static_cast<int>(floor(x + 0.5));
39 40
}
#endif
Daniel Kang's avatar
Daniel Kang committed
41

42
const int kNumCoeffs = 256;
Daniel Kang's avatar
Daniel Kang committed
43 44 45 46 47 48 49 50
const double PI = 3.1415926535898;
void reference2_16x16_idct_2d(double *input, double *output) {
  double x;
  for (int l = 0; l < 16; ++l) {
    for (int k = 0; k < 16; ++k) {
      double s = 0;
      for (int i = 0; i < 16; ++i) {
        for (int j = 0; j < 16; ++j) {
Yaowu Xu's avatar
Yaowu Xu committed
51 52 53
          x = cos(PI * j * (l + 0.5) / 16.0) *
              cos(PI * i * (k + 0.5) / 16.0) *
              input[i * 16 + j] / 256;
Daniel Kang's avatar
Daniel Kang committed
54 55 56 57 58 59 60 61 62 63 64 65
          if (i != 0)
            x *= sqrt(2.0);
          if (j != 0)
            x *= sqrt(2.0);
          s += x;
        }
      }
      output[k*16+l] = s;
    }
  }
}

66

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
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;
82

Jingning Han's avatar
Jingning Han committed
83
void butterfly_16x16_dct_1d(double input[16], double output[16]) {
Daniel Kang's avatar
Daniel Kang committed
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
  double step[16];
  double intermediate[16];
  double temp1, temp2;

  // step 1
  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];
  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];

116 117
  temp1 = step[ 8] * C7;
  temp2 = step[15] * C9;
Daniel Kang's avatar
Daniel Kang committed
118 119
  output[ 8] = temp1 + temp2;

120 121
  temp1 = step[ 9] * C11;
  temp2 = step[14] * C5;
Daniel Kang's avatar
Daniel Kang committed
122 123
  output[ 9] = temp1 - temp2;

124 125
  temp1 = step[10] * C3;
  temp2 = step[13] * C13;
Daniel Kang's avatar
Daniel Kang committed
126 127
  output[10] = temp1 + temp2;

128 129
  temp1 = step[11] * C15;
  temp2 = step[12] * C1;
Daniel Kang's avatar
Daniel Kang committed
130 131
  output[11] = temp1 - temp2;

132 133
  temp1 = step[11] * C1;
  temp2 = step[12] * C15;
Daniel Kang's avatar
Daniel Kang committed
134 135
  output[12] = temp2 + temp1;

136 137
  temp1 = step[10] * C13;
  temp2 = step[13] * C3;
Daniel Kang's avatar
Daniel Kang committed
138 139
  output[13] = temp2 - temp1;

140 141
  temp1 = step[ 9] * C5;
  temp2 = step[14] * C11;
Daniel Kang's avatar
Daniel Kang committed
142 143
  output[14] = temp2 + temp1;

144 145
  temp1 = step[ 8] * C9;
  temp2 = step[15] * C7;
Daniel Kang's avatar
Daniel Kang committed
146 147 148 149 150 151 152 153
  output[15] = temp2 - temp1;

  // step 3
  step[ 0] = output[0] + output[3];
  step[ 1] = output[1] + output[2];
  step[ 2] = output[1] - output[2];
  step[ 3] = output[0] - output[3];

154 155
  temp1 = output[4] * C14;
  temp2 = output[7] * C2;
Daniel Kang's avatar
Daniel Kang committed
156 157
  step[ 4] = temp1 + temp2;

158 159
  temp1 = output[5] * C10;
  temp2 = output[6] * C6;
Daniel Kang's avatar
Daniel Kang committed
160 161
  step[ 5] = temp1 + temp2;

162 163
  temp1 = output[5] * C6;
  temp2 = output[6] * C10;
Daniel Kang's avatar
Daniel Kang committed
164 165
  step[ 6] = temp2 - temp1;

166 167
  temp1 = output[4] * C2;
  temp2 = output[7] * C14;
Daniel Kang's avatar
Daniel Kang committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
  step[ 7] = temp2 - temp1;

  step[ 8] = output[ 8] + output[11];
  step[ 9] = output[ 9] + output[10];
  step[10] = output[ 9] - output[10];
  step[11] = output[ 8] - output[11];

  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
  output[ 0] = (step[ 0] + step[ 1]);
  output[ 8] = (step[ 0] - step[ 1]);

184 185
  temp1 = step[2] * C12;
  temp2 = step[3] * C4;
Daniel Kang's avatar
Daniel Kang committed
186
  temp1 = temp1 + temp2;
187
  output[ 4] = 2*(temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
188

189 190
  temp1 = step[2] * C4;
  temp2 = step[3] * C12;
Daniel Kang's avatar
Daniel Kang committed
191
  temp1 = temp2 - temp1;
192
  output[12] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
193

194 195
  output[ 2] = 2 * ((step[4] + step[ 5]) * C8);
  output[14] = 2 * ((step[7] - step[ 6]) * C8);
Daniel Kang's avatar
Daniel Kang committed
196 197 198 199 200 201 202 203 204

  temp1 = step[4] - step[5];
  temp2 = step[6] + step[7];
  output[ 6] = (temp1 + temp2);
  output[10] = (temp1 - temp2);

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

205 206
  temp1 = intermediate[8] * C12;
  temp2 = intermediate[9] * C4;
Daniel Kang's avatar
Daniel Kang committed
207
  temp1 = temp1 - temp2;
208
  output[3] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
209

210 211
  temp1 = intermediate[8] * C4;
  temp2 = intermediate[9] * C12;
Daniel Kang's avatar
Daniel Kang committed
212
  temp1 = temp2 + temp1;
213
  output[13] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
214

215
  output[ 9] = 2 * ((step[10] + step[11]) * C8);
Daniel Kang's avatar
Daniel Kang committed
216 217 218 219 220 221 222 223 224 225

  intermediate[11] = step[10] - step[11];
  intermediate[12] = step[12] + step[13];
  intermediate[13] = step[12] - step[13];
  intermediate[14] = step[ 8] - step[14];
  intermediate[15] = step[ 9] - step[15];

  output[15] = (intermediate[11] + intermediate[12]);
  output[ 1] = -(intermediate[11] - intermediate[12]);

226
  output[ 7] = 2 * (intermediate[13] * C8);
Daniel Kang's avatar
Daniel Kang committed
227

228 229
  temp1 = intermediate[14] * C12;
  temp2 = intermediate[15] * C4;
Daniel Kang's avatar
Daniel Kang committed
230
  temp1 = temp1 - temp2;
231
  output[11] = -2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
232

233 234
  temp1 = intermediate[14] * C4;
  temp2 = intermediate[15] * C12;
Daniel Kang's avatar
Daniel Kang committed
235
  temp1 = temp2 + temp1;
236
  output[ 5] = 2 * (temp1 * C8);
Daniel Kang's avatar
Daniel Kang committed
237 238
}

239
void reference_16x16_dct_2d(int16_t input[256], double output[256]) {
Daniel Kang's avatar
Daniel Kang committed
240 241 242 243
  // First transform columns
  for (int i = 0; i < 16; ++i) {
    double temp_in[16], temp_out[16];
    for (int j = 0; j < 16; ++j)
244
      temp_in[j] = input[j * 16 + i];
Daniel Kang's avatar
Daniel Kang committed
245 246
    butterfly_16x16_dct_1d(temp_in, temp_out);
    for (int j = 0; j < 16; ++j)
247
      output[j * 16 + i] = temp_out[j];
Daniel Kang's avatar
Daniel Kang committed
248 249 250 251 252
  }
  // Then transform rows
  for (int i = 0; i < 16; ++i) {
    double temp_in[16], temp_out[16];
    for (int j = 0; j < 16; ++j)
253
      temp_in[j] = output[j + i * 16];
Daniel Kang's avatar
Daniel Kang committed
254 255 256
    butterfly_16x16_dct_1d(temp_in, temp_out);
    // Scale by some magic number
    for (int j = 0; j < 16; ++j)
257
      output[j + i * 16] = temp_out[j]/2;
Daniel Kang's avatar
Daniel Kang committed
258 259 260
  }
}

261 262 263 264 265
typedef void (*fdct_t)(const int16_t *in, int16_t *out, int stride);
typedef void (*idct_t)(const int16_t *in, uint8_t *out, int stride);
typedef void (*fht_t) (const int16_t *in, int16_t *out, int stride,
                       int tx_type);
typedef void (*iht_t) (const int16_t *in, uint8_t *out, int stride,
266
                       int tx_type);
Daniel Kang's avatar
Daniel Kang committed
267

268 269 270
typedef std::tr1::tuple<fdct_t, idct_t, int> dct_16x16_param_t;
typedef std::tr1::tuple<fht_t, iht_t, int> ht_16x16_param_t;

271
void fdct16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) {
272
  vp9_fdct16x16_c(in, out, stride);
273 274
}

275
void fht16x16_ref(const int16_t *in, int16_t *out, int stride, int tx_type) {
276
  vp9_fht16x16_c(in, out, stride, tx_type);
277 278
}

279
class Trans16x16TestBase {
280
 public:
281
  virtual ~Trans16x16TestBase() {}
282

283
 protected:
284
  virtual void RunFwdTxfm(int16_t *in, int16_t *out, int stride) = 0;
285

286
  virtual void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) = 0;
287 288 289

  void RunAccuracyCheck() {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
290 291
    uint32_t max_error = 0;
    int64_t total_error = 0;
292 293 294 295 296 297 298
    const int count_test_block = 10000;
    for (int i = 0; i < count_test_block; ++i) {
      DECLARE_ALIGNED_ARRAY(16, int16_t, test_input_block, kNumCoeffs);
      DECLARE_ALIGNED_ARRAY(16, int16_t, test_temp_block, kNumCoeffs);
      DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
      DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);

299
      // Initialize a test block with input range [-255, 255].
300 301 302 303 304 305
      for (int j = 0; j < kNumCoeffs; ++j) {
        src[j] = rnd.Rand8();
        dst[j] = rnd.Rand8();
        test_input_block[j] = src[j] - dst[j];
      }

306 307 308
      REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
                                      test_temp_block, pitch_));
      REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
309 310

      for (int j = 0; j < kNumCoeffs; ++j) {
311 312
        const uint32_t diff = dst[j] - src[j];
        const uint32_t error = diff * diff;
313 314 315 316
        if (max_error < error)
          max_error = error;
        total_error += error;
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
317
    }
Daniel Kang's avatar
Daniel Kang committed
318

319
    EXPECT_GE(1u, max_error)
320 321 322 323
        << "Error: 16x16 FHT/IHT has an individual round trip error > 1";

    EXPECT_GE(count_test_block , total_error)
        << "Error: 16x16 FHT/IHT has average round trip error > 1 per block";
324 325
  }

326
  void RunCoeffCheck() {
327 328
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 1000;
329 330 331 332
    DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs);

333
    for (int i = 0; i < count_test_block; ++i) {
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
      // Initialize a test block with input range [-255, 255].
      for (int j = 0; j < kNumCoeffs; ++j)
        input_block[j] = rnd.Rand8() - rnd.Rand8();

      fwd_txfm_ref(input_block, output_ref_block, pitch_, tx_type_);
      REGISTER_STATE_CHECK(RunFwdTxfm(input_block, output_block, pitch_));

      // 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;
    DECLARE_ALIGNED_ARRAY(16, int16_t, input_block, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, int16_t, input_extreme_block, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, int16_t, output_ref_block, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, int16_t, output_block, kNumCoeffs);
Scott LaVarnway's avatar
Scott LaVarnway committed
354

355
    for (int i = 0; i < count_test_block; ++i) {
356
      // Initialize a test block with input range [-255, 255].
357 358 359 360 361 362 363
      for (int j = 0; j < kNumCoeffs; ++j) {
        input_block[j] = rnd.Rand8() - rnd.Rand8();
        input_extreme_block[j] = rnd.Rand8() % 2 ? 255 : -255;
      }
      if (i == 0)
        for (int j = 0; j < kNumCoeffs; ++j)
          input_extreme_block[j] = 255;
364 365 366
      if (i == 1)
        for (int j = 0; j < kNumCoeffs; ++j)
          input_extreme_block[j] = -255;
367

368
      fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
369
      REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
370
                                      output_block, pitch_));
371 372 373

      // The minimum quant value is 4.
      for (int j = 0; j < kNumCoeffs; ++j) {
374
        EXPECT_EQ(output_block[j], output_ref_block[j]);
375 376 377
        EXPECT_GE(4 * DCT_MAX_VALUE, abs(output_block[j]))
            << "Error: 16x16 FDCT has coefficient larger than 4*DCT_MAX_VALUE";
      }
378
    }
379 380 381 382 383
  }

  void RunInvAccuracyCheck() {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 1000;
384 385 386 387
    DECLARE_ALIGNED_ARRAY(16, int16_t, in, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, int16_t, coeff, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, uint8_t, dst, kNumCoeffs);
    DECLARE_ALIGNED_ARRAY(16, uint8_t, src, kNumCoeffs);
Daniel Kang's avatar
Daniel Kang committed
388

389 390
    for (int i = 0; i < count_test_block; ++i) {
      double out_r[kNumCoeffs];
Daniel Kang's avatar
Daniel Kang committed
391

392 393 394 395 396 397 398 399 400 401 402
      // Initialize a test block with input range [-255, 255].
      for (int j = 0; j < kNumCoeffs; ++j) {
        src[j] = rnd.Rand8();
        dst[j] = rnd.Rand8();
        in[j] = src[j] - dst[j];
      }

      reference_16x16_dct_2d(in, out_r);
      for (int j = 0; j < kNumCoeffs; ++j)
        coeff[j] = round(out_r[j]);

403
      REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
404 405

      for (int j = 0; j < kNumCoeffs; ++j) {
406 407 408
        const uint32_t diff = dst[j] - src[j];
        const uint32_t error = diff * diff;
        EXPECT_GE(1u, error)
409 410 411
            << "Error: 16x16 IDCT has error " << error
            << " at index " << j;
      }
Daniel Kang's avatar
Daniel Kang committed
412 413
    }
  }
414 415 416
  int pitch_;
  int tx_type_;
  fht_t fwd_txfm_ref;
417
};
Daniel Kang's avatar
Daniel Kang committed
418

419 420 421
class Trans16x16DCT
    : public Trans16x16TestBase,
      public ::testing::TestWithParam<dct_16x16_param_t> {
422 423
 public:
  virtual ~Trans16x16DCT() {}
Daniel Kang's avatar
Daniel Kang committed
424

425 426 427 428
  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    inv_txfm_ = GET_PARAM(1);
    tx_type_  = GET_PARAM(2);
429
    pitch_    = 16;
430
    fwd_txfm_ref = fdct16x16_ref;
431 432
  }
  virtual void TearDown() { libvpx_test::ClearSystemState(); }
Daniel Kang's avatar
Daniel Kang committed
433

434
 protected:
435
  void RunFwdTxfm(int16_t *in, int16_t *out, int stride) {
436 437
    fwd_txfm_(in, out, stride);
  }
438
  void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) {
439
    inv_txfm_(out, dst, stride);
Daniel Kang's avatar
Daniel Kang committed
440
  }
441 442 443 444 445 446 447

  fdct_t fwd_txfm_;
  idct_t inv_txfm_;
};

TEST_P(Trans16x16DCT, AccuracyCheck) {
  RunAccuracyCheck();
Daniel Kang's avatar
Daniel Kang committed
448
}
449

450 451 452 453 454 455
TEST_P(Trans16x16DCT, CoeffCheck) {
  RunCoeffCheck();
}

TEST_P(Trans16x16DCT, MemCheck) {
  RunMemCheck();
456 457 458 459 460 461
}

TEST_P(Trans16x16DCT, InvAccuracyCheck) {
  RunInvAccuracyCheck();
}

462 463 464
class Trans16x16HT
    : public Trans16x16TestBase,
      public ::testing::TestWithParam<ht_16x16_param_t> {
465 466 467 468 469 470 471
 public:
  virtual ~Trans16x16HT() {}

  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    inv_txfm_ = GET_PARAM(1);
    tx_type_  = GET_PARAM(2);
472 473
    pitch_    = 16;
    fwd_txfm_ref = fht16x16_ref;
474
  }
475 476 477
  virtual void TearDown() { libvpx_test::ClearSystemState(); }

 protected:
478 479
  void RunFwdTxfm(int16_t *in, int16_t *out, int stride) {
    fwd_txfm_(in, out, stride, tx_type_);
480
  }
481 482
  void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) {
    inv_txfm_(out, dst, stride, tx_type_);
483 484 485 486 487 488 489 490 491 492
  }

  fht_t fwd_txfm_;
  iht_t inv_txfm_;
};

TEST_P(Trans16x16HT, AccuracyCheck) {
  RunAccuracyCheck();
}

493 494 495 496 497 498
TEST_P(Trans16x16HT, CoeffCheck) {
  RunCoeffCheck();
}

TEST_P(Trans16x16HT, MemCheck) {
  RunMemCheck();
499 500
}

501 502 503 504 505
using std::tr1::make_tuple;

INSTANTIATE_TEST_CASE_P(
    C, Trans16x16DCT,
    ::testing::Values(
506
        make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0)));
507 508 509
INSTANTIATE_TEST_CASE_P(
    C, Trans16x16HT,
    ::testing::Values(
510 511 512 513
        make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 0),
        make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 1),
        make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 2),
        make_tuple(&vp9_fht16x16_c, &vp9_iht16x16_256_add_c, 3)));
514

515
#if HAVE_NEON_ASM
James Zern's avatar
James Zern committed
516 517 518 519 520 521 522
INSTANTIATE_TEST_CASE_P(
    NEON, Trans16x16DCT,
    ::testing::Values(
        make_tuple(&vp9_fdct16x16_c,
                   &vp9_idct16x16_256_add_neon, 0)));
#endif

523 524 525 526
#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16DCT,
    ::testing::Values(
527
        make_tuple(&vp9_fdct16x16_sse2,
528
                   &vp9_idct16x16_256_add_sse2, 0)));
529 530 531
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16HT,
    ::testing::Values(
532 533 534 535
        make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0),
        make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1),
        make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2),
        make_tuple(&vp9_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3)));
536
#endif
537 538 539 540 541 542 543

#if HAVE_SSSE3
INSTANTIATE_TEST_CASE_P(
    SSSE3, Trans16x16DCT,
    ::testing::Values(
        make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_ssse3, 0)));
#endif
Daniel Kang's avatar
Daniel Kang committed
544
}  // namespace