dct16x16_test.cc 14.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
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
21

extern "C" {
Yaowu Xu's avatar
Yaowu Xu committed
22
#include "vp9/common/vp9_entropy.h"
Yaowu Xu's avatar
Yaowu Xu committed
23
#include "./vp9_rtcd.h"
24
void vp9_idct16x16_256_add_c(const int16_t *input, uint8_t *output, int pitch);
Daniel Kang's avatar
Daniel Kang committed
25
26
27
28
29
30
}
#include "vpx/vpx_integer.h"

using libvpx_test::ACMRandom;

namespace {
31
32
33
34

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

41
const int kNumCoeffs = 256;
Daniel Kang's avatar
Daniel Kang committed
42
43
44
45
46
47
48
49
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
50
51
52
          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
53
54
55
56
57
58
59
60
61
62
63
64
          if (i != 0)
            x *= sqrt(2.0);
          if (j != 0)
            x *= sqrt(2.0);
          s += x;
        }
      }
      output[k*16+l] = s;
    }
  }
}

65

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

Jingning Han's avatar
Jingning Han committed
82
void butterfly_16x16_dct_1d(double input[16], double output[16]) {
Daniel Kang's avatar
Daniel Kang committed
83
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
  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];

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

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

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

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

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

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

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

143
144
  temp1 = step[ 8] * C9;
  temp2 = step[15] * C7;
Daniel Kang's avatar
Daniel Kang committed
145
146
147
148
149
150
151
152
  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];

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

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

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

165
166
  temp1 = output[4] * C2;
  temp2 = output[7] * C14;
Daniel Kang's avatar
Daniel Kang committed
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  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]);

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

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

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

  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];

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

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

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

  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]);

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

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

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

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

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

266
void fdct16x16_ref(int16_t *in, int16_t *out, int stride, int tx_type) {
267
  vp9_fdct16x16_c(in, out, stride);
268
269
270
271
272
273
}

void fht16x16_ref(int16_t *in, int16_t *out, int stride, int tx_type) {
  vp9_short_fht16x16_c(in, out, stride, tx_type);
}

274
class Trans16x16TestBase {
275
 public:
276
  virtual ~Trans16x16TestBase() {}
277

278
 protected:
279
  virtual void RunFwdTxfm(int16_t *in, int16_t *out, int stride) = 0;
280

281
  virtual void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) = 0;
282
283
284

  void RunAccuracyCheck() {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
285
286
    uint32_t max_error = 0;
    int64_t total_error = 0;
287
288
289
290
291
292
293
    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);

294
      // Initialize a test block with input range [-255, 255].
295
296
297
298
299
300
      for (int j = 0; j < kNumCoeffs; ++j) {
        src[j] = rnd.Rand8();
        dst[j] = rnd.Rand8();
        test_input_block[j] = src[j] - dst[j];
      }

301
302
303
      REGISTER_STATE_CHECK(RunFwdTxfm(test_input_block,
                                      test_temp_block, pitch_));
      REGISTER_STATE_CHECK(RunInvTxfm(test_temp_block, dst, pitch_));
304
305

      for (int j = 0; j < kNumCoeffs; ++j) {
306
307
        const uint32_t diff = dst[j] - src[j];
        const uint32_t error = diff * diff;
308
309
310
311
        if (max_error < error)
          max_error = error;
        total_error += error;
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
312
    }
Daniel Kang's avatar
Daniel Kang committed
313

314
    EXPECT_GE(1u, max_error)
315
316
317
318
        << "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";
319
320
  }

321
  void RunCoeffCheck() {
322
323
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 1000;
324
325
326
327
    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);

328
    for (int i = 0; i < count_test_block; ++i) {
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
      // 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
349

350
    for (int i = 0; i < count_test_block; ++i) {
351
      // Initialize a test block with input range [-255, 255].
352
353
354
355
356
357
358
      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;
359
360
361
      if (i == 1)
        for (int j = 0; j < kNumCoeffs; ++j)
          input_extreme_block[j] = -255;
362

363
      fwd_txfm_ref(input_extreme_block, output_ref_block, pitch_, tx_type_);
364
      REGISTER_STATE_CHECK(RunFwdTxfm(input_extreme_block,
365
                                      output_block, pitch_));
366
367
368

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

  void RunInvAccuracyCheck() {
    ACMRandom rnd(ACMRandom::DeterministicSeed());
    const int count_test_block = 1000;
379
380
381
382
    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
383

384
385
    for (int i = 0; i < count_test_block; ++i) {
      double out_r[kNumCoeffs];
Daniel Kang's avatar
Daniel Kang committed
386

387
388
389
390
391
392
393
394
395
396
397
      // 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]);

398
      REGISTER_STATE_CHECK(RunInvTxfm(coeff, dst, 16));
399
400

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

414
415
416
417
class Trans16x16DCT : public Trans16x16TestBase,
                      public PARAMS(fdct_t, idct_t, int) {
 public:
  virtual ~Trans16x16DCT() {}
Daniel Kang's avatar
Daniel Kang committed
418

419
420
421
422
  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    inv_txfm_ = GET_PARAM(1);
    tx_type_  = GET_PARAM(2);
423
    pitch_    = 16;
424
    fwd_txfm_ref = fdct16x16_ref;
425
426
  }
  virtual void TearDown() { libvpx_test::ClearSystemState(); }
Daniel Kang's avatar
Daniel Kang committed
427

428
 protected:
429
  void RunFwdTxfm(int16_t *in, int16_t *out, int stride) {
430
431
    fwd_txfm_(in, out, stride);
  }
432
  void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) {
433
    inv_txfm_(out, dst, stride);
Daniel Kang's avatar
Daniel Kang committed
434
  }
435
436
437
438
439
440
441

  fdct_t fwd_txfm_;
  idct_t inv_txfm_;
};

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

444
445
446
447
448
449
TEST_P(Trans16x16DCT, CoeffCheck) {
  RunCoeffCheck();
}

TEST_P(Trans16x16DCT, MemCheck) {
  RunMemCheck();
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
}

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

class Trans16x16HT : public Trans16x16TestBase,
                     public PARAMS(fht_t, iht_t, int) {
 public:
  virtual ~Trans16x16HT() {}

  virtual void SetUp() {
    fwd_txfm_ = GET_PARAM(0);
    inv_txfm_ = GET_PARAM(1);
    tx_type_  = GET_PARAM(2);
465
466
    pitch_    = 16;
    fwd_txfm_ref = fht16x16_ref;
467
  }
468
469
470
  virtual void TearDown() { libvpx_test::ClearSystemState(); }

 protected:
471
472
  void RunFwdTxfm(int16_t *in, int16_t *out, int stride) {
    fwd_txfm_(in, out, stride, tx_type_);
473
  }
474
475
  void RunInvTxfm(int16_t *out, uint8_t *dst, int stride) {
    inv_txfm_(out, dst, stride, tx_type_);
476
477
478
479
480
481
482
483
484
485
  }

  fht_t fwd_txfm_;
  iht_t inv_txfm_;
};

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

486
487
488
489
490
491
TEST_P(Trans16x16HT, CoeffCheck) {
  RunCoeffCheck();
}

TEST_P(Trans16x16HT, MemCheck) {
  RunMemCheck();
492
493
}

494
495
496
497
498
using std::tr1::make_tuple;

INSTANTIATE_TEST_CASE_P(
    C, Trans16x16DCT,
    ::testing::Values(
499
        make_tuple(&vp9_fdct16x16_c, &vp9_idct16x16_256_add_c, 0)));
500
501
502
INSTANTIATE_TEST_CASE_P(
    C, Trans16x16HT,
    ::testing::Values(
503
504
505
506
        make_tuple(&vp9_short_fht16x16_c, &vp9_iht16x16_256_add_c, 0),
        make_tuple(&vp9_short_fht16x16_c, &vp9_iht16x16_256_add_c, 1),
        make_tuple(&vp9_short_fht16x16_c, &vp9_iht16x16_256_add_c, 2),
        make_tuple(&vp9_short_fht16x16_c, &vp9_iht16x16_256_add_c, 3)));
507
508
509
510
511

#if HAVE_SSE2
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16DCT,
    ::testing::Values(
512
        make_tuple(&vp9_fdct16x16_sse2,
513
                   &vp9_idct16x16_256_add_sse2, 0)));
514
515
516
INSTANTIATE_TEST_CASE_P(
    SSE2, Trans16x16HT,
    ::testing::Values(
517
518
519
520
        make_tuple(&vp9_short_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 0),
        make_tuple(&vp9_short_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 1),
        make_tuple(&vp9_short_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 2),
        make_tuple(&vp9_short_fht16x16_sse2, &vp9_iht16x16_256_add_sse2, 3)));
521
#endif
Daniel Kang's avatar
Daniel Kang committed
522
}  // namespace