diff options
Diffstat (limited to 'vp8/encoder/quantize.c')
-rw-r--r-- | vp8/encoder/quantize.c | 290 |
1 files changed, 170 insertions, 120 deletions
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 6028ebf56..5e65fadb3 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. * - * Use of this source code is governed by a BSD-style license and patent - * grant that can be found in the LICENSE file in the root of the source - * tree. All contributing project authors may be found in the AUTHORS - * file in the root of the source tree. + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. */ @@ -15,18 +16,21 @@ #include "entropy.h" #include "predictdc.h" +//#define EXACT_QUANT +#ifdef EXACT_QUANT void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) { int i, rc, eob; int zbin; int x, y, z, sz; - short *coeff_ptr = &b->coeff[0]; - short *zbin_ptr = &b->zbin[0][0]; - short *round_ptr = &b->round[0][0]; - short *quant_ptr = &b->quant[0][0]; - short *qcoeff_ptr = d->qcoeff; - short *dqcoeff_ptr = d->dqcoeff; - short *dequant_ptr = &d->dequant[0][0]; + short *coeff_ptr = b->coeff; + short *zbin_ptr = b->zbin; + short *round_ptr = b->round; + short *quant_ptr = b->quant; + short *quant_shift_ptr = b->quant_shift; + short *qcoeff_ptr = d->qcoeff; + short *dqcoeff_ptr = d->dqcoeff; + short *dequant_ptr = d->dequant; vpx_memset(qcoeff_ptr, 0, 32); vpx_memset(dqcoeff_ptr, 0, 32); @@ -44,7 +48,9 @@ void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) if (x >= zbin) { - y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) + x += round_ptr[rc]; + y = (((x * quant_ptr[rc]) >> 16) + x) + >> quant_shift_ptr[rc]; // quantize (x) x = (y ^ sz) - sz; // get the sign back qcoeff_ptr[rc] = x; // write to destination dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value @@ -55,9 +61,7 @@ void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) } } } - d->eob = eob + 1; - } void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) @@ -65,15 +69,16 @@ void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) int i, rc, eob; int zbin; int x, y, z, sz; - short *zbin_boost_ptr = &b->zrun_zbin_boost[0]; - short *coeff_ptr = &b->coeff[0]; - short *zbin_ptr = &b->zbin[0][0]; - short *round_ptr = &b->round[0][0]; - short *quant_ptr = &b->quant[0][0]; - short *qcoeff_ptr = d->qcoeff; - short *dqcoeff_ptr = d->dqcoeff; - short *dequant_ptr = &d->dequant[0][0]; - short zbin_oq_value = b->zbin_extra; + short *zbin_boost_ptr = b->zrun_zbin_boost; + short *coeff_ptr = b->coeff; + short *zbin_ptr = b->zbin; + short *round_ptr = b->round; + short *quant_ptr = b->quant; + short *quant_shift_ptr = b->quant_shift; + short *qcoeff_ptr = d->qcoeff; + short *dqcoeff_ptr = d->dqcoeff; + short *dequant_ptr = d->dequant; + short zbin_oq_value = b->zbin_extra; vpx_memset(qcoeff_ptr, 0, 32); vpx_memset(dqcoeff_ptr, 0, 32); @@ -96,7 +101,9 @@ void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) if (x >= zbin) { - y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) + x += round_ptr[rc]; + y = (((x * quant_ptr[rc]) >> 16) + x) + >> quant_shift_ptr[rc]; // quantize (x) x = (y ^ sz) - sz; // get the sign back qcoeff_ptr[rc] = x; // write to destination dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value @@ -111,139 +118,182 @@ void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) d->eob = eob + 1; } -void vp8_quantize_mby(MACROBLOCK *x) + +/* Perform regular quantization, with unbiased rounding and no zero bin. */ +void vp8_strict_quantize_b(BLOCK *b, BLOCKD *d) { int i; - - if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV) + int rc; + int eob; + int x; + int y; + int z; + int sz; + short *coeff_ptr; + short *quant_ptr; + short *quant_shift_ptr; + short *qcoeff_ptr; + short *dqcoeff_ptr; + short *dequant_ptr; + + coeff_ptr = b->coeff; + quant_ptr = b->quant; + quant_shift_ptr = b->quant_shift; + qcoeff_ptr = d->qcoeff; + dqcoeff_ptr = d->dqcoeff; + dequant_ptr = d->dequant; + eob = - 1; + vpx_memset(qcoeff_ptr, 0, 32); + vpx_memset(dqcoeff_ptr, 0, 32); + for (i = 0; i < 16; i++) { - for (i = 0; i < 16; i++) + int dq; + int round; + + /*TODO: These arrays should be stored in zig-zag order.*/ + rc = vp8_default_zig_zag1d[i]; + z = coeff_ptr[rc]; + dq = dequant_ptr[rc]; + round = dq >> 1; + /* Sign of z. */ + sz = -(z < 0); + x = (z + sz) ^ sz; + x += round; + if (x >= dq) { - x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2); + /* Quantize x. */ + y = (((x * quant_ptr[rc]) >> 16) + x) >> quant_shift_ptr[rc]; + /* Put the sign back. */ + x = (y + sz) ^ sz; + /* Save the coefficient and its dequantized value. */ + qcoeff_ptr[rc] = x; + dqcoeff_ptr[rc] = x * dq; + /* Remember the last non-zero coefficient. */ + if (y) + eob = i; } + } - x->quantize_b(&x->block[24], &x->e_mbd.block[24]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[24].eob); + d->eob = eob + 1; +} - } - else +#else +void vp8_fast_quantize_b_c(BLOCK *b, BLOCKD *d) +{ + int i, rc, eob; + int zbin; + int x, y, z, sz; + short *coeff_ptr = b->coeff; + short *round_ptr = b->round; + short *quant_ptr = b->quant; + short *qcoeff_ptr = d->qcoeff; + short *dqcoeff_ptr = d->dqcoeff; + short *dequant_ptr = d->dequant; + + eob = -1; + for (i = 0; i < 16; i++) { - for (i = 0; i < 16; i++) + rc = vp8_default_zig_zag1d[i]; + z = coeff_ptr[rc]; + + sz = (z >> 31); // sign of z + x = (z ^ sz) - sz; // x = abs(z) + + y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) + x = (y ^ sz) - sz; // get the sign back + qcoeff_ptr[rc] = x; // write to destination + dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value + + if (y) { - x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); + eob = i; // last nonzero coeffs } } + d->eob = eob + 1; } -void vp8_quantize_mb(MACROBLOCK *x) +void vp8_regular_quantize_b(BLOCK *b, BLOCKD *d) { - int i; + int i, rc, eob; + int zbin; + int x, y, z, sz; + short *zbin_boost_ptr = b->zrun_zbin_boost; + short *coeff_ptr = b->coeff; + short *zbin_ptr = b->zbin; + short *round_ptr = b->round; + short *quant_ptr = b->quant; + short *qcoeff_ptr = d->qcoeff; + short *dqcoeff_ptr = d->dqcoeff; + short *dequant_ptr = d->dequant; + short zbin_oq_value = b->zbin_extra; - x->e_mbd.mbmi.mb_skip_coeff = 1; + vpx_memset(qcoeff_ptr, 0, 32); + vpx_memset(dqcoeff_ptr, 0, 32); - if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV) - { - for (i = 0; i < 16; i++) - { - x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2); - } + eob = -1; - for (i = 16; i < 25; i++) - { - x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); - } - } - else + for (i = 0; i < 16; i++) { - for (i = 0; i < 24; i++) + rc = vp8_default_zig_zag1d[i]; + z = coeff_ptr[rc]; + + //if ( i == 0 ) + // zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value/2; + //else + zbin = zbin_ptr[rc] + *zbin_boost_ptr + zbin_oq_value; + + zbin_boost_ptr ++; + sz = (z >> 31); // sign of z + x = (z ^ sz) - sz; // x = abs(z) + + if (x >= zbin) { - x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); + y = ((x + round_ptr[rc]) * quant_ptr[rc]) >> 16; // quantize (x) + x = (y ^ sz) - sz; // get the sign back + qcoeff_ptr[rc] = x; // write to destination + dqcoeff_ptr[rc] = x * dequant_ptr[rc]; // dequantized value + + if (y) + { + eob = i; // last nonzero coeffs + zbin_boost_ptr = &b->zrun_zbin_boost[0]; // reset zero runlength + } } } + d->eob = eob + 1; } +#endif -void vp8_quantize_mbuv(MACROBLOCK *x) +void vp8_quantize_mby(MACROBLOCK *x) { int i; + int has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED + && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); - for (i = 16; i < 24; i++) - { + for (i = 0; i < 16; i++) x->quantize_b(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); - } -} - -// This function is not currently called -void vp8_quantize_mbrd(MACROBLOCK *x) -{ - int i; - - x->e_mbd.mbmi.mb_skip_coeff = 1; - - if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV) - { - for (i = 0; i < 16; i++) - { - x->quantize_brd(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2); - } - for (i = 16; i < 25; i++) - { - x->quantize_brd(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); - } - } - else - { - for (i = 0; i < 24; i++) - { - x->quantize_brd(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); - } - } + if(has_2nd_order) + x->quantize_b(&x->block[24], &x->e_mbd.block[24]); } -void vp8_quantize_mbuvrd(MACROBLOCK *x) +void vp8_quantize_mb(MACROBLOCK *x) { int i; + int has_2nd_order=(x->e_mbd.mode_info_context->mbmi.mode != B_PRED + && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV); - for (i = 16; i < 24; i++) - { - x->quantize_brd(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); - } + for (i = 0; i < 24+has_2nd_order; i++) + x->quantize_b(&x->block[i], &x->e_mbd.block[i]); } -void vp8_quantize_mbyrd(MACROBLOCK *x) + +void vp8_quantize_mbuv(MACROBLOCK *x) { int i; - if (x->e_mbd.mbmi.mode != B_PRED && x->e_mbd.mbmi.mode != SPLITMV) - { - for (i = 0; i < 16; i++) - { - x->quantize_brd(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (x->e_mbd.block[i].eob < 2); - } - - x->quantize_brd(&x->block[24], &x->e_mbd.block[24]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[24].eob); - - } - else - { - for (i = 0; i < 16; i++) - { - x->quantize_brd(&x->block[i], &x->e_mbd.block[i]); - x->e_mbd.mbmi.mb_skip_coeff &= (!x->e_mbd.block[i].eob); - } - } + for (i = 16; i < 24; i++) + x->quantize_b(&x->block[i], &x->e_mbd.block[i]); } |