xref: /aosp_15_r20/external/libvpx/vp9/encoder/vp9_quantize.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker  *
4*fb1b10abSAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker  */
10*fb1b10abSAndroid Build Coastguard Worker 
11*fb1b10abSAndroid Build Coastguard Worker #include <assert.h>
12*fb1b10abSAndroid Build Coastguard Worker #include <math.h>
13*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_dsp_rtcd.h"
14*fb1b10abSAndroid Build Coastguard Worker #include "vpx_mem/vpx_mem.h"
15*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/bitops.h"
16*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
17*fb1b10abSAndroid Build Coastguard Worker 
18*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_quant_common.h"
19*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_scan.h"
20*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_seg_common.h"
21*fb1b10abSAndroid Build Coastguard Worker 
22*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encoder.h"
23*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_quantize.h"
24*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_rd.h"
25*fb1b10abSAndroid Build Coastguard Worker 
vp9_quantize_fp_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const struct macroblock_plane * const mb_plane,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const struct ScanOrder * const scan_order)26*fb1b10abSAndroid Build Coastguard Worker void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
27*fb1b10abSAndroid Build Coastguard Worker                        const struct macroblock_plane *const mb_plane,
28*fb1b10abSAndroid Build Coastguard Worker                        tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
29*fb1b10abSAndroid Build Coastguard Worker                        const int16_t *dequant_ptr, uint16_t *eob_ptr,
30*fb1b10abSAndroid Build Coastguard Worker                        const struct ScanOrder *const scan_order) {
31*fb1b10abSAndroid Build Coastguard Worker   int i, eob = -1;
32*fb1b10abSAndroid Build Coastguard Worker   const int16_t *round_ptr = mb_plane->round_fp;
33*fb1b10abSAndroid Build Coastguard Worker   const int16_t *quant_ptr = mb_plane->quant_fp;
34*fb1b10abSAndroid Build Coastguard Worker   const int16_t *scan = scan_order->scan;
35*fb1b10abSAndroid Build Coastguard Worker 
36*fb1b10abSAndroid Build Coastguard Worker   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
37*fb1b10abSAndroid Build Coastguard Worker   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
38*fb1b10abSAndroid Build Coastguard Worker 
39*fb1b10abSAndroid Build Coastguard Worker   // Quantization pass: All coefficients with index >= zero_flag are
40*fb1b10abSAndroid Build Coastguard Worker   // skippable. Note: zero_flag can be zero.
41*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < n_coeffs; i++) {
42*fb1b10abSAndroid Build Coastguard Worker     const int rc = scan[i];
43*fb1b10abSAndroid Build Coastguard Worker     const int coeff = coeff_ptr[rc];
44*fb1b10abSAndroid Build Coastguard Worker     const int coeff_sign = (coeff >> 31);
45*fb1b10abSAndroid Build Coastguard Worker     const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
46*fb1b10abSAndroid Build Coastguard Worker 
47*fb1b10abSAndroid Build Coastguard Worker     int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
48*fb1b10abSAndroid Build Coastguard Worker     tmp = (tmp * quant_ptr[rc != 0]) >> 16;
49*fb1b10abSAndroid Build Coastguard Worker 
50*fb1b10abSAndroid Build Coastguard Worker     qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
51*fb1b10abSAndroid Build Coastguard Worker     dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
52*fb1b10abSAndroid Build Coastguard Worker 
53*fb1b10abSAndroid Build Coastguard Worker     if (tmp) eob = i;
54*fb1b10abSAndroid Build Coastguard Worker   }
55*fb1b10abSAndroid Build Coastguard Worker   *eob_ptr = eob + 1;
56*fb1b10abSAndroid Build Coastguard Worker }
57*fb1b10abSAndroid Build Coastguard Worker 
58*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
vp9_highbd_quantize_fp_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const struct macroblock_plane * const mb_plane,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const struct ScanOrder * const scan_order)59*fb1b10abSAndroid Build Coastguard Worker void vp9_highbd_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
60*fb1b10abSAndroid Build Coastguard Worker                               const struct macroblock_plane *const mb_plane,
61*fb1b10abSAndroid Build Coastguard Worker                               tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
62*fb1b10abSAndroid Build Coastguard Worker                               const int16_t *dequant_ptr, uint16_t *eob_ptr,
63*fb1b10abSAndroid Build Coastguard Worker                               const struct ScanOrder *const scan_order) {
64*fb1b10abSAndroid Build Coastguard Worker   int i;
65*fb1b10abSAndroid Build Coastguard Worker   int eob = -1;
66*fb1b10abSAndroid Build Coastguard Worker   const int16_t *round_ptr = mb_plane->round_fp;
67*fb1b10abSAndroid Build Coastguard Worker   const int16_t *quant_ptr = mb_plane->quant_fp;
68*fb1b10abSAndroid Build Coastguard Worker   const int16_t *scan = scan_order->scan;
69*fb1b10abSAndroid Build Coastguard Worker 
70*fb1b10abSAndroid Build Coastguard Worker   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
71*fb1b10abSAndroid Build Coastguard Worker   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
72*fb1b10abSAndroid Build Coastguard Worker 
73*fb1b10abSAndroid Build Coastguard Worker   // Quantization pass: All coefficients with index >= zero_flag are
74*fb1b10abSAndroid Build Coastguard Worker   // skippable. Note: zero_flag can be zero.
75*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < n_coeffs; i++) {
76*fb1b10abSAndroid Build Coastguard Worker     const int rc = scan[i];
77*fb1b10abSAndroid Build Coastguard Worker     const int coeff = coeff_ptr[rc];
78*fb1b10abSAndroid Build Coastguard Worker     const int coeff_sign = (coeff >> 31);
79*fb1b10abSAndroid Build Coastguard Worker     const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
80*fb1b10abSAndroid Build Coastguard Worker     const int64_t tmp = abs_coeff + round_ptr[rc != 0];
81*fb1b10abSAndroid Build Coastguard Worker     const int abs_qcoeff = (int)((tmp * quant_ptr[rc != 0]) >> 16);
82*fb1b10abSAndroid Build Coastguard Worker     qcoeff_ptr[rc] = (tran_low_t)(abs_qcoeff ^ coeff_sign) - coeff_sign;
83*fb1b10abSAndroid Build Coastguard Worker     dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
84*fb1b10abSAndroid Build Coastguard Worker     if (abs_qcoeff) eob = i;
85*fb1b10abSAndroid Build Coastguard Worker   }
86*fb1b10abSAndroid Build Coastguard Worker   *eob_ptr = eob + 1;
87*fb1b10abSAndroid Build Coastguard Worker }
88*fb1b10abSAndroid Build Coastguard Worker #endif
89*fb1b10abSAndroid Build Coastguard Worker 
90*fb1b10abSAndroid Build Coastguard Worker // TODO(jingning) Refactor this file and combine functions with similar
91*fb1b10abSAndroid Build Coastguard Worker // operations.
vp9_quantize_fp_32x32_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const struct macroblock_plane * const mb_plane,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const struct ScanOrder * const scan_order)92*fb1b10abSAndroid Build Coastguard Worker void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs,
93*fb1b10abSAndroid Build Coastguard Worker                              const struct macroblock_plane *const mb_plane,
94*fb1b10abSAndroid Build Coastguard Worker                              tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr,
95*fb1b10abSAndroid Build Coastguard Worker                              const int16_t *dequant_ptr, uint16_t *eob_ptr,
96*fb1b10abSAndroid Build Coastguard Worker                              const struct ScanOrder *const scan_order) {
97*fb1b10abSAndroid Build Coastguard Worker   int i, eob = -1;
98*fb1b10abSAndroid Build Coastguard Worker   const int16_t *round_ptr = mb_plane->round_fp;
99*fb1b10abSAndroid Build Coastguard Worker   const int16_t *quant_ptr = mb_plane->quant_fp;
100*fb1b10abSAndroid Build Coastguard Worker   const int16_t *scan = scan_order->scan;
101*fb1b10abSAndroid Build Coastguard Worker 
102*fb1b10abSAndroid Build Coastguard Worker   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
103*fb1b10abSAndroid Build Coastguard Worker   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
104*fb1b10abSAndroid Build Coastguard Worker 
105*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < n_coeffs; i++) {
106*fb1b10abSAndroid Build Coastguard Worker     const int rc = scan[i];
107*fb1b10abSAndroid Build Coastguard Worker     const int coeff = coeff_ptr[rc];
108*fb1b10abSAndroid Build Coastguard Worker     const int coeff_sign = (coeff >> 31);
109*fb1b10abSAndroid Build Coastguard Worker     int tmp = 0;
110*fb1b10abSAndroid Build Coastguard Worker     int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
111*fb1b10abSAndroid Build Coastguard Worker 
112*fb1b10abSAndroid Build Coastguard Worker     if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) {
113*fb1b10abSAndroid Build Coastguard Worker       abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
114*fb1b10abSAndroid Build Coastguard Worker       abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
115*fb1b10abSAndroid Build Coastguard Worker       tmp = (abs_coeff * quant_ptr[rc != 0]) >> 15;
116*fb1b10abSAndroid Build Coastguard Worker       qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
117*fb1b10abSAndroid Build Coastguard Worker       dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
118*fb1b10abSAndroid Build Coastguard Worker     }
119*fb1b10abSAndroid Build Coastguard Worker 
120*fb1b10abSAndroid Build Coastguard Worker     if (tmp) eob = i;
121*fb1b10abSAndroid Build Coastguard Worker   }
122*fb1b10abSAndroid Build Coastguard Worker   *eob_ptr = eob + 1;
123*fb1b10abSAndroid Build Coastguard Worker }
124*fb1b10abSAndroid Build Coastguard Worker 
125*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
vp9_highbd_quantize_fp_32x32_c(const tran_low_t * coeff_ptr,intptr_t n_coeffs,const struct macroblock_plane * const mb_plane,tran_low_t * qcoeff_ptr,tran_low_t * dqcoeff_ptr,const int16_t * dequant_ptr,uint16_t * eob_ptr,const struct ScanOrder * const scan_order)126*fb1b10abSAndroid Build Coastguard Worker void vp9_highbd_quantize_fp_32x32_c(
127*fb1b10abSAndroid Build Coastguard Worker     const tran_low_t *coeff_ptr, intptr_t n_coeffs,
128*fb1b10abSAndroid Build Coastguard Worker     const struct macroblock_plane *const mb_plane, tran_low_t *qcoeff_ptr,
129*fb1b10abSAndroid Build Coastguard Worker     tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr,
130*fb1b10abSAndroid Build Coastguard Worker     const struct ScanOrder *const scan_order) {
131*fb1b10abSAndroid Build Coastguard Worker   int i, eob = -1;
132*fb1b10abSAndroid Build Coastguard Worker   const int16_t *round_ptr = mb_plane->round_fp;
133*fb1b10abSAndroid Build Coastguard Worker   const int16_t *quant_ptr = mb_plane->quant_fp;
134*fb1b10abSAndroid Build Coastguard Worker   const int16_t *scan = scan_order->scan;
135*fb1b10abSAndroid Build Coastguard Worker 
136*fb1b10abSAndroid Build Coastguard Worker   memset(qcoeff_ptr, 0, n_coeffs * sizeof(*qcoeff_ptr));
137*fb1b10abSAndroid Build Coastguard Worker   memset(dqcoeff_ptr, 0, n_coeffs * sizeof(*dqcoeff_ptr));
138*fb1b10abSAndroid Build Coastguard Worker 
139*fb1b10abSAndroid Build Coastguard Worker   for (i = 0; i < n_coeffs; i++) {
140*fb1b10abSAndroid Build Coastguard Worker     int abs_qcoeff = 0;
141*fb1b10abSAndroid Build Coastguard Worker     const int rc = scan[i];
142*fb1b10abSAndroid Build Coastguard Worker     const int coeff = coeff_ptr[rc];
143*fb1b10abSAndroid Build Coastguard Worker     const int coeff_sign = (coeff >> 31);
144*fb1b10abSAndroid Build Coastguard Worker     const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
145*fb1b10abSAndroid Build Coastguard Worker 
146*fb1b10abSAndroid Build Coastguard Worker     if (abs_coeff >= (dequant_ptr[rc != 0] >> 2)) {
147*fb1b10abSAndroid Build Coastguard Worker       const int64_t tmp = abs_coeff + ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
148*fb1b10abSAndroid Build Coastguard Worker       abs_qcoeff = (int)((tmp * quant_ptr[rc != 0]) >> 15);
149*fb1b10abSAndroid Build Coastguard Worker       qcoeff_ptr[rc] = (tran_low_t)((abs_qcoeff ^ coeff_sign) - coeff_sign);
150*fb1b10abSAndroid Build Coastguard Worker       dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
151*fb1b10abSAndroid Build Coastguard Worker     }
152*fb1b10abSAndroid Build Coastguard Worker 
153*fb1b10abSAndroid Build Coastguard Worker     if (abs_qcoeff) eob = i;
154*fb1b10abSAndroid Build Coastguard Worker   }
155*fb1b10abSAndroid Build Coastguard Worker   *eob_ptr = eob + 1;
156*fb1b10abSAndroid Build Coastguard Worker }
157*fb1b10abSAndroid Build Coastguard Worker #endif
158*fb1b10abSAndroid Build Coastguard Worker 
invert_quant(int16_t * quant,int16_t * shift,int d)159*fb1b10abSAndroid Build Coastguard Worker static void invert_quant(int16_t *quant, int16_t *shift, int d) {
160*fb1b10abSAndroid Build Coastguard Worker   unsigned int t;
161*fb1b10abSAndroid Build Coastguard Worker   int l, m;
162*fb1b10abSAndroid Build Coastguard Worker   t = (unsigned int)d;
163*fb1b10abSAndroid Build Coastguard Worker   l = get_msb(t);
164*fb1b10abSAndroid Build Coastguard Worker   m = 1 + (1 << (16 + l)) / d;
165*fb1b10abSAndroid Build Coastguard Worker   *quant = (int16_t)(m - (1 << 16));
166*fb1b10abSAndroid Build Coastguard Worker   *shift = 1 << (16 - l);
167*fb1b10abSAndroid Build Coastguard Worker }
168*fb1b10abSAndroid Build Coastguard Worker 
get_qzbin_factor(int q,vpx_bit_depth_t bit_depth)169*fb1b10abSAndroid Build Coastguard Worker static int get_qzbin_factor(int q, vpx_bit_depth_t bit_depth) {
170*fb1b10abSAndroid Build Coastguard Worker   const int quant = vp9_dc_quant(q, 0, bit_depth);
171*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
172*fb1b10abSAndroid Build Coastguard Worker   switch (bit_depth) {
173*fb1b10abSAndroid Build Coastguard Worker     case VPX_BITS_8: return q == 0 ? 64 : (quant < 148 ? 84 : 80);
174*fb1b10abSAndroid Build Coastguard Worker     case VPX_BITS_10: return q == 0 ? 64 : (quant < 592 ? 84 : 80);
175*fb1b10abSAndroid Build Coastguard Worker     default:
176*fb1b10abSAndroid Build Coastguard Worker       assert(bit_depth == VPX_BITS_12);
177*fb1b10abSAndroid Build Coastguard Worker       return q == 0 ? 64 : (quant < 2368 ? 84 : 80);
178*fb1b10abSAndroid Build Coastguard Worker   }
179*fb1b10abSAndroid Build Coastguard Worker #else
180*fb1b10abSAndroid Build Coastguard Worker   (void)bit_depth;
181*fb1b10abSAndroid Build Coastguard Worker   return q == 0 ? 64 : (quant < 148 ? 84 : 80);
182*fb1b10abSAndroid Build Coastguard Worker #endif
183*fb1b10abSAndroid Build Coastguard Worker }
184*fb1b10abSAndroid Build Coastguard Worker 
vp9_init_quantizer(VP9_COMP * cpi)185*fb1b10abSAndroid Build Coastguard Worker void vp9_init_quantizer(VP9_COMP *cpi) {
186*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *const cm = &cpi->common;
187*fb1b10abSAndroid Build Coastguard Worker   QUANTS *const quants = &cpi->quants;
188*fb1b10abSAndroid Build Coastguard Worker   int i, q, quant;
189*fb1b10abSAndroid Build Coastguard Worker 
190*fb1b10abSAndroid Build Coastguard Worker   for (q = 0; q < QINDEX_RANGE; q++) {
191*fb1b10abSAndroid Build Coastguard Worker     int qzbin_factor = get_qzbin_factor(q, cm->bit_depth);
192*fb1b10abSAndroid Build Coastguard Worker     int qrounding_factor = q == 0 ? 64 : 48;
193*fb1b10abSAndroid Build Coastguard Worker     const int sharpness_adjustment = 16 * (7 - cpi->oxcf.sharpness) / 7;
194*fb1b10abSAndroid Build Coastguard Worker 
195*fb1b10abSAndroid Build Coastguard Worker     if (cpi->oxcf.sharpness > 0 && q > 0) {
196*fb1b10abSAndroid Build Coastguard Worker       qzbin_factor = 64 + sharpness_adjustment;
197*fb1b10abSAndroid Build Coastguard Worker       qrounding_factor = 64 - sharpness_adjustment;
198*fb1b10abSAndroid Build Coastguard Worker     }
199*fb1b10abSAndroid Build Coastguard Worker 
200*fb1b10abSAndroid Build Coastguard Worker     for (i = 0; i < 2; ++i) {
201*fb1b10abSAndroid Build Coastguard Worker       int qrounding_factor_fp = i == 0 ? 48 : 42;
202*fb1b10abSAndroid Build Coastguard Worker       if (q == 0) qrounding_factor_fp = 64;
203*fb1b10abSAndroid Build Coastguard Worker       if (cpi->oxcf.sharpness > 0)
204*fb1b10abSAndroid Build Coastguard Worker         qrounding_factor_fp = 64 - sharpness_adjustment;
205*fb1b10abSAndroid Build Coastguard Worker       // y
206*fb1b10abSAndroid Build Coastguard Worker       quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q, cm->bit_depth)
207*fb1b10abSAndroid Build Coastguard Worker                      : vp9_ac_quant(q, 0, cm->bit_depth);
208*fb1b10abSAndroid Build Coastguard Worker       invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], quant);
209*fb1b10abSAndroid Build Coastguard Worker       quants->y_quant_fp[q][i] = (1 << 16) / quant;
210*fb1b10abSAndroid Build Coastguard Worker       quants->y_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7;
211*fb1b10abSAndroid Build Coastguard Worker       quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
212*fb1b10abSAndroid Build Coastguard Worker       quants->y_round[q][i] = (qrounding_factor * quant) >> 7;
213*fb1b10abSAndroid Build Coastguard Worker       cpi->y_dequant[q][i] = quant;
214*fb1b10abSAndroid Build Coastguard Worker 
215*fb1b10abSAndroid Build Coastguard Worker       // uv
216*fb1b10abSAndroid Build Coastguard Worker       quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q, cm->bit_depth)
217*fb1b10abSAndroid Build Coastguard Worker                      : vp9_ac_quant(q, cm->uv_ac_delta_q, cm->bit_depth);
218*fb1b10abSAndroid Build Coastguard Worker       invert_quant(&quants->uv_quant[q][i], &quants->uv_quant_shift[q][i],
219*fb1b10abSAndroid Build Coastguard Worker                    quant);
220*fb1b10abSAndroid Build Coastguard Worker       quants->uv_quant_fp[q][i] = (1 << 16) / quant;
221*fb1b10abSAndroid Build Coastguard Worker       quants->uv_round_fp[q][i] = (qrounding_factor_fp * quant) >> 7;
222*fb1b10abSAndroid Build Coastguard Worker       quants->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
223*fb1b10abSAndroid Build Coastguard Worker       quants->uv_round[q][i] = (qrounding_factor * quant) >> 7;
224*fb1b10abSAndroid Build Coastguard Worker       cpi->uv_dequant[q][i] = quant;
225*fb1b10abSAndroid Build Coastguard Worker     }
226*fb1b10abSAndroid Build Coastguard Worker 
227*fb1b10abSAndroid Build Coastguard Worker     for (i = 2; i < 8; i++) {
228*fb1b10abSAndroid Build Coastguard Worker       quants->y_quant[q][i] = quants->y_quant[q][1];
229*fb1b10abSAndroid Build Coastguard Worker       quants->y_quant_fp[q][i] = quants->y_quant_fp[q][1];
230*fb1b10abSAndroid Build Coastguard Worker       quants->y_round_fp[q][i] = quants->y_round_fp[q][1];
231*fb1b10abSAndroid Build Coastguard Worker       quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
232*fb1b10abSAndroid Build Coastguard Worker       quants->y_zbin[q][i] = quants->y_zbin[q][1];
233*fb1b10abSAndroid Build Coastguard Worker       quants->y_round[q][i] = quants->y_round[q][1];
234*fb1b10abSAndroid Build Coastguard Worker       cpi->y_dequant[q][i] = cpi->y_dequant[q][1];
235*fb1b10abSAndroid Build Coastguard Worker 
236*fb1b10abSAndroid Build Coastguard Worker       quants->uv_quant[q][i] = quants->uv_quant[q][1];
237*fb1b10abSAndroid Build Coastguard Worker       quants->uv_quant_fp[q][i] = quants->uv_quant_fp[q][1];
238*fb1b10abSAndroid Build Coastguard Worker       quants->uv_round_fp[q][i] = quants->uv_round_fp[q][1];
239*fb1b10abSAndroid Build Coastguard Worker       quants->uv_quant_shift[q][i] = quants->uv_quant_shift[q][1];
240*fb1b10abSAndroid Build Coastguard Worker       quants->uv_zbin[q][i] = quants->uv_zbin[q][1];
241*fb1b10abSAndroid Build Coastguard Worker       quants->uv_round[q][i] = quants->uv_round[q][1];
242*fb1b10abSAndroid Build Coastguard Worker       cpi->uv_dequant[q][i] = cpi->uv_dequant[q][1];
243*fb1b10abSAndroid Build Coastguard Worker     }
244*fb1b10abSAndroid Build Coastguard Worker   }
245*fb1b10abSAndroid Build Coastguard Worker }
246*fb1b10abSAndroid Build Coastguard Worker 
vp9_init_plane_quantizers(VP9_COMP * cpi,MACROBLOCK * x)247*fb1b10abSAndroid Build Coastguard Worker void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) {
248*fb1b10abSAndroid Build Coastguard Worker   const VP9_COMMON *const cm = &cpi->common;
249*fb1b10abSAndroid Build Coastguard Worker   MACROBLOCKD *const xd = &x->e_mbd;
250*fb1b10abSAndroid Build Coastguard Worker   QUANTS *const quants = &cpi->quants;
251*fb1b10abSAndroid Build Coastguard Worker   const int segment_id = xd->mi[0]->segment_id;
252*fb1b10abSAndroid Build Coastguard Worker   const int qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex);
253*fb1b10abSAndroid Build Coastguard Worker   const int rdmult = vp9_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q);
254*fb1b10abSAndroid Build Coastguard Worker   int i;
255*fb1b10abSAndroid Build Coastguard Worker 
256*fb1b10abSAndroid Build Coastguard Worker   // Y
257*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].quant = quants->y_quant[qindex];
258*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].quant_fp = quants->y_quant_fp[qindex];
259*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].round_fp = quants->y_round_fp[qindex];
260*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].quant_shift = quants->y_quant_shift[qindex];
261*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].zbin = quants->y_zbin[qindex];
262*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].round = quants->y_round[qindex];
263*fb1b10abSAndroid Build Coastguard Worker   xd->plane[0].dequant = cpi->y_dequant[qindex];
264*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].quant_thred[0] = x->plane[0].zbin[0] * x->plane[0].zbin[0];
265*fb1b10abSAndroid Build Coastguard Worker   x->plane[0].quant_thred[1] = x->plane[0].zbin[1] * x->plane[0].zbin[1];
266*fb1b10abSAndroid Build Coastguard Worker 
267*fb1b10abSAndroid Build Coastguard Worker   // UV
268*fb1b10abSAndroid Build Coastguard Worker   for (i = 1; i < 3; i++) {
269*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].quant = quants->uv_quant[qindex];
270*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].quant_fp = quants->uv_quant_fp[qindex];
271*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].round_fp = quants->uv_round_fp[qindex];
272*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].quant_shift = quants->uv_quant_shift[qindex];
273*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].zbin = quants->uv_zbin[qindex];
274*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].round = quants->uv_round[qindex];
275*fb1b10abSAndroid Build Coastguard Worker     xd->plane[i].dequant = cpi->uv_dequant[qindex];
276*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].quant_thred[0] = x->plane[i].zbin[0] * x->plane[i].zbin[0];
277*fb1b10abSAndroid Build Coastguard Worker     x->plane[i].quant_thred[1] = x->plane[i].zbin[1] * x->plane[i].zbin[1];
278*fb1b10abSAndroid Build Coastguard Worker   }
279*fb1b10abSAndroid Build Coastguard Worker 
280*fb1b10abSAndroid Build Coastguard Worker   x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
281*fb1b10abSAndroid Build Coastguard Worker   x->q_index = qindex;
282*fb1b10abSAndroid Build Coastguard Worker 
283*fb1b10abSAndroid Build Coastguard Worker   set_error_per_bit(x, rdmult);
284*fb1b10abSAndroid Build Coastguard Worker 
285*fb1b10abSAndroid Build Coastguard Worker   vp9_initialize_me_consts(cpi, x, x->q_index);
286*fb1b10abSAndroid Build Coastguard Worker }
287*fb1b10abSAndroid Build Coastguard Worker 
vp9_frame_init_quantizer(VP9_COMP * cpi)288*fb1b10abSAndroid Build Coastguard Worker void vp9_frame_init_quantizer(VP9_COMP *cpi) {
289*fb1b10abSAndroid Build Coastguard Worker   vp9_init_plane_quantizers(cpi, &cpi->td.mb);
290*fb1b10abSAndroid Build Coastguard Worker }
291*fb1b10abSAndroid Build Coastguard Worker 
vp9_set_quantizer(VP9_COMP * cpi,int q)292*fb1b10abSAndroid Build Coastguard Worker void vp9_set_quantizer(VP9_COMP *cpi, int q) {
293*fb1b10abSAndroid Build Coastguard Worker   VP9_COMMON *cm = &cpi->common;
294*fb1b10abSAndroid Build Coastguard Worker   // quantizer has to be reinitialized with vp9_init_quantizer() if any
295*fb1b10abSAndroid Build Coastguard Worker   // delta_q changes.
296*fb1b10abSAndroid Build Coastguard Worker   cm->base_qindex = q;
297*fb1b10abSAndroid Build Coastguard Worker   cm->y_dc_delta_q = 0;
298*fb1b10abSAndroid Build Coastguard Worker   cm->uv_dc_delta_q = 0;
299*fb1b10abSAndroid Build Coastguard Worker   cm->uv_ac_delta_q = 0;
300*fb1b10abSAndroid Build Coastguard Worker   if (cpi->oxcf.delta_q_uv != 0) {
301*fb1b10abSAndroid Build Coastguard Worker     cm->uv_dc_delta_q = cm->uv_ac_delta_q = cpi->oxcf.delta_q_uv;
302*fb1b10abSAndroid Build Coastguard Worker     vp9_init_quantizer(cpi);
303*fb1b10abSAndroid Build Coastguard Worker   }
304*fb1b10abSAndroid Build Coastguard Worker }
305*fb1b10abSAndroid Build Coastguard Worker 
306*fb1b10abSAndroid Build Coastguard Worker // Table that converts 0-63 Q-range values passed in outside to the Qindex
307*fb1b10abSAndroid Build Coastguard Worker // range used internally.
308*fb1b10abSAndroid Build Coastguard Worker static const int quantizer_to_qindex[] = {
309*fb1b10abSAndroid Build Coastguard Worker   0,   4,   8,   12,  16,  20,  24,  28,  32,  36,  40,  44,  48,
310*fb1b10abSAndroid Build Coastguard Worker   52,  56,  60,  64,  68,  72,  76,  80,  84,  88,  92,  96,  100,
311*fb1b10abSAndroid Build Coastguard Worker   104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152,
312*fb1b10abSAndroid Build Coastguard Worker   156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204,
313*fb1b10abSAndroid Build Coastguard Worker   208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 249, 255,
314*fb1b10abSAndroid Build Coastguard Worker };
315*fb1b10abSAndroid Build Coastguard Worker 
vp9_quantizer_to_qindex(int quantizer)316*fb1b10abSAndroid Build Coastguard Worker int vp9_quantizer_to_qindex(int quantizer) {
317*fb1b10abSAndroid Build Coastguard Worker   return quantizer_to_qindex[quantizer];
318*fb1b10abSAndroid Build Coastguard Worker }
319*fb1b10abSAndroid Build Coastguard Worker 
vp9_qindex_to_quantizer(int qindex)320*fb1b10abSAndroid Build Coastguard Worker int vp9_qindex_to_quantizer(int qindex) {
321*fb1b10abSAndroid Build Coastguard Worker   int quantizer;
322*fb1b10abSAndroid Build Coastguard Worker 
323*fb1b10abSAndroid Build Coastguard Worker   for (quantizer = 0; quantizer < 64; ++quantizer)
324*fb1b10abSAndroid Build Coastguard Worker     if (quantizer_to_qindex[quantizer] >= qindex) return quantizer;
325*fb1b10abSAndroid Build Coastguard Worker 
326*fb1b10abSAndroid Build Coastguard Worker   return 63;
327*fb1b10abSAndroid Build Coastguard Worker }
328