1 // Copyright 2021 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/quantizer.h"
16
17 #include <cstdint>
18
19 #include "gtest/gtest.h"
20 #include "src/obu_parser.h"
21 #include "src/utils/constants.h"
22 #include "src/utils/types.h"
23
24 namespace libgav1 {
25 namespace {
26
TEST(QuantizerTest,GetQIndex)27 TEST(QuantizerTest, GetQIndex) {
28 const int kBaseQIndex = 40;
29 const int kDelta = 10;
30 const int kOutOfRangeIndex = 200;
31 Segmentation segmentation = {};
32
33 EXPECT_EQ(GetQIndex(segmentation, 0, kBaseQIndex), kBaseQIndex);
34 EXPECT_EQ(GetQIndex(segmentation, kOutOfRangeIndex, kBaseQIndex),
35 kBaseQIndex);
36
37 segmentation.enabled = true;
38 EXPECT_EQ(GetQIndex(segmentation, 0, kBaseQIndex), kBaseQIndex);
39 EXPECT_EQ(GetQIndex(segmentation, kOutOfRangeIndex, kBaseQIndex),
40 kBaseQIndex);
41
42 segmentation.feature_enabled[1][kSegmentFeatureQuantizer] = true;
43 segmentation.feature_data[1][kSegmentFeatureQuantizer] = kDelta;
44 EXPECT_EQ(GetQIndex(segmentation, 1, kBaseQIndex), kBaseQIndex + kDelta);
45 EXPECT_EQ(GetQIndex(segmentation, kOutOfRangeIndex, kBaseQIndex),
46 kBaseQIndex);
47
48 segmentation.enabled = false;
49 EXPECT_EQ(GetQIndex(segmentation, 1, kBaseQIndex), kBaseQIndex);
50 EXPECT_EQ(GetQIndex(segmentation, kOutOfRangeIndex, kBaseQIndex),
51 kBaseQIndex);
52 }
53
TEST(QuantizerTest,GetDcValue)54 TEST(QuantizerTest, GetDcValue) {
55 QuantizerParameters params = {};
56 params.delta_dc[kPlaneY] = 1;
57 params.delta_dc[kPlaneU] = 2;
58 params.delta_dc[kPlaneV] = 3;
59
60 // Test lookups of Dc_Qlookup[0][0], Dc_Qlookup[0][11], Dc_Qlookup[0][12],
61 // and Dc_Qlookup[0][255] in the spec, including the clipping of qindex.
62 {
63 Quantizer quantizer(8, ¶ms);
64 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, -2), 4);
65 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, -1), 4);
66 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 10), 16);
67 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 11), 17);
68 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 254), 1336);
69 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 255), 1336);
70 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, -3), 4);
71 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, -2), 4);
72 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 9), 16);
73 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 10), 17);
74 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 253), 1336);
75 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 254), 1336);
76 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, -4), 4);
77 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, -3), 4);
78 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 8), 16);
79 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 9), 17);
80 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 252), 1336);
81 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 253), 1336);
82 }
83
84 #if LIBGAV1_MAX_BITDEPTH >= 10
85 // Test lookups of Dc_Qlookup[1][0], Dc_Qlookup[1][11], Dc_Qlookup[1][12],
86 // and Dc_Qlookup[1][255] in the spec, including the clipping of qindex.
87 {
88 Quantizer quantizer(10, ¶ms);
89 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, -2), 4);
90 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, -1), 4);
91 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 10), 34);
92 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 11), 37);
93 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 254), 5347);
94 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 255), 5347);
95 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, -3), 4);
96 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, -2), 4);
97 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 9), 34);
98 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 10), 37);
99 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 253), 5347);
100 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 254), 5347);
101 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, -4), 4);
102 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, -3), 4);
103 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 8), 34);
104 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 9), 37);
105 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 254), 5347);
106 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 253), 5347);
107 }
108 #endif // LIBGAV1_MAX_BITDEPTH >= 10
109
110 #if LIBGAV1_MAX_BITDEPTH == 12
111 // Test lookups of Dc_Qlookup[2][0], Dc_Qlookup[2][11], Dc_Qlookup[2][12],
112 // and Dc_Qlookup[2][255] in the spec, including the clipping of qindex.
113 {
114 Quantizer quantizer(12, ¶ms);
115 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, -2), 4);
116 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, -1), 4);
117 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 10), 103);
118 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 11), 115);
119 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 254), 21387);
120 EXPECT_EQ(quantizer.GetDcValue(kPlaneY, 255), 21387);
121 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, -3), 4);
122 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, -2), 4);
123 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 9), 103);
124 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 10), 115);
125 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 253), 21387);
126 EXPECT_EQ(quantizer.GetDcValue(kPlaneU, 254), 21387);
127 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, -4), 4);
128 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, -3), 4);
129 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 8), 103);
130 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 9), 115);
131 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 254), 21387);
132 EXPECT_EQ(quantizer.GetDcValue(kPlaneV, 253), 21387);
133 }
134 #endif // LIBGAV1_MAX_BITDEPTH == 12
135 }
136
TEST(QuantizerTest,GetAcValue)137 TEST(QuantizerTest, GetAcValue) {
138 QuantizerParameters params = {};
139 params.delta_ac[kPlaneU] = 1;
140 params.delta_ac[kPlaneV] = 2;
141
142 // Test lookups of Ac_Qlookup[0][0], Ac_Qlookup[0][11], Ac_Qlookup[0][12],
143 // and Ac_Qlookup[0][255] in the spec, including the clipping of qindex.
144 {
145 Quantizer quantizer(8, ¶ms);
146 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, -1), 4);
147 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 0), 4);
148 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 11), 18);
149 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 12), 19);
150 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 255), 1828);
151 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 256), 1828);
152 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, -2), 4);
153 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, -1), 4);
154 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 10), 18);
155 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 11), 19);
156 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 254), 1828);
157 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 255), 1828);
158 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, -3), 4);
159 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, -2), 4);
160 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 9), 18);
161 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 10), 19);
162 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 253), 1828);
163 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 254), 1828);
164 }
165
166 #if LIBGAV1_MAX_BITDEPTH >= 10
167 // Test lookups of Ac_Qlookup[1][0], Ac_Qlookup[1][11], Ac_Qlookup[1][12],
168 // and Ac_Qlookup[1][255] in the spec, including the clipping of qindex.
169 {
170 Quantizer quantizer(10, ¶ms);
171 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, -1), 4);
172 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 0), 4);
173 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 11), 37);
174 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 12), 40);
175 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 255), 7312);
176 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 256), 7312);
177 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, -2), 4);
178 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, -1), 4);
179 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 10), 37);
180 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 11), 40);
181 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 254), 7312);
182 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 255), 7312);
183 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, -3), 4);
184 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, -2), 4);
185 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 9), 37);
186 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 10), 40);
187 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 253), 7312);
188 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 254), 7312);
189 }
190 #endif // LIBGAV1_MAX_BITDEPTH >= 10
191
192 #if LIBGAV1_MAX_BITDEPTH == 12
193 // Test lookups of Ac_Qlookup[1][0], Ac_Qlookup[1][11], Ac_Qlookup[1][12],
194 // and Ac_Qlookup[1][255] in the spec, including the clipping of qindex.
195 {
196 Quantizer quantizer(12, ¶ms);
197 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, -1), 4);
198 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 0), 4);
199 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 11), 112);
200 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 12), 126);
201 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 255), 29247);
202 EXPECT_EQ(quantizer.GetAcValue(kPlaneY, 256), 29247);
203 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, -2), 4);
204 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, -1), 4);
205 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 10), 112);
206 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 11), 126);
207 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 254), 29247);
208 EXPECT_EQ(quantizer.GetAcValue(kPlaneU, 255), 29247);
209 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, -3), 4);
210 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, -2), 4);
211 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 9), 112);
212 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 10), 126);
213 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 253), 29247);
214 EXPECT_EQ(quantizer.GetAcValue(kPlaneV, 254), 29247);
215 }
216 #endif // LIBGAV1_MAX_BITDEPTH == 12
217 }
218
219 } // namespace
220 } // namespace libgav1
221