blob: cb8b8fba13e71b27a25824a741f87b7d6dab9fc8 [file] [log] [blame]
Yi Luo229690a2016-06-13 17:01:17 -07001/*
2 * Copyright (c) 2016 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "third_party/googletest/src/include/gtest/gtest.h"
12
13#include "./vp10_rtcd.h"
14#include "test/acm_random.h"
15#include "test/clear_system_state.h"
16#include "test/register_state_check.h"
17#include "test/util.h"
18
19namespace {
20
21using std::tr1::tuple;
Yaowu Xuc27fc142016-08-22 16:08:15 -070022using libaom_test::ACMRandom;
Yi Luo229690a2016-06-13 17:01:17 -070023
clang-format3a826f12016-08-11 17:46:05 -070024typedef void (*conv_filter_t)(const uint8_t *, int, uint8_t *, int, int, int,
25 const InterpFilterParams, const int, int, int);
Yi Luo8cacca72016-07-08 15:41:59 -070026#if CONFIG_VP9_HIGHBITDEPTH
clang-format3a826f12016-08-11 17:46:05 -070027typedef void (*hbd_conv_filter_t)(const uint16_t *, int, uint16_t *, int, int,
28 int, const InterpFilterParams, const int, int,
29 int, int);
Yi Luo8cacca72016-07-08 15:41:59 -070030#endif
31
Yi Luo229690a2016-06-13 17:01:17 -070032// Test parameter list:
Yi Luo81ad9532016-06-21 12:17:39 -070033// <convolve_horiz_func, convolve_vert_func,
34// <width, height>, filter_params, subpel_x_q4, avg>
Yi Luo229690a2016-06-13 17:01:17 -070035typedef tuple<int, int> BlockDimension;
clang-format3a826f12016-08-11 17:46:05 -070036typedef tuple<conv_filter_t, conv_filter_t, BlockDimension, INTERP_FILTER, int,
37 int> ConvParams;
Yi Luo8cacca72016-07-08 15:41:59 -070038#if CONFIG_VP9_HIGHBITDEPTH
39// Test parameter list:
40// <convolve_horiz_func, convolve_vert_func,
41// <width, height>, filter_params, subpel_x_q4, avg, bit_dpeth>
42typedef tuple<hbd_conv_filter_t, hbd_conv_filter_t, BlockDimension,
43 INTERP_FILTER, int, int, int> HbdConvParams;
44#endif
Yi Luo229690a2016-06-13 17:01:17 -070045
46// Note:
47// src_ and src_ref_ have special boundary requirement
48// dst_ and dst_ref_ don't
49const size_t maxWidth = 256;
50const size_t maxHeight = 256;
51const size_t maxBlockSize = maxWidth * maxHeight;
52const int horizOffset = 32;
53const int vertiOffset = 32;
Yi Luo84042532016-06-24 17:29:21 -070054const size_t testMaxBlk = 128;
Yi Luo229690a2016-06-13 17:01:17 -070055const int stride = 128;
56const int x_step_q4 = 16;
57
58class VP10ConvolveOptimzTest : public ::testing::TestWithParam<ConvParams> {
59 public:
60 virtual ~VP10ConvolveOptimzTest() {}
61 virtual void SetUp() {
Yi Luo81ad9532016-06-21 12:17:39 -070062 conv_horiz_ = GET_PARAM(0);
63 conv_vert_ = GET_PARAM(1);
64 BlockDimension block = GET_PARAM(2);
Yi Luo229690a2016-06-13 17:01:17 -070065 width_ = std::tr1::get<0>(block);
66 height_ = std::tr1::get<1>(block);
Yi Luo81ad9532016-06-21 12:17:39 -070067 filter_ = GET_PARAM(3);
68 subpel_ = GET_PARAM(4);
69 avg_ = GET_PARAM(5);
Yi Luo229690a2016-06-13 17:01:17 -070070
71 alloc_ = new uint8_t[maxBlockSize * 4];
72 src_ = alloc_ + (vertiOffset * maxWidth);
73 src_ += horizOffset;
74 src_ref_ = src_ + maxBlockSize;
75
76 dst_ = alloc_ + 2 * maxBlockSize;
77 dst_ref_ = alloc_ + 3 * maxBlockSize;
78 }
79
80 virtual void TearDown() {
81 delete[] alloc_;
Yaowu Xuc27fc142016-08-22 16:08:15 -070082 libaom_test::ClearSystemState();
Yi Luo229690a2016-06-13 17:01:17 -070083 }
84
85 protected:
86 void RunHorizFilterBitExactCheck();
Yi Luo81ad9532016-06-21 12:17:39 -070087 void RunVertFilterBitExactCheck();
Yi Luo229690a2016-06-13 17:01:17 -070088
89 private:
Yi Luo8cacca72016-07-08 15:41:59 -070090 void PrepFilterBuffer(int w, int h);
91 void DiffFilterBuffer();
Yi Luo81ad9532016-06-21 12:17:39 -070092 conv_filter_t conv_horiz_;
93 conv_filter_t conv_vert_;
Yi Luo229690a2016-06-13 17:01:17 -070094 uint8_t *alloc_;
95 uint8_t *src_;
96 uint8_t *dst_;
97 uint8_t *src_ref_;
98 uint8_t *dst_ref_;
99 int width_;
100 int height_;
101 int filter_;
102 int subpel_;
103 int avg_;
104};
105
Yi Luo8cacca72016-07-08 15:41:59 -0700106void VP10ConvolveOptimzTest::PrepFilterBuffer(int w, int h) {
Yi Luo229690a2016-06-13 17:01:17 -0700107 int r, c;
108 ACMRandom rnd(ACMRandom::DeterministicSeed());
109
Yi Luo81ad9532016-06-21 12:17:39 -0700110 memset(alloc_, 0, 4 * maxBlockSize * sizeof(alloc_[0]));
Yi Luo229690a2016-06-13 17:01:17 -0700111
Yi Luo8cacca72016-07-08 15:41:59 -0700112 uint8_t *src_ptr = src_;
113 uint8_t *dst_ptr = dst_;
114 uint8_t *src_ref_ptr = src_ref_;
115 uint8_t *dst_ref_ptr = dst_ref_;
Yi Luo229690a2016-06-13 17:01:17 -0700116
117 for (r = 0; r < height_; ++r) {
118 for (c = 0; c < width_; ++c) {
119 src_ptr[c] = rnd.Rand8();
120 src_ref_ptr[c] = src_ptr[c];
121 dst_ptr[c] = rnd.Rand8();
122 dst_ref_ptr[c] = dst_ptr[c];
123 }
124 src_ptr += stride;
125 src_ref_ptr += stride;
126 dst_ptr += stride;
127 dst_ref_ptr += stride;
128 }
129}
130
Yi Luo8cacca72016-07-08 15:41:59 -0700131void VP10ConvolveOptimzTest::DiffFilterBuffer() {
Yi Luo229690a2016-06-13 17:01:17 -0700132 int r, c;
Yi Luo8cacca72016-07-08 15:41:59 -0700133 const uint8_t *dst_ptr = dst_;
134 const uint8_t *dst_ref_ptr = dst_ref_;
135 for (r = 0; r < height_; ++r) {
136 for (c = 0; c < width_; ++c) {
Yi Luo229690a2016-06-13 17:01:17 -0700137 EXPECT_EQ((uint8_t)dst_ref_ptr[c], (uint8_t)dst_ptr[c])
clang-format3a826f12016-08-11 17:46:05 -0700138 << "Error at row: " << r << " col: " << c << " "
139 << "w = " << width_ << " "
140 << "h = " << height_ << " "
141 << "filter group index = " << filter_ << " "
142 << "filter index = " << subpel_;
Yi Luo229690a2016-06-13 17:01:17 -0700143 }
144 dst_ptr += stride;
145 dst_ref_ptr += stride;
146 }
147}
148
149void VP10ConvolveOptimzTest::RunHorizFilterBitExactCheck() {
Yi Luo8cacca72016-07-08 15:41:59 -0700150 PrepFilterBuffer(testMaxBlk, testMaxBlk);
Yi Luo229690a2016-06-13 17:01:17 -0700151
152 InterpFilterParams filter_params = vp10_get_interp_filter_params(filter_);
153
154 vp10_convolve_horiz_c(src_ref_, stride, dst_ref_, stride, width_, height_,
155 filter_params, subpel_, x_step_q4, avg_);
156
clang-format3a826f12016-08-11 17:46:05 -0700157 conv_horiz_(src_, stride, dst_, stride, width_, height_, filter_params,
158 subpel_, x_step_q4, avg_);
Yi Luo229690a2016-06-13 17:01:17 -0700159
Yi Luo8cacca72016-07-08 15:41:59 -0700160 DiffFilterBuffer();
Yi Luo229690a2016-06-13 17:01:17 -0700161
162 // Note:
163 // Here we need calculate a height which is different from the specified one
164 // and test again.
165 int intermediate_height =
166 (((height_ - 1) * 16 + subpel_) >> SUBPEL_BITS) + filter_params.taps;
Yi Luo8cacca72016-07-08 15:41:59 -0700167 PrepFilterBuffer(testMaxBlk, testMaxBlk);
Yi Luo229690a2016-06-13 17:01:17 -0700168
169 vp10_convolve_horiz_c(src_ref_, stride, dst_ref_, stride, width_,
170 intermediate_height, filter_params, subpel_, x_step_q4,
171 avg_);
172
clang-format3a826f12016-08-11 17:46:05 -0700173 conv_horiz_(src_, stride, dst_, stride, width_, intermediate_height,
174 filter_params, subpel_, x_step_q4, avg_);
Yi Luo229690a2016-06-13 17:01:17 -0700175
Yi Luo8cacca72016-07-08 15:41:59 -0700176 DiffFilterBuffer();
Yi Luo229690a2016-06-13 17:01:17 -0700177}
178
Yi Luo81ad9532016-06-21 12:17:39 -0700179void VP10ConvolveOptimzTest::RunVertFilterBitExactCheck() {
Yi Luo8cacca72016-07-08 15:41:59 -0700180 PrepFilterBuffer(testMaxBlk, testMaxBlk);
Yi Luo81ad9532016-06-21 12:17:39 -0700181
182 InterpFilterParams filter_params = vp10_get_interp_filter_params(filter_);
183
184 vp10_convolve_vert_c(src_ref_, stride, dst_ref_, stride, width_, height_,
185 filter_params, subpel_, x_step_q4, avg_);
186
clang-format3a826f12016-08-11 17:46:05 -0700187 conv_vert_(src_, stride, dst_, stride, width_, height_, filter_params,
188 subpel_, x_step_q4, avg_);
Yi Luo81ad9532016-06-21 12:17:39 -0700189
Yi Luo8cacca72016-07-08 15:41:59 -0700190 DiffFilterBuffer();
Yi Luo81ad9532016-06-21 12:17:39 -0700191}
192
Yi Luo229690a2016-06-13 17:01:17 -0700193TEST_P(VP10ConvolveOptimzTest, HorizBitExactCheck) {
194 RunHorizFilterBitExactCheck();
195}
Yi Luo81ad9532016-06-21 12:17:39 -0700196TEST_P(VP10ConvolveOptimzTest, VerticalBitExactCheck) {
197 RunVertFilterBitExactCheck();
198}
Yi Luo229690a2016-06-13 17:01:17 -0700199
200using std::tr1::make_tuple;
201
Yi Luo8cacca72016-07-08 15:41:59 -0700202#if (HAVE_SSSE3 || HAVE_SSE4_1) && CONFIG_EXT_INTERP
Yi Luo229690a2016-06-13 17:01:17 -0700203const BlockDimension kBlockDim[] = {
clang-format3a826f12016-08-11 17:46:05 -0700204 make_tuple(2, 2), make_tuple(2, 4), make_tuple(4, 4),
205 make_tuple(4, 8), make_tuple(8, 4), make_tuple(8, 8),
206 make_tuple(8, 16), make_tuple(16, 8), make_tuple(16, 16),
207 make_tuple(16, 32), make_tuple(32, 16), make_tuple(32, 32),
208 make_tuple(32, 64), make_tuple(64, 32), make_tuple(64, 64),
209 make_tuple(64, 128), make_tuple(128, 64), make_tuple(128, 128),
Yi Luo229690a2016-06-13 17:01:17 -0700210};
Sarah Parker95763742016-06-28 17:13:03 -0700211
Yi Luo229690a2016-06-13 17:01:17 -0700212// 10/12-tap filters
clang-format3a826f12016-08-11 17:46:05 -0700213const INTERP_FILTER kFilter[] = { 6, 4, 2 };
Yi Luo229690a2016-06-13 17:01:17 -0700214
clang-format3a826f12016-08-11 17:46:05 -0700215const int kSubpelQ4[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Yi Luo229690a2016-06-13 17:01:17 -0700216
clang-format3a826f12016-08-11 17:46:05 -0700217const int kAvg[] = { 0, 1 };
Yi Luo8cacca72016-07-08 15:41:59 -0700218#endif
Yi Luo229690a2016-06-13 17:01:17 -0700219
Yi Luo8cacca72016-07-08 15:41:59 -0700220#if HAVE_SSSE3 && CONFIG_EXT_INTERP
Yi Luo229690a2016-06-13 17:01:17 -0700221INSTANTIATE_TEST_CASE_P(
222 SSSE3, VP10ConvolveOptimzTest,
clang-format3a826f12016-08-11 17:46:05 -0700223 ::testing::Combine(::testing::Values(vp10_convolve_horiz_ssse3),
224 ::testing::Values(vp10_convolve_vert_ssse3),
225 ::testing::ValuesIn(kBlockDim),
226 ::testing::ValuesIn(kFilter),
227 ::testing::ValuesIn(kSubpelQ4),
228 ::testing::ValuesIn(kAvg)));
Yi Luo229690a2016-06-13 17:01:17 -0700229#endif // HAVE_SSSE3 && CONFIG_EXT_INTERP
Yi Luo8cacca72016-07-08 15:41:59 -0700230
231#if CONFIG_VP9_HIGHBITDEPTH
232typedef ::testing::TestWithParam<HbdConvParams> TestWithHbdConvParams;
233class VP10HbdConvolveOptimzTest : public TestWithHbdConvParams {
234 public:
235 virtual ~VP10HbdConvolveOptimzTest() {}
236 virtual void SetUp() {
237 conv_horiz_ = GET_PARAM(0);
238 conv_vert_ = GET_PARAM(1);
239 BlockDimension block = GET_PARAM(2);
240 width_ = std::tr1::get<0>(block);
241 height_ = std::tr1::get<1>(block);
242 filter_ = GET_PARAM(3);
243 subpel_ = GET_PARAM(4);
244 avg_ = GET_PARAM(5);
245 bit_depth_ = GET_PARAM(6);
246
247 alloc_ = new uint16_t[maxBlockSize * 4];
248 src_ = alloc_ + (vertiOffset * maxWidth);
249 src_ += horizOffset;
250 src_ref_ = src_ + maxBlockSize;
251
252 dst_ = alloc_ + 2 * maxBlockSize;
253 dst_ref_ = alloc_ + 3 * maxBlockSize;
254 }
255
256 virtual void TearDown() {
257 delete[] alloc_;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700258 libaom_test::ClearSystemState();
Yi Luo8cacca72016-07-08 15:41:59 -0700259 }
260
261 protected:
262 void RunHorizFilterBitExactCheck();
263 void RunVertFilterBitExactCheck();
264
265 private:
266 void PrepFilterBuffer(int w, int h);
267 void DiffFilterBuffer();
268 hbd_conv_filter_t conv_horiz_;
269 hbd_conv_filter_t conv_vert_;
270 uint16_t *alloc_;
271 uint16_t *src_;
272 uint16_t *dst_;
273 uint16_t *src_ref_;
274 uint16_t *dst_ref_;
275 int width_;
276 int height_;
277 int filter_;
278 int subpel_;
279 int avg_;
280 int bit_depth_;
281};
282
283void VP10HbdConvolveOptimzTest::PrepFilterBuffer(int w, int h) {
284 int r, c;
285 ACMRandom rnd(ACMRandom::DeterministicSeed());
286
287 memset(alloc_, 0, 4 * maxBlockSize * sizeof(alloc_[0]));
288
289 uint16_t *src_ptr = src_;
290 uint16_t *dst_ptr = dst_;
291 uint16_t *dst_ref_ptr = dst_ref_;
292 uint16_t hbd_mask = (1 << bit_depth_) - 1;
293
294 for (r = 0; r < height_; ++r) {
295 for (c = 0; c < width_; ++c) {
296 src_ptr[c] = rnd.Rand16() & hbd_mask;
297 dst_ptr[c] = rnd.Rand16() & hbd_mask;
298 dst_ref_ptr[c] = dst_ptr[c];
299 }
300 src_ptr += stride;
301 dst_ptr += stride;
302 dst_ref_ptr += stride;
303 }
304}
305
306void VP10HbdConvolveOptimzTest::DiffFilterBuffer() {
307 int r, c;
308 const uint16_t *dst_ptr = dst_;
309 const uint16_t *dst_ref_ptr = dst_ref_;
310 for (r = 0; r < height_; ++r) {
311 for (c = 0; c < width_; ++c) {
312 EXPECT_EQ((uint16_t)dst_ref_ptr[c], (uint16_t)dst_ptr[c])
clang-format3a826f12016-08-11 17:46:05 -0700313 << "Error at row: " << r << " col: " << c << " "
314 << "w = " << width_ << " "
315 << "h = " << height_ << " "
316 << "filter group index = " << filter_ << " "
317 << "filter index = " << subpel_ << " "
318 << "bit depth = " << bit_depth_;
Yi Luo8cacca72016-07-08 15:41:59 -0700319 }
320 dst_ptr += stride;
321 dst_ref_ptr += stride;
322 }
323}
324
325void VP10HbdConvolveOptimzTest::RunHorizFilterBitExactCheck() {
326 PrepFilterBuffer(testMaxBlk, testMaxBlk);
327
328 InterpFilterParams filter_params = vp10_get_interp_filter_params(filter_);
329
clang-format3a826f12016-08-11 17:46:05 -0700330 vp10_highbd_convolve_horiz_c(src_, stride, dst_ref_, stride, width_, height_,
331 filter_params, subpel_, x_step_q4, avg_,
332 bit_depth_);
Yi Luo8cacca72016-07-08 15:41:59 -0700333
clang-format3a826f12016-08-11 17:46:05 -0700334 conv_horiz_(src_, stride, dst_, stride, width_, height_, filter_params,
335 subpel_, x_step_q4, avg_, bit_depth_);
Yi Luo8cacca72016-07-08 15:41:59 -0700336
337 DiffFilterBuffer();
338
339 // Note:
340 // Here we need calculate a height which is different from the specified one
341 // and test again.
342 int intermediate_height =
343 (((height_ - 1) * 16 + subpel_) >> SUBPEL_BITS) + filter_params.taps;
344 PrepFilterBuffer(testMaxBlk, testMaxBlk);
345
346 vp10_highbd_convolve_horiz_c(src_, stride, dst_ref_, stride, width_,
347 intermediate_height, filter_params, subpel_,
348 x_step_q4, avg_, bit_depth_);
349
350 conv_horiz_(src_, stride, dst_, stride, width_, intermediate_height,
351 filter_params, subpel_, x_step_q4, avg_, bit_depth_);
352
353 DiffFilterBuffer();
354}
355
356void VP10HbdConvolveOptimzTest::RunVertFilterBitExactCheck() {
357 PrepFilterBuffer(testMaxBlk, testMaxBlk);
358
359 InterpFilterParams filter_params = vp10_get_interp_filter_params(filter_);
360
361 vp10_highbd_convolve_vert_c(src_, stride, dst_ref_, stride, width_, height_,
362 filter_params, subpel_, x_step_q4, avg_,
363 bit_depth_);
364
clang-format3a826f12016-08-11 17:46:05 -0700365 conv_vert_(src_, stride, dst_, stride, width_, height_, filter_params,
366 subpel_, x_step_q4, avg_, bit_depth_);
Yi Luo8cacca72016-07-08 15:41:59 -0700367
368 DiffFilterBuffer();
369}
370
371TEST_P(VP10HbdConvolveOptimzTest, HorizBitExactCheck) {
372 RunHorizFilterBitExactCheck();
373}
374TEST_P(VP10HbdConvolveOptimzTest, VertBitExactCheck) {
375 RunVertFilterBitExactCheck();
376}
377
378#if HAVE_SSE4_1 && CONFIG_EXT_INTERP
379
clang-format3a826f12016-08-11 17:46:05 -0700380const int kBitdepth[] = { 10, 12 };
Yi Luo8cacca72016-07-08 15:41:59 -0700381
382INSTANTIATE_TEST_CASE_P(
383 SSE4_1, VP10HbdConvolveOptimzTest,
clang-format3a826f12016-08-11 17:46:05 -0700384 ::testing::Combine(::testing::Values(vp10_highbd_convolve_horiz_sse4_1),
385 ::testing::Values(vp10_highbd_convolve_vert_sse4_1),
386 ::testing::ValuesIn(kBlockDim),
387 ::testing::ValuesIn(kFilter),
388 ::testing::ValuesIn(kSubpelQ4),
389 ::testing::ValuesIn(kAvg),
390 ::testing::ValuesIn(kBitdepth)));
Yi Luo8cacca72016-07-08 15:41:59 -0700391#endif // HAVE_SSE4_1 && CONFIG_EXT_INTERP
392#endif // CONFIG_VP9_HIGHBITDEPTH
Yi Luo229690a2016-06-13 17:01:17 -0700393} // namespace