1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * 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.
10 */
11
12 #include <math.h>
13
14 #include "config/aom_dsp_rtcd.h"
15
16 #include "aom_dsp/quantize.h"
17 #include "aom_mem/aom_mem.h"
18 #include "aom_ports/mem.h"
19
20 #include "av1/common/idct.h"
21 #include "av1/common/quant_common.h"
22 #include "av1/common/scan.h"
23 #include "av1/common/seg_common.h"
24
25 #include "av1/encoder/av1_quantize.h"
26 #include "av1/encoder/encoder.h"
27 #include "av1/encoder/rd.h"
28
av1_quantize_skip(intptr_t n_coeffs,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,uint16_t * eob_ptr)29 void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr,
30 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr) {
31 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
32 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
33 *eob_ptr = 0;
34 }
35
av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2],const int16_t dequant_ptr[2],const int16_t round_ptr[2],int log_scale,const int16_t * scan,int coeff_count,const tran_low_t * coeff_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr)36 int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2],
37 const int16_t dequant_ptr[2],
38 const int16_t round_ptr[2], int log_scale,
39 const int16_t *scan, int coeff_count,
40 const tran_low_t *coeff_ptr,
41 tran_low_t *qcoeff_ptr,
42 tran_low_t *dqcoeff_ptr) {
43 memset(qcoeff_ptr, 0, coeff_count * sizeof(*qcoeff_ptr));
44 memset(dqcoeff_ptr, 0, coeff_count * sizeof(*dqcoeff_ptr));
45 const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
46 ROUND_POWER_OF_TWO(round_ptr[1], log_scale) };
47 int eob = 0;
48 for (int i = 0; i < coeff_count; i++) {
49 const int rc = scan[i];
50 const int32_t thresh = (int32_t)(dequant_ptr[rc != 0]);
51 const int coeff = coeff_ptr[rc];
52 const int coeff_sign = AOMSIGN(coeff);
53 int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
54 int tmp32 = 0;
55 if ((abs_coeff << (1 + log_scale)) >= thresh) {
56 abs_coeff = clamp64(abs_coeff + rounding[rc != 0], INT16_MIN, INT16_MAX);
57 tmp32 = (int)((abs_coeff * quant_ptr[rc != 0]) >> (16 - log_scale));
58 if (tmp32) {
59 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
60 const tran_low_t abs_dqcoeff =
61 (tmp32 * dequant_ptr[rc != 0]) >> log_scale;
62 dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
63 }
64 }
65 if (tmp32) eob = i + 1;
66 }
67 return eob;
68 }
69
quantize_fp_helper_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan,const qm_val_t * qm_ptr,const qm_val_t * iqm_ptr,int log_scale)70 static void quantize_fp_helper_c(
71 const tran_low_t *coeff_ptr, intptr_t n_coeffs, const int16_t *zbin_ptr,
72 const int16_t *round_ptr, const int16_t *quant_ptr,
73 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
74 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
75 const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
76 const qm_val_t *iqm_ptr, int log_scale) {
77 int i, eob = -1;
78 const int rounding[2] = { ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
79 ROUND_POWER_OF_TWO(round_ptr[1], log_scale) };
80 // TODO(jingning) Decide the need of these arguments after the
81 // quantization process is completed.
82 (void)zbin_ptr;
83 (void)quant_shift_ptr;
84 (void)iscan;
85
86 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
87 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
88
89 if (qm_ptr == NULL && iqm_ptr == NULL) {
90 *eob_ptr = av1_quantize_fp_no_qmatrix(quant_ptr, dequant_ptr, round_ptr,
91 log_scale, scan, (int)n_coeffs,
92 coeff_ptr, qcoeff_ptr, dqcoeff_ptr);
93 } else {
94 // Quantization pass: All coefficients with index >= zero_flag are
95 // skippable. Note: zero_flag can be zero.
96 for (i = 0; i < n_coeffs; i++) {
97 const int rc = scan[i];
98 const int coeff = coeff_ptr[rc];
99 const qm_val_t wt = qm_ptr ? qm_ptr[rc] : (1 << AOM_QM_BITS);
100 const qm_val_t iwt = iqm_ptr ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
101 const int dequant =
102 (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
103 AOM_QM_BITS;
104 const int coeff_sign = AOMSIGN(coeff);
105 int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
106 int tmp32 = 0;
107 if (abs_coeff * wt >=
108 (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
109 abs_coeff += rounding[rc != 0];
110 abs_coeff = clamp64(abs_coeff, INT16_MIN, INT16_MAX);
111 tmp32 = (int)((abs_coeff * wt * quant_ptr[rc != 0]) >>
112 (16 - log_scale + AOM_QM_BITS));
113 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
114 const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
115 dqcoeff_ptr[rc] = (abs_dqcoeff ^ coeff_sign) - coeff_sign;
116 }
117
118 if (tmp32) eob = i;
119 }
120 *eob_ptr = eob + 1;
121 }
122 }
123
124 #if CONFIG_AV1_HIGHBITDEPTH
highbd_quantize_fp_helper_c(const tran_low_t * coeff_ptr,intptr_t count,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan,const qm_val_t * qm_ptr,const qm_val_t * iqm_ptr,int log_scale)125 static void highbd_quantize_fp_helper_c(
126 const tran_low_t *coeff_ptr, intptr_t count, const int16_t *zbin_ptr,
127 const int16_t *round_ptr, const int16_t *quant_ptr,
128 const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr,
129 tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
130 const int16_t *scan, const int16_t *iscan, const qm_val_t *qm_ptr,
131 const qm_val_t *iqm_ptr, int log_scale) {
132 int i;
133 int eob = -1;
134 const int shift = 16 - log_scale;
135 // TODO(jingning) Decide the need of these arguments after the
136 // quantization process is completed.
137 (void)zbin_ptr;
138 (void)quant_shift_ptr;
139 (void)iscan;
140
141 if (qm_ptr || iqm_ptr) {
142 // Quantization pass: All coefficients with index >= zero_flag are
143 // skippable. Note: zero_flag can be zero.
144 for (i = 0; i < count; i++) {
145 const int rc = scan[i];
146 const int coeff = coeff_ptr[rc];
147 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
148 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
149 const int dequant =
150 (dequant_ptr[rc != 0] * iwt + (1 << (AOM_QM_BITS - 1))) >>
151 AOM_QM_BITS;
152 const int coeff_sign = AOMSIGN(coeff);
153 const int64_t abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
154 int abs_qcoeff = 0;
155 if (abs_coeff * wt >=
156 (dequant_ptr[rc != 0] << (AOM_QM_BITS - (1 + log_scale)))) {
157 const int64_t tmp =
158 abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale);
159 abs_qcoeff =
160 (int)((tmp * quant_ptr[rc != 0] * wt) >> (shift + AOM_QM_BITS));
161 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
162 const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
163 dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
164 if (abs_qcoeff) eob = i;
165 } else {
166 qcoeff_ptr[rc] = 0;
167 dqcoeff_ptr[rc] = 0;
168 }
169 }
170 } else {
171 const int log_scaled_round_arr[2] = {
172 ROUND_POWER_OF_TWO(round_ptr[0], log_scale),
173 ROUND_POWER_OF_TWO(round_ptr[1], log_scale),
174 };
175 for (i = 0; i < count; i++) {
176 const int rc = scan[i];
177 const int coeff = coeff_ptr[rc];
178 const int rc01 = (rc != 0);
179 const int coeff_sign = AOMSIGN(coeff);
180 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
181 const int log_scaled_round = log_scaled_round_arr[rc01];
182 if ((abs_coeff << (1 + log_scale)) >= dequant_ptr[rc01]) {
183 const int quant = quant_ptr[rc01];
184 const int dequant = dequant_ptr[rc01];
185 const int64_t tmp = (int64_t)abs_coeff + log_scaled_round;
186 const int abs_qcoeff = (int)((tmp * quant) >> shift);
187 qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
188 const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
189 if (abs_qcoeff) eob = i;
190 dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
191 } else {
192 qcoeff_ptr[rc] = 0;
193 dqcoeff_ptr[rc] = 0;
194 }
195 }
196 }
197 *eob_ptr = eob + 1;
198 }
199 #endif // CONFIG_AV1_HIGHBITDEPTH
200
av1_quantize_fp_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)201 void av1_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
202 const int16_t *zbin_ptr, const int16_t *round_ptr,
203 const int16_t *quant_ptr, const int16_t *quant_shift_ptr,
204 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
205 const int16_t *dequant_ptr, uint16_t *eob_ptr,
206 const int16_t *scan, const int16_t *iscan) {
207 quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
208 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
209 eob_ptr, scan, iscan, NULL, NULL, 0);
210 }
211
av1_quantize_lp_c(const int16_t * coeff_ptr,intptr_t n_coeffs,const int16_t * round_ptr,const int16_t * quant_ptr,int16_t * qcoeff_ptr,int16_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)212 void av1_quantize_lp_c(const int16_t *coeff_ptr, intptr_t n_coeffs,
213 const int16_t *round_ptr, const int16_t *quant_ptr,
214 int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
215 const int16_t *dequant_ptr, uint16_t *eob_ptr,
216 const int16_t *scan, const int16_t *iscan) {
217 (void)iscan;
218 int eob = -1;
219
220 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
221 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
222
223 // Quantization pass: All coefficients with index >= zero_flag are
224 // skippable. Note: zero_flag can be zero.
225 for (int i = 0; i < n_coeffs; i++) {
226 const int rc = scan[i];
227 const int coeff = coeff_ptr[rc];
228 const int coeff_sign = AOMSIGN(coeff);
229 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
230
231 int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
232 tmp = (tmp * quant_ptr[rc != 0]) >> 16;
233
234 qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
235 dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
236
237 if (tmp) eob = i;
238 }
239 *eob_ptr = eob + 1;
240 }
241
av1_quantize_fp_32x32_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)242 void av1_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
243 const int16_t *zbin_ptr, const int16_t *round_ptr,
244 const int16_t *quant_ptr,
245 const int16_t *quant_shift_ptr,
246 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
247 const int16_t *dequant_ptr, uint16_t *eob_ptr,
248 const int16_t *scan, const int16_t *iscan) {
249 quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
250 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
251 eob_ptr, scan, iscan, NULL, NULL, 1);
252 }
253
av1_quantize_fp_64x64_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan)254 void av1_quantize_fp_64x64_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
255 const int16_t *zbin_ptr, const int16_t *round_ptr,
256 const int16_t *quant_ptr,
257 const int16_t *quant_shift_ptr,
258 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
259 const int16_t *dequant_ptr, uint16_t *eob_ptr,
260 const int16_t *scan, const int16_t *iscan) {
261 quantize_fp_helper_c(coeff_ptr, n_coeffs, zbin_ptr, round_ptr, quant_ptr,
262 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr, dequant_ptr,
263 eob_ptr, scan, iscan, NULL, NULL, 2);
264 }
265
av1_quantize_fp_facade(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const MACROBLOCK_PLANE * p,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,uint16_t * eob_ptr,const SCAN_ORDER * sc,const QUANT_PARAM * qparam)266 void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
267 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
268 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
269 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
270 const qm_val_t *qm_ptr = qparam->qmatrix;
271 const qm_val_t *iqm_ptr = qparam->iqmatrix;
272 if (qm_ptr != NULL && iqm_ptr != NULL) {
273 quantize_fp_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
274 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
275 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
276 sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
277 } else {
278 switch (qparam->log_scale) {
279 case 0:
280 av1_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
281 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
282 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
283 sc->iscan);
284 break;
285 case 1:
286 av1_quantize_fp_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
287 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
288 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
289 sc->iscan);
290 break;
291 case 2:
292 av1_quantize_fp_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
293 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
294 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
295 sc->iscan);
296 break;
297 default: assert(0);
298 }
299 }
300 }
301
av1_quantize_b_facade(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const MACROBLOCK_PLANE * p,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,uint16_t * eob_ptr,const SCAN_ORDER * sc,const QUANT_PARAM * qparam)302 void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
303 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
304 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
305 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
306 const qm_val_t *qm_ptr = qparam->qmatrix;
307 const qm_val_t *iqm_ptr = qparam->iqmatrix;
308 if (qparam->use_quant_b_adapt) {
309 // TODO(sarahparker) These quantize_b optimizations need SIMD
310 // implementations
311 if (qm_ptr != NULL && iqm_ptr != NULL) {
312 aom_quantize_b_adaptive_helper_c(
313 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
314 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
315 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
316 } else {
317 switch (qparam->log_scale) {
318 case 0:
319 aom_quantize_b_adaptive(coeff_ptr, n_coeffs, p->zbin_QTX,
320 p->round_QTX, p->quant_QTX,
321 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
322 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
323 break;
324 case 1:
325 aom_quantize_b_32x32_adaptive(
326 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
327 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
328 eob_ptr, sc->scan, sc->iscan);
329 break;
330 case 2:
331 aom_quantize_b_64x64_adaptive(
332 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
333 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
334 eob_ptr, sc->scan, sc->iscan);
335 break;
336 default: assert(0);
337 }
338 }
339 } else {
340 if (qm_ptr != NULL && iqm_ptr != NULL) {
341 aom_quantize_b_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
342 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
343 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
344 sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
345 } else {
346 switch (qparam->log_scale) {
347 case 0:
348 aom_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
349 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
350 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
351 sc->iscan);
352 break;
353 case 1:
354 aom_quantize_b_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
355 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
356 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
357 sc->iscan);
358 break;
359 case 2:
360 aom_quantize_b_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
361 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
362 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
363 sc->iscan);
364 break;
365 default: assert(0);
366 }
367 }
368 }
369 }
370
quantize_dc(const tran_low_t * coeff_ptr,int n_coeffs,int skip_block,const int16_t * round_ptr,const int16_t quant,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t dequant_ptr,uint16_t * eob_ptr,const qm_val_t * qm_ptr,const qm_val_t * iqm_ptr,const int log_scale)371 static void quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
372 int skip_block, const int16_t *round_ptr,
373 const int16_t quant, tran_low_t *qcoeff_ptr,
374 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
375 uint16_t *eob_ptr, const qm_val_t *qm_ptr,
376 const qm_val_t *iqm_ptr, const int log_scale) {
377 const int rc = 0;
378 const int coeff = coeff_ptr[rc];
379 const int coeff_sign = AOMSIGN(coeff);
380 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
381 int64_t tmp;
382 int eob = -1;
383 int32_t tmp32;
384 int dequant;
385
386 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
387 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
388
389 if (!skip_block) {
390 const int wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
391 const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
392 tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale),
393 INT16_MIN, INT16_MAX);
394 tmp32 = (int32_t)((tmp * wt * quant) >> (16 - log_scale + AOM_QM_BITS));
395 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
396 dequant = (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
397 const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
398 dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
399 if (tmp32) eob = 0;
400 }
401 *eob_ptr = eob + 1;
402 }
403
av1_quantize_dc_facade(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const MACROBLOCK_PLANE * p,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,uint16_t * eob_ptr,const SCAN_ORDER * sc,const QUANT_PARAM * qparam)404 void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
405 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
406 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
407 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
408 // obsolete skip_block
409 const int skip_block = 0;
410 (void)sc;
411 assert(qparam->log_scale >= 0 && qparam->log_scale < (3));
412 const qm_val_t *qm_ptr = qparam->qmatrix;
413 const qm_val_t *iqm_ptr = qparam->iqmatrix;
414 quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
415 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX[0],
416 eob_ptr, qm_ptr, iqm_ptr, qparam->log_scale);
417 }
418
419 #if CONFIG_AV1_HIGHBITDEPTH
av1_highbd_quantize_fp_facade(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const MACROBLOCK_PLANE * p,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,uint16_t * eob_ptr,const SCAN_ORDER * sc,const QUANT_PARAM * qparam)420 void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
421 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
422 tran_low_t *qcoeff_ptr,
423 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
424 const SCAN_ORDER *sc,
425 const QUANT_PARAM *qparam) {
426 const qm_val_t *qm_ptr = qparam->qmatrix;
427 const qm_val_t *iqm_ptr = qparam->iqmatrix;
428 if (qm_ptr != NULL && iqm_ptr != NULL) {
429 highbd_quantize_fp_helper_c(
430 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, p->quant_fp_QTX,
431 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
432 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
433 } else {
434 av1_highbd_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
435 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
436 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
437 sc->iscan, qparam->log_scale);
438 }
439 }
440
av1_highbd_quantize_b_facade(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const MACROBLOCK_PLANE * p,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,uint16_t * eob_ptr,const SCAN_ORDER * sc,const QUANT_PARAM * qparam)441 void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
442 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
443 tran_low_t *qcoeff_ptr,
444 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
445 const SCAN_ORDER *sc,
446 const QUANT_PARAM *qparam) {
447 const qm_val_t *qm_ptr = qparam->qmatrix;
448 const qm_val_t *iqm_ptr = qparam->iqmatrix;
449 if (qparam->use_quant_b_adapt) {
450 if (qm_ptr != NULL && iqm_ptr != NULL) {
451 aom_highbd_quantize_b_adaptive_helper_c(
452 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
453 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
454 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
455 } else {
456 switch (qparam->log_scale) {
457 case 0:
458 aom_highbd_quantize_b_adaptive(
459 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
460 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
461 eob_ptr, sc->scan, sc->iscan);
462 break;
463 case 1:
464 aom_highbd_quantize_b_32x32_adaptive(
465 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
466 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
467 eob_ptr, sc->scan, sc->iscan);
468 break;
469 case 2:
470 aom_highbd_quantize_b_64x64_adaptive(
471 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
472 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
473 eob_ptr, sc->scan, sc->iscan);
474 break;
475 default: assert(0);
476 }
477 }
478 } else {
479 if (qm_ptr != NULL && iqm_ptr != NULL) {
480 aom_highbd_quantize_b_helper_c(
481 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
482 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
483 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
484 } else {
485 switch (qparam->log_scale) {
486 case 0:
487 aom_highbd_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
488 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
489 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
490 sc->iscan);
491 break;
492 case 1:
493 aom_highbd_quantize_b_32x32(
494 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
495 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
496 eob_ptr, sc->scan, sc->iscan);
497 break;
498 case 2:
499 aom_highbd_quantize_b_64x64(
500 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
501 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
502 eob_ptr, sc->scan, sc->iscan);
503 break;
504 default: assert(0);
505 }
506 }
507 }
508 }
509
highbd_quantize_dc(const tran_low_t * coeff_ptr,int n_coeffs,int skip_block,const int16_t * round_ptr,const int16_t quant,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t dequant_ptr,uint16_t * eob_ptr,const qm_val_t * qm_ptr,const qm_val_t * iqm_ptr,const int log_scale)510 static INLINE void highbd_quantize_dc(
511 const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
512 const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr,
513 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, uint16_t *eob_ptr,
514 const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr, const int log_scale) {
515 int eob = -1;
516
517 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
518 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
519
520 if (!skip_block) {
521 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[0] : (1 << AOM_QM_BITS);
522 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[0] : (1 << AOM_QM_BITS);
523 const int coeff = coeff_ptr[0];
524 const int coeff_sign = AOMSIGN(coeff);
525 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
526 const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], log_scale);
527 const int64_t tmpw = tmp * wt;
528 const int abs_qcoeff =
529 (int)((tmpw * quant) >> (16 - log_scale + AOM_QM_BITS));
530 qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
531 const int dequant =
532 (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
533
534 const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
535 dqcoeff_ptr[0] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
536 if (abs_qcoeff) eob = 0;
537 }
538 *eob_ptr = eob + 1;
539 }
540
av1_highbd_quantize_dc_facade(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const MACROBLOCK_PLANE * p,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,uint16_t * eob_ptr,const SCAN_ORDER * sc,const QUANT_PARAM * qparam)541 void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
542 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
543 tran_low_t *qcoeff_ptr,
544 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
545 const SCAN_ORDER *sc,
546 const QUANT_PARAM *qparam) {
547 // obsolete skip_block
548 const int skip_block = 0;
549 const qm_val_t *qm_ptr = qparam->qmatrix;
550 const qm_val_t *iqm_ptr = qparam->iqmatrix;
551 (void)sc;
552
553 highbd_quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
554 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr,
555 p->dequant_QTX[0], eob_ptr, qm_ptr, iqm_ptr,
556 qparam->log_scale);
557 }
558
av1_highbd_quantize_fp_c(const tran_low_t * coeff_ptr,intptr_t count,const int16_t * zbin_ptr,const int16_t * round_ptr,const int16_t * quant_ptr,const int16_t * quant_shift_ptr,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const int16_t * scan,const int16_t * iscan,int log_scale)559 void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
560 const int16_t *zbin_ptr, const int16_t *round_ptr,
561 const int16_t *quant_ptr,
562 const int16_t *quant_shift_ptr,
563 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
564 const int16_t *dequant_ptr, uint16_t *eob_ptr,
565 const int16_t *scan, const int16_t *iscan,
566 int log_scale) {
567 highbd_quantize_fp_helper_c(coeff_ptr, count, zbin_ptr, round_ptr, quant_ptr,
568 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
569 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL,
570 log_scale);
571 }
572 #endif // CONFIG_AV1_HIGHBITDEPTH
573
invert_quant(int16_t * quant,int16_t * shift,int d)574 static void invert_quant(int16_t *quant, int16_t *shift, int d) {
575 uint32_t t;
576 int l, m;
577 t = d;
578 for (l = 0; t > 1; l++) t >>= 1;
579 m = 1 + (1 << (16 + l)) / d;
580 *quant = (int16_t)(m - (1 << 16));
581 *shift = 1 << (16 - l);
582 }
583
get_qzbin_factor(int q,aom_bit_depth_t bit_depth)584 static int get_qzbin_factor(int q, aom_bit_depth_t bit_depth) {
585 const int quant = av1_dc_quant_QTX(q, 0, bit_depth);
586 switch (bit_depth) {
587 case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
588 case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
589 case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
590 default:
591 assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
592 return -1;
593 }
594 }
595
av1_build_quantizer(aom_bit_depth_t bit_depth,int y_dc_delta_q,int u_dc_delta_q,int u_ac_delta_q,int v_dc_delta_q,int v_ac_delta_q,QUANTS * const quants,Dequants * const deq)596 void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q,
597 int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q,
598 int v_ac_delta_q, QUANTS *const quants,
599 Dequants *const deq) {
600 int i, q, quant_QTX;
601
602 for (q = 0; q < QINDEX_RANGE; q++) {
603 const int qzbin_factor = get_qzbin_factor(q, bit_depth);
604 const int qrounding_factor = q == 0 ? 64 : 48;
605
606 for (i = 0; i < 2; ++i) {
607 const int qrounding_factor_fp = 64;
608 // y quantizer with TX scale
609 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth)
610 : av1_ac_quant_QTX(q, 0, bit_depth);
611 invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i],
612 quant_QTX);
613 quants->y_quant_fp[q][i] = (1 << 16) / quant_QTX;
614 quants->y_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
615 quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
616 quants->y_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
617 deq->y_dequant_QTX[q][i] = quant_QTX;
618
619 // u quantizer with TX scale
620 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth)
621 : av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth);
622 invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i],
623 quant_QTX);
624 quants->u_quant_fp[q][i] = (1 << 16) / quant_QTX;
625 quants->u_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
626 quants->u_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
627 quants->u_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
628 deq->u_dequant_QTX[q][i] = quant_QTX;
629
630 // v quantizer with TX scale
631 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth)
632 : av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth);
633 invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i],
634 quant_QTX);
635 quants->v_quant_fp[q][i] = (1 << 16) / quant_QTX;
636 quants->v_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
637 quants->v_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
638 quants->v_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
639 deq->v_dequant_QTX[q][i] = quant_QTX;
640 }
641
642 for (i = 2; i < 8; i++) { // 8: SIMD width
643 quants->y_quant[q][i] = quants->y_quant[q][1];
644 quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
645 quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
646 quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
647 quants->y_zbin[q][i] = quants->y_zbin[q][1];
648 quants->y_round[q][i] = quants->y_round[q][1];
649 deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1];
650
651 quants->u_quant[q][i] = quants->u_quant[q][1];
652 quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1];
653 quants->u_round_fp[q][i] = quants->u_round_fp[q][1];
654 quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1];
655 quants->u_zbin[q][i] = quants->u_zbin[q][1];
656 quants->u_round[q][i] = quants->u_round[q][1];
657 deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1];
658
659 quants->v_quant[q][i] = quants->v_quant[q][1];
660 quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1];
661 quants->v_round_fp[q][i] = quants->v_round_fp[q][1];
662 quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1];
663 quants->v_zbin[q][i] = quants->v_zbin[q][1];
664 quants->v_round[q][i] = quants->v_round[q][1];
665 deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1];
666 }
667 }
668 }
669
av1_init_quantizer(EncQuantDequantParams * const enc_quant_dequant_params,const CommonQuantParams * quant_params,aom_bit_depth_t bit_depth)670 void av1_init_quantizer(EncQuantDequantParams *const enc_quant_dequant_params,
671 const CommonQuantParams *quant_params,
672 aom_bit_depth_t bit_depth) {
673 QUANTS *const quants = &enc_quant_dequant_params->quants;
674 Dequants *const dequants = &enc_quant_dequant_params->dequants;
675 av1_build_quantizer(bit_depth, quant_params->y_dc_delta_q,
676 quant_params->u_dc_delta_q, quant_params->u_ac_delta_q,
677 quant_params->v_dc_delta_q, quant_params->v_ac_delta_q,
678 quants, dequants);
679 }
680
av1_set_q_index(const EncQuantDequantParams * enc_quant_dequant_params,int qindex,MACROBLOCK * x)681 void av1_set_q_index(const EncQuantDequantParams *enc_quant_dequant_params,
682 int qindex, MACROBLOCK *x) {
683 const QUANTS *const quants = &enc_quant_dequant_params->quants;
684 const Dequants *const dequants = &enc_quant_dequant_params->dequants;
685 x->qindex = qindex;
686 x->seg_skip_block =
687 0; // TODO(angiebird): Find a proper place to init this variable.
688
689 // Y
690 x->plane[0].quant_QTX = quants->y_quant[qindex];
691 x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex];
692 x->plane[0].round_fp_QTX = quants->y_round_fp[qindex];
693 x->plane[0].quant_shift_QTX = quants->y_quant_shift[qindex];
694 x->plane[0].zbin_QTX = quants->y_zbin[qindex];
695 x->plane[0].round_QTX = quants->y_round[qindex];
696 x->plane[0].dequant_QTX = dequants->y_dequant_QTX[qindex];
697
698 // U
699 x->plane[1].quant_QTX = quants->u_quant[qindex];
700 x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex];
701 x->plane[1].round_fp_QTX = quants->u_round_fp[qindex];
702 x->plane[1].quant_shift_QTX = quants->u_quant_shift[qindex];
703 x->plane[1].zbin_QTX = quants->u_zbin[qindex];
704 x->plane[1].round_QTX = quants->u_round[qindex];
705 x->plane[1].dequant_QTX = dequants->u_dequant_QTX[qindex];
706
707 // V
708 x->plane[2].quant_QTX = quants->v_quant[qindex];
709 x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex];
710 x->plane[2].round_fp_QTX = quants->v_round_fp[qindex];
711 x->plane[2].quant_shift_QTX = quants->v_quant_shift[qindex];
712 x->plane[2].zbin_QTX = quants->v_zbin[qindex];
713 x->plane[2].round_QTX = quants->v_round[qindex];
714 x->plane[2].dequant_QTX = dequants->v_dequant_QTX[qindex];
715 }
716
av1_set_qmatrix(const CommonQuantParams * quant_params,int segment_id,MACROBLOCKD * xd)717 void av1_set_qmatrix(const CommonQuantParams *quant_params, int segment_id,
718 MACROBLOCKD *xd) {
719 const int use_qmatrix = av1_use_qmatrix(quant_params, xd, segment_id);
720 const int qmlevel_y =
721 use_qmatrix ? quant_params->qmatrix_level_y : NUM_QM_LEVELS - 1;
722 const int qmlevel_u =
723 use_qmatrix ? quant_params->qmatrix_level_u : NUM_QM_LEVELS - 1;
724 const int qmlevel_v =
725 use_qmatrix ? quant_params->qmatrix_level_v : NUM_QM_LEVELS - 1;
726 const int qmlevel_ls[MAX_MB_PLANE] = { qmlevel_y, qmlevel_u, qmlevel_v };
727 for (int i = 0; i < MAX_MB_PLANE; ++i) {
728 const int qmlevel = qmlevel_ls[i];
729 memcpy(&xd->plane[i].seg_qmatrix[segment_id],
730 quant_params->gqmatrix[qmlevel][i],
731 sizeof(quant_params->gqmatrix[qmlevel][i]));
732 memcpy(&xd->plane[i].seg_iqmatrix[segment_id],
733 quant_params->giqmatrix[qmlevel][i],
734 sizeof(quant_params->giqmatrix[qmlevel][i]));
735 }
736 }
737
av1_init_plane_quantizers(const AV1_COMP * cpi,MACROBLOCK * x,int segment_id)738 void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x,
739 int segment_id) {
740 const AV1_COMMON *const cm = &cpi->common;
741 const CommonQuantParams *const quant_params = &cm->quant_params;
742 const int current_qindex = AOMMAX(
743 0,
744 AOMMIN(QINDEX_RANGE - 1, cm->delta_q_info.delta_q_present_flag
745 ? quant_params->base_qindex + x->delta_qindex
746 : quant_params->base_qindex));
747 const int qindex = av1_get_qindex(&cm->seg, segment_id, current_qindex);
748 const int rdmult =
749 av1_compute_rd_mult(cpi, qindex + quant_params->y_dc_delta_q);
750 av1_set_q_index(&cpi->enc_quant_dequant_params, qindex, x);
751
752 MACROBLOCKD *const xd = &x->e_mbd;
753 av1_set_qmatrix(quant_params, segment_id, xd);
754
755 x->seg_skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
756
757 av1_set_error_per_bit(&x->errorperbit, rdmult);
758 av1_set_sad_per_bit(cpi, &x->sadperbit, qindex);
759 }
760
av1_frame_init_quantizer(AV1_COMP * cpi)761 void av1_frame_init_quantizer(AV1_COMP *cpi) {
762 MACROBLOCK *const x = &cpi->td.mb;
763 MACROBLOCKD *const xd = &x->e_mbd;
764 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id);
765 }
766
av1_set_quantizer(AV1_COMMON * const cm,int min_qmlevel,int max_qmlevel,int q,int enable_chroma_deltaq)767 void av1_set_quantizer(AV1_COMMON *const cm, int min_qmlevel, int max_qmlevel,
768 int q, int enable_chroma_deltaq) {
769 // quantizer has to be reinitialized with av1_init_quantizer() if any
770 // delta_q changes.
771 CommonQuantParams *quant_params = &cm->quant_params;
772 quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q);
773
774 quant_params->y_dc_delta_q = 0;
775 if (enable_chroma_deltaq) {
776 // TODO(aomedia:2717): need to design better delta
777 quant_params->u_dc_delta_q = 2;
778 quant_params->u_ac_delta_q = 2;
779 quant_params->v_dc_delta_q = 2;
780 quant_params->v_ac_delta_q = 2;
781 } else {
782 quant_params->u_dc_delta_q = 0;
783 quant_params->u_ac_delta_q = 0;
784 quant_params->v_dc_delta_q = 0;
785 quant_params->v_ac_delta_q = 0;
786 }
787
788 quant_params->qmatrix_level_y =
789 aom_get_qmlevel(quant_params->base_qindex, min_qmlevel, max_qmlevel);
790 quant_params->qmatrix_level_u =
791 aom_get_qmlevel(quant_params->base_qindex + quant_params->u_ac_delta_q,
792 min_qmlevel, max_qmlevel);
793
794 if (!cm->seq_params->separate_uv_delta_q)
795 quant_params->qmatrix_level_v = quant_params->qmatrix_level_u;
796 else
797 quant_params->qmatrix_level_v =
798 aom_get_qmlevel(quant_params->base_qindex + quant_params->v_ac_delta_q,
799 min_qmlevel, max_qmlevel);
800 }
801
802 // Table that converts 0-63 Q-range values passed in outside to the Qindex
803 // range used internally.
804 static const int quantizer_to_qindex[] = {
805 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
806 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100,
807 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
808 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204,
809 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255,
810 };
811
av1_quantizer_to_qindex(int quantizer)812 int av1_quantizer_to_qindex(int quantizer) {
813 return quantizer_to_qindex[quantizer];
814 }
815
av1_qindex_to_quantizer(int qindex)816 int av1_qindex_to_quantizer(int qindex) {
817 int quantizer;
818
819 for (quantizer = 0; quantizer < 64; ++quantizer)
820 if (quantizer_to_qindex[quantizer] >= qindex) return quantizer;
821
822 return 63;
823 }
824