xref: /aosp_15_r20/external/libaom/av1/encoder/av1_quantize.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_AV1_ENCODER_AV1_QUANTIZE_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_ENCODER_AV1_QUANTIZE_H_
14*77c1e3ccSAndroid Build Coastguard Worker 
15*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
16*77c1e3ccSAndroid Build Coastguard Worker 
17*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/quant_common.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/scan.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/block.h"
20*77c1e3ccSAndroid Build Coastguard Worker 
21*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
22*77c1e3ccSAndroid Build Coastguard Worker extern "C" {
23*77c1e3ccSAndroid Build Coastguard Worker #endif
24*77c1e3ccSAndroid Build Coastguard Worker 
25*77c1e3ccSAndroid Build Coastguard Worker typedef struct QUANT_PARAM {
26*77c1e3ccSAndroid Build Coastguard Worker   int log_scale;
27*77c1e3ccSAndroid Build Coastguard Worker   TX_SIZE tx_size;
28*77c1e3ccSAndroid Build Coastguard Worker   const qm_val_t *qmatrix;
29*77c1e3ccSAndroid Build Coastguard Worker   const qm_val_t *iqmatrix;
30*77c1e3ccSAndroid Build Coastguard Worker   int use_quant_b_adapt;
31*77c1e3ccSAndroid Build Coastguard Worker   int use_optimize_b;
32*77c1e3ccSAndroid Build Coastguard Worker   int xform_quant_idx;
33*77c1e3ccSAndroid Build Coastguard Worker } QUANT_PARAM;
34*77c1e3ccSAndroid Build Coastguard Worker 
35*77c1e3ccSAndroid Build Coastguard Worker typedef void (*AV1_QUANT_FACADE)(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
36*77c1e3ccSAndroid Build Coastguard Worker                                  const MACROBLOCK_PLANE *p,
37*77c1e3ccSAndroid Build Coastguard Worker                                  tran_low_t *qcoeff_ptr,
38*77c1e3ccSAndroid Build Coastguard Worker                                  tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
39*77c1e3ccSAndroid Build Coastguard Worker                                  const SCAN_ORDER *sc,
40*77c1e3ccSAndroid Build Coastguard Worker                                  const QUANT_PARAM *qparam);
41*77c1e3ccSAndroid Build Coastguard Worker 
42*77c1e3ccSAndroid Build Coastguard Worker // The QUANTS structure is used only for internal quantizer setup in
43*77c1e3ccSAndroid Build Coastguard Worker // av1_quantize.c.
44*77c1e3ccSAndroid Build Coastguard Worker // All of its fields use the same coefficient shift/scaling at TX.
45*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
46*77c1e3ccSAndroid Build Coastguard Worker   // 0: dc 1: ac 2-8: ac repeated to SIMD width
47*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, y_quant[QINDEX_RANGE][8]);
48*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, y_quant_shift[QINDEX_RANGE][8]);
49*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, y_zbin[QINDEX_RANGE][8]);
50*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, y_round[QINDEX_RANGE][8]);
51*77c1e3ccSAndroid Build Coastguard Worker 
52*77c1e3ccSAndroid Build Coastguard Worker   // TODO(jingning): in progress of re-working the quantization. will decide
53*77c1e3ccSAndroid Build Coastguard Worker   // if we want to deprecate the current use of y_quant.
54*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, y_quant_fp[QINDEX_RANGE][8]);
55*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, u_quant_fp[QINDEX_RANGE][8]);
56*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, v_quant_fp[QINDEX_RANGE][8]);
57*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, y_round_fp[QINDEX_RANGE][8]);
58*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, u_round_fp[QINDEX_RANGE][8]);
59*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, v_round_fp[QINDEX_RANGE][8]);
60*77c1e3ccSAndroid Build Coastguard Worker 
61*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, u_quant[QINDEX_RANGE][8]);
62*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, v_quant[QINDEX_RANGE][8]);
63*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, u_quant_shift[QINDEX_RANGE][8]);
64*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, v_quant_shift[QINDEX_RANGE][8]);
65*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, u_zbin[QINDEX_RANGE][8]);
66*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, v_zbin[QINDEX_RANGE][8]);
67*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, u_round[QINDEX_RANGE][8]);
68*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t, v_round[QINDEX_RANGE][8]);
69*77c1e3ccSAndroid Build Coastguard Worker } QUANTS;
70*77c1e3ccSAndroid Build Coastguard Worker 
71*77c1e3ccSAndroid Build Coastguard Worker // The Dequants structure is used only for internal quantizer setup in
72*77c1e3ccSAndroid Build Coastguard Worker // av1_quantize.c.
73*77c1e3ccSAndroid Build Coastguard Worker // Fields are suffixed according to whether or not they're expressed in
74*77c1e3ccSAndroid Build Coastguard Worker // the same coefficient shift/precision as TX or a fixed Q3 format.
75*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
76*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t,
77*77c1e3ccSAndroid Build Coastguard Worker                   y_dequant_QTX[QINDEX_RANGE][8]);  // 8: SIMD width
78*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t,
79*77c1e3ccSAndroid Build Coastguard Worker                   u_dequant_QTX[QINDEX_RANGE][8]);  // 8: SIMD width
80*77c1e3ccSAndroid Build Coastguard Worker   DECLARE_ALIGNED(16, int16_t,
81*77c1e3ccSAndroid Build Coastguard Worker                   v_dequant_QTX[QINDEX_RANGE][8]);  // 8: SIMD width
82*77c1e3ccSAndroid Build Coastguard Worker } Dequants;
83*77c1e3ccSAndroid Build Coastguard Worker 
84*77c1e3ccSAndroid Build Coastguard Worker // The DeltaQuantParams structure holds the dc/ac deltaq parameters.
85*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
86*77c1e3ccSAndroid Build Coastguard Worker   int y_dc_delta_q;
87*77c1e3ccSAndroid Build Coastguard Worker   int u_dc_delta_q;
88*77c1e3ccSAndroid Build Coastguard Worker   int u_ac_delta_q;
89*77c1e3ccSAndroid Build Coastguard Worker   int v_dc_delta_q;
90*77c1e3ccSAndroid Build Coastguard Worker   int v_ac_delta_q;
91*77c1e3ccSAndroid Build Coastguard Worker } DeltaQuantParams;
92*77c1e3ccSAndroid Build Coastguard Worker 
93*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
94*77c1e3ccSAndroid Build Coastguard Worker   // Quantization parameters for internal quantizer setup.
95*77c1e3ccSAndroid Build Coastguard Worker   QUANTS quants;
96*77c1e3ccSAndroid Build Coastguard Worker   // Dequantization parameters for internal quantizer setup.
97*77c1e3ccSAndroid Build Coastguard Worker   Dequants dequants;
98*77c1e3ccSAndroid Build Coastguard Worker   // Deltaq parameters to track the state of the dc/ac deltaq parameters in
99*77c1e3ccSAndroid Build Coastguard Worker   // cm->quant_params. It is used to decide whether the quantizer tables need
100*77c1e3ccSAndroid Build Coastguard Worker   // to be re-initialized.
101*77c1e3ccSAndroid Build Coastguard Worker   DeltaQuantParams prev_deltaq_params;
102*77c1e3ccSAndroid Build Coastguard Worker } EncQuantDequantParams;
103*77c1e3ccSAndroid Build Coastguard Worker 
104*77c1e3ccSAndroid Build Coastguard Worker struct AV1_COMP;
105*77c1e3ccSAndroid Build Coastguard Worker struct AV1Common;
106*77c1e3ccSAndroid Build Coastguard Worker 
107*77c1e3ccSAndroid Build Coastguard Worker void av1_frame_init_quantizer(struct AV1_COMP *cpi);
108*77c1e3ccSAndroid Build Coastguard Worker 
109*77c1e3ccSAndroid Build Coastguard Worker void av1_init_plane_quantizers(const struct AV1_COMP *cpi, MACROBLOCK *x,
110*77c1e3ccSAndroid Build Coastguard Worker                                int segment_id, const int do_update);
111*77c1e3ccSAndroid Build Coastguard Worker 
112*77c1e3ccSAndroid Build Coastguard Worker void av1_build_quantizer(aom_bit_depth_t bit_depth, int y_dc_delta_q,
113*77c1e3ccSAndroid Build Coastguard Worker                          int u_dc_delta_q, int u_ac_delta_q, int v_dc_delta_q,
114*77c1e3ccSAndroid Build Coastguard Worker                          int v_ac_delta_q, QUANTS *const quants,
115*77c1e3ccSAndroid Build Coastguard Worker                          Dequants *const deq);
116*77c1e3ccSAndroid Build Coastguard Worker 
117*77c1e3ccSAndroid Build Coastguard Worker void av1_init_quantizer(EncQuantDequantParams *const enc_quant_dequant_params,
118*77c1e3ccSAndroid Build Coastguard Worker                         const CommonQuantParams *quant_params,
119*77c1e3ccSAndroid Build Coastguard Worker                         aom_bit_depth_t bit_depth);
120*77c1e3ccSAndroid Build Coastguard Worker 
121*77c1e3ccSAndroid Build Coastguard Worker void av1_set_quantizer(struct AV1Common *const cm, int min_qmlevel,
122*77c1e3ccSAndroid Build Coastguard Worker                        int max_qmlevel, int q, int enable_chroma_deltaq,
123*77c1e3ccSAndroid Build Coastguard Worker                        int enable_hdr_deltaq);
124*77c1e3ccSAndroid Build Coastguard Worker 
125*77c1e3ccSAndroid Build Coastguard Worker int av1_quantizer_to_qindex(int quantizer);
126*77c1e3ccSAndroid Build Coastguard Worker 
127*77c1e3ccSAndroid Build Coastguard Worker int av1_qindex_to_quantizer(int qindex);
128*77c1e3ccSAndroid Build Coastguard Worker 
129*77c1e3ccSAndroid Build Coastguard Worker void av1_quantize_skip(intptr_t n_coeffs, tran_low_t *qcoeff_ptr,
130*77c1e3ccSAndroid Build Coastguard Worker                        tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr);
131*77c1e3ccSAndroid Build Coastguard Worker 
132*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Quantize transform coefficients without using qmatrix
133*77c1e3ccSAndroid Build Coastguard Worker  *
134*77c1e3ccSAndroid Build Coastguard Worker  * quant_ptr, dequant_ptr and round_ptr are size 2 arrays,
135*77c1e3ccSAndroid Build Coastguard Worker  * where index 0 corresponds to dc coeff and index 1 corresponds to ac coeffs.
136*77c1e3ccSAndroid Build Coastguard Worker  *
137*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  quant_ptr    16-bit fixed point representation of inverse
138*77c1e3ccSAndroid Build Coastguard Worker  *                          quantize step size, i.e. 2^16/dequant
139*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  dequant_ptr  quantize step size
140*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  round_ptr    rounding
141*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  log_scale    the relative log scale of the transform
142*77c1e3ccSAndroid Build Coastguard Worker  *                          coefficients
143*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  scan         scan[i] indicates the position of ith to-be-coded
144*77c1e3ccSAndroid Build Coastguard Worker  *                          coefficient
145*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  coeff_count  number of coefficients
146*77c1e3ccSAndroid Build Coastguard Worker  * \param[out] qcoeff_ptr   quantized coefficients
147*77c1e3ccSAndroid Build Coastguard Worker  * \param[out] dqcoeff_ptr  dequantized coefficients
148*77c1e3ccSAndroid Build Coastguard Worker  *
149*77c1e3ccSAndroid Build Coastguard Worker  * \return The last non-zero coefficient's scan index plus 1
150*77c1e3ccSAndroid Build Coastguard Worker  */
151*77c1e3ccSAndroid Build Coastguard Worker int av1_quantize_fp_no_qmatrix(const int16_t quant_ptr[2],
152*77c1e3ccSAndroid Build Coastguard Worker                                const int16_t dequant_ptr[2],
153*77c1e3ccSAndroid Build Coastguard Worker                                const int16_t round_ptr[2], int log_scale,
154*77c1e3ccSAndroid Build Coastguard Worker                                const int16_t *scan, int coeff_count,
155*77c1e3ccSAndroid Build Coastguard Worker                                const tran_low_t *coeff_ptr,
156*77c1e3ccSAndroid Build Coastguard Worker                                tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr);
157*77c1e3ccSAndroid Build Coastguard Worker 
158*77c1e3ccSAndroid Build Coastguard Worker void av1_quantize_fp_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
159*77c1e3ccSAndroid Build Coastguard Worker                             const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
160*77c1e3ccSAndroid Build Coastguard Worker                             tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
161*77c1e3ccSAndroid Build Coastguard Worker                             const SCAN_ORDER *sc, const QUANT_PARAM *qparam);
162*77c1e3ccSAndroid Build Coastguard Worker 
163*77c1e3ccSAndroid Build Coastguard Worker void av1_quantize_b_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
164*77c1e3ccSAndroid Build Coastguard Worker                            const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
165*77c1e3ccSAndroid Build Coastguard Worker                            tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
166*77c1e3ccSAndroid Build Coastguard Worker                            const SCAN_ORDER *sc, const QUANT_PARAM *qparam);
167*77c1e3ccSAndroid Build Coastguard Worker 
168*77c1e3ccSAndroid Build Coastguard Worker void av1_quantize_dc_facade(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
169*77c1e3ccSAndroid Build Coastguard Worker                             const MACROBLOCK_PLANE *p, tran_low_t *qcoeff_ptr,
170*77c1e3ccSAndroid Build Coastguard Worker                             tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
171*77c1e3ccSAndroid Build Coastguard Worker                             const SCAN_ORDER *sc, const QUANT_PARAM *qparam);
172*77c1e3ccSAndroid Build Coastguard Worker 
173*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
174*77c1e3ccSAndroid Build Coastguard Worker void av1_highbd_quantize_fp_facade(const tran_low_t *coeff_ptr,
175*77c1e3ccSAndroid Build Coastguard Worker                                    intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
176*77c1e3ccSAndroid Build Coastguard Worker                                    tran_low_t *qcoeff_ptr,
177*77c1e3ccSAndroid Build Coastguard Worker                                    tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
178*77c1e3ccSAndroid Build Coastguard Worker                                    const SCAN_ORDER *sc,
179*77c1e3ccSAndroid Build Coastguard Worker                                    const QUANT_PARAM *qparam);
180*77c1e3ccSAndroid Build Coastguard Worker 
181*77c1e3ccSAndroid Build Coastguard Worker void av1_highbd_quantize_b_facade(const tran_low_t *coeff_ptr,
182*77c1e3ccSAndroid Build Coastguard Worker                                   intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
183*77c1e3ccSAndroid Build Coastguard Worker                                   tran_low_t *qcoeff_ptr,
184*77c1e3ccSAndroid Build Coastguard Worker                                   tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
185*77c1e3ccSAndroid Build Coastguard Worker                                   const SCAN_ORDER *sc,
186*77c1e3ccSAndroid Build Coastguard Worker                                   const QUANT_PARAM *qparam);
187*77c1e3ccSAndroid Build Coastguard Worker 
188*77c1e3ccSAndroid Build Coastguard Worker void av1_highbd_quantize_dc_facade(const tran_low_t *coeff_ptr,
189*77c1e3ccSAndroid Build Coastguard Worker                                    intptr_t n_coeffs, const MACROBLOCK_PLANE *p,
190*77c1e3ccSAndroid Build Coastguard Worker                                    tran_low_t *qcoeff_ptr,
191*77c1e3ccSAndroid Build Coastguard Worker                                    tran_low_t *dqcoeff_ptr, uint16_t *eob_ptr,
192*77c1e3ccSAndroid Build Coastguard Worker                                    const SCAN_ORDER *sc,
193*77c1e3ccSAndroid Build Coastguard Worker                                    const QUANT_PARAM *qparam);
194*77c1e3ccSAndroid Build Coastguard Worker 
195*77c1e3ccSAndroid Build Coastguard Worker #endif
196*77c1e3ccSAndroid Build Coastguard Worker 
197*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
198*77c1e3ccSAndroid Build Coastguard Worker }  // extern "C"
199*77c1e3ccSAndroid Build Coastguard Worker #endif
200*77c1e3ccSAndroid Build Coastguard Worker 
201*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_AV1_ENCODER_AV1_QUANTIZE_H_
202