convolve_test.cc 19.9 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
2
3
4
5
6
7
8
9
10
/*
 *  Copyright (c) 2010 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.
 */

James Zern's avatar
James Zern committed
11
12
13
14
#include "test/acm_random.h"
#include "test/register_state_check.h"
#include "test/util.h"
#include "third_party/googletest/src/include/gtest/gtest.h"
John Koleszar's avatar
John Koleszar committed
15
16
17
18

extern "C" {
#include "./vpx_config.h"
#include "./vp9_rtcd.h"
19
#include "vp9/common/vp9_filter.h"
20
#include "vpx_mem/vpx_mem.h"
21
#include "vpx_ports/mem.h"
John Koleszar's avatar
John Koleszar committed
22
23
24
}

namespace {
25
26
typedef void (*convolve_fn_t)(const uint8_t *src, ptrdiff_t src_stride,
                              uint8_t *dst, ptrdiff_t dst_stride,
John Koleszar's avatar
John Koleszar committed
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
                              const int16_t *filter_x, int filter_x_stride,
                              const int16_t *filter_y, int filter_y_stride,
                              int w, int h);

struct ConvolveFunctions {
  ConvolveFunctions(convolve_fn_t h8, convolve_fn_t h8_avg,
                    convolve_fn_t v8, convolve_fn_t v8_avg,
                    convolve_fn_t hv8, convolve_fn_t hv8_avg)
      : h8_(h8), v8_(v8), hv8_(hv8), h8_avg_(h8_avg), v8_avg_(v8_avg),
        hv8_avg_(hv8_avg) {}

  convolve_fn_t h8_;
  convolve_fn_t v8_;
  convolve_fn_t hv8_;
  convolve_fn_t h8_avg_;
  convolve_fn_t v8_avg_;
  convolve_fn_t hv8_avg_;
};

// Reference 8-tap subpixel filter, slightly modified to fit into this test.
#define VP9_FILTER_WEIGHT 128
#define VP9_FILTER_SHIFT 7
James Zern's avatar
James Zern committed
49
uint8_t clip_pixel(int x) {
John Koleszar's avatar
John Koleszar committed
50
51
52
53
54
  return x < 0 ? 0 :
         x > 255 ? 255 :
         x;
}

James Zern's avatar
James Zern committed
55
56
57
58
59
60
61
62
void filter_block2d_8_c(const uint8_t *src_ptr,
                        const unsigned int src_stride,
                        const int16_t *HFilter,
                        const int16_t *VFilter,
                        uint8_t *dst_ptr,
                        unsigned int dst_stride,
                        unsigned int output_width,
                        unsigned int output_height) {
John Koleszar's avatar
John Koleszar committed
63
64
65
66
67
68
  // Between passes, we use an intermediate buffer whose height is extended to
  // have enough horizontally filtered values as input for the vertical pass.
  // This buffer is allocated to be big enough for the largest block type we
  // support.
  const int kInterp_Extend = 4;
  const unsigned int intermediate_height =
James Zern's avatar
James Zern committed
69
      (kInterp_Extend - 1) + output_height + kInterp_Extend;
John Koleszar's avatar
John Koleszar committed
70
71
72
73
74
75
76
77

  /* Size of intermediate_buffer is max_intermediate_height * filter_max_width,
   * where max_intermediate_height = (kInterp_Extend - 1) + filter_max_height
   *                                 + kInterp_Extend
   *                               = 3 + 16 + 4
   *                               = 23
   * and filter_max_width = 16
   */
78
  uint8_t intermediate_buffer[71 * 64];
John Koleszar's avatar
John Koleszar committed
79
80
81
82
83
84
85
86
87
88
89
  const int intermediate_next_stride = 1 - intermediate_height * output_width;

  // Horizontal pass (src -> transposed intermediate).
  {
    uint8_t *output_ptr = intermediate_buffer;
    const int src_next_row_stride = src_stride - output_width;
    unsigned int i, j;
    src_ptr -= (kInterp_Extend - 1) * src_stride + (kInterp_Extend - 1);
    for (i = 0; i < intermediate_height; ++i) {
      for (j = 0; j < output_width; ++j) {
        // Apply filter...
James Zern's avatar
James Zern committed
90
91
92
93
94
95
96
97
98
        const int temp = (src_ptr[0] * HFilter[0]) +
                         (src_ptr[1] * HFilter[1]) +
                         (src_ptr[2] * HFilter[2]) +
                         (src_ptr[3] * HFilter[3]) +
                         (src_ptr[4] * HFilter[4]) +
                         (src_ptr[5] * HFilter[5]) +
                         (src_ptr[6] * HFilter[6]) +
                         (src_ptr[7] * HFilter[7]) +
                         (VP9_FILTER_WEIGHT >> 1);  // Rounding
John Koleszar's avatar
John Koleszar committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117

        // Normalize back to 0-255...
        *output_ptr = clip_pixel(temp >> VP9_FILTER_SHIFT);
        ++src_ptr;
        output_ptr += intermediate_height;
      }
      src_ptr += src_next_row_stride;
      output_ptr += intermediate_next_stride;
    }
  }

  // Vertical pass (transposed intermediate -> dst).
  {
    uint8_t *src_ptr = intermediate_buffer;
    const int dst_next_row_stride = dst_stride - output_width;
    unsigned int i, j;
    for (i = 0; i < output_height; ++i) {
      for (j = 0; j < output_width; ++j) {
        // Apply filter...
James Zern's avatar
James Zern committed
118
119
120
121
122
123
124
125
126
        const int temp = (src_ptr[0] * VFilter[0]) +
                         (src_ptr[1] * VFilter[1]) +
                         (src_ptr[2] * VFilter[2]) +
                         (src_ptr[3] * VFilter[3]) +
                         (src_ptr[4] * VFilter[4]) +
                         (src_ptr[5] * VFilter[5]) +
                         (src_ptr[6] * VFilter[6]) +
                         (src_ptr[7] * VFilter[7]) +
                         (VP9_FILTER_WEIGHT >> 1);  // Rounding
John Koleszar's avatar
John Koleszar committed
127
128
129
130
131
132
133
134
135
136
137

        // Normalize back to 0-255...
        *dst_ptr++ = clip_pixel(temp >> VP9_FILTER_SHIFT);
        src_ptr += intermediate_height;
      }
      src_ptr += intermediate_next_stride;
      dst_ptr += dst_next_row_stride;
    }
  }
}

James Zern's avatar
James Zern committed
138
139
140
141
142
143
void block2d_average_c(uint8_t *src,
                       unsigned int src_stride,
                       uint8_t *output_ptr,
                       unsigned int output_stride,
                       unsigned int output_width,
                       unsigned int output_height) {
John Koleszar's avatar
John Koleszar committed
144
145
146
147
148
149
150
151
152
  unsigned int i, j;
  for (i = 0; i < output_height; ++i) {
    for (j = 0; j < output_width; ++j) {
      output_ptr[j] = (output_ptr[j] + src[i * src_stride + j] + 1) >> 1;
    }
    output_ptr += output_stride;
  }
}

James Zern's avatar
James Zern committed
153
154
155
156
157
158
159
160
161
void filter_average_block2d_8_c(const uint8_t *src_ptr,
                                const unsigned int src_stride,
                                const int16_t *HFilter,
                                const int16_t *VFilter,
                                uint8_t *dst_ptr,
                                unsigned int dst_stride,
                                unsigned int output_width,
                                unsigned int output_height) {
  uint8_t tmp[64 * 64];
John Koleszar's avatar
John Koleszar committed
162

163
164
165
  assert(output_width <= 64);
  assert(output_height <= 64);
  filter_block2d_8_c(src_ptr, src_stride, HFilter, VFilter, tmp, 64,
John Koleszar's avatar
John Koleszar committed
166
                     output_width, output_height);
167
  block2d_average_c(tmp, 64, dst_ptr, dst_stride,
John Koleszar's avatar
John Koleszar committed
168
169
170
171
                    output_width, output_height);
}

class ConvolveTest : public PARAMS(int, int, const ConvolveFunctions*) {
172
173
174
175
 public:
  static void SetUpTestCase() {
    // Force input_ to be unaligned, output to be 16 byte aligned.
    input_ = reinterpret_cast<uint8_t*>(
176
        vpx_memalign(kDataAlignment, kInputBufferSize + 1)) + 1;
177
    output_ = reinterpret_cast<uint8_t*>(
178
        vpx_memalign(kDataAlignment, kOutputBufferSize));
179
180
181
182
183
184
185
186
187
  }

  static void TearDownTestCase() {
    vpx_free(input_ - 1);
    input_ = NULL;
    vpx_free(output_);
    output_ = NULL;
  }

James Zern's avatar
James Zern committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
 protected:
  static const int kDataAlignment = 16;
  static const int kOuterBlockSize = 128;
  static const int kInputStride = kOuterBlockSize;
  static const int kOutputStride = kOuterBlockSize;
  static const int kMaxDimension = 64;
  static const int kInputBufferSize = kOuterBlockSize * kOuterBlockSize;
  static const int kOutputBufferSize = kOuterBlockSize * kOuterBlockSize;

  int Width() const { return GET_PARAM(0); }
  int Height() const { return GET_PARAM(1); }
  int BorderLeft() const {
    const int center = (kOuterBlockSize - Width()) / 2;
    return (center + (kDataAlignment - 1)) & ~(kDataAlignment - 1);
  }
  int BorderTop() const { return (kOuterBlockSize - Height()) / 2; }
John Koleszar's avatar
John Koleszar committed
204

James Zern's avatar
James Zern committed
205
206
207
208
209
210
  bool IsIndexInBorder(int i) {
    return (i < BorderTop() * kOuterBlockSize ||
            i >= (BorderTop() + Height()) * kOuterBlockSize ||
            i % kOuterBlockSize < BorderLeft() ||
            i % kOuterBlockSize >= (BorderLeft() + Width()));
  }
John Koleszar's avatar
John Koleszar committed
211

James Zern's avatar
James Zern committed
212
213
  virtual void SetUp() {
    UUT_ = GET_PARAM(2);
Johann's avatar
Johann committed
214
    /* Set up guard blocks for an inner block centered in the outer block */
James Zern's avatar
James Zern committed
215
216
217
218
219
    for (int i = 0; i < kOutputBufferSize; ++i) {
      if (IsIndexInBorder(i))
        output_[i] = 255;
      else
        output_[i] = 0;
John Koleszar's avatar
John Koleszar committed
220
221
    }

James Zern's avatar
James Zern committed
222
223
224
225
    ::libvpx_test::ACMRandom prng;
    for (int i = 0; i < kInputBufferSize; ++i)
      input_[i] = prng.Rand8Extremes();
  }
John Koleszar's avatar
John Koleszar committed
226

James Zern's avatar
James Zern committed
227
228
229
230
  void CheckGuardBlocks() {
    for (int i = 0; i < kOutputBufferSize; ++i) {
      if (IsIndexInBorder(i))
        EXPECT_EQ(255, output_[i]);
John Koleszar's avatar
John Koleszar committed
231
    }
James Zern's avatar
James Zern committed
232
  }
John Koleszar's avatar
John Koleszar committed
233

James Zern's avatar
James Zern committed
234
235
236
  uint8_t* input() const {
    return input_ + BorderTop() * kOuterBlockSize + BorderLeft();
  }
John Koleszar's avatar
John Koleszar committed
237

James Zern's avatar
James Zern committed
238
239
240
241
242
243
244
  uint8_t* output() const {
    return output_ + BorderTop() * kOuterBlockSize + BorderLeft();
  }

  const ConvolveFunctions* UUT_;
  static uint8_t* input_;
  static uint8_t* output_;
John Koleszar's avatar
John Koleszar committed
245
};
246
247
uint8_t* ConvolveTest::input_ = NULL;
uint8_t* ConvolveTest::output_ = NULL;
John Koleszar's avatar
John Koleszar committed
248
249
250
251
252
253
254
255

TEST_P(ConvolveTest, GuardBlocks) {
  CheckGuardBlocks();
}

TEST_P(ConvolveTest, CopyHoriz) {
  uint8_t* const in = input();
  uint8_t* const out = output();
256
  DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0};
John Koleszar's avatar
John Koleszar committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

  REGISTER_STATE_CHECK(
      UUT_->h8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16,
                Width(), Height()));

  CheckGuardBlocks();

  for (int y = 0; y < Height(); ++y)
    for (int x = 0; x < Width(); ++x)
      ASSERT_EQ(out[y * kOutputStride + x], in[y * kInputStride + x])
          << "(" << x << "," << y << ")";
}

TEST_P(ConvolveTest, CopyVert) {
  uint8_t* const in = input();
  uint8_t* const out = output();
273
  DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0};
John Koleszar's avatar
John Koleszar committed
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289

  REGISTER_STATE_CHECK(
      UUT_->v8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16,
                Width(), Height()));

  CheckGuardBlocks();

  for (int y = 0; y < Height(); ++y)
    for (int x = 0; x < Width(); ++x)
      ASSERT_EQ(out[y * kOutputStride + x], in[y * kInputStride + x])
          << "(" << x << "," << y << ")";
}

TEST_P(ConvolveTest, Copy2D) {
  uint8_t* const in = input();
  uint8_t* const out = output();
290
  DECLARE_ALIGNED(256, const int16_t, filter8[8]) = {0, 0, 0, 128, 0, 0, 0, 0};
John Koleszar's avatar
John Koleszar committed
291
292
293
294
295
296
297
298
299
300
301
302
303

  REGISTER_STATE_CHECK(
      UUT_->hv8_(in, kInputStride, out, kOutputStride, filter8, 16, filter8, 16,
                 Width(), Height()));

  CheckGuardBlocks();

  for (int y = 0; y < Height(); ++y)
    for (int x = 0; x < Width(); ++x)
      ASSERT_EQ(out[y * kOutputStride + x], in[y * kInputStride + x])
          << "(" << x << "," << y << ")";
}

304
305
306
307
308
309
const int16_t (*kTestFilterList[])[8] = {
  vp9_bilinear_filters,
  vp9_sub_pel_filters_8,
  vp9_sub_pel_filters_8s,
  vp9_sub_pel_filters_8lp
};
310
const int kNumFilterBanks = sizeof(kTestFilterList) /
James Zern's avatar
James Zern committed
311
                            sizeof(kTestFilterList[0]);
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
const int kNumFilters = 16;

TEST(ConvolveTest, FiltersWontSaturateWhenAddedPairwise) {
  for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
    const int16_t (*filters)[8] = kTestFilterList[filter_bank];
    for (int i = 0; i < kNumFilters; i++) {
      const int p0 = filters[i][0] + filters[i][1];
      const int p1 = filters[i][2] + filters[i][3];
      const int p2 = filters[i][4] + filters[i][5];
      const int p3 = filters[i][6] + filters[i][7];
      EXPECT_LE(p0, 128);
      EXPECT_LE(p1, 128);
      EXPECT_LE(p2, 128);
      EXPECT_LE(p3, 128);
      EXPECT_LE(p0 + p3, 128);
      EXPECT_LE(p0 + p3 + p1, 128);
      EXPECT_LE(p0 + p3 + p1 + p2, 128);
      EXPECT_EQ(p0 + p1 + p2 + p3, 128);
    }
  }
}
333

334
335
const int16_t kInvalidFilter[8] = { 0 };

John Koleszar's avatar
John Koleszar committed
336
337
338
339
340
TEST_P(ConvolveTest, MatchesReferenceSubpixelFilter) {
  uint8_t* const in = input();
  uint8_t* const out = output();
  uint8_t ref[kOutputStride * kMaxDimension];

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359

  for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
    const int16_t (*filters)[8] = kTestFilterList[filter_bank];

    for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
      for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
        filter_block2d_8_c(in, kInputStride,
                           filters[filter_x], filters[filter_y],
                           ref, kOutputStride,
                           Width(), Height());

        if (filters == vp9_sub_pel_filters_8lp || (filter_x && filter_y))
          REGISTER_STATE_CHECK(
              UUT_->hv8_(in, kInputStride, out, kOutputStride,
                         filters[filter_x], 16, filters[filter_y], 16,
                         Width(), Height()));
        else if (filter_y)
          REGISTER_STATE_CHECK(
              UUT_->v8_(in, kInputStride, out, kOutputStride,
360
                        kInvalidFilter, 16, filters[filter_y], 16,
361
362
363
364
                        Width(), Height()));
        else
          REGISTER_STATE_CHECK(
              UUT_->h8_(in, kInputStride, out, kOutputStride,
365
                        filters[filter_x], 16, kInvalidFilter, 16,
366
367
368
369
370
371
372
373
374
375
376
                        Width(), Height()));

        CheckGuardBlocks();

        for (int y = 0; y < Height(); ++y)
          for (int x = 0; x < Width(); ++x)
            ASSERT_EQ(ref[y * kOutputStride + x], out[y * kOutputStride + x])
                << "mismatch at (" << x << "," << y << "), "
                << "filters (" << filter_bank << ","
                << filter_x << "," << filter_y << ")";
      }
John Koleszar's avatar
John Koleszar committed
377
378
379
380
381
382
383
384
385
386
387
388
389
    }
  }
}

TEST_P(ConvolveTest, MatchesReferenceAveragingSubpixelFilter) {
  uint8_t* const in = input();
  uint8_t* const out = output();
  uint8_t ref[kOutputStride * kMaxDimension];

  // Populate ref and out with some random data
  ::libvpx_test::ACMRandom prng;
  for (int y = 0; y < Height(); ++y) {
    for (int x = 0; x < Width(); ++x) {
390
      const uint8_t r = prng.Rand8Extremes();
John Koleszar's avatar
John Koleszar committed
391
392
393
394
395
396

      out[y * kOutputStride + x] = r;
      ref[y * kOutputStride + x] = r;
    }
  }

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
  const int kNumFilterBanks = sizeof(kTestFilterList) /
      sizeof(kTestFilterList[0]);

  for (int filter_bank = 0; filter_bank < kNumFilterBanks; ++filter_bank) {
    const int16_t (*filters)[8] = kTestFilterList[filter_bank];
    const int kNumFilters = 16;

    for (int filter_x = 0; filter_x < kNumFilters; ++filter_x) {
      for (int filter_y = 0; filter_y < kNumFilters; ++filter_y) {
        filter_average_block2d_8_c(in, kInputStride,
                                   filters[filter_x], filters[filter_y],
                                   ref, kOutputStride,
                                   Width(), Height());

        if (filters == vp9_sub_pel_filters_8lp || (filter_x && filter_y))
          REGISTER_STATE_CHECK(
              UUT_->hv8_avg_(in, kInputStride, out, kOutputStride,
                             filters[filter_x], 16, filters[filter_y], 16,
                             Width(), Height()));
        else if (filter_y)
          REGISTER_STATE_CHECK(
              UUT_->v8_avg_(in, kInputStride, out, kOutputStride,
                            filters[filter_x], 16, filters[filter_y], 16,
                            Width(), Height()));
        else
          REGISTER_STATE_CHECK(
              UUT_->h8_avg_(in, kInputStride, out, kOutputStride,
                            filters[filter_x], 16, filters[filter_y], 16,
                            Width(), Height()));

        CheckGuardBlocks();

        for (int y = 0; y < Height(); ++y)
          for (int x = 0; x < Width(); ++x)
            ASSERT_EQ(ref[y * kOutputStride + x], out[y * kOutputStride + x])
                << "mismatch at (" << x << "," << y << "), "
                << "filters (" << filter_bank << ","
                << filter_x << "," << filter_y << ")";
      }
John Koleszar's avatar
John Koleszar committed
436
437
438
439
    }
  }
}

440
DECLARE_ALIGNED(256, const int16_t, kChangeFilters[16][8]) = {
John Koleszar's avatar
John Koleszar committed
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    { 0,   0,   0,   0,   0,   0,   0, 128},
    { 0,   0,   0,   0,   0,   0, 128},
    { 0,   0,   0,   0,   0, 128},
    { 0,   0,   0,   0, 128},
    { 0,   0,   0, 128},
    { 0,   0, 128},
    { 0, 128},
    { 128},
    { 0,   0,   0,   0,   0,   0,   0, 128},
    { 0,   0,   0,   0,   0,   0, 128},
    { 0,   0,   0,   0,   0, 128},
    { 0,   0,   0,   0, 128},
    { 0,   0,   0, 128},
    { 0,   0, 128},
    { 0, 128},
456
457
458
459
460
461
    { 128}
};

TEST_P(ConvolveTest, ChangeFilterWorks) {
  uint8_t* const in = input();
  uint8_t* const out = output();
462
  const int kPixelSelected = 4;
John Koleszar's avatar
John Koleszar committed
463
464

  REGISTER_STATE_CHECK(UUT_->h8_(in, kInputStride, out, kOutputStride,
465
                                 kChangeFilters[8], 17, kChangeFilters[4], 16,
John Koleszar's avatar
John Koleszar committed
466
467
                                 Width(), Height()));

468
  for (int x = 0; x < Width(); ++x) {
469
470
471
472
    const int kQ4StepAdjust = x >> 4;
    const int kFilterPeriodAdjust = (x >> 3) << 3;
    const int ref_x = kQ4StepAdjust + kFilterPeriodAdjust + kPixelSelected;
    ASSERT_EQ(in[ref_x], out[x]) << "x == " << x;
John Koleszar's avatar
John Koleszar committed
473
474
475
  }

  REGISTER_STATE_CHECK(UUT_->v8_(in, kInputStride, out, kOutputStride,
476
                                 kChangeFilters[4], 16, kChangeFilters[8], 17,
John Koleszar's avatar
John Koleszar committed
477
478
                                 Width(), Height()));

479
  for (int y = 0; y < Height(); ++y) {
480
481
482
483
    const int kQ4StepAdjust = y >> 4;
    const int kFilterPeriodAdjust = (y >> 3) << 3;
    const int ref_y = kQ4StepAdjust + kFilterPeriodAdjust + kPixelSelected;
    ASSERT_EQ(in[ref_y * kInputStride], out[y * kInputStride]) << "y == " << y;
John Koleszar's avatar
John Koleszar committed
484
485
486
  }

  REGISTER_STATE_CHECK(UUT_->hv8_(in, kInputStride, out, kOutputStride,
487
                                  kChangeFilters[8], 17, kChangeFilters[8], 17,
John Koleszar's avatar
John Koleszar committed
488
489
                                  Width(), Height()));

490
  for (int y = 0; y < Height(); ++y) {
491
492
493
    const int kQ4StepAdjustY = y >> 4;
    const int kFilterPeriodAdjustY = (y >> 3) << 3;
    const int ref_y = kQ4StepAdjustY + kFilterPeriodAdjustY + kPixelSelected;
494
    for (int x = 0; x < Width(); ++x) {
495
496
497
      const int kQ4StepAdjustX = x >> 4;
      const int kFilterPeriodAdjustX = (x >> 3) << 3;
      const int ref_x = kQ4StepAdjustX + kFilterPeriodAdjustX + kPixelSelected;
498
499

      ASSERT_EQ(in[ref_y * kInputStride + ref_x], out[y * kOutputStride + x])
John Koleszar's avatar
John Koleszar committed
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
          << "x == " << x << ", y == " << y;
    }
  }
}


using std::tr1::make_tuple;

const ConvolveFunctions convolve8_c(
    vp9_convolve8_horiz_c, vp9_convolve8_avg_horiz_c,
    vp9_convolve8_vert_c, vp9_convolve8_avg_vert_c,
    vp9_convolve8_c, vp9_convolve8_avg_c);

INSTANTIATE_TEST_CASE_P(C, ConvolveTest, ::testing::Values(
    make_tuple(4, 4, &convolve8_c),
    make_tuple(8, 4, &convolve8_c),
516
    make_tuple(4, 8, &convolve8_c),
John Koleszar's avatar
John Koleszar committed
517
    make_tuple(8, 8, &convolve8_c),
518
    make_tuple(16, 8, &convolve8_c),
519
520
521
522
523
524
525
526
    make_tuple(8, 16, &convolve8_c),
    make_tuple(16, 16, &convolve8_c),
    make_tuple(32, 16, &convolve8_c),
    make_tuple(16, 32, &convolve8_c),
    make_tuple(32, 32, &convolve8_c),
    make_tuple(64, 32, &convolve8_c),
    make_tuple(32, 64, &convolve8_c),
    make_tuple(64, 64, &convolve8_c)));
527
528
529
530
531
532
533
534
535
536

#if HAVE_SSSE3
const ConvolveFunctions convolve8_ssse3(
    vp9_convolve8_horiz_ssse3, vp9_convolve8_avg_horiz_c,
    vp9_convolve8_vert_ssse3, vp9_convolve8_avg_vert_c,
    vp9_convolve8_ssse3, vp9_convolve8_avg_c);

INSTANTIATE_TEST_CASE_P(SSSE3, ConvolveTest, ::testing::Values(
    make_tuple(4, 4, &convolve8_ssse3),
    make_tuple(8, 4, &convolve8_ssse3),
537
    make_tuple(4, 8, &convolve8_ssse3),
538
    make_tuple(8, 8, &convolve8_ssse3),
539
    make_tuple(16, 8, &convolve8_ssse3),
540
541
542
543
544
545
546
547
    make_tuple(8, 16, &convolve8_ssse3),
    make_tuple(16, 16, &convolve8_ssse3),
    make_tuple(32, 16, &convolve8_ssse3),
    make_tuple(16, 32, &convolve8_ssse3),
    make_tuple(32, 32, &convolve8_ssse3),
    make_tuple(64, 32, &convolve8_ssse3),
    make_tuple(32, 64, &convolve8_ssse3),
    make_tuple(64, 64, &convolve8_ssse3)));
548
#endif
Johann's avatar
Johann committed
549
550
551

#if HAVE_NEON
const ConvolveFunctions convolve8_neon(
Johann's avatar
Johann committed
552
553
    vp9_convolve8_horiz_neon, vp9_convolve8_avg_horiz_neon,
    vp9_convolve8_vert_neon, vp9_convolve8_avg_vert_neon,
Johann's avatar
Johann committed
554
    vp9_convolve8_neon, vp9_convolve8_avg_neon);
Johann's avatar
Johann committed
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570

INSTANTIATE_TEST_CASE_P(NEON, ConvolveTest, ::testing::Values(
    make_tuple(4, 4, &convolve8_neon),
    make_tuple(8, 4, &convolve8_neon),
    make_tuple(4, 8, &convolve8_neon),
    make_tuple(8, 8, &convolve8_neon),
    make_tuple(16, 8, &convolve8_neon),
    make_tuple(8, 16, &convolve8_neon),
    make_tuple(16, 16, &convolve8_neon),
    make_tuple(32, 16, &convolve8_neon),
    make_tuple(16, 32, &convolve8_neon),
    make_tuple(32, 32, &convolve8_neon),
    make_tuple(64, 32, &convolve8_neon),
    make_tuple(32, 64, &convolve8_neon),
    make_tuple(64, 64, &convolve8_neon)));
#endif
James Zern's avatar
James Zern committed
571
}  // namespace