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