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