| Index: source/libvpx/vp9/encoder/vp9_quantize.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_quantize.c (revision 207479)
|
| +++ source/libvpx/vp9/encoder/vp9_quantize.c (working copy)
|
| @@ -35,6 +35,153 @@
|
| uint16_t *eob_ptr,
|
| const int *scan, int mul) {
|
| int i, rc, eob;
|
| + int zbins[2], nzbins[2], zbin;
|
| + int x, y, z, sz;
|
| + int zero_run = 0;
|
| + int16_t *zbin_boost_ptr = zbin_boost_orig_ptr;
|
| + int zero_flag = n_coeffs;
|
| +
|
| + vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
|
| + vpx_memset(dqcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
|
| +
|
| + eob = -1;
|
| +
|
| + // Base ZBIN
|
| + zbins[0] = zbin_ptr[0] + zbin_oq_value;
|
| + zbins[1] = zbin_ptr[1] + zbin_oq_value;
|
| + nzbins[0] = zbins[0] * -1;
|
| + nzbins[1] = zbins[1] * -1;
|
| +
|
| + if (!skip_block) {
|
| + // Pre-scan pass
|
| + for (i = n_coeffs - 1; i >= 0; i--) {
|
| + rc = scan[i];
|
| + z = coeff_ptr[rc] * mul;
|
| +
|
| + if (z < zbins[rc != 0] && z > nzbins[rc != 0]) {
|
| + zero_flag--;
|
| + } else {
|
| + break;
|
| + }
|
| + }
|
| +
|
| + // Quantization pass: All coefficients with index >= zero_flag are
|
| + // skippable. Note: zero_flag can be zero.
|
| + for (i = 0; i < zero_flag; i++) {
|
| + rc = scan[i];
|
| + z = coeff_ptr[rc] * mul;
|
| +
|
| + zbin = (zbins[rc != 0] + zbin_boost_ptr[zero_run]);
|
| + zero_run += (zero_run < 15);
|
| +
|
| + sz = (z >> 31); // sign of z
|
| + x = (z ^ sz) - sz;
|
| +
|
| + if (x >= zbin) {
|
| + x += (round_ptr[rc != 0]);
|
| + y = ((int)(((int)(x * quant_ptr[rc != 0]) >> 16) + x))
|
| + >> quant_shift_ptr[rc != 0]; // quantize (x)
|
| + x = (y ^ sz) - sz; // get the sign back
|
| + qcoeff_ptr[rc] = x; // write to destination
|
| + dqcoeff_ptr[rc] = x * dequant_ptr[rc != 0] / mul; // dequantized value
|
| +
|
| + if (y) {
|
| + eob = i; // last nonzero coeffs
|
| + zero_run = 0; // set zero_run
|
| + }
|
| + }
|
| + }
|
| + }
|
| + *eob_ptr = eob + 1;
|
| +}
|
| +
|
| +// This function works well for large transform size.
|
| +static void quantize_sparse(int16_t *zbin_boost_orig_ptr,
|
| + int16_t *coeff_ptr, int n_coeffs, int skip_block,
|
| + int16_t *zbin_ptr, int16_t *round_ptr,
|
| + int16_t *quant_ptr, uint8_t *quant_shift_ptr,
|
| + int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
|
| + int16_t *dequant_ptr, int zbin_oq_value,
|
| + uint16_t *eob_ptr, const int *scan, int mul,
|
| + int *idx_arr) {
|
| + int i, rc, eob;
|
| + int zbins[2], pzbins[2], nzbins[2], zbin;
|
| + int x, y, z, sz;
|
| + int zero_run = 0;
|
| + int16_t *zbin_boost_ptr = zbin_boost_orig_ptr;
|
| + int idx = 0;
|
| + int pre_idx = 0;
|
| +
|
| + vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
|
| + vpx_memset(dqcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
|
| +
|
| + eob = -1;
|
| +
|
| + // Base ZBIN
|
| + zbins[0] = zbin_ptr[0] + zbin_oq_value;
|
| + zbins[1] = zbin_ptr[1] + zbin_oq_value;
|
| + // Positive and negative ZBIN
|
| + pzbins[0] = zbins[0]/mul;
|
| + pzbins[1] = zbins[1]/mul;
|
| + nzbins[0] = pzbins[0] * -1;
|
| + nzbins[1] = pzbins[1] * -1;
|
| +
|
| + if (!skip_block) {
|
| + // Pre-scan pass
|
| + for (i = 0; i < n_coeffs; i++) {
|
| + rc = scan[i];
|
| + z = coeff_ptr[rc];
|
| +
|
| + // If the coefficient is out of the base ZBIN range, keep it for
|
| + // quantization.
|
| + if (z >= pzbins[rc != 0] || z <= nzbins[rc != 0])
|
| + idx_arr[idx++] = i;
|
| + }
|
| +
|
| + // Quantization pass: only process the coefficients selected in
|
| + // pre-scan pass. Note: idx can be zero.
|
| + for (i = 0; i < idx; i++) {
|
| + rc = scan[idx_arr[i]];
|
| +
|
| + // Calculate ZBIN
|
| + zero_run += idx_arr[i] - pre_idx;
|
| + if(zero_run > 15) zero_run = 15;
|
| + zbin = (zbins[rc != 0] + zbin_boost_ptr[zero_run]);
|
| +
|
| + pre_idx = idx_arr[i];
|
| + z = coeff_ptr[rc] * mul;
|
| + sz = (z >> 31); // sign of z
|
| + x = (z ^ sz) - sz; // x = abs(z)
|
| +
|
| + if (x >= zbin) {
|
| + x += (round_ptr[rc != 0]);
|
| + y = ((int)(((int)(x * quant_ptr[rc != 0]) >> 16) + x))
|
| + >> quant_shift_ptr[rc != 0]; // quantize (x)
|
| +
|
| + x = (y ^ sz) - sz; // get the sign back
|
| + qcoeff_ptr[rc] = x; // write to destination
|
| + dqcoeff_ptr[rc] = x * dequant_ptr[rc != 0] / mul; // dequantized value
|
| +
|
| + if (y) {
|
| + eob = idx_arr[i]; // last nonzero coeffs
|
| + zero_run = -1; // set zero_run
|
| + }
|
| + }
|
| + }
|
| + }
|
| + *eob_ptr = eob + 1;
|
| +}
|
| +#if 0
|
| +// Original quantize function
|
| +static void quantize(int16_t *zbin_boost_orig_ptr,
|
| + int16_t *coeff_ptr, int n_coeffs, int skip_block,
|
| + int16_t *zbin_ptr, int16_t *round_ptr, int16_t *quant_ptr,
|
| + uint8_t *quant_shift_ptr,
|
| + int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
|
| + int16_t *dequant_ptr, int zbin_oq_value,
|
| + uint16_t *eob_ptr,
|
| + const int *scan, int mul) {
|
| + int i, rc, eob;
|
| int zbin;
|
| int x, y, z, sz;
|
| int zero_run = 0;
|
| @@ -74,6 +221,7 @@
|
|
|
| *eob_ptr = eob + 1;
|
| }
|
| +#endif
|
|
|
| void vp9_quantize(MACROBLOCK *mb, int plane, int block, int n_coeffs,
|
| TX_TYPE tx_type) {
|
| @@ -97,19 +245,40 @@
|
| break;
|
| }
|
|
|
| - quantize(mb->plane[plane].zrun_zbin_boost,
|
| - BLOCK_OFFSET(mb->plane[plane].coeff, block, 16),
|
| - n_coeffs, mb->skip_block,
|
| - mb->plane[plane].zbin,
|
| - mb->plane[plane].round,
|
| - mb->plane[plane].quant,
|
| - mb->plane[plane].quant_shift,
|
| - BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16),
|
| - BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16),
|
| - xd->plane[plane].dequant,
|
| - mb->plane[plane].zbin_extra,
|
| - &xd->plane[plane].eobs[block],
|
| - scan, mul);
|
| + // Call different quantization for different transform size.
|
| + if (n_coeffs >= 1024) {
|
| + // Save index of picked coefficient in pre-scan pass.
|
| + int idx_arr[1024];
|
| +
|
| + quantize_sparse(mb->plane[plane].zrun_zbin_boost,
|
| + BLOCK_OFFSET(mb->plane[plane].coeff, block, 16),
|
| + n_coeffs, mb->skip_block,
|
| + mb->plane[plane].zbin,
|
| + mb->plane[plane].round,
|
| + mb->plane[plane].quant,
|
| + mb->plane[plane].quant_shift,
|
| + BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16),
|
| + BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16),
|
| + xd->plane[plane].dequant,
|
| + mb->plane[plane].zbin_extra,
|
| + &xd->plane[plane].eobs[block],
|
| + scan, mul, idx_arr);
|
| + }
|
| + else {
|
| + quantize(mb->plane[plane].zrun_zbin_boost,
|
| + BLOCK_OFFSET(mb->plane[plane].coeff, block, 16),
|
| + n_coeffs, mb->skip_block,
|
| + mb->plane[plane].zbin,
|
| + mb->plane[plane].round,
|
| + mb->plane[plane].quant,
|
| + mb->plane[plane].quant_shift,
|
| + BLOCK_OFFSET(xd->plane[plane].qcoeff, block, 16),
|
| + BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16),
|
| + xd->plane[plane].dequant,
|
| + mb->plane[plane].zbin_extra,
|
| + &xd->plane[plane].eobs[block],
|
| + scan, mul);
|
| + }
|
| }
|
|
|
| void vp9_regular_quantize_b_4x4(MACROBLOCK *mb, int b_idx, TX_TYPE tx_type,
|
|
|