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