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