Re-worked header files
[aom.git] / test / vp9_quantize_test.cc
blob943c00b870802b2ac8cab04fcddf9aa826b53dc3
1 /*
2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved.
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 */
11 #include <math.h>
12 #include <stdlib.h>
13 #include <string.h>
15 #include "third_party/googletest/src/include/gtest/gtest.h"
17 #include "test/acm_random.h"
18 #include "test/clear_system_state.h"
19 #include "test/register_state_check.h"
20 #include "test/util.h"
21 #include "./vpx_config.h"
22 #include "./vp9_rtcd.h"
23 #include "vp9/common/vp9_entropy.h"
24 #include "vp9/common/vp9_scan.h"
25 #include "vpx/vpx_codec.h"
26 #include "vpx/vpx_integer.h"
28 using libvpx_test::ACMRandom;
30 namespace {
31 #if CONFIG_VP9_HIGHBITDEPTH
32 const int number_of_iterations = 100;
34 typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
35 int skip_block, const int16_t *zbin,
36 const int16_t *round, const int16_t *quant,
37 const int16_t *quant_shift,
38 tran_low_t *qcoeff, tran_low_t *dqcoeff,
39 const int16_t *dequant,
40 uint16_t *eob, const int16_t *scan,
41 const int16_t *iscan);
42 typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t>
43 QuantizeParam;
45 class VP9QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
46 public:
47 virtual ~VP9QuantizeTest() {}
48 virtual void SetUp() {
49 quantize_op_ = GET_PARAM(0);
50 ref_quantize_op_ = GET_PARAM(1);
51 bit_depth_ = GET_PARAM(2);
52 mask_ = (1 << bit_depth_) - 1;
55 virtual void TearDown() { libvpx_test::ClearSystemState(); }
57 protected:
58 vpx_bit_depth_t bit_depth_;
59 int mask_;
60 QuantizeFunc quantize_op_;
61 QuantizeFunc ref_quantize_op_;
64 class VP9Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
65 public:
66 virtual ~VP9Quantize32Test() {}
67 virtual void SetUp() {
68 quantize_op_ = GET_PARAM(0);
69 ref_quantize_op_ = GET_PARAM(1);
70 bit_depth_ = GET_PARAM(2);
71 mask_ = (1 << bit_depth_) - 1;
74 virtual void TearDown() { libvpx_test::ClearSystemState(); }
76 protected:
77 vpx_bit_depth_t bit_depth_;
78 int mask_;
79 QuantizeFunc quantize_op_;
80 QuantizeFunc ref_quantize_op_;
83 TEST_P(VP9QuantizeTest, OperationCheck) {
84 ACMRandom rnd(ACMRandom::DeterministicSeed());
85 DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
86 DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
87 DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
88 DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
89 DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
90 DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
91 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
92 DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
93 DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
94 DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
95 DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
96 DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
97 int err_count_total = 0;
98 int first_failure = -1;
99 for (int i = 0; i < number_of_iterations; ++i) {
100 const int skip_block = i == 0;
101 const TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
102 const TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
103 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
104 const int count = (4 << sz) * (4 << sz); // 16, 64, 256
105 int err_count = 0;
106 *eob_ptr = rnd.Rand16();
107 *ref_eob_ptr = *eob_ptr;
108 for (int j = 0; j < count; j++) {
109 coeff_ptr[j] = rnd.Rand16()&mask_;
111 for (int j = 0; j < 2; j++) {
112 zbin_ptr[j] = rnd.Rand16()&mask_;
113 round_ptr[j] = rnd.Rand16();
114 quant_ptr[j] = rnd.Rand16();
115 quant_shift_ptr[j] = rnd.Rand16();
116 dequant_ptr[j] = rnd.Rand16();
118 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
119 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
120 ref_dqcoeff_ptr, dequant_ptr,
121 ref_eob_ptr, scan_order->scan, scan_order->iscan);
122 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
123 zbin_ptr, round_ptr, quant_ptr,
124 quant_shift_ptr, qcoeff_ptr,
125 dqcoeff_ptr, dequant_ptr, eob_ptr,
126 scan_order->scan, scan_order->iscan));
127 for (int j = 0; j < sz; ++j) {
128 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
129 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
131 err_count += (*ref_eob_ptr != *eob_ptr);
132 if (err_count && !err_count_total) {
133 first_failure = i;
135 err_count_total += err_count;
137 EXPECT_EQ(0, err_count_total)
138 << "Error: Quantization Test, C output doesn't match SSE2 output. "
139 << "First failed at test case " << first_failure;
142 TEST_P(VP9Quantize32Test, OperationCheck) {
143 ACMRandom rnd(ACMRandom::DeterministicSeed());
144 DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
145 DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
146 DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
147 DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
148 DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
149 DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
150 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
151 DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
152 DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
153 DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
154 DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
155 DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
156 int err_count_total = 0;
157 int first_failure = -1;
158 for (int i = 0; i < number_of_iterations; ++i) {
159 const int skip_block = i == 0;
160 const TX_SIZE sz = TX_32X32;
161 const TX_TYPE tx_type = (TX_TYPE)(i % 4);
162 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
163 const int count = (4 << sz) * (4 << sz); // 1024
164 int err_count = 0;
165 *eob_ptr = rnd.Rand16();
166 *ref_eob_ptr = *eob_ptr;
167 for (int j = 0; j < count; j++) {
168 coeff_ptr[j] = rnd.Rand16()&mask_;
170 for (int j = 0; j < 2; j++) {
171 zbin_ptr[j] = rnd.Rand16()&mask_;
172 round_ptr[j] = rnd.Rand16();
173 quant_ptr[j] = rnd.Rand16();
174 quant_shift_ptr[j] = rnd.Rand16();
175 dequant_ptr[j] = rnd.Rand16();
177 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
178 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
179 ref_dqcoeff_ptr, dequant_ptr,
180 ref_eob_ptr, scan_order->scan, scan_order->iscan);
181 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
182 zbin_ptr, round_ptr, quant_ptr,
183 quant_shift_ptr, qcoeff_ptr,
184 dqcoeff_ptr, dequant_ptr, eob_ptr,
185 scan_order->scan, scan_order->iscan));
186 for (int j = 0; j < sz; ++j) {
187 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
188 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
190 err_count += (*ref_eob_ptr != *eob_ptr);
191 if (err_count && !err_count_total) {
192 first_failure = i;
194 err_count_total += err_count;
196 EXPECT_EQ(0, err_count_total)
197 << "Error: Quantization Test, C output doesn't match SSE2 output. "
198 << "First failed at test case " << first_failure;
201 TEST_P(VP9QuantizeTest, EOBCheck) {
202 ACMRandom rnd(ACMRandom::DeterministicSeed());
203 DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[256]);
204 DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
205 DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
206 DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
207 DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
208 DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[256]);
209 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[256]);
210 DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[256]);
211 DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[256]);
212 DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
213 DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
214 DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
215 int err_count_total = 0;
216 int first_failure = -1;
217 for (int i = 0; i < number_of_iterations; ++i) {
218 int skip_block = i == 0;
219 TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
220 TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
221 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
222 int count = (4 << sz) * (4 << sz); // 16, 64, 256
223 int err_count = 0;
224 *eob_ptr = rnd.Rand16();
225 *ref_eob_ptr = *eob_ptr;
226 // Two random entries
227 for (int j = 0; j < count; j++) {
228 coeff_ptr[j] = 0;
230 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
231 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
232 for (int j = 0; j < 2; j++) {
233 zbin_ptr[j] = rnd.Rand16()&mask_;
234 round_ptr[j] = rnd.Rand16();
235 quant_ptr[j] = rnd.Rand16();
236 quant_shift_ptr[j] = rnd.Rand16();
237 dequant_ptr[j] = rnd.Rand16();
240 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
241 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
242 ref_dqcoeff_ptr, dequant_ptr,
243 ref_eob_ptr, scan_order->scan, scan_order->iscan);
244 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
245 zbin_ptr, round_ptr, quant_ptr,
246 quant_shift_ptr, qcoeff_ptr,
247 dqcoeff_ptr, dequant_ptr, eob_ptr,
248 scan_order->scan, scan_order->iscan));
250 for (int j = 0; j < sz; ++j) {
251 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
252 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
254 err_count += (*ref_eob_ptr != *eob_ptr);
255 if (err_count && !err_count_total) {
256 first_failure = i;
258 err_count_total += err_count;
260 EXPECT_EQ(0, err_count_total)
261 << "Error: Quantization Test, C output doesn't match SSE2 output. "
262 << "First failed at test case " << first_failure;
265 TEST_P(VP9Quantize32Test, EOBCheck) {
266 ACMRandom rnd(ACMRandom::DeterministicSeed());
267 DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[1024]);
268 DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
269 DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
270 DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
271 DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
272 DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[1024]);
273 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[1024]);
274 DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[1024]);
275 DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[1024]);
276 DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
277 DECLARE_ALIGNED(16, uint16_t, eob_ptr[1]);
278 DECLARE_ALIGNED(16, uint16_t, ref_eob_ptr[1]);
279 int err_count_total = 0;
280 int first_failure = -1;
281 for (int i = 0; i < number_of_iterations; ++i) {
282 int skip_block = i == 0;
283 TX_SIZE sz = TX_32X32;
284 TX_TYPE tx_type = (TX_TYPE)(i % 4);
285 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
286 int count = (4 << sz) * (4 << sz); // 1024
287 int err_count = 0;
288 *eob_ptr = rnd.Rand16();
289 *ref_eob_ptr = *eob_ptr;
290 for (int j = 0; j < count; j++) {
291 coeff_ptr[j] = 0;
293 // Two random entries
294 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
295 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
296 for (int j = 0; j < 2; j++) {
297 zbin_ptr[j] = rnd.Rand16()&mask_;
298 round_ptr[j] = rnd.Rand16();
299 quant_ptr[j] = rnd.Rand16();
300 quant_shift_ptr[j] = rnd.Rand16();
301 dequant_ptr[j] = rnd.Rand16();
304 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
305 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
306 ref_dqcoeff_ptr, dequant_ptr,
307 ref_eob_ptr, scan_order->scan, scan_order->iscan);
308 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
309 zbin_ptr, round_ptr, quant_ptr,
310 quant_shift_ptr, qcoeff_ptr,
311 dqcoeff_ptr, dequant_ptr, eob_ptr,
312 scan_order->scan, scan_order->iscan));
314 for (int j = 0; j < sz; ++j) {
315 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
316 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
318 err_count += (*ref_eob_ptr != *eob_ptr);
319 if (err_count && !err_count_total) {
320 first_failure = i;
322 err_count_total += err_count;
324 EXPECT_EQ(0, err_count_total)
325 << "Error: Quantization Test, C output doesn't match SSE2 output. "
326 << "First failed at test case " << first_failure;
328 using std::tr1::make_tuple;
330 #if HAVE_SSE2
331 INSTANTIATE_TEST_CASE_P(
332 SSE2, VP9QuantizeTest,
333 ::testing::Values(
334 make_tuple(&vp9_highbd_quantize_b_sse2,
335 &vp9_highbd_quantize_b_c, VPX_BITS_8),
336 make_tuple(&vp9_highbd_quantize_b_sse2,
337 &vp9_highbd_quantize_b_c, VPX_BITS_10),
338 make_tuple(&vp9_highbd_quantize_b_sse2,
339 &vp9_highbd_quantize_b_c, VPX_BITS_12)));
340 INSTANTIATE_TEST_CASE_P(
341 SSE2, VP9Quantize32Test,
342 ::testing::Values(
343 make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
344 &vp9_highbd_quantize_b_32x32_c, VPX_BITS_8),
345 make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
346 &vp9_highbd_quantize_b_32x32_c, VPX_BITS_10),
347 make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
348 &vp9_highbd_quantize_b_32x32_c, VPX_BITS_12)));
349 #endif // HAVE_SSE2
350 #endif // CONFIG_VP9_HIGHBITDEPTH
351 } // namespace