blob: 667b5581e4a39937e8355c109a2b8b7c9cdc029a [file] [log] [blame]
Yi Luob2663a82016-07-15 16:41:30 -07001/*
Yaowu Xubde4ac82016-11-28 15:26:06 -08002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yi Luob2663a82016-07-15 16:41:30 -07003 *
Yaowu Xubde4ac82016-11-28 15:26:06 -08004 * 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.
Yi Luob2663a82016-07-15 16:41:30 -070010 */
Yi Luob2663a82016-07-15 16:41:30 -070011#include <stdlib.h>
12
13#include "third_party/googletest/src/include/gtest/gtest.h"
14
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_config.h"
16#include "./av1_rtcd.h"
Yi Luob2663a82016-07-15 16:41:30 -070017#include "test/acm_random.h"
18#include "test/clear_system_state.h"
19#include "test/register_state_check.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070020#include "av1/common/scan.h"
Yi Luob2663a82016-07-15 16:41:30 -070021
22namespace {
23
clang-format3a826f12016-08-11 17:46:05 -070024typedef void (*QuantizeFpFunc)(
25 const tran_low_t *coeff_ptr, intptr_t count, int skip_block,
26 const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr,
27 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
28 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
29 const int16_t *scan, const int16_t *iscan, const int log_scale);
Yi Luob2663a82016-07-15 16:41:30 -070030
31struct QuantizeFuncParams {
32 QuantizeFuncParams(QuantizeFpFunc qF = NULL, QuantizeFpFunc qRefF = NULL,
clang-format3a826f12016-08-11 17:46:05 -070033 int count = 16)
34 : qFunc(qF), qFuncRef(qRefF), coeffCount(count) {}
Yi Luob2663a82016-07-15 16:41:30 -070035 QuantizeFpFunc qFunc;
36 QuantizeFpFunc qFuncRef;
37 int coeffCount;
38};
39
Yaowu Xuc27fc142016-08-22 16:08:15 -070040using libaom_test::ACMRandom;
Yi Luob2663a82016-07-15 16:41:30 -070041
42const int numTests = 1000;
43const int maxSize = 1024;
44const int roundFactorRange = 127;
45const int dequantRange = 32768;
46const int coeffRange = (1 << 20) - 1;
47
Yaowu Xuf883b422016-08-30 14:01:10 -070048class AV1QuantizeTest : public ::testing::TestWithParam<QuantizeFuncParams> {
Yi Luob2663a82016-07-15 16:41:30 -070049 public:
50 void RunQuantizeTest() {
51 ACMRandom rnd(ACMRandom::DeterministicSeed());
52 DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[maxSize]);
53 DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
54 DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
55 DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
56 DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
57 DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[maxSize]);
58 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[maxSize]);
59 DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[maxSize]);
60 DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[maxSize]);
61 DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
62 uint16_t eob;
63 uint16_t ref_eob;
64 int err_count_total = 0;
65 int first_failure = -1;
66 int skip_block = 0;
67 int count = params_.coeffCount;
68 const TX_SIZE txSize = getTxSize(count);
69 int log_scale = (txSize == TX_32X32);
70 QuantizeFpFunc quanFunc = params_.qFunc;
71 QuantizeFpFunc quanFuncRef = params_.qFuncRef;
72
Urvang Joshi03f6fdc2016-10-14 15:53:39 -070073 const SCAN_ORDER scanOrder = av1_default_scan_orders[txSize];
Yi Luob2663a82016-07-15 16:41:30 -070074 for (int i = 0; i < numTests; i++) {
75 int err_count = 0;
76 ref_eob = eob = -1;
77 for (int j = 0; j < count; j++) {
78 coeff_ptr[j] = rnd(coeffRange);
79 }
80
81 for (int j = 0; j < 2; j++) {
82 zbin_ptr[j] = rnd.Rand16();
83 quant_shift_ptr[j] = rnd.Rand16();
84 // int16_t positive
85 dequant_ptr[j] = abs(rnd(dequantRange));
86 quant_ptr[j] = (1 << 16) / dequant_ptr[j];
87 round_ptr[j] = (abs(rnd(roundFactorRange)) * dequant_ptr[j]) >> 7;
88 }
89
clang-format3a826f12016-08-11 17:46:05 -070090 quanFuncRef(coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
91 quant_shift_ptr, ref_qcoeff_ptr, ref_dqcoeff_ptr, dequant_ptr,
92 &ref_eob, scanOrder.scan, scanOrder.iscan, log_scale);
Yi Luob2663a82016-07-15 16:41:30 -070093
clang-format3a826f12016-08-11 17:46:05 -070094 ASM_REGISTER_STATE_CHECK(
95 quanFunc(coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
96 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, &eob,
97 scanOrder.scan, scanOrder.iscan, log_scale));
Yi Luob2663a82016-07-15 16:41:30 -070098
99 for (int j = 0; j < count; ++j) {
clang-format3a826f12016-08-11 17:46:05 -0700100 err_count += (ref_qcoeff_ptr[j] != qcoeff_ptr[j]) |
101 (ref_dqcoeff_ptr[j] != dqcoeff_ptr[j]);
102 EXPECT_EQ(ref_qcoeff_ptr[j], qcoeff_ptr[j]) << "qcoeff error: i = " << i
103 << " j = " << j << "\n";
Yi Luob2663a82016-07-15 16:41:30 -0700104 EXPECT_EQ(ref_dqcoeff_ptr[j], dqcoeff_ptr[j])
105 << "dqcoeff error: i = " << i << " j = " << j << "\n";
106 }
clang-format3a826f12016-08-11 17:46:05 -0700107 EXPECT_EQ(ref_eob, eob) << "eob error: "
108 << "i = " << i << "\n";
Yi Luob2663a82016-07-15 16:41:30 -0700109 err_count += (ref_eob != eob);
110 if (err_count && !err_count_total) {
111 first_failure = i;
112 }
113 err_count_total += err_count;
114 }
115 EXPECT_EQ(0, err_count_total)
116 << "Error: Quantization Test, C output doesn't match SSE2 output. "
117 << "First failed at test case " << first_failure;
118 }
119
120 void RunEobTest() {
121 ACMRandom rnd(ACMRandom::DeterministicSeed());
122 DECLARE_ALIGNED(16, tran_low_t, coeff_ptr[maxSize]);
123 DECLARE_ALIGNED(16, int16_t, zbin_ptr[2]);
124 DECLARE_ALIGNED(16, int16_t, round_ptr[2]);
125 DECLARE_ALIGNED(16, int16_t, quant_ptr[2]);
126 DECLARE_ALIGNED(16, int16_t, quant_shift_ptr[2]);
127 DECLARE_ALIGNED(16, tran_low_t, qcoeff_ptr[maxSize]);
128 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_ptr[maxSize]);
129 DECLARE_ALIGNED(16, tran_low_t, ref_qcoeff_ptr[maxSize]);
130 DECLARE_ALIGNED(16, tran_low_t, ref_dqcoeff_ptr[maxSize]);
131 DECLARE_ALIGNED(16, int16_t, dequant_ptr[2]);
132 uint16_t eob;
133 uint16_t ref_eob;
134 int skip_block = 0;
135 int count = params_.coeffCount;
136 const TX_SIZE txSize = getTxSize(count);
137 int log_scale = (txSize == TX_32X32);
138 QuantizeFpFunc quanFunc = params_.qFunc;
139 QuantizeFpFunc quanFuncRef = params_.qFuncRef;
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700140 const SCAN_ORDER scanOrder = av1_default_scan_orders[txSize];
Yi Luob2663a82016-07-15 16:41:30 -0700141
142 for (int i = 0; i < numTests; i++) {
143 ref_eob = eob = -1;
144 for (int j = 0; j < count; j++) {
145 coeff_ptr[j] = 0;
146 }
147
148 coeff_ptr[rnd(count)] = rnd(coeffRange);
149 coeff_ptr[rnd(count)] = rnd(coeffRange);
150 coeff_ptr[rnd(count)] = rnd(coeffRange);
151
152 for (int j = 0; j < 2; j++) {
153 zbin_ptr[j] = rnd.Rand16();
154 quant_shift_ptr[j] = rnd.Rand16();
155 // int16_t positive
156 dequant_ptr[j] = abs(rnd(dequantRange));
157 quant_ptr[j] = (1 << 16) / dequant_ptr[j];
158 round_ptr[j] = (abs(rnd(roundFactorRange)) * dequant_ptr[j]) >> 7;
159 }
160
clang-format3a826f12016-08-11 17:46:05 -0700161 quanFuncRef(coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
162 quant_shift_ptr, ref_qcoeff_ptr, ref_dqcoeff_ptr, dequant_ptr,
163 &ref_eob, scanOrder.scan, scanOrder.iscan, log_scale);
Yi Luob2663a82016-07-15 16:41:30 -0700164
clang-format3a826f12016-08-11 17:46:05 -0700165 ASM_REGISTER_STATE_CHECK(
166 quanFunc(coeff_ptr, count, skip_block, zbin_ptr, round_ptr, quant_ptr,
167 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr, &eob,
168 scanOrder.scan, scanOrder.iscan, log_scale));
169 EXPECT_EQ(ref_eob, eob) << "eob error: "
170 << "i = " << i << "\n";
Yi Luob2663a82016-07-15 16:41:30 -0700171 }
172 }
173
clang-format3a826f12016-08-11 17:46:05 -0700174 virtual void SetUp() { params_ = GetParam(); }
Yi Luob2663a82016-07-15 16:41:30 -0700175
Yaowu Xuc27fc142016-08-22 16:08:15 -0700176 virtual void TearDown() { libaom_test::ClearSystemState(); }
Yi Luob2663a82016-07-15 16:41:30 -0700177
Yaowu Xuf883b422016-08-30 14:01:10 -0700178 virtual ~AV1QuantizeTest() {}
Yi Luob2663a82016-07-15 16:41:30 -0700179
180 private:
181 TX_SIZE getTxSize(int count) {
Urvang Joshicb586f32016-09-20 11:36:33 -0700182 switch (count) {
183 case 16: return TX_4X4;
184 case 64: return TX_8X8;
185 case 256: return TX_16X16;
186 case 1024: return TX_32X32;
187 default: return TX_4X4;
Yi Luob2663a82016-07-15 16:41:30 -0700188 }
Yi Luob2663a82016-07-15 16:41:30 -0700189 }
190
191 QuantizeFuncParams params_;
192};
193
Yaowu Xuf883b422016-08-30 14:01:10 -0700194TEST_P(AV1QuantizeTest, BitExactCheck) { RunQuantizeTest(); }
195TEST_P(AV1QuantizeTest, EobVerify) { RunEobTest(); }
Yi Luob2663a82016-07-15 16:41:30 -0700196
197#if HAVE_SSE4_1
Yaowu Xu0dd04632016-10-19 09:31:50 -0700198#if !CONFIG_AOM_QM
Yi Luob2663a82016-07-15 16:41:30 -0700199INSTANTIATE_TEST_CASE_P(
Yaowu Xuf883b422016-08-30 14:01:10 -0700200 SSE4_1, AV1QuantizeTest,
201 ::testing::Values(QuantizeFuncParams(&av1_highbd_quantize_fp_sse4_1,
202 &av1_highbd_quantize_fp_c, 16),
203 QuantizeFuncParams(&av1_highbd_quantize_fp_sse4_1,
204 &av1_highbd_quantize_fp_c, 64),
205 QuantizeFuncParams(&av1_highbd_quantize_fp_sse4_1,
206 &av1_highbd_quantize_fp_c, 256),
207 QuantizeFuncParams(&av1_highbd_quantize_fp_sse4_1,
208 &av1_highbd_quantize_fp_c, 1024)));
Yaowu Xu0dd04632016-10-19 09:31:50 -0700209#endif // !CONFIG_AOM_QM
Yi Luob2663a82016-07-15 16:41:30 -0700210#endif // HAVE_SSE4_1
211} // namespace