xref: /aosp_15_r20/external/libaom/av1/encoder/av1_quantize.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
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