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