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
13#include "vpx_mem/vpx_mem.h"
14
15#include "vp9/common/vp9_quant_common.h"
16#include "vp9/common/vp9_seg_common.h"
17
18#include "vp9/encoder/vp9_onyx_int.h"
19#include "vp9/encoder/vp9_quantize.h"
20#include "vp9/encoder/vp9_rdopt.h"
21
22void vp9_quantize_b_c(const int16_t *coeff_ptr, intptr_t count,
23                      int skip_block,
24                      const int16_t *zbin_ptr, const int16_t *round_ptr,
25                      const int16_t *quant_ptr, const int16_t *quant_shift_ptr,
26                      int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
27                      const int16_t *dequant_ptr,
28                      int zbin_oq_value, uint16_t *eob_ptr,
29                      const int16_t *scan, const int16_t *iscan) {
30  int i, non_zero_count = (int)count, eob = -1;
31  const int zbins[2] = { zbin_ptr[0] + zbin_oq_value,
32                         zbin_ptr[1] + zbin_oq_value };
33  const int nzbins[2] = { zbins[0] * -1,
34                          zbins[1] * -1 };
35
36  vpx_memset(qcoeff_ptr, 0, count * sizeof(int16_t));
37  vpx_memset(dqcoeff_ptr, 0, count * sizeof(int16_t));
38
39  if (!skip_block) {
40    // Pre-scan pass
41    for (i = (int)count - 1; i >= 0; i--) {
42      const int rc = scan[i];
43      const int coeff = coeff_ptr[rc];
44
45      if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0])
46        non_zero_count--;
47      else
48        break;
49    }
50
51    // Quantization pass: All coefficients with index >= zero_flag are
52    // skippable. Note: zero_flag can be zero.
53    for (i = 0; i < non_zero_count; i++) {
54      const int rc = scan[i];
55      const int coeff = coeff_ptr[rc];
56      const int coeff_sign = (coeff >> 31);
57      const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
58
59      if (abs_coeff >= zbins[rc != 0]) {
60        int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX);
61        tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) *
62                  quant_shift_ptr[rc != 0]) >> 16;  // quantization
63        qcoeff_ptr[rc]  = (tmp ^ coeff_sign) - coeff_sign;
64        dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0];
65
66        if (tmp)
67          eob = i;
68      }
69    }
70  }
71  *eob_ptr = eob + 1;
72}
73
74void vp9_quantize_b_32x32_c(const int16_t *coeff_ptr, intptr_t n_coeffs,
75                            int skip_block,
76                            const int16_t *zbin_ptr, const int16_t *round_ptr,
77                            const int16_t *quant_ptr,
78                            const int16_t *quant_shift_ptr,
79                            int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
80                            const int16_t *dequant_ptr,
81                            int zbin_oq_value, uint16_t *eob_ptr,
82                            const int16_t *scan, const int16_t *iscan) {
83  const int zbins[2] = { ROUND_POWER_OF_TWO(zbin_ptr[0] + zbin_oq_value, 1),
84                         ROUND_POWER_OF_TWO(zbin_ptr[1] + zbin_oq_value, 1) };
85  const int nzbins[2] = {zbins[0] * -1, zbins[1] * -1};
86
87  int idx = 0;
88  int idx_arr[1024];
89  int i, eob = -1;
90
91  vpx_memset(qcoeff_ptr, 0, n_coeffs * sizeof(int16_t));
92  vpx_memset(dqcoeff_ptr, 0, n_coeffs * sizeof(int16_t));
93
94  if (!skip_block) {
95    // Pre-scan pass
96    for (i = 0; i < n_coeffs; i++) {
97      const int rc = scan[i];
98      const int coeff = coeff_ptr[rc];
99
100      // If the coefficient is out of the base ZBIN range, keep it for
101      // quantization.
102      if (coeff >= zbins[rc != 0] || coeff <= nzbins[rc != 0])
103        idx_arr[idx++] = i;
104    }
105
106    // Quantization pass: only process the coefficients selected in
107    // pre-scan pass. Note: idx can be zero.
108    for (i = 0; i < idx; i++) {
109      const int rc = scan[idx_arr[i]];
110      const int coeff = coeff_ptr[rc];
111      const int coeff_sign = (coeff >> 31);
112      int tmp;
113      int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
114      abs_coeff += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1);
115      abs_coeff = clamp(abs_coeff, INT16_MIN, INT16_MAX);
116      tmp = ((((abs_coeff * quant_ptr[rc != 0]) >> 16) + abs_coeff) *
117               quant_shift_ptr[rc != 0]) >> 15;
118
119      qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign;
120      dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0] / 2;
121
122      if (tmp)
123        eob = idx_arr[i];
124    }
125  }
126  *eob_ptr = eob + 1;
127}
128
129void vp9_regular_quantize_b_4x4(MACROBLOCK *x, int plane, int block,
130                                const int16_t *scan, const int16_t *iscan) {
131  MACROBLOCKD *const xd = &x->e_mbd;
132  struct macroblock_plane *p = &x->plane[plane];
133  struct macroblockd_plane *pd = &xd->plane[plane];
134
135  vp9_quantize_b(BLOCK_OFFSET(p->coeff, block),
136           16, x->skip_block,
137           p->zbin, p->round, p->quant, p->quant_shift,
138           BLOCK_OFFSET(p->qcoeff, block),
139           BLOCK_OFFSET(pd->dqcoeff, block),
140           pd->dequant, p->zbin_extra, &p->eobs[block], scan, iscan);
141}
142
143static void invert_quant(int16_t *quant, int16_t *shift, int d) {
144  unsigned t;
145  int l;
146  t = d;
147  for (l = 0; t > 1; l++)
148    t >>= 1;
149  t = 1 + (1 << (16 + l)) / d;
150  *quant = (int16_t)(t - (1 << 16));
151  *shift = 1 << (16 - l);
152}
153
154void vp9_init_quantizer(VP9_COMP *cpi) {
155  VP9_COMMON *const cm = &cpi->common;
156  QUANTS *const quants = &cpi->quants;
157  int i, q, quant;
158
159  for (q = 0; q < QINDEX_RANGE; q++) {
160    const int qzbin_factor = q == 0 ? 64 : (vp9_dc_quant(q, 0) < 148 ? 84 : 80);
161    const int qrounding_factor = q == 0 ? 64 : 48;
162
163    for (i = 0; i < 2; ++i) {
164      // y
165      quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q)
166                     : vp9_ac_quant(q, 0);
167      invert_quant(&quants->y_quant[q][i], &quants->y_quant_shift[q][i], quant);
168      quants->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
169      quants->y_round[q][i] = (qrounding_factor * quant) >> 7;
170      cm->y_dequant[q][i] = quant;
171
172      // uv
173      quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q)
174                     : vp9_ac_quant(q, cm->uv_ac_delta_q);
175      invert_quant(&quants->uv_quant[q][i],
176                   &quants->uv_quant_shift[q][i], quant);
177      quants->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
178      quants->uv_round[q][i] = (qrounding_factor * quant) >> 7;
179      cm->uv_dequant[q][i] = quant;
180
181#if CONFIG_ALPHA
182      // alpha
183      quant = i == 0 ? vp9_dc_quant(q, cm->a_dc_delta_q)
184                     : vp9_ac_quant(q, cm->a_ac_delta_q);
185      invert_quant(&quants->a_quant[q][i], &quants->a_quant_shift[q][i], quant);
186      quants->a_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7);
187      quants->a_round[q][i] = (qrounding_factor * quant) >> 7;
188      cm->a_dequant[q][i] = quant;
189#endif
190    }
191
192    for (i = 2; i < 8; i++) {
193      quants->y_quant[q][i] = quants->y_quant[q][1];
194      quants->y_quant_shift[q][i] = quants->y_quant_shift[q][1];
195      quants->y_zbin[q][i] = quants->y_zbin[q][1];
196      quants->y_round[q][i] = quants->y_round[q][1];
197      cm->y_dequant[q][i] = cm->y_dequant[q][1];
198
199      quants->uv_quant[q][i] = quants->uv_quant[q][1];
200      quants->uv_quant_shift[q][i] = quants->uv_quant_shift[q][1];
201      quants->uv_zbin[q][i] = quants->uv_zbin[q][1];
202      quants->uv_round[q][i] = quants->uv_round[q][1];
203      cm->uv_dequant[q][i] = cm->uv_dequant[q][1];
204
205#if CONFIG_ALPHA
206      quants->a_quant[q][i] = quants->a_quant[q][1];
207      quants->a_quant_shift[q][i] = quants->a_quant_shift[q][1];
208      quants->a_zbin[q][i] = quants->a_zbin[q][1];
209      quants->a_round[q][i] = quants->a_round[q][1];
210      cm->a_dequant[q][i] = cm->a_dequant[q][1];
211#endif
212    }
213  }
214}
215
216void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) {
217  const VP9_COMMON *const cm = &cpi->common;
218  MACROBLOCKD *const xd = &x->e_mbd;
219  QUANTS *const quants = &cpi->quants;
220  const int segment_id = xd->mi[0]->mbmi.segment_id;
221  const int qindex = vp9_get_qindex(&cm->seg, segment_id, cm->base_qindex);
222  const int rdmult = vp9_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q);
223  const int zbin = cpi->zbin_mode_boost + x->act_zbin_adj;
224  int i;
225
226  // Y
227  x->plane[0].quant = quants->y_quant[qindex];
228  x->plane[0].quant_shift = quants->y_quant_shift[qindex];
229  x->plane[0].zbin = quants->y_zbin[qindex];
230  x->plane[0].round = quants->y_round[qindex];
231  x->plane[0].zbin_extra = (int16_t)((cm->y_dequant[qindex][1] * zbin) >> 7);
232  xd->plane[0].dequant = cm->y_dequant[qindex];
233
234  // UV
235  for (i = 1; i < 3; i++) {
236    x->plane[i].quant = quants->uv_quant[qindex];
237    x->plane[i].quant_shift = quants->uv_quant_shift[qindex];
238    x->plane[i].zbin = quants->uv_zbin[qindex];
239    x->plane[i].round = quants->uv_round[qindex];
240    x->plane[i].zbin_extra = (int16_t)((cm->uv_dequant[qindex][1] * zbin) >> 7);
241    xd->plane[i].dequant = cm->uv_dequant[qindex];
242  }
243
244#if CONFIG_ALPHA
245  x->plane[3].quant = cpi->a_quant[qindex];
246  x->plane[3].quant_shift = cpi->a_quant_shift[qindex];
247  x->plane[3].zbin = cpi->a_zbin[qindex];
248  x->plane[3].round = cpi->a_round[qindex];
249  x->plane[3].zbin_extra = (int16_t)((cm->a_dequant[qindex][1] * zbin) >> 7);
250  xd->plane[3].dequant = cm->a_dequant[qindex];
251#endif
252
253  x->skip_block = vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
254  x->q_index = qindex;
255
256  x->errorperbit = rdmult >> 6;
257  x->errorperbit += (x->errorperbit == 0);
258
259  vp9_initialize_me_consts(cpi, x->q_index);
260}
261
262void vp9_update_zbin_extra(VP9_COMP *cpi, MACROBLOCK *x) {
263  const int qindex = x->q_index;
264  const int y_zbin_extra = (cpi->common.y_dequant[qindex][1] *
265                (cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7;
266  const int uv_zbin_extra = (cpi->common.uv_dequant[qindex][1] *
267                  (cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7;
268
269  x->plane[0].zbin_extra = (int16_t)y_zbin_extra;
270  x->plane[1].zbin_extra = (int16_t)uv_zbin_extra;
271  x->plane[2].zbin_extra = (int16_t)uv_zbin_extra;
272}
273
274void vp9_frame_init_quantizer(VP9_COMP *cpi) {
275  cpi->zbin_mode_boost = 0;
276  vp9_init_plane_quantizers(cpi, &cpi->mb);
277}
278
279void vp9_set_quantizer(VP9_COMMON *cm, int q) {
280  // quantizer has to be reinitialized with vp9_init_quantizer() if any
281  // delta_q changes.
282  cm->base_qindex = q;
283  cm->y_dc_delta_q = 0;
284  cm->uv_dc_delta_q = 0;
285  cm->uv_ac_delta_q = 0;
286}
287