]> granicus.if.org Git - libvpx/blob - test/vp9_quantize_test.cc
Merge "tests: enable resize_test for vp8"
[libvpx] / test / vp9_quantize_test.cc
1 /*
2  *  Copyright (c) 2014 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 <math.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "third_party/googletest/src/include/gtest/gtest.h"
16
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"
25
26 using libvpx_test::ACMRandom;
27
28 namespace {
29 #if CONFIG_VP9_HIGHBITDEPTH
30 const int number_of_iterations = 100;
31
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>
41     QuantizeParam;
42
43 class VP9QuantizeTest : public ::testing::TestWithParam<QuantizeParam> {
44  public:
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;
51   }
52
53   virtual void TearDown() { libvpx_test::ClearSystemState(); }
54
55  protected:
56   vpx_bit_depth_t bit_depth_;
57   int mask_;
58   QuantizeFunc quantize_op_;
59   QuantizeFunc ref_quantize_op_;
60 };
61
62 class VP9Quantize32Test : public ::testing::TestWithParam<QuantizeParam> {
63  public:
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;
70   }
71
72   virtual void TearDown() { libvpx_test::ClearSystemState(); }
73
74  protected:
75   vpx_bit_depth_t bit_depth_;
76   int mask_;
77   QuantizeFunc quantize_op_;
78   QuantizeFunc ref_quantize_op_;
79 };
80
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
104     int err_count = 0;
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_;
109     }
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();
116     }
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]);
130     }
131     err_count += (*ref_eob_ptr != *eob_ptr);
132     if (err_count && !err_count_total) {
133       first_failure = i;
134     }
135     err_count_total += err_count;
136   }
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;
140 }
141
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
165     int err_count = 0;
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_;
170     }
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();
177     }
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]);
191     }
192     err_count += (*ref_eob_ptr != *eob_ptr);
193     if (err_count && !err_count_total) {
194       first_failure = i;
195     }
196     err_count_total += err_count;
197   }
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;
201 }
202
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
226     int err_count = 0;
227     *eob_ptr = rnd.Rand16();
228     *ref_eob_ptr = *eob_ptr;
229     // Two random entries
230     for (int j = 0; j < count; j++) {
231       coeff_ptr[j] = 0;
232     }
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();
241     }
242
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));
253
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]);
257     }
258     err_count += (*ref_eob_ptr != *eob_ptr);
259     if (err_count && !err_count_total) {
260       first_failure = i;
261     }
262     err_count_total += err_count;
263   }
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;
267 }
268
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
292     int err_count = 0;
293     *eob_ptr = rnd.Rand16();
294     *ref_eob_ptr = *eob_ptr;
295     for (int j = 0; j < count; j++) {
296       coeff_ptr[j] = 0;
297     }
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();
307     }
308
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));
319
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]);
323     }
324     err_count += (*ref_eob_ptr != *eob_ptr);
325     if (err_count && !err_count_total) {
326       first_failure = i;
327     }
328     err_count_total += err_count;
329   }
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;
333 }
334 using std::tr1::make_tuple;
335
336 #if HAVE_SSE2
337 INSTANTIATE_TEST_CASE_P(
338     SSE2, VP9QuantizeTest,
339     ::testing::Values(
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,
348     ::testing::Values(
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)));
355 #endif  // HAVE_SSE2
356 #endif  // CONFIG_VP9_HIGHBITDEPTH
357 }  // namespace