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