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.
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 "vpx/vpx_integer.h"
26 using libvpx_test::ACMRandom;
29 #if CONFIG_VP9_HIGHBITDEPTH
30 const int number_of_iterations = 100;
32 typedef void (*QuantizeFunc)(const tran_low_t *coeff, intptr_t count,
33 int skip_block, const int16_t *zbin,
34 const int16_t *round, const int16_t *quant,
35 const int16_t *quant_shift,
36 tran_low_t *qcoeff, tran_low_t *dqcoeff,
37 const int16_t *dequant, int zbin_oq_value,
38 uint16_t *eob, const int16_t *scan,
39 const int16_t *iscan);
40 typedef std::tr1::tuple<QuantizeFunc, QuantizeFunc, vpx_bit_depth_t>
43 class VP9QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
45 virtual ~VP9QuantizeTest() {}
46 virtual void SetUp() {
47 quantize_op_ = GET_PARAM(0);
48 ref_quantize_op_ = GET_PARAM(1);
49 bit_depth_ = GET_PARAM(2);
50 mask_ = (1 << bit_depth_) - 1;
53 virtual void TearDown() { libvpx_test::ClearSystemState(); }
56 vpx_bit_depth_t bit_depth_;
58 QuantizeFunc quantize_op_;
59 QuantizeFunc ref_quantize_op_;
62 class VP9Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
64 virtual ~VP9Quantize32Test() {}
65 virtual void SetUp() {
66 quantize_op_ = GET_PARAM(0);
67 ref_quantize_op_ = GET_PARAM(1);
68 bit_depth_ = GET_PARAM(2);
69 mask_ = (1 << bit_depth_) - 1;
72 virtual void TearDown() { libvpx_test::ClearSystemState(); }
75 vpx_bit_depth_t bit_depth_;
77 QuantizeFunc quantize_op_;
78 QuantizeFunc ref_quantize_op_;
81 TEST_P(VP9QuantizeTest, OperationCheck) {
82 ACMRandom rnd(ACMRandom::DeterministicSeed());
83 int zbin_oq_value = 0;
84 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 256);
85 DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
86 DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
87 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
88 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
89 DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 256);
90 DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 256);
91 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 256);
92 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 256);
93 DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
94 DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
95 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
96 int err_count_total = 0;
97 int first_failure = -1;
98 for (int i = 0; i < number_of_iterations; ++i) {
99 const int skip_block = i == 0;
100 const TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
101 const TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
102 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
103 const int count = (4 << sz) * (4 << sz); // 16, 64, 256
105 *eob_ptr = rnd.Rand16();
106 *ref_eob_ptr = *eob_ptr;
107 for (int j = 0; j < count; j++) {
108 coeff_ptr[j] = rnd.Rand16()&mask_;
110 for (int j = 0; j < 2; j++) {
111 zbin_ptr[j] = rnd.Rand16()&mask_;
112 round_ptr[j] = rnd.Rand16();
113 quant_ptr[j] = rnd.Rand16();
114 quant_shift_ptr[j] = rnd.Rand16();
115 dequant_ptr[j] = rnd.Rand16();
117 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
118 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
119 ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
120 ref_eob_ptr, scan_order->scan, scan_order->iscan);
121 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
122 zbin_ptr, round_ptr, quant_ptr,
123 quant_shift_ptr, qcoeff_ptr,
124 dqcoeff_ptr, dequant_ptr,
125 zbin_oq_value, 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) {
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 int zbin_oq_value = 0;
145 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 1024);
146 DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
147 DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
148 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
149 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
150 DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 1024);
151 DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 1024);
152 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 1024);
153 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 1024);
154 DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
155 DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
156 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
157 int err_count_total = 0;
158 int first_failure = -1;
159 for (int i = 0; i < number_of_iterations; ++i) {
160 const int skip_block = i == 0;
161 const TX_SIZE sz = TX_32X32;
162 const TX_TYPE tx_type = (TX_TYPE)(i % 4);
163 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
164 const int count = (4 << sz) * (4 << sz); // 1024
166 *eob_ptr = rnd.Rand16();
167 *ref_eob_ptr = *eob_ptr;
168 for (int j = 0; j < count; j++) {
169 coeff_ptr[j] = rnd.Rand16()&mask_;
171 for (int j = 0; j < 2; j++) {
172 zbin_ptr[j] = rnd.Rand16()&mask_;
173 round_ptr[j] = rnd.Rand16();
174 quant_ptr[j] = rnd.Rand16();
175 quant_shift_ptr[j] = rnd.Rand16();
176 dequant_ptr[j] = rnd.Rand16();
178 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
179 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
180 ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
181 ref_eob_ptr, scan_order->scan, scan_order->iscan);
182 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
183 zbin_ptr, round_ptr, quant_ptr,
184 quant_shift_ptr, qcoeff_ptr,
185 dqcoeff_ptr, dequant_ptr,
186 zbin_oq_value, eob_ptr,
187 scan_order->scan, scan_order->iscan));
188 for (int j = 0; j < sz; ++j) {
189 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
190 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
192 err_count += (*ref_eob_ptr != *eob_ptr);
193 if (err_count && !err_count_total) {
196 err_count_total += err_count;
198 EXPECT_EQ(0, err_count_total)
199 << "Error: Quantization Test, C output doesn't match SSE2 output. "
200 << "First failed at test case " << first_failure;
203 TEST_P(VP9QuantizeTest, EOBCheck) {
204 ACMRandom rnd(ACMRandom::DeterministicSeed());
205 int zbin_oq_value = 0;
206 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 256);
207 DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
208 DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
209 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
210 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
211 DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 256);
212 DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 256);
213 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 256);
214 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 256);
215 DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
216 DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
217 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
218 int err_count_total = 0;
219 int first_failure = -1;
220 for (int i = 0; i < number_of_iterations; ++i) {
221 int skip_block = i == 0;
222 TX_SIZE sz = (TX_SIZE)(i % 3); // TX_4X4, TX_8X8 TX_16X16
223 TX_TYPE tx_type = (TX_TYPE)((i >> 2) % 3);
224 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
225 int count = (4 << sz) * (4 << sz); // 16, 64, 256
227 *eob_ptr = rnd.Rand16();
228 *ref_eob_ptr = *eob_ptr;
229 // Two random entries
230 for (int j = 0; j < count; j++) {
233 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
234 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
235 for (int j = 0; j < 2; j++) {
236 zbin_ptr[j] = rnd.Rand16()&mask_;
237 round_ptr[j] = rnd.Rand16();
238 quant_ptr[j] = rnd.Rand16();
239 quant_shift_ptr[j] = rnd.Rand16();
240 dequant_ptr[j] = rnd.Rand16();
243 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
244 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
245 ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
246 ref_eob_ptr, scan_order->scan, scan_order->iscan);
247 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
248 zbin_ptr, round_ptr, quant_ptr,
249 quant_shift_ptr, qcoeff_ptr,
250 dqcoeff_ptr, dequant_ptr,
251 zbin_oq_value, eob_ptr,
252 scan_order->scan, scan_order->iscan));
254 for (int j = 0; j < sz; ++j) {
255 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
256 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
258 err_count += (*ref_eob_ptr != *eob_ptr);
259 if (err_count && !err_count_total) {
262 err_count_total += err_count;
264 EXPECT_EQ(0, err_count_total)
265 << "Error: Quantization Test, C output doesn't match SSE2 output. "
266 << "First failed at test case " << first_failure;
269 TEST_P(VP9Quantize32Test, EOBCheck) {
270 ACMRandom rnd(ACMRandom::DeterministicSeed());
271 int zbin_oq_value = 0;
272 DECLARE_ALIGNED_ARRAY(16, tran_low_t, coeff_ptr, 1024);
273 DECLARE_ALIGNED_ARRAY(16, int16_t, zbin_ptr, 2);
274 DECLARE_ALIGNED_ARRAY(16, int16_t, round_ptr, 2);
275 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_ptr, 2);
276 DECLARE_ALIGNED_ARRAY(16, int16_t, quant_shift_ptr, 2);
277 DECLARE_ALIGNED_ARRAY(16, tran_low_t, qcoeff_ptr, 1024);
278 DECLARE_ALIGNED_ARRAY(16, tran_low_t, dqcoeff_ptr, 1024);
279 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_qcoeff_ptr, 1024);
280 DECLARE_ALIGNED_ARRAY(16, tran_low_t, ref_dqcoeff_ptr, 1024);
281 DECLARE_ALIGNED_ARRAY(16, int16_t, dequant_ptr, 2);
282 DECLARE_ALIGNED_ARRAY(16, uint16_t, eob_ptr, 1);
283 DECLARE_ALIGNED_ARRAY(16, uint16_t, ref_eob_ptr, 1);
284 int err_count_total = 0;
285 int first_failure = -1;
286 for (int i = 0; i < number_of_iterations; ++i) {
287 int skip_block = i == 0;
288 TX_SIZE sz = TX_32X32;
289 TX_TYPE tx_type = (TX_TYPE)(i % 4);
290 const scan_order *scan_order = &vp9_scan_orders[sz][tx_type];
291 int count = (4 << sz) * (4 << sz); // 1024
293 *eob_ptr = rnd.Rand16();
294 *ref_eob_ptr = *eob_ptr;
295 for (int j = 0; j < count; j++) {
298 // Two random entries
299 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
300 coeff_ptr[rnd(count)] = rnd.Rand16()&mask_;
301 for (int j = 0; j < 2; j++) {
302 zbin_ptr[j] = rnd.Rand16()&mask_;
303 round_ptr[j] = rnd.Rand16();
304 quant_ptr[j] = rnd.Rand16();
305 quant_shift_ptr[j] = rnd.Rand16();
306 dequant_ptr[j] = rnd.Rand16();
309 ref_quantize_op_(coeff_ptr, count, skip_block, zbin_ptr, round_ptr,
310 quant_ptr, quant_shift_ptr, ref_qcoeff_ptr,
311 ref_dqcoeff_ptr, dequant_ptr, zbin_oq_value,
312 ref_eob_ptr, scan_order->scan, scan_order->iscan);
313 ASM_REGISTER_STATE_CHECK(quantize_op_(coeff_ptr, count, skip_block,
314 zbin_ptr, round_ptr, quant_ptr,
315 quant_shift_ptr, qcoeff_ptr,
316 dqcoeff_ptr, dequant_ptr,
317 zbin_oq_value, eob_ptr,
318 scan_order->scan, scan_order->iscan));
320 for (int j = 0; j < sz; ++j) {
321 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
322 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
324 err_count += (*ref_eob_ptr != *eob_ptr);
325 if (err_count && !err_count_total) {
328 err_count_total += err_count;
330 EXPECT_EQ(0, err_count_total)
331 << "Error: Quantization Test, C output doesn't match SSE2 output. "
332 << "First failed at test case " << first_failure;
334 using std::tr1::make_tuple;
337 INSTANTIATE_TEST_CASE_P(
338 SSE2, VP9QuantizeTest,
340 make_tuple(&vp9_highbd_quantize_b_sse2,
341 &vp9_highbd_quantize_b_c, VPX_BITS_8),
342 make_tuple(&vp9_highbd_quantize_b_sse2,
343 &vp9_highbd_quantize_b_c, VPX_BITS_10),
344 make_tuple(&vp9_highbd_quantize_b_sse2,
345 &vp9_highbd_quantize_b_c, VPX_BITS_12)));
346 INSTANTIATE_TEST_CASE_P(
347 SSE2, VP9Quantize32Test,
349 make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
350 &vp9_highbd_quantize_b_32x32_c, VPX_BITS_8),
351 make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
352 &vp9_highbd_quantize_b_32x32_c, VPX_BITS_10),
353 make_tuple(&vp9_highbd_quantize_b_32x32_sse2,
354 &vp9_highbd_quantize_b_32x32_c, VPX_BITS_12)));
356 #endif // CONFIG_VP9_HIGHBITDEPTH