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 !CONFIG_REALTIME_ONLY
309 if (qparam->use_quant_b_adapt) {
310 // TODO(sarahparker) These quantize_b optimizations need SIMD
311 // implementations
312 if (qm_ptr != NULL && iqm_ptr != NULL) {
313 aom_quantize_b_adaptive_helper_c(
314 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
315 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
316 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
317 } else {
318 switch (qparam->log_scale) {
319 case 0:
320 aom_quantize_b_adaptive(coeff_ptr, n_coeffs, p->zbin_QTX,
321 p->round_QTX, p->quant_QTX,
322 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr,
323 p->dequant_QTX, eob_ptr, sc->scan, sc->iscan);
324 break;
325 case 1:
326 aom_quantize_b_32x32_adaptive(
327 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
328 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
329 eob_ptr, sc->scan, sc->iscan);
330 break;
331 case 2:
332 aom_quantize_b_64x64_adaptive(
333 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
334 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
335 eob_ptr, sc->scan, sc->iscan);
336 break;
337 default: assert(0);
338 }
339 }
340 return;
341 }
342 #endif // !CONFIG_REALTIME_ONLY
343
344 if (qm_ptr != NULL && iqm_ptr != NULL) {
345 aom_quantize_b_helper_c(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
346 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
347 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
348 sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
349 } else {
350 switch (qparam->log_scale) {
351 case 0:
352 aom_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
353 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
354 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
355 sc->iscan);
356 break;
357 case 1:
358 aom_quantize_b_32x32(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
359 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
360 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
361 sc->iscan);
362 break;
363 case 2:
364 aom_quantize_b_64x64(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
365 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
366 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
367 sc->iscan);
368 break;
369 default: assert(0);
370 }
371 }
372 }
373
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)374 static void quantize_dc(const tran_low_t *coeff_ptr, int n_coeffs,
375 int skip_block, const int16_t *round_ptr,
376 const int16_t quant, tran_low_t *qcoeff_ptr,
377 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr,
378 uint16_t *eob_ptr, const qm_val_t *qm_ptr,
379 const qm_val_t *iqm_ptr, const int log_scale) {
380 const int rc = 0;
381 const int coeff = coeff_ptr[rc];
382 const int coeff_sign = AOMSIGN(coeff);
383 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
384 int64_t tmp;
385 int eob = -1;
386 int32_t tmp32;
387 int dequant;
388
389 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
390 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
391
392 if (!skip_block) {
393 const int wt = qm_ptr != NULL ? qm_ptr[rc] : (1 << AOM_QM_BITS);
394 const int iwt = iqm_ptr != NULL ? iqm_ptr[rc] : (1 << AOM_QM_BITS);
395 tmp = clamp(abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], log_scale),
396 INT16_MIN, INT16_MAX);
397 tmp32 = (int32_t)((tmp * wt * quant) >> (16 - log_scale + AOM_QM_BITS));
398 qcoeff_ptr[rc] = (tmp32 ^ coeff_sign) - coeff_sign;
399 dequant = (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
400 const tran_low_t abs_dqcoeff = (tmp32 * dequant) >> log_scale;
401 dqcoeff_ptr[rc] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
402 if (tmp32) eob = 0;
403 }
404 *eob_ptr = eob + 1;
405 }
406
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)407 void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
408 const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
409 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
410 const SCAN_ORDER *sc, const QUANT_PARAM *qparam) {
411 // obsolete skip_block
412 const int skip_block = 0;
413 (void)sc;
414 assert(qparam->log_scale >= 0 && qparam->log_scale < (3));
415 const qm_val_t *qm_ptr = qparam->qmatrix;
416 const qm_val_t *iqm_ptr = qparam->iqmatrix;
417 quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
418 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX[0],
419 eob_ptr, qm_ptr, iqm_ptr, qparam->log_scale);
420 }
421
422 #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)423 void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
424 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
425 tran_low_t *qcoeff_ptr,
426 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
427 const SCAN_ORDER *sc,
428 const QUANT_PARAM *qparam) {
429 const qm_val_t *qm_ptr = qparam->qmatrix;
430 const qm_val_t *iqm_ptr = qparam->iqmatrix;
431 if (qm_ptr != NULL && iqm_ptr != NULL) {
432 highbd_quantize_fp_helper_c(
433 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX, p->quant_fp_QTX,
434 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
435 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
436 } else {
437 av1_highbd_quantize_fp(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_fp_QTX,
438 p->quant_fp_QTX, p->quant_shift_QTX, qcoeff_ptr,
439 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
440 sc->iscan, qparam->log_scale);
441 }
442 }
443
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)444 void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
445 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
446 tran_low_t *qcoeff_ptr,
447 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
448 const SCAN_ORDER *sc,
449 const QUANT_PARAM *qparam) {
450 const qm_val_t *qm_ptr = qparam->qmatrix;
451 const qm_val_t *iqm_ptr = qparam->iqmatrix;
452 #if !CONFIG_REALTIME_ONLY
453 if (qparam->use_quant_b_adapt) {
454 if (qm_ptr != NULL && iqm_ptr != NULL) {
455 aom_highbd_quantize_b_adaptive_helper_c(
456 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
457 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
458 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
459 } else {
460 switch (qparam->log_scale) {
461 case 0:
462 aom_highbd_quantize_b_adaptive(
463 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
464 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
465 eob_ptr, sc->scan, sc->iscan);
466 break;
467 case 1:
468 aom_highbd_quantize_b_32x32_adaptive(
469 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
470 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
471 eob_ptr, sc->scan, sc->iscan);
472 break;
473 case 2:
474 aom_highbd_quantize_b_64x64_adaptive(
475 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
476 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
477 eob_ptr, sc->scan, sc->iscan);
478 break;
479 default: assert(0);
480 }
481 }
482 return;
483 }
484 #endif // !CONFIG_REALTIME_ONLY
485
486 if (qm_ptr != NULL && iqm_ptr != NULL) {
487 aom_highbd_quantize_b_helper_c(
488 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
489 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX, eob_ptr,
490 sc->scan, sc->iscan, qm_ptr, iqm_ptr, qparam->log_scale);
491 } else {
492 switch (qparam->log_scale) {
493 case 0:
494 aom_highbd_quantize_b(coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX,
495 p->quant_QTX, p->quant_shift_QTX, qcoeff_ptr,
496 dqcoeff_ptr, p->dequant_QTX, eob_ptr, sc->scan,
497 sc->iscan);
498 break;
499 case 1:
500 aom_highbd_quantize_b_32x32(
501 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
502 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
503 eob_ptr, sc->scan, sc->iscan);
504 break;
505 case 2:
506 aom_highbd_quantize_b_64x64(
507 coeff_ptr, n_coeffs, p->zbin_QTX, p->round_QTX, p->quant_QTX,
508 p->quant_shift_QTX, qcoeff_ptr, dqcoeff_ptr, p->dequant_QTX,
509 eob_ptr, sc->scan, sc->iscan);
510 break;
511 default: assert(0);
512 }
513 }
514 }
515
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)516 static INLINE void highbd_quantize_dc(
517 const tran_low_t *coeff_ptr, int n_coeffs, int skip_block,
518 const int16_t *round_ptr, const int16_t quant, tran_low_t *qcoeff_ptr,
519 tran_low_t *dqcoeff_ptr, const int16_t dequant_ptr, uint16_t *eob_ptr,
520 const qm_val_t *qm_ptr, const qm_val_t *iqm_ptr, const int log_scale) {
521 int eob = -1;
522
523 memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
524 memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
525
526 if (!skip_block) {
527 const qm_val_t wt = qm_ptr != NULL ? qm_ptr[0] : (1 << AOM_QM_BITS);
528 const qm_val_t iwt = iqm_ptr != NULL ? iqm_ptr[0] : (1 << AOM_QM_BITS);
529 const int coeff = coeff_ptr[0];
530 const int coeff_sign = AOMSIGN(coeff);
531 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
532 const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[0], log_scale);
533 const int64_t tmpw = tmp * wt;
534 const int abs_qcoeff =
535 (int)((tmpw * quant) >> (16 - log_scale + AOM_QM_BITS));
536 qcoeff_ptr[0] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
537 const int dequant =
538 (dequant_ptr * iwt + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
539
540 const tran_low_t abs_dqcoeff = (abs_qcoeff * dequant) >> log_scale;
541 dqcoeff_ptr[0] = (tran_low_t)((abs_dqcoeff ^ coeff_sign) - coeff_sign);
542 if (abs_qcoeff) eob = 0;
543 }
544 *eob_ptr = eob + 1;
545 }
546
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)547 void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
548 intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
549 tran_low_t *qcoeff_ptr,
550 tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
551 const SCAN_ORDER *sc,
552 const QUANT_PARAM *qparam) {
553 // obsolete skip_block
554 const int skip_block = 0;
555 const qm_val_t *qm_ptr = qparam->qmatrix;
556 const qm_val_t *iqm_ptr = qparam->iqmatrix;
557 (void)sc;
558
559 highbd_quantize_dc(coeff_ptr, (int)n_coeffs, skip_block, p->round_QTX,
560 p->quant_fp_QTX[0], qcoeff_ptr, dqcoeff_ptr,
561 p->dequant_QTX[0], eob_ptr, qm_ptr, iqm_ptr,
562 qparam->log_scale);
563 }
564
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)565 void av1_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t count,
566 const int16_t *zbin_ptr, const int16_t *round_ptr,
567 const int16_t *quant_ptr,
568 const int16_t *quant_shift_ptr,
569 tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
570 const int16_t *dequant_ptr, uint16_t *eob_ptr,
571 const int16_t *scan, const int16_t *iscan,
572 int log_scale) {
573 highbd_quantize_fp_helper_c(coeff_ptr, count, zbin_ptr, round_ptr, quant_ptr,
574 quant_shift_ptr, qcoeff_ptr, dqcoeff_ptr,
575 dequant_ptr, eob_ptr, scan, iscan, NULL, NULL,
576 log_scale);
577 }
578 #endif // CONFIG_AV1_HIGHBITDEPTH
579
invert_quant(int16_t * quant,int16_t * shift,int d)580 static void invert_quant(int16_t *quant, int16_t *shift, int d) {
581 uint32_t t;
582 int l, m;
583 t = d;
584 for (l = 0; t > 1; l++) t >>= 1;
585 m = 1 + (1 << (16 + l)) / d;
586 *quant = (int16_t)(m - (1 << 16));
587 *shift = 1 << (16 - l);
588 }
589
get_qzbin_factor(int q,aom_bit_depth_t bit_depth)590 static int get_qzbin_factor(int q, aom_bit_depth_t bit_depth) {
591 const int quant = av1_dc_quant_QTX(q, 0, bit_depth);
592 switch (bit_depth) {
593 case AOM_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
594 case AOM_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
595 case AOM_BITS_12: return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
596 default:
597 assert(0 && "bit_depth should be AOM_BITS_8, AOM_BITS_10 or AOM_BITS_12");
598 return -1;
599 }
600 }
601
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)602 void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q,
603 int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q,
604 int v_ac_delta_q, QUANTS *const quants,
605 Dequants *const deq) {
606 int i, q, quant_QTX;
607
608 for (q = 0; q < QINDEX_RANGE; q++) {
609 const int qzbin_factor = get_qzbin_factor(q, bit_depth);
610 const int qrounding_factor = q == 0 ? 64 : 48;
611
612 for (i = 0; i < 2; ++i) {
613 const int qrounding_factor_fp = 64;
614 // y quantizer with TX scale
615 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, y_dc_delta_q, bit_depth)
616 : av1_ac_quant_QTX(q, 0, bit_depth);
617 invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i],
618 quant_QTX);
619 quants->y_quant_fp[q][i] = (1 << 16) / quant_QTX;
620 quants->y_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
621 quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
622 quants->y_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
623 deq->y_dequant_QTX[q][i] = quant_QTX;
624
625 // u quantizer with TX scale
626 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, u_dc_delta_q, bit_depth)
627 : av1_ac_quant_QTX(q, u_ac_delta_q, bit_depth);
628 invert_quant(&quants->u_quant[q][i], &quants->u_quant_shift[q][i],
629 quant_QTX);
630 quants->u_quant_fp[q][i] = (1 << 16) / quant_QTX;
631 quants->u_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
632 quants->u_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
633 quants->u_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
634 deq->u_dequant_QTX[q][i] = quant_QTX;
635
636 // v quantizer with TX scale
637 quant_QTX = i == 0 ? av1_dc_quant_QTX(q, v_dc_delta_q, bit_depth)
638 : av1_ac_quant_QTX(q, v_ac_delta_q, bit_depth);
639 invert_quant(&quants->v_quant[q][i], &quants->v_quant_shift[q][i],
640 quant_QTX);
641 quants->v_quant_fp[q][i] = (1 << 16) / quant_QTX;
642 quants->v_round_fp[q][i] = (qrounding_factor_fp * quant_QTX) >> 7;
643 quants->v_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant_QTX, 7);
644 quants->v_round[q][i] = (qrounding_factor * quant_QTX) >> 7;
645 deq->v_dequant_QTX[q][i] = quant_QTX;
646 }
647
648 for (i = 2; i < 8; i++) { // 8: SIMD width
649 quants->y_quant[q][i] = quants->y_quant[q][1];
650 quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
651 quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
652 quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
653 quants->y_zbin[q][i] = quants->y_zbin[q][1];
654 quants->y_round[q][i] = quants->y_round[q][1];
655 deq->y_dequant_QTX[q][i] = deq->y_dequant_QTX[q][1];
656
657 quants->u_quant[q][i] = quants->u_quant[q][1];
658 quants->u_quant_fp[q][i] = quants->u_quant_fp[q][1];
659 quants->u_round_fp[q][i] = quants->u_round_fp[q][1];
660 quants->u_quant_shift[q][i] = quants->u_quant_shift[q][1];
661 quants->u_zbin[q][i] = quants->u_zbin[q][1];
662 quants->u_round[q][i] = quants->u_round[q][1];
663 deq->u_dequant_QTX[q][i] = deq->u_dequant_QTX[q][1];
664
665 quants->v_quant[q][i] = quants->v_quant[q][1];
666 quants->v_quant_fp[q][i] = quants->v_quant_fp[q][1];
667 quants->v_round_fp[q][i] = quants->v_round_fp[q][1];
668 quants->v_quant_shift[q][i] = quants->v_quant_shift[q][1];
669 quants->v_zbin[q][i] = quants->v_zbin[q][1];
670 quants->v_round[q][i] = quants->v_round[q][1];
671 deq->v_dequant_QTX[q][i] = deq->v_dequant_QTX[q][1];
672 }
673 }
674 }
675
av1_init_quantizer(EncQuantDequantParams * const enc_quant_dequant_params,const CommonQuantParams * quant_params,aom_bit_depth_t bit_depth)676 void av1_init_quantizer(EncQuantDequantParams *const enc_quant_dequant_params,
677 const CommonQuantParams *quant_params,
678 aom_bit_depth_t bit_depth) {
679 QUANTS *const quants = &enc_quant_dequant_params->quants;
680 Dequants *const dequants = &enc_quant_dequant_params->dequants;
681 av1_build_quantizer(bit_depth, quant_params->y_dc_delta_q,
682 quant_params->u_dc_delta_q, quant_params->u_ac_delta_q,
683 quant_params->v_dc_delta_q, quant_params->v_ac_delta_q,
684 quants, dequants);
685 }
686
av1_set_q_index(const EncQuantDequantParams * enc_quant_dequant_params,int qindex,MACROBLOCK * x)687 void av1_set_q_index(const EncQuantDequantParams *enc_quant_dequant_params,
688 int qindex, MACROBLOCK *x) {
689 const QUANTS *const quants = &enc_quant_dequant_params->quants;
690 const Dequants *const dequants = &enc_quant_dequant_params->dequants;
691 x->qindex = qindex;
692 x->seg_skip_block =
693 0; // TODO(angiebird): Find a proper place to init this variable.
694
695 // Y
696 x->plane[0].quant_QTX = quants->y_quant[qindex];
697 x->plane[0].quant_fp_QTX = quants->y_quant_fp[qindex];
698 x->plane[0].round_fp_QTX = quants->y_round_fp[qindex];
699 x->plane[0].quant_shift_QTX = quants->y_quant_shift[qindex];
700 x->plane[0].zbin_QTX = quants->y_zbin[qindex];
701 x->plane[0].round_QTX = quants->y_round[qindex];
702 x->plane[0].dequant_QTX = dequants->y_dequant_QTX[qindex];
703
704 // U
705 x->plane[1].quant_QTX = quants->u_quant[qindex];
706 x->plane[1].quant_fp_QTX = quants->u_quant_fp[qindex];
707 x->plane[1].round_fp_QTX = quants->u_round_fp[qindex];
708 x->plane[1].quant_shift_QTX = quants->u_quant_shift[qindex];
709 x->plane[1].zbin_QTX = quants->u_zbin[qindex];
710 x->plane[1].round_QTX = quants->u_round[qindex];
711 x->plane[1].dequant_QTX = dequants->u_dequant_QTX[qindex];
712
713 // V
714 x->plane[2].quant_QTX = quants->v_quant[qindex];
715 x->plane[2].quant_fp_QTX = quants->v_quant_fp[qindex];
716 x->plane[2].round_fp_QTX = quants->v_round_fp[qindex];
717 x->plane[2].quant_shift_QTX = quants->v_quant_shift[qindex];
718 x->plane[2].zbin_QTX = quants->v_zbin[qindex];
719 x->plane[2].round_QTX = quants->v_round[qindex];
720 x->plane[2].dequant_QTX = dequants->v_dequant_QTX[qindex];
721 }
722
av1_set_qmatrix(const CommonQuantParams * quant_params,int segment_id,MACROBLOCKD * xd)723 void av1_set_qmatrix(const CommonQuantParams *quant_params, int segment_id,
724 MACROBLOCKD *xd) {
725 const int use_qmatrix = av1_use_qmatrix(quant_params, xd, segment_id);
726 const int qmlevel_y =
727 use_qmatrix ? quant_params->qmatrix_level_y : NUM_QM_LEVELS - 1;
728 const int qmlevel_u =
729 use_qmatrix ? quant_params->qmatrix_level_u : NUM_QM_LEVELS - 1;
730 const int qmlevel_v =
731 use_qmatrix ? quant_params->qmatrix_level_v : NUM_QM_LEVELS - 1;
732 const int qmlevel_ls[MAX_MB_PLANE] = { qmlevel_y, qmlevel_u, qmlevel_v };
733 for (int i = 0; i < MAX_MB_PLANE; ++i) {
734 const int qmlevel = qmlevel_ls[i];
735 memcpy(&xd->plane[i].seg_qmatrix[segment_id],
736 quant_params->gqmatrix[qmlevel][i],
737 sizeof(quant_params->gqmatrix[qmlevel][i]));
738 memcpy(&xd->plane[i].seg_iqmatrix[segment_id],
739 quant_params->giqmatrix[qmlevel][i],
740 sizeof(quant_params->giqmatrix[qmlevel][i]));
741 }
742 }
743
av1_init_plane_quantizers(const AV1_COMP * cpi,MACROBLOCK * x,int segment_id,const int do_update)744 void av1_init_plane_quantizers(const AV1_COMP *cpi, MACROBLOCK *x,
745 int segment_id, const int do_update) {
746 const AV1_COMMON *const cm = &cpi->common;
747 const CommonQuantParams *const quant_params = &cm->quant_params;
748 const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
749 const int boost_index = AOMMIN(15, (cpi->ppi->p_rc.gfu_boost / 100));
750 const int layer_depth = AOMMIN(gf_group->layer_depth[cpi->gf_frame_index], 6);
751 const FRAME_TYPE frame_type = cm->current_frame.frame_type;
752 int qindex_rd;
753
754 const int current_qindex = AOMMAX(
755 0,
756 AOMMIN(QINDEX_RANGE - 1, cm->delta_q_info.delta_q_present_flag
757 ? quant_params->base_qindex + x->delta_qindex
758 : quant_params->base_qindex));
759 const int qindex = av1_get_qindex(&cm->seg, segment_id, current_qindex);
760
761 if (cpi->oxcf.sb_qp_sweep) {
762 const int current_rd_qindex =
763 AOMMAX(0, AOMMIN(QINDEX_RANGE - 1, cm->delta_q_info.delta_q_present_flag
764 ? quant_params->base_qindex +
765 x->rdmult_delta_qindex
766 : quant_params->base_qindex));
767 qindex_rd = av1_get_qindex(&cm->seg, segment_id, current_rd_qindex);
768 } else {
769 qindex_rd = qindex;
770 }
771
772 const int qindex_rdmult = qindex_rd + quant_params->y_dc_delta_q;
773 const int rdmult = av1_compute_rd_mult(
774 qindex_rdmult, cm->seq_params->bit_depth,
775 cpi->ppi->gf_group.update_type[cpi->gf_frame_index], layer_depth,
776 boost_index, frame_type, cpi->oxcf.q_cfg.use_fixed_qp_offsets,
777 is_stat_consumption_stage(cpi));
778
779 const int qindex_change = x->qindex != qindex;
780 if (qindex_change || do_update) {
781 av1_set_q_index(&cpi->enc_quant_dequant_params, qindex, x);
782 }
783
784 MACROBLOCKD *const xd = &x->e_mbd;
785 if ((segment_id != x->prev_segment_id) ||
786 av1_use_qmatrix(quant_params, xd, segment_id)) {
787 av1_set_qmatrix(quant_params, segment_id, xd);
788 }
789
790 x->seg_skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
791
792 av1_set_error_per_bit(&x->errorperbit, rdmult);
793 av1_set_sad_per_bit(cpi, &x->sadperbit, qindex_rd);
794
795 x->prev_segment_id = segment_id;
796 }
797
av1_frame_init_quantizer(AV1_COMP * cpi)798 void av1_frame_init_quantizer(AV1_COMP *cpi) {
799 MACROBLOCK *const x = &cpi->td.mb;
800 MACROBLOCKD *const xd = &x->e_mbd;
801 x->prev_segment_id = -1;
802 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 1);
803 }
804
adjust_hdr_cb_deltaq(int base_qindex)805 static int adjust_hdr_cb_deltaq(int base_qindex) {
806 double baseQp = base_qindex / QP_SCALE_FACTOR;
807 const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET;
808 const double dcbQP = CHROMA_CB_QP_SCALE * chromaQp * QP_SCALE_FACTOR;
809 int dqpCb = (int)(dcbQP + (dcbQP < 0 ? -0.5 : 0.5));
810 dqpCb = AOMMIN(0, dqpCb);
811 dqpCb = (int)CLIP(dqpCb, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR);
812 return dqpCb;
813 }
814
adjust_hdr_cr_deltaq(int base_qindex)815 static int adjust_hdr_cr_deltaq(int base_qindex) {
816 double baseQp = base_qindex / QP_SCALE_FACTOR;
817 const double chromaQp = CHROMA_QP_SCALE * baseQp + CHROMA_QP_OFFSET;
818 const double dcrQP = CHROMA_CR_QP_SCALE * chromaQp * QP_SCALE_FACTOR;
819 int dqpCr = (int)(dcrQP + (dcrQP < 0 ? -0.5 : 0.5));
820 dqpCr = AOMMIN(0, dqpCr);
821 dqpCr = (int)CLIP(dqpCr, -12 * QP_SCALE_FACTOR, 12 * QP_SCALE_FACTOR);
822 return dqpCr;
823 }
824
av1_set_quantizer(AV1_COMMON * const cm,int min_qmlevel,int max_qmlevel,int q,int enable_chroma_deltaq,int enable_hdr_deltaq)825 void av1_set_quantizer(AV1_COMMON *const cm, int min_qmlevel, int max_qmlevel,
826 int q, int enable_chroma_deltaq, int enable_hdr_deltaq) {
827 // quantizer has to be reinitialized with av1_init_quantizer() if any
828 // delta_q changes.
829 CommonQuantParams *quant_params = &cm->quant_params;
830 quant_params->base_qindex = AOMMAX(cm->delta_q_info.delta_q_present_flag, q);
831 quant_params->y_dc_delta_q = 0;
832
833 if (enable_chroma_deltaq) {
834 // TODO(aomedia:2717): need to design better delta
835 quant_params->u_dc_delta_q = 2;
836 quant_params->u_ac_delta_q = 2;
837 quant_params->v_dc_delta_q = 2;
838 quant_params->v_ac_delta_q = 2;
839 } else {
840 quant_params->u_dc_delta_q = 0;
841 quant_params->u_ac_delta_q = 0;
842 quant_params->v_dc_delta_q = 0;
843 quant_params->v_ac_delta_q = 0;
844 }
845
846 // following section 8.3.2 in T-REC-H.Sup15 document
847 // to apply to AV1 qindex in the range of [0, 255]
848 if (enable_hdr_deltaq) {
849 int dqpCb = adjust_hdr_cb_deltaq(quant_params->base_qindex);
850 int dqpCr = adjust_hdr_cr_deltaq(quant_params->base_qindex);
851 quant_params->u_dc_delta_q = quant_params->u_ac_delta_q = dqpCb;
852 quant_params->v_dc_delta_q = quant_params->v_ac_delta_q = dqpCr;
853 if (dqpCb != dqpCr) {
854 cm->seq_params->separate_uv_delta_q = 1;
855 }
856 }
857
858 quant_params->qmatrix_level_y =
859 aom_get_qmlevel(quant_params->base_qindex, min_qmlevel, max_qmlevel);
860 quant_params->qmatrix_level_u =
861 aom_get_qmlevel(quant_params->base_qindex + quant_params->u_ac_delta_q,
862 min_qmlevel, max_qmlevel);
863
864 if (!cm->seq_params->separate_uv_delta_q)
865 quant_params->qmatrix_level_v = quant_params->qmatrix_level_u;
866 else
867 quant_params->qmatrix_level_v =
868 aom_get_qmlevel(quant_params->base_qindex + quant_params->v_ac_delta_q,
869 min_qmlevel, max_qmlevel);
870 }
871
872 // Table that converts 0-63 Q-range values passed in outside to the Qindex
873 // range used internally.
874 static const int quantizer_to_qindex[] = {
875 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
876 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100,
877 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
878 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204,
879 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255,
880 };
881
av1_quantizer_to_qindex(int quantizer)882 int av1_quantizer_to_qindex(int quantizer) {
883 return quantizer_to_qindex[quantizer];
884 }
885
av1_qindex_to_quantizer(int qindex)886 int av1_qindex_to_quantizer(int qindex) {
887 int quantizer;
888
889 for (quantizer = 0; quantizer < 64; ++quantizer)
890 if (quantizer_to_qindex[quantizer] >= qindex) return quantizer;
891
892 return 63;
893 }
894