1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp9/encoder/vp9_quantize.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,348 @@ 1.4 +/* 1.5 + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 +#include <math.h> 1.15 +#include "vpx_mem/vpx_mem.h" 1.16 + 1.17 +#include "vp9/encoder/vp9_onyx_int.h" 1.18 +#include "vp9/encoder/vp9_rdopt.h" 1.19 +#include "vp9/encoder/vp9_quantize.h" 1.20 +#include "vp9/common/vp9_quant_common.h" 1.21 + 1.22 +#include "vp9/common/vp9_seg_common.h" 1.23 + 1.24 +#ifdef ENC_DEBUG 1.25 +extern int enc_debug; 1.26 +#endif 1.27 + 1.28 +void vp9_quantize_b_c(const int16_t *coeff_ptr, intptr_t count, 1.29 + int skip_block, 1.30 + const int16_t *zbin_ptr, const int16_t *round_ptr, 1.31 + const int16_t *quant_ptr, const int16_t *quant_shift_ptr, 1.32 + int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr, 1.33 + const int16_t *dequant_ptr, 1.34 + int zbin_oq_value, uint16_t *eob_ptr, 1.35 + const int16_t *scan, const int16_t *iscan) { 1.36 + int i, non_zero_count = count, eob = -1; 1.37 + const int zbins[2] = { zbin_ptr[0] + zbin_oq_value, 1.38 + zbin_ptr[1] + zbin_oq_value }; 1.39 + const int nzbins[2] = { zbins[0] * -1, 1.40 + zbins[1] * -1 }; 1.41 + 1.42 + vpx_memset(qcoeff_ptr, 0, count * sizeof(int16_t)); 1.43 + vpx_memset(dqcoeff_ptr, 0, count * sizeof(int16_t)); 1.44 + 1.45 + if (!skip_block) { 1.46 + // Pre-scan pass 1.47 + for (i = count - 1; i >= 0; i--) { 1.48 + const int rc = scan[i]; 1.49 + const int coeff = coeff_ptr[rc]; 1.50 + 1.51 + if (coeff < zbins[rc != 0] && coeff > nzbins[rc != 0]) 1.52 + non_zero_count--; 1.53 + else 1.54 + break; 1.55 + } 1.56 + 1.57 + // Quantization pass: All coefficients with index >= zero_flag are 1.58 + // skippable. Note: zero_flag can be zero. 1.59 + for (i = 0; i < non_zero_count; i++) { 1.60 + const int rc = scan[i]; 1.61 + const int coeff = coeff_ptr[rc]; 1.62 + const int coeff_sign = (coeff >> 31); 1.63 + const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign; 1.64 + 1.65 + if (abs_coeff >= zbins[rc != 0]) { 1.66 + int tmp = clamp(abs_coeff + round_ptr[rc != 0], INT16_MIN, INT16_MAX); 1.67 + tmp = ((((tmp * quant_ptr[rc != 0]) >> 16) + tmp) * 1.68 + quant_shift_ptr[rc != 0]) >> 16; // quantization 1.69 + qcoeff_ptr[rc] = (tmp ^ coeff_sign) - coeff_sign; 1.70 + dqcoeff_ptr[rc] = qcoeff_ptr[rc] * dequant_ptr[rc != 0]; 1.71 + 1.72 + if (tmp) 1.73 + eob = i; 1.74 + } 1.75 + } 1.76 + } 1.77 + *eob_ptr = eob + 1; 1.78 +} 1.79 + 1.80 +void vp9_quantize_b_32x32_c(const int16_t *coeff_ptr, intptr_t n_coeffs, 1.81 + int skip_block, 1.82 + const int16_t *zbin_ptr, const int16_t *round_ptr, 1.83 + const int16_t *quant_ptr, 1.84 + const int16_t *quant_shift_ptr, 1.85 + int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr, 1.86 + const int16_t *dequant_ptr, 1.87 + int zbin_oq_value, uint16_t *eob_ptr, 1.88 + const int16_t *scan, const int16_t *iscan) { 1.89 + int i, rc, eob; 1.90 + int zbins[2], nzbins[2]; 1.91 + int x, y, z, sz; 1.92 + int idx = 0; 1.93 + int idx_arr[1024]; 1.94 + 1.95 + vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t)); 1.96 + vpx_memset(dqcoeff_ptr, 0, n_coeffs*sizeof(int16_t)); 1.97 + 1.98 + eob = -1; 1.99 + 1.100 + // Base ZBIN 1.101 + zbins[0] = ROUND_POWER_OF_TWO(zbin_ptr[0] + zbin_oq_value, 1); 1.102 + zbins[1] = ROUND_POWER_OF_TWO(zbin_ptr[1] + zbin_oq_value, 1); 1.103 + nzbins[0] = zbins[0] * -1; 1.104 + nzbins[1] = zbins[1] * -1; 1.105 + 1.106 + if (!skip_block) { 1.107 + // Pre-scan pass 1.108 + for (i = 0; i < n_coeffs; i++) { 1.109 + rc = scan[i]; 1.110 + z = coeff_ptr[rc]; 1.111 + 1.112 + // If the coefficient is out of the base ZBIN range, keep it for 1.113 + // quantization. 1.114 + if (z >= zbins[rc != 0] || z <= nzbins[rc != 0]) 1.115 + idx_arr[idx++] = i; 1.116 + } 1.117 + 1.118 + // Quantization pass: only process the coefficients selected in 1.119 + // pre-scan pass. Note: idx can be zero. 1.120 + for (i = 0; i < idx; i++) { 1.121 + rc = scan[idx_arr[i]]; 1.122 + 1.123 + z = coeff_ptr[rc]; 1.124 + sz = (z >> 31); // sign of z 1.125 + x = (z ^ sz) - sz; // x = abs(z) 1.126 + 1.127 + x += ROUND_POWER_OF_TWO(round_ptr[rc != 0], 1); 1.128 + x = clamp(x, INT16_MIN, INT16_MAX); 1.129 + y = ((((x * quant_ptr[rc != 0]) >> 16) + x) * 1.130 + quant_shift_ptr[rc != 0]) >> 15; // quantize (x) 1.131 + 1.132 + x = (y ^ sz) - sz; // get the sign back 1.133 + qcoeff_ptr[rc] = x; // write to destination 1.134 + dqcoeff_ptr[rc] = x * dequant_ptr[rc != 0] / 2; // dequantized value 1.135 + 1.136 + if (y) 1.137 + eob = idx_arr[i]; // last nonzero coeffs 1.138 + } 1.139 + } 1.140 + *eob_ptr = eob + 1; 1.141 +} 1.142 + 1.143 +struct plane_block_idx { 1.144 + int plane; 1.145 + int block; 1.146 +}; 1.147 + 1.148 +// TODO(jkoleszar): returning a struct so it can be used in a const context, 1.149 +// expect to refactor this further later. 1.150 +static INLINE struct plane_block_idx plane_block_idx(int y_blocks, 1.151 + int b_idx) { 1.152 + const int v_offset = y_blocks * 5 / 4; 1.153 + struct plane_block_idx res; 1.154 + 1.155 + if (b_idx < y_blocks) { 1.156 + res.plane = 0; 1.157 + res.block = b_idx; 1.158 + } else if (b_idx < v_offset) { 1.159 + res.plane = 1; 1.160 + res.block = b_idx - y_blocks; 1.161 + } else { 1.162 + assert(b_idx < y_blocks * 3 / 2); 1.163 + res.plane = 2; 1.164 + res.block = b_idx - v_offset; 1.165 + } 1.166 + return res; 1.167 +} 1.168 + 1.169 +void vp9_regular_quantize_b_4x4(MACROBLOCK *x, int y_blocks, int b_idx, 1.170 + const int16_t *scan, const int16_t *iscan) { 1.171 + MACROBLOCKD *const xd = &x->e_mbd; 1.172 + const struct plane_block_idx pb_idx = plane_block_idx(y_blocks, b_idx); 1.173 + struct macroblock_plane* p = &x->plane[pb_idx.plane]; 1.174 + struct macroblockd_plane* pd = &xd->plane[pb_idx.plane]; 1.175 + 1.176 + vp9_quantize_b(BLOCK_OFFSET(p->coeff, pb_idx.block), 1.177 + 16, x->skip_block, 1.178 + p->zbin, p->round, p->quant, p->quant_shift, 1.179 + BLOCK_OFFSET(pd->qcoeff, pb_idx.block), 1.180 + BLOCK_OFFSET(pd->dqcoeff, pb_idx.block), 1.181 + pd->dequant, p->zbin_extra, &pd->eobs[pb_idx.block], scan, iscan); 1.182 +} 1.183 + 1.184 +static void invert_quant(int16_t *quant, int16_t *shift, int d) { 1.185 + unsigned t; 1.186 + int l; 1.187 + t = d; 1.188 + for (l = 0; t > 1; l++) 1.189 + t >>= 1; 1.190 + t = 1 + (1 << (16 + l)) / d; 1.191 + *quant = (int16_t)(t - (1 << 16)); 1.192 + *shift = 1 << (16 - l); 1.193 +} 1.194 + 1.195 +void vp9_init_quantizer(VP9_COMP *cpi) { 1.196 + int i, q; 1.197 + VP9_COMMON *const cm = &cpi->common; 1.198 + 1.199 + for (q = 0; q < QINDEX_RANGE; q++) { 1.200 + const int qzbin_factor = q == 0 ? 64 : (vp9_dc_quant(q, 0) < 148 ? 84 : 80); 1.201 + const int qrounding_factor = q == 0 ? 64 : 48; 1.202 + 1.203 + // y 1.204 + for (i = 0; i < 2; ++i) { 1.205 + const int quant = i == 0 ? vp9_dc_quant(q, cm->y_dc_delta_q) 1.206 + : vp9_ac_quant(q, 0); 1.207 + invert_quant(&cpi->y_quant[q][i], &cpi->y_quant_shift[q][i], quant); 1.208 + cpi->y_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); 1.209 + cpi->y_round[q][i] = (qrounding_factor * quant) >> 7; 1.210 + cm->y_dequant[q][i] = quant; 1.211 + } 1.212 + 1.213 + // uv 1.214 + for (i = 0; i < 2; ++i) { 1.215 + const int quant = i == 0 ? vp9_dc_quant(q, cm->uv_dc_delta_q) 1.216 + : vp9_ac_quant(q, cm->uv_ac_delta_q); 1.217 + invert_quant(&cpi->uv_quant[q][i], &cpi->uv_quant_shift[q][i], quant); 1.218 + cpi->uv_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); 1.219 + cpi->uv_round[q][i] = (qrounding_factor * quant) >> 7; 1.220 + cm->uv_dequant[q][i] = quant; 1.221 + } 1.222 + 1.223 +#if CONFIG_ALPHA 1.224 + // alpha 1.225 + for (i = 0; i < 2; ++i) { 1.226 + const int quant = i == 0 ? vp9_dc_quant(q, cm->a_dc_delta_q) 1.227 + : vp9_ac_quant(q, cm->a_ac_delta_q); 1.228 + invert_quant(&cpi->a_quant[q][i], &cpi->a_quant_shift[q][i], quant); 1.229 + cpi->a_zbin[q][i] = ROUND_POWER_OF_TWO(qzbin_factor * quant, 7); 1.230 + cpi->a_round[q][i] = (qrounding_factor * quant) >> 7; 1.231 + cm->a_dequant[q][i] = quant; 1.232 + } 1.233 +#endif 1.234 + 1.235 + for (i = 2; i < 8; i++) { 1.236 + cpi->y_quant[q][i] = cpi->y_quant[q][1]; 1.237 + cpi->y_quant_shift[q][i] = cpi->y_quant_shift[q][1]; 1.238 + cpi->y_zbin[q][i] = cpi->y_zbin[q][1]; 1.239 + cpi->y_round[q][i] = cpi->y_round[q][1]; 1.240 + cm->y_dequant[q][i] = cm->y_dequant[q][1]; 1.241 + 1.242 + cpi->uv_quant[q][i] = cpi->uv_quant[q][1]; 1.243 + cpi->uv_quant_shift[q][i] = cpi->uv_quant_shift[q][1]; 1.244 + cpi->uv_zbin[q][i] = cpi->uv_zbin[q][1]; 1.245 + cpi->uv_round[q][i] = cpi->uv_round[q][1]; 1.246 + cm->uv_dequant[q][i] = cm->uv_dequant[q][1]; 1.247 + 1.248 +#if CONFIG_ALPHA 1.249 + cpi->a_quant[q][i] = cpi->a_quant[q][1]; 1.250 + cpi->a_quant_shift[q][i] = cpi->a_quant_shift[q][1]; 1.251 + cpi->a_zbin[q][i] = cpi->a_zbin[q][1]; 1.252 + cpi->a_round[q][i] = cpi->a_round[q][1]; 1.253 + cm->a_dequant[q][i] = cm->a_dequant[q][1]; 1.254 +#endif 1.255 + } 1.256 + } 1.257 +} 1.258 + 1.259 +void vp9_mb_init_quantizer(VP9_COMP *cpi, MACROBLOCK *x) { 1.260 + int i; 1.261 + VP9_COMMON *const cm = &cpi->common; 1.262 + MACROBLOCKD *xd = &x->e_mbd; 1.263 + int zbin_extra; 1.264 + int segment_id = xd->mi_8x8[0]->mbmi.segment_id; 1.265 + const int qindex = vp9_get_qindex(&cpi->common.seg, segment_id, 1.266 + cpi->common.base_qindex); 1.267 + 1.268 + int rdmult = vp9_compute_rd_mult(cpi, qindex + cm->y_dc_delta_q); 1.269 + 1.270 + // Y 1.271 + zbin_extra = (cpi->common.y_dequant[qindex][1] * 1.272 + (cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7; 1.273 + 1.274 + x->plane[0].quant = cpi->y_quant[qindex]; 1.275 + x->plane[0].quant_shift = cpi->y_quant_shift[qindex]; 1.276 + x->plane[0].zbin = cpi->y_zbin[qindex]; 1.277 + x->plane[0].round = cpi->y_round[qindex]; 1.278 + x->plane[0].zbin_extra = (int16_t)zbin_extra; 1.279 + x->e_mbd.plane[0].dequant = cpi->common.y_dequant[qindex]; 1.280 + 1.281 + // UV 1.282 + zbin_extra = (cpi->common.uv_dequant[qindex][1] * 1.283 + (cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7; 1.284 + 1.285 + for (i = 1; i < 3; i++) { 1.286 + x->plane[i].quant = cpi->uv_quant[qindex]; 1.287 + x->plane[i].quant_shift = cpi->uv_quant_shift[qindex]; 1.288 + x->plane[i].zbin = cpi->uv_zbin[qindex]; 1.289 + x->plane[i].round = cpi->uv_round[qindex]; 1.290 + x->plane[i].zbin_extra = (int16_t)zbin_extra; 1.291 + x->e_mbd.plane[i].dequant = cpi->common.uv_dequant[qindex]; 1.292 + } 1.293 + 1.294 +#if CONFIG_ALPHA 1.295 + x->plane[3].quant = cpi->a_quant[qindex]; 1.296 + x->plane[3].quant_shift = cpi->a_quant_shift[qindex]; 1.297 + x->plane[3].zbin = cpi->a_zbin[qindex]; 1.298 + x->plane[3].round = cpi->a_round[qindex]; 1.299 + x->plane[3].zbin_extra = (int16_t)zbin_extra; 1.300 + x->e_mbd.plane[3].dequant = cpi->common.a_dequant[qindex]; 1.301 +#endif 1.302 + 1.303 + x->skip_block = vp9_segfeature_active(&cpi->common.seg, segment_id, 1.304 + SEG_LVL_SKIP); 1.305 + 1.306 + /* save this macroblock QIndex for vp9_update_zbin_extra() */ 1.307 + x->q_index = qindex; 1.308 + 1.309 + /* R/D setup */ 1.310 + cpi->mb.errorperbit = rdmult >> 6; 1.311 + cpi->mb.errorperbit += (cpi->mb.errorperbit == 0); 1.312 + 1.313 + vp9_initialize_me_consts(cpi, x->q_index); 1.314 +} 1.315 + 1.316 +void vp9_update_zbin_extra(VP9_COMP *cpi, MACROBLOCK *x) { 1.317 + const int qindex = x->q_index; 1.318 + const int y_zbin_extra = (cpi->common.y_dequant[qindex][1] * 1.319 + (cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7; 1.320 + const int uv_zbin_extra = (cpi->common.uv_dequant[qindex][1] * 1.321 + (cpi->zbin_mode_boost + x->act_zbin_adj)) >> 7; 1.322 + 1.323 + x->plane[0].zbin_extra = (int16_t)y_zbin_extra; 1.324 + x->plane[1].zbin_extra = (int16_t)uv_zbin_extra; 1.325 + x->plane[2].zbin_extra = (int16_t)uv_zbin_extra; 1.326 +} 1.327 + 1.328 +void vp9_frame_init_quantizer(VP9_COMP *cpi) { 1.329 + // Clear Zbin mode boost for default case 1.330 + cpi->zbin_mode_boost = 0; 1.331 + 1.332 + // MB level quantizer setup 1.333 + vp9_mb_init_quantizer(cpi, &cpi->mb); 1.334 +} 1.335 + 1.336 +void vp9_set_quantizer(struct VP9_COMP *cpi, int q) { 1.337 + VP9_COMMON *cm = &cpi->common; 1.338 + 1.339 + cm->base_qindex = q; 1.340 + 1.341 + // if any of the delta_q values are changing update flag will 1.342 + // have to be set. 1.343 + cm->y_dc_delta_q = 0; 1.344 + cm->uv_dc_delta_q = 0; 1.345 + cm->uv_ac_delta_q = 0; 1.346 + 1.347 + // quantizer has to be reinitialized if any delta_q changes. 1.348 + // As there are not any here for now this is inactive code. 1.349 + // if(update) 1.350 + // vp9_init_quantizer(cpi); 1.351 +}