blob: cf10f87393a13b03fdb15b508cfae040ea052adc [file] [log] [blame]
David Barker8295c7c2017-06-02 15:21:43 +01001/*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12#include "test/av1_convolve_2d_test_util.h"
13
Scott LaVarnway8b909182017-12-28 11:39:41 -080014#include "aom_ports/aom_timer.h"
Cheng Chen03c75492017-11-02 16:38:14 -070015#include "av1/common/common_data.h"
Scott LaVarnway8b909182017-12-28 11:39:41 -080016#include "av1/common/convolve.h"
David Barker8295c7c2017-06-02 15:21:43 +010017
James Zern95612802018-03-30 11:37:54 -070018using ::testing::make_tuple;
19using ::testing::tuple;
David Barker8295c7c2017-06-02 15:21:43 +010020
21namespace libaom_test {
22
Linfeng Zhanga3e9c502018-01-09 10:04:20 -080023const int kMaxSize = 128 + 32; // padding
David Barker8295c7c2017-06-02 15:21:43 +010024namespace AV1Convolve2D {
25
26::testing::internal::ParamGenerator<Convolve2DParam> BuildParams(
sarahparker3c38cce2018-03-15 14:12:49 -070027 convolve_2d_func filter, int has_subx, int has_suby) {
28 return ::testing::Combine(::testing::Values(filter),
29 ::testing::Values(has_subx),
30 ::testing::Values(has_suby),
31 ::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL));
David Barker8295c7c2017-06-02 15:21:43 +010032}
33
Linfeng Zhang5f0485b2018-01-09 10:21:57 -080034AV1Convolve2DSrTest::~AV1Convolve2DSrTest() {}
35void AV1Convolve2DSrTest::SetUp() {
36 rnd_.Reset(ACMRandom::DeterministicSeed());
37}
38
39void AV1Convolve2DSrTest::TearDown() { libaom_test::ClearSystemState(); }
40
41void AV1Convolve2DSrTest::RunCheckOutput(convolve_2d_func test_impl) {
42 const int w = kMaxSize, h = kMaxSize;
43 const int has_subx = GET_PARAM(1);
44 const int has_suby = GET_PARAM(2);
sarahparker3c38cce2018-03-15 14:12:49 -070045 const int block_idx = GET_PARAM(3);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -080046 int hfilter, vfilter, subx, suby;
47 uint8_t input[kMaxSize * kMaxSize];
48 DECLARE_ALIGNED(32, uint8_t, output[MAX_SB_SQUARE]);
49 DECLARE_ALIGNED(32, uint8_t, output2[MAX_SB_SQUARE]);
50
Linfeng Zhang5f0485b2018-01-09 10:21:57 -080051 for (int i = 0; i < h; ++i)
52 for (int j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand8();
53 for (int i = 0; i < MAX_SB_SQUARE; ++i)
54 output[i] = output2[i] = rnd_.Rand31();
55
Sarah Parker30d4e532018-03-14 17:53:39 -070056 // Make sure that sizes 2xN and Nx2 are also tested for chroma.
57 const int num_sizes =
58 (block_size_wide[block_idx] == 4 || block_size_high[block_idx] == 4) ? 2
59 : 1;
60 for (int shift = 0; shift < num_sizes; ++shift) { // luma and chroma
61 const int out_w = block_size_wide[block_idx] >> shift;
62 const int out_h = block_size_high[block_idx] >> shift;
63 for (hfilter = EIGHTTAP_REGULAR; hfilter < INTERP_FILTERS_ALL; ++hfilter) {
64 for (vfilter = EIGHTTAP_REGULAR; vfilter < INTERP_FILTERS_ALL;
65 ++vfilter) {
66 InterpFilterParams filter_params_x =
67 av1_get_interp_filter_params((InterpFilter)hfilter);
68 InterpFilterParams filter_params_y =
69 av1_get_interp_filter_params((InterpFilter)vfilter);
70 for (int do_average = 0; do_average < 1; ++do_average) {
71 ConvolveParams conv_params1 =
72 get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, 8);
73 ConvolveParams conv_params2 =
74 get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, 8);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -080075
Sarah Parker30d4e532018-03-14 17:53:39 -070076 const int subx_range = has_subx ? 16 : 1;
77 const int suby_range = has_suby ? 16 : 1;
78 for (subx = 0; subx < subx_range; ++subx) {
79 for (suby = 0; suby < suby_range; ++suby) {
80 // Choose random locations within the source block
81 const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7);
82 const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7);
83 av1_convolve_2d_sr_c(input + offset_r * w + offset_c, w, output,
84 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
85 &filter_params_y, subx, suby, &conv_params1);
86 test_impl(input + offset_r * w + offset_c, w, output2,
87 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
88 &filter_params_y, subx, suby, &conv_params2);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -080089
Sarah Parker30d4e532018-03-14 17:53:39 -070090 if (memcmp(output, output2, sizeof(output))) {
91 for (int i = 0; i < MAX_SB_SIZE; ++i) {
92 for (int j = 0; j < MAX_SB_SIZE; ++j) {
93 int idx = i * MAX_SB_SIZE + j;
94 ASSERT_EQ(output[idx], output2[idx])
95 << out_w << "x" << out_h << " Pixel mismatch at index "
96 << idx << " = (" << i << ", " << j
97 << "), sub pixel offset = (" << suby << ", " << subx
98 << ")";
Linfeng Zhang5f0485b2018-01-09 10:21:57 -080099 }
100 }
101 }
102 }
103 }
104 }
105 }
106 }
107 }
108}
109
110void AV1Convolve2DSrTest::RunSpeedTest(convolve_2d_func test_impl) {
111 const int w = kMaxSize, h = kMaxSize;
112 const int has_subx = GET_PARAM(1);
113 const int has_suby = GET_PARAM(2);
sarahparker3c38cce2018-03-15 14:12:49 -0700114 const int block_idx = GET_PARAM(3);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -0800115
116 uint8_t input[kMaxSize * kMaxSize];
117 DECLARE_ALIGNED(32, uint8_t, output[MAX_SB_SQUARE]);
118
119 for (int i = 0; i < h; ++i)
120 for (int j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand8();
121
122 int hfilter = EIGHTTAP_REGULAR, vfilter = EIGHTTAP_REGULAR;
123 int subx = 0, suby = 0;
124
125 InterpFilterParams filter_params_x =
126 av1_get_interp_filter_params((InterpFilter)hfilter);
127 InterpFilterParams filter_params_y =
128 av1_get_interp_filter_params((InterpFilter)vfilter);
129 const int do_average = 0;
130 ConvolveParams conv_params2 =
Debargha Mukherjee7be4de42018-02-18 03:37:23 -0800131 get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, 8);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -0800132
Sarah Parker30d4e532018-03-14 17:53:39 -0700133 // Make sure that sizes 2xN and Nx2 are also tested for chroma.
134 const int num_sizes =
135 (block_size_wide[block_idx] == 4 || block_size_high[block_idx] == 4) ? 2
136 : 1;
137 for (int shift = 0; shift < num_sizes; ++shift) { // luma and chroma
138 const int out_w = block_size_wide[block_idx] >> shift;
139 const int out_h = block_size_high[block_idx] >> shift;
140 const int num_loops = 1000000000 / (out_w + out_h);
141 aom_usec_timer timer;
142 aom_usec_timer_start(&timer);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -0800143
Sarah Parker30d4e532018-03-14 17:53:39 -0700144 for (int i = 0; i < num_loops; ++i)
145 test_impl(input, w, output, MAX_SB_SIZE, out_w, out_h, &filter_params_x,
146 &filter_params_y, subx, suby, &conv_params2);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -0800147
Sarah Parker30d4e532018-03-14 17:53:39 -0700148 aom_usec_timer_mark(&timer);
149 const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
sarahparker3c38cce2018-03-15 14:12:49 -0700150 printf("%d,%d convolve %3dx%-3d: %7.2f us\n", has_subx, has_suby, out_w,
Sarah Parker30d4e532018-03-14 17:53:39 -0700151 out_h, 1000.0 * elapsed_time / num_loops);
Linfeng Zhang5f0485b2018-01-09 10:21:57 -0800152 }
153}
154
Cheng Chen56d8b952017-11-03 18:55:55 -0700155AV1JntConvolve2DTest::~AV1JntConvolve2DTest() {}
156void AV1JntConvolve2DTest::SetUp() {
157 rnd_.Reset(ACMRandom::DeterministicSeed());
158}
159
160void AV1JntConvolve2DTest::TearDown() { libaom_test::ClearSystemState(); }
161
162void AV1JntConvolve2DTest::RunCheckOutput(convolve_2d_func test_impl) {
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800163 const int w = kMaxSize, h = kMaxSize;
164 const int has_subx = GET_PARAM(1);
165 const int has_suby = GET_PARAM(2);
sarahparker3c38cce2018-03-15 14:12:49 -0700166 const int block_idx = GET_PARAM(3);
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800167 int hfilter, vfilter, subx, suby;
168 uint8_t input[kMaxSize * kMaxSize];
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530169 DECLARE_ALIGNED(32, CONV_BUF_TYPE, output1[MAX_SB_SQUARE]);
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800170 DECLARE_ALIGNED(32, CONV_BUF_TYPE, output2[MAX_SB_SQUARE]);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530171 DECLARE_ALIGNED(16, uint8_t, output8_1[MAX_SB_SQUARE]);
172 DECLARE_ALIGNED(16, uint8_t, output8_2[MAX_SB_SQUARE]);
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800173
Linfeng Zhang5f0485b2018-01-09 10:21:57 -0800174 for (int i = 0; i < h; ++i)
175 for (int j = 0; j < w; ++j) input[i * w + j] = rnd_.Rand8();
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530176 for (int i = 0; i < MAX_SB_SQUARE; ++i) {
177 output1[i] = output2[i] = rnd_.Rand16();
178 output8_1[i] = output8_2[i] = rnd_.Rand8();
179 }
Cheng Chen03c75492017-11-02 16:38:14 -0700180
Sarah Parker30d4e532018-03-14 17:53:39 -0700181 const int out_w = block_size_wide[block_idx];
182 const int out_h = block_size_high[block_idx];
183 for (hfilter = EIGHTTAP_REGULAR; hfilter < INTERP_FILTERS_ALL; ++hfilter) {
184 for (vfilter = EIGHTTAP_REGULAR; vfilter < INTERP_FILTERS_ALL; ++vfilter) {
185 InterpFilterParams filter_params_x =
186 av1_get_interp_filter_params((InterpFilter)hfilter);
187 InterpFilterParams filter_params_y =
188 av1_get_interp_filter_params((InterpFilter)vfilter);
189 for (int do_average = 0; do_average <= 1; ++do_average) {
190 ConvolveParams conv_params1 = get_conv_params_no_round(
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530191 0, do_average, 0, output1, MAX_SB_SIZE, 1, 8);
Sarah Parker30d4e532018-03-14 17:53:39 -0700192 ConvolveParams conv_params2 = get_conv_params_no_round(
193 0, do_average, 0, output2, MAX_SB_SIZE, 1, 8);
Cheng Chen03c75492017-11-02 16:38:14 -0700194
Sarah Parker30d4e532018-03-14 17:53:39 -0700195 // Test special case where jnt_comp_avg is not used
196 conv_params1.use_jnt_comp_avg = 0;
197 conv_params2.use_jnt_comp_avg = 0;
Cheng Chen03c75492017-11-02 16:38:14 -0700198
Sarah Parker30d4e532018-03-14 17:53:39 -0700199 const int subx_range = has_subx ? 16 : 1;
200 const int suby_range = has_suby ? 16 : 1;
201 for (subx = 0; subx < subx_range; ++subx) {
202 for (suby = 0; suby < suby_range; ++suby) {
203 // Choose random locations within the source block
204 const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7);
205 const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530206 av1_jnt_convolve_2d_c(input + offset_r * w + offset_c, w, output8_1,
207 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
Sarah Parker30d4e532018-03-14 17:53:39 -0700208 &filter_params_y, subx, suby, &conv_params1);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530209 test_impl(input + offset_r * w + offset_c, w, output8_2,
210 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
211 &filter_params_y, subx, suby, &conv_params2);
Cheng Chen03c75492017-11-02 16:38:14 -0700212
Sarah Parker30d4e532018-03-14 17:53:39 -0700213 for (int i = 0; i < out_h; ++i) {
214 for (int j = 0; j < out_w; ++j) {
215 int idx = i * MAX_SB_SIZE + j;
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530216 ASSERT_EQ(output1[idx], output2[idx])
Sarah Parker30d4e532018-03-14 17:53:39 -0700217 << "Mismatch at unit tests for av1_jnt_convolve_2d\n"
218 << out_w << "x" << out_h << " Pixel mismatch at index "
219 << idx << " = (" << i << ", " << j
220 << "), sub pixel offset = (" << suby << ", " << subx << ")";
Cheng Chen03c75492017-11-02 16:38:14 -0700221 }
222 }
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530223
224 if (memcmp(output8_1, output8_2, sizeof(output8_1))) {
225 for (int i = 0; i < MAX_SB_SIZE; ++i) {
226 for (int j = 0; j < MAX_SB_SIZE; ++j) {
227 int idx = i * MAX_SB_SIZE + j;
228 ASSERT_EQ(output8_1[idx], output8_2[idx])
229 << out_w << "x" << out_h << " Pixel mismatch at index "
230 << idx << " = (" << i << ", " << j
231 << "), sub pixel offset = (" << suby << ", " << subx
232 << ")";
233 }
234 }
235 }
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800236 }
Sarah Parker30d4e532018-03-14 17:53:39 -0700237 }
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800238
Sarah Parker30d4e532018-03-14 17:53:39 -0700239 // Test different combination of fwd and bck offset weights
240 for (int k = 0; k < 2; ++k) {
241 for (int l = 0; l < 4; ++l) {
242 conv_params1.use_jnt_comp_avg = 1;
243 conv_params2.use_jnt_comp_avg = 1;
244 conv_params1.fwd_offset = quant_dist_lookup_table[k][l][0];
245 conv_params1.bck_offset = quant_dist_lookup_table[k][l][1];
246 conv_params2.fwd_offset = quant_dist_lookup_table[k][l][0];
247 conv_params2.bck_offset = quant_dist_lookup_table[k][l][1];
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800248
Sarah Parker30d4e532018-03-14 17:53:39 -0700249 for (subx = 0; subx < subx_range; ++subx) {
250 for (suby = 0; suby < suby_range; ++suby) {
251 // Choose random locations within the source block
252 const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7);
253 const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530254 av1_jnt_convolve_2d_c(input + offset_r * w + offset_c, w,
255 output8_1, MAX_SB_SIZE, out_w, out_h,
256 &filter_params_x, &filter_params_y, subx,
257 suby, &conv_params1);
258 test_impl(input + offset_r * w + offset_c, w, output8_2,
259 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
260 &filter_params_y, subx, suby, &conv_params2);
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800261
Sarah Parker30d4e532018-03-14 17:53:39 -0700262 for (int i = 0; i < out_h; ++i) {
263 for (int j = 0; j < out_w; ++j) {
264 int idx = i * MAX_SB_SIZE + j;
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530265 ASSERT_EQ(output1[idx], output2[idx])
Sarah Parker30d4e532018-03-14 17:53:39 -0700266 << "Mismatch at unit tests for "
267 "av1_jnt_convolve_2d\n"
268 << out_w << "x" << out_h << " Pixel mismatch at index "
269 << idx << " = (" << i << ", " << j
270 << "), sub pixel offset = (" << suby << ", " << subx
271 << ")";
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800272 }
273 }
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530274 if (memcmp(output8_1, output8_2, sizeof(output8_1))) {
275 for (int i = 0; i < MAX_SB_SIZE; ++i) {
276 for (int j = 0; j < MAX_SB_SIZE; ++j) {
277 int idx = i * MAX_SB_SIZE + j;
278 ASSERT_EQ(output8_1[idx], output8_2[idx])
279 << out_w << "x" << out_h
280 << " Pixel mismatch at index " << idx << " = (" << i
281 << ", " << j << "), sub pixel offset = (" << suby
282 << ", " << subx << ")";
283 }
284 }
285 }
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800286 }
287 }
288 }
Cheng Chen03c75492017-11-02 16:38:14 -0700289 }
290 }
291 }
292 }
Cheng Chen03c75492017-11-02 16:38:14 -0700293}
David Barker8295c7c2017-06-02 15:21:43 +0100294} // namespace AV1Convolve2D
295
David Barker8295c7c2017-06-02 15:21:43 +0100296namespace AV1HighbdConvolve2D {
David Barker8295c7c2017-06-02 15:21:43 +0100297::testing::internal::ParamGenerator<HighbdConvolve2DParam> BuildParams(
sarahparker3c38cce2018-03-15 14:12:49 -0700298 highbd_convolve_2d_func filter, int has_subx, int has_suby) {
299 return ::testing::Combine(
300 ::testing::Range(8, 12, 2), ::testing::Values(filter),
301 ::testing::Values(has_subx), ::testing::Values(has_suby),
302 ::testing::Range(BLOCK_4X4, BLOCK_SIZES_ALL));
David Barker8295c7c2017-06-02 15:21:43 +0100303}
304
Cherma Rajan A09d45302018-02-22 17:25:15 +0530305AV1HighbdConvolve2DSrTest::~AV1HighbdConvolve2DSrTest() {}
306void AV1HighbdConvolve2DSrTest::SetUp() {
307 rnd_.Reset(ACMRandom::DeterministicSeed());
308}
309
310void AV1HighbdConvolve2DSrTest::TearDown() { libaom_test::ClearSystemState(); }
311
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530312void AV1HighbdConvolve2DSrTest::RunSpeedTest(
313 highbd_convolve_2d_func test_impl) {
314 const int w = kMaxSize, h = kMaxSize;
315 const int bd = GET_PARAM(0);
Ravi Chaudhary79363c82018-03-08 18:46:41 +0530316 const int has_subx = GET_PARAM(2);
317 const int has_suby = GET_PARAM(3);
sarahparker3c38cce2018-03-15 14:12:49 -0700318 const int block_idx = GET_PARAM(4);
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530319 int hfilter, vfilter, subx, suby;
320 uint16_t input[kMaxSize * kMaxSize];
321 DECLARE_ALIGNED(32, uint16_t, output[MAX_SB_SQUARE]);
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530322
323 for (int i = 0; i < h; ++i)
324 for (int j = 0; j < w; ++j)
325 input[i * w + j] = rnd_.Rand16() & ((1 << bd) - 1);
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530326
327 hfilter = EIGHTTAP_REGULAR;
328 vfilter = EIGHTTAP_REGULAR;
329 int do_average = 0;
330
Ravi Chaudhary79363c82018-03-08 18:46:41 +0530331 const int offset_r = 3;
332 const int offset_c = 3;
333 subx = 0;
334 suby = 0;
335
336 InterpFilterParams filter_params_x =
337 av1_get_interp_filter_params((InterpFilter)hfilter);
338 InterpFilterParams filter_params_y =
339 av1_get_interp_filter_params((InterpFilter)vfilter);
340
341 ConvolveParams conv_params =
342 get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, bd);
343
Sarah Parker30d4e532018-03-14 17:53:39 -0700344 // Make sure that sizes 2xN and Nx2 are also tested for chroma.
345 const int num_sizes =
346 (block_size_wide[block_idx] == 4 || block_size_high[block_idx] == 4) ? 2
347 : 1;
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530348
Sarah Parker30d4e532018-03-14 17:53:39 -0700349 for (int shift = 0; shift < num_sizes; ++shift) { // luma and chroma
350 const int out_w = block_size_wide[block_idx] >> shift;
351 const int out_h = block_size_high[block_idx] >> shift;
352 const int num_loops = 1000000000 / (out_w + out_h);
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530353
Sarah Parker30d4e532018-03-14 17:53:39 -0700354 aom_usec_timer timer;
355 aom_usec_timer_start(&timer);
356 for (int i = 0; i < num_loops; ++i)
357 test_impl(input + offset_r * w + offset_c, w, output, MAX_SB_SIZE, out_w,
358 out_h, &filter_params_x, &filter_params_y, subx, suby,
359 &conv_params, bd);
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530360
Sarah Parker30d4e532018-03-14 17:53:39 -0700361 aom_usec_timer_mark(&timer);
362 const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
sarahparker3c38cce2018-03-15 14:12:49 -0700363 printf("%d,%d convolve %3dx%-3d: %7.2f us\n", has_subx, has_suby, out_w,
Sarah Parker30d4e532018-03-14 17:53:39 -0700364 out_h, 1000.0 * elapsed_time / num_loops);
Ravi Chaudharybe4dd102018-03-07 09:19:17 +0530365 }
366}
367
Cherma Rajan A09d45302018-02-22 17:25:15 +0530368void AV1HighbdConvolve2DSrTest::RunCheckOutput(
369 highbd_convolve_2d_func test_impl) {
370 const int w = kMaxSize, h = kMaxSize;
371 const int bd = GET_PARAM(0);
372 const int has_subx = GET_PARAM(2);
373 const int has_suby = GET_PARAM(3);
sarahparker3c38cce2018-03-15 14:12:49 -0700374 const int block_idx = GET_PARAM(4);
Cherma Rajan A09d45302018-02-22 17:25:15 +0530375 int hfilter, vfilter, subx, suby;
376 uint16_t input[kMaxSize * kMaxSize];
377 DECLARE_ALIGNED(32, uint16_t, output[MAX_SB_SQUARE]);
378 DECLARE_ALIGNED(32, uint16_t, output2[MAX_SB_SQUARE]);
Cherma Rajan A09d45302018-02-22 17:25:15 +0530379
380 for (int i = 0; i < h; ++i)
381 for (int j = 0; j < w; ++j)
382 input[i * w + j] = rnd_.Rand16() & ((1 << bd) - 1);
383 for (int i = 0; i < MAX_SB_SQUARE; ++i)
384 output[i] = output2[i] = rnd_.Rand31();
385
Sarah Parker30d4e532018-03-14 17:53:39 -0700386 // Make sure that sizes 2xN and Nx2 are also tested for chroma.
387 const int num_sizes =
388 (block_size_wide[block_idx] == 4 || block_size_high[block_idx] == 4) ? 2
389 : 1;
390 for (int shift = 0; shift < num_sizes; ++shift) { // luma and chroma
391 const int out_w = block_size_wide[block_idx] >> shift;
392 const int out_h = block_size_high[block_idx] >> shift;
393 for (hfilter = EIGHTTAP_REGULAR; hfilter < INTERP_FILTERS_ALL; ++hfilter) {
394 for (vfilter = EIGHTTAP_REGULAR; vfilter < INTERP_FILTERS_ALL;
395 ++vfilter) {
396 InterpFilterParams filter_params_x =
397 av1_get_interp_filter_params((InterpFilter)hfilter);
398 InterpFilterParams filter_params_y =
399 av1_get_interp_filter_params((InterpFilter)vfilter);
400 for (int do_average = 0; do_average < 1; ++do_average) {
401 ConvolveParams conv_params1 =
402 get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, bd);
403 ConvolveParams conv_params2 =
404 get_conv_params_no_round(0, do_average, 0, NULL, 0, 0, bd);
Cherma Rajan A09d45302018-02-22 17:25:15 +0530405
Sarah Parker30d4e532018-03-14 17:53:39 -0700406 const int subx_range = has_subx ? 16 : 1;
407 const int suby_range = has_suby ? 16 : 1;
408 for (subx = 0; subx < subx_range; ++subx) {
409 for (suby = 0; suby < suby_range; ++suby) {
410 // Choose random locations within the source block
411 const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7);
412 const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7);
413 av1_highbd_convolve_2d_sr_c(input + offset_r * w + offset_c, w,
414 output, MAX_SB_SIZE, out_w, out_h,
415 &filter_params_x, &filter_params_y,
416 subx, suby, &conv_params1, bd);
417 test_impl(input + offset_r * w + offset_c, w, output2,
418 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
419 &filter_params_y, subx, suby, &conv_params2, bd);
Cherma Rajan A09d45302018-02-22 17:25:15 +0530420
Sarah Parker30d4e532018-03-14 17:53:39 -0700421 if (memcmp(output, output2, sizeof(output))) {
422 for (int i = 0; i < MAX_SB_SIZE; ++i) {
423 for (int j = 0; j < MAX_SB_SIZE; ++j) {
424 int idx = i * MAX_SB_SIZE + j;
425 ASSERT_EQ(output[idx], output2[idx])
426 << out_w << "x" << out_h << " Pixel mismatch at index "
427 << idx << " = (" << i << ", " << j
428 << "), sub pixel offset = (" << suby << ", " << subx
429 << ")";
Cherma Rajan A09d45302018-02-22 17:25:15 +0530430 }
431 }
432 }
433 }
434 }
435 }
436 }
437 }
438 }
439}
440
Cheng Chen56d8b952017-11-03 18:55:55 -0700441AV1HighbdJntConvolve2DTest::~AV1HighbdJntConvolve2DTest() {}
442void AV1HighbdJntConvolve2DTest::SetUp() {
443 rnd_.Reset(ACMRandom::DeterministicSeed());
444}
445
446void AV1HighbdJntConvolve2DTest::TearDown() { libaom_test::ClearSystemState(); }
447
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530448void AV1HighbdJntConvolve2DTest::RunSpeedTest(
449 highbd_convolve_2d_func test_impl) {
450 const int w = kMaxSize, h = kMaxSize;
451 const int bd = GET_PARAM(0);
sarahparker3c38cce2018-03-15 14:12:49 -0700452 const int block_idx = GET_PARAM(4);
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530453 int hfilter, vfilter, subx, suby;
454 uint16_t input[kMaxSize * kMaxSize];
455 DECLARE_ALIGNED(32, CONV_BUF_TYPE, output[MAX_SB_SQUARE]);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530456 DECLARE_ALIGNED(32, uint16_t, output16[MAX_SB_SQUARE]);
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530457
458 for (int i = 0; i < h; ++i)
459 for (int j = 0; j < w; ++j)
460 input[i * w + j] = rnd_.Rand16() & ((1 << bd) - 1);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530461 for (int i = 0; i < MAX_SB_SQUARE; ++i) output[i] = rnd_.Rand16();
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530462 hfilter = EIGHTTAP_REGULAR;
463 vfilter = EIGHTTAP_REGULAR;
464 int do_average = 0;
Sarah Parker30d4e532018-03-14 17:53:39 -0700465 const int out_w = block_size_wide[block_idx];
466 const int out_h = block_size_high[block_idx];
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530467
Sarah Parker30d4e532018-03-14 17:53:39 -0700468 InterpFilterParams filter_params_x =
469 av1_get_interp_filter_params((InterpFilter)hfilter);
470 InterpFilterParams filter_params_y =
471 av1_get_interp_filter_params((InterpFilter)vfilter);
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530472
Sarah Parker30d4e532018-03-14 17:53:39 -0700473 ConvolveParams conv_params =
474 get_conv_params_no_round(0, do_average, 0, output, MAX_SB_SIZE, 1, bd);
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530475
Sarah Parker30d4e532018-03-14 17:53:39 -0700476 // Test special case where jnt_comp_avg is not used
477 conv_params.use_jnt_comp_avg = 0;
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530478
Sarah Parker30d4e532018-03-14 17:53:39 -0700479 subx = 0;
480 suby = 0;
481 // Choose random locations within the source block
482 const int offset_r = 3;
483 const int offset_c = 3;
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530484
Sarah Parker30d4e532018-03-14 17:53:39 -0700485 const int num_loops = 1000000000 / (out_w + out_h);
486 aom_usec_timer timer;
487 aom_usec_timer_start(&timer);
488 for (int i = 0; i < num_loops; ++i)
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530489 test_impl(input + offset_r * w + offset_c, w, output16, MAX_SB_SIZE, out_w,
490 out_h, &filter_params_x, &filter_params_y, subx, suby,
491 &conv_params, bd);
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530492
Sarah Parker30d4e532018-03-14 17:53:39 -0700493 aom_usec_timer_mark(&timer);
494 const int elapsed_time = static_cast<int>(aom_usec_timer_elapsed(&timer));
sarahparker3c38cce2018-03-15 14:12:49 -0700495 printf("convolve %3dx%-3d: %7.2f us\n", out_w, out_h,
Sarah Parker30d4e532018-03-14 17:53:39 -0700496 1000.0 * elapsed_time / num_loops);
Ravi Chaudharybb6a7692018-03-02 15:30:05 +0530497}
498
Cheng Chen56d8b952017-11-03 18:55:55 -0700499void AV1HighbdJntConvolve2DTest::RunCheckOutput(
500 highbd_convolve_2d_func test_impl) {
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800501 const int w = kMaxSize, h = kMaxSize;
502 const int bd = GET_PARAM(0);
Cherma Rajan Acb4622d2018-02-23 16:17:08 +0530503 const int has_subx = GET_PARAM(2);
504 const int has_suby = GET_PARAM(3);
sarahparker3c38cce2018-03-15 14:12:49 -0700505 const int block_idx = GET_PARAM(4);
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800506 int hfilter, vfilter, subx, suby;
507 uint16_t input[kMaxSize * kMaxSize];
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530508 DECLARE_ALIGNED(32, CONV_BUF_TYPE, output1[MAX_SB_SQUARE]);
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800509 DECLARE_ALIGNED(32, CONV_BUF_TYPE, output2[MAX_SB_SQUARE]);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530510 DECLARE_ALIGNED(32, uint16_t, output16_1[MAX_SB_SQUARE]);
511 DECLARE_ALIGNED(32, uint16_t, output16_2[MAX_SB_SQUARE]);
Cheng Chen56d8b952017-11-03 18:55:55 -0700512
Linfeng Zhang5f0485b2018-01-09 10:21:57 -0800513 for (int i = 0; i < h; ++i)
514 for (int j = 0; j < w; ++j)
515 input[i * w + j] = rnd_.Rand16() & ((1 << bd) - 1);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530516 for (int i = 0; i < MAX_SB_SQUARE; ++i) {
517 output1[i] = output2[i] = rnd_.Rand16();
518 output16_1[i] = output16_2[i] = rnd_.Rand16();
519 }
Cheng Chen56d8b952017-11-03 18:55:55 -0700520
Sarah Parker30d4e532018-03-14 17:53:39 -0700521 const int out_w = block_size_wide[block_idx];
522 const int out_h = block_size_high[block_idx];
523 for (hfilter = EIGHTTAP_REGULAR; hfilter < INTERP_FILTERS_ALL; ++hfilter) {
524 for (vfilter = EIGHTTAP_REGULAR; vfilter < INTERP_FILTERS_ALL; ++vfilter) {
525 InterpFilterParams filter_params_x =
526 av1_get_interp_filter_params((InterpFilter)hfilter);
527 InterpFilterParams filter_params_y =
528 av1_get_interp_filter_params((InterpFilter)vfilter);
529 for (int do_average = 0; do_average <= 1; ++do_average) {
530 ConvolveParams conv_params1 = get_conv_params_no_round(
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530531 0, do_average, 0, output1, MAX_SB_SIZE, 1, bd);
Sarah Parker30d4e532018-03-14 17:53:39 -0700532 ConvolveParams conv_params2 = get_conv_params_no_round(
533 0, do_average, 0, output2, MAX_SB_SIZE, 1, bd);
Cheng Chen56d8b952017-11-03 18:55:55 -0700534
Sarah Parker30d4e532018-03-14 17:53:39 -0700535 // Test special case where jnt_comp_avg is not used
536 conv_params1.use_jnt_comp_avg = 0;
537 conv_params2.use_jnt_comp_avg = 0;
Cheng Chen56d8b952017-11-03 18:55:55 -0700538
Sarah Parker30d4e532018-03-14 17:53:39 -0700539 const int subx_range = has_subx ? 16 : 1;
540 const int suby_range = has_suby ? 16 : 1;
541 for (subx = 0; subx < subx_range; ++subx) {
542 for (suby = 0; suby < suby_range; ++suby) {
543 // Choose random locations within the source block
544 const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7);
545 const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7);
546 av1_highbd_jnt_convolve_2d_c(input + offset_r * w + offset_c, w,
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530547 output16_1, MAX_SB_SIZE, out_w, out_h,
Sarah Parker30d4e532018-03-14 17:53:39 -0700548 &filter_params_x, &filter_params_y,
549 subx, suby, &conv_params1, bd);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530550 test_impl(input + offset_r * w + offset_c, w, output16_2,
551 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
552 &filter_params_y, subx, suby, &conv_params2, bd);
Cheng Chen56d8b952017-11-03 18:55:55 -0700553
Sarah Parker30d4e532018-03-14 17:53:39 -0700554 for (int i = 0; i < out_h; ++i) {
555 for (int j = 0; j < out_w; ++j) {
556 int idx = i * MAX_SB_SIZE + j;
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530557 ASSERT_EQ(output1[idx], output2[idx])
Sarah Parker30d4e532018-03-14 17:53:39 -0700558 << out_w << "x" << out_h << " Pixel mismatch at index "
559 << idx << " = (" << i << ", " << j
560 << "), sub pixel offset = (" << suby << ", " << subx << ")";
Cheng Chen56d8b952017-11-03 18:55:55 -0700561 }
562 }
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530563
564 if (memcmp(output16_1, output16_2, sizeof(output16_1))) {
565 for (int i = 0; i < MAX_SB_SIZE; ++i) {
566 for (int j = 0; j < MAX_SB_SIZE; ++j) {
567 int idx = i * MAX_SB_SIZE + j;
568 ASSERT_EQ(output16_1[idx], output16_2[idx])
569 << out_w << "x" << out_h << " Pixel mismatch at index "
570 << idx << " = (" << i << ", " << j
571 << "), sub pixel offset = (" << suby << ", " << subx
572 << ")";
573 }
574 }
575 }
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800576 }
Sarah Parker30d4e532018-03-14 17:53:39 -0700577 }
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800578
Sarah Parker30d4e532018-03-14 17:53:39 -0700579 // Test different combination of fwd and bck offset weights
580 for (int k = 0; k < 2; ++k) {
581 for (int l = 0; l < 4; ++l) {
582 conv_params1.use_jnt_comp_avg = 1;
583 conv_params2.use_jnt_comp_avg = 1;
584 conv_params1.fwd_offset = quant_dist_lookup_table[k][l][0];
585 conv_params1.bck_offset = quant_dist_lookup_table[k][l][1];
586 conv_params2.fwd_offset = quant_dist_lookup_table[k][l][0];
587 conv_params2.bck_offset = quant_dist_lookup_table[k][l][1];
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800588
Sarah Parker30d4e532018-03-14 17:53:39 -0700589 const int subx_range = has_subx ? 16 : 1;
590 const int suby_range = has_suby ? 16 : 1;
591 for (subx = 0; subx < subx_range; ++subx) {
592 for (suby = 0; suby < suby_range; ++suby) {
593 // Choose random locations within the source block
594 const int offset_r = 3 + rnd_.PseudoUniform(h - out_h - 7);
595 const int offset_c = 3 + rnd_.PseudoUniform(w - out_w - 7);
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530596 av1_highbd_jnt_convolve_2d_c(
597 input + offset_r * w + offset_c, w, output16_1, MAX_SB_SIZE,
598 out_w, out_h, &filter_params_x, &filter_params_y, subx,
599 suby, &conv_params1, bd);
600 test_impl(input + offset_r * w + offset_c, w, output16_2,
601 MAX_SB_SIZE, out_w, out_h, &filter_params_x,
602 &filter_params_y, subx, suby, &conv_params2, bd);
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800603
Sarah Parker30d4e532018-03-14 17:53:39 -0700604 for (int i = 0; i < out_h; ++i) {
605 for (int j = 0; j < out_w; ++j) {
606 int idx = i * MAX_SB_SIZE + j;
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530607 ASSERT_EQ(output1[idx], output2[idx])
Sarah Parker30d4e532018-03-14 17:53:39 -0700608 << out_w << "x" << out_h << " Pixel mismatch at index "
609 << idx << " = (" << i << ", " << j
610 << "), sub pixel offset = (" << suby << ", " << subx
611 << ")";
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800612 }
613 }
Cherma Rajan Aa7be3682018-03-20 10:00:51 +0530614
615 if (memcmp(output16_1, output16_2, sizeof(output16_1))) {
616 for (int i = 0; i < MAX_SB_SIZE; ++i) {
617 for (int j = 0; j < MAX_SB_SIZE; ++j) {
618 int idx = i * MAX_SB_SIZE + j;
619 ASSERT_EQ(output16_1[idx], output16_2[idx])
620 << out_w << "x" << out_h
621 << " Pixel mismatch at index " << idx << " = (" << i
622 << ", " << j << "), sub pixel offset = (" << suby
623 << ", " << subx << ")";
624 }
625 }
626 }
Linfeng Zhanga3e9c502018-01-09 10:04:20 -0800627 }
628 }
629 }
Cheng Chen56d8b952017-11-03 18:55:55 -0700630 }
631 }
632 }
633 }
Cheng Chen56d8b952017-11-03 18:55:55 -0700634}
David Barker8295c7c2017-06-02 15:21:43 +0100635} // namespace AV1HighbdConvolve2D
David Barker8295c7c2017-06-02 15:21:43 +0100636} // namespace libaom_test