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 "vp9/common/vp9_scan.h"
25 #include "vpx/vpx_codec.h"
26 #include "vpx/vpx_integer.h"
28 using libvpx_test::ACMRandom
;
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
>
45 class VP9QuantizeTest
: public ::testing::TestWithParam
<QuantizeParam
> {
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(); }
58 vpx_bit_depth_t bit_depth_
;
60 QuantizeFunc quantize_op_
;
61 QuantizeFunc ref_quantize_op_
;
64 class VP9Quantize32Test
: public ::testing::TestWithParam
<QuantizeParam
> {
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(); }
77 vpx_bit_depth_t bit_depth_
;
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
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
) {
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
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
) {
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
224 *eob_ptr
= rnd
.Rand16();
225 *ref_eob_ptr
= *eob_ptr
;
226 // Two random entries
227 for (int j
= 0; j
< count
; j
++) {
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
) {
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
288 *eob_ptr
= rnd
.Rand16();
289 *ref_eob_ptr
= *eob_ptr
;
290 for (int j
= 0; j
< count
; j
++) {
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
) {
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
;
331 INSTANTIATE_TEST_CASE_P(
332 SSE2
, VP9QuantizeTest
,
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
,
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
)));
350 #endif // CONFIG_VP9_HIGHBITDEPTH