80,
};
+static void vp8cx_invert_quant(short *quant, short *shift, short d)
+{
+ unsigned t;
+ int l;
+ t = d;
+ for(l = 0; t > 1; l++)
+ t>>=1;
+ t = 1 + (1<<(16+l))/d;
+ *quant = (short)(t - (1<<16));
+ *shift = l;
+}
+
void vp8cx_init_quantizer(VP8_COMP *cpi)
{
int r, c;
{
// dc values
quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q);
- cpi->Y1quant[Q][0][0] = (1 << 16) / quant_val;
+ vp8cx_invert_quant(cpi->Y1quant[Q][0] + 0,
+ cpi->Y1quant_shift[Q][0] + 0, quant_val);
cpi->Y1zbin[Q][0][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->Y1round[Q][0][0] = (qrounding_factors[Q] * quant_val) >> 7;
cpi->common.Y1dequant[Q][0][0] = quant_val;
cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7;
quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q);
- cpi->Y2quant[Q][0][0] = (1 << 16) / quant_val;
+ vp8cx_invert_quant(cpi->Y2quant[Q][0] + 0,
+ cpi->Y2quant_shift[Q][0] + 0, quant_val);
cpi->Y2zbin[Q][0][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->Y2round[Q][0][0] = (qrounding_factors[Q] * quant_val) >> 7;
cpi->common.Y2dequant[Q][0][0] = quant_val;
cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7;
quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q);
- cpi->UVquant[Q][0][0] = (1 << 16) / quant_val;
+ vp8cx_invert_quant(cpi->UVquant[Q][0] + 0,
+ cpi->UVquant_shift[Q][0] + 0, quant_val);
cpi->UVzbin[Q][0][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;;
cpi->UVround[Q][0][0] = (qrounding_factors[Q] * quant_val) >> 7;
cpi->common.UVdequant[Q][0][0] = quant_val;
c = (rc & 3);
quant_val = vp8_ac_yquant(Q);
- cpi->Y1quant[Q][r][c] = (1 << 16) / quant_val;
+ vp8cx_invert_quant(cpi->Y1quant[Q][r] + c,
+ cpi->Y1quant_shift[Q][r] + c, quant_val);
cpi->Y1zbin[Q][r][c] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->Y1round[Q][r][c] = (qrounding_factors[Q] * quant_val) >> 7;
cpi->common.Y1dequant[Q][r][c] = quant_val;
cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7;
quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q);
- cpi->Y2quant[Q][r][c] = (1 << 16) / quant_val;
+ vp8cx_invert_quant(cpi->Y2quant[Q][r] + c,
+ cpi->Y2quant_shift[Q][r] + c, quant_val);
cpi->Y2zbin[Q][r][c] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->Y2round[Q][r][c] = (qrounding_factors[Q] * quant_val) >> 7;
cpi->common.Y2dequant[Q][r][c] = quant_val;
cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7;
quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q);
- cpi->UVquant[Q][r][c] = (1 << 16) / quant_val;
+ vp8cx_invert_quant(cpi->UVquant[Q][r] + c,
+ cpi->UVquant_shift[Q][r] + c, quant_val);
cpi->UVzbin[Q][r][c] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;
cpi->UVround[Q][r][c] = (qrounding_factors[Q] * quant_val) >> 7;
cpi->common.UVdequant[Q][r][c] = quant_val;
for (i = 0; i < 16; i++)
{
x->block[i].quant = cpi->Y1quant[QIndex];
+ x->block[i].quant_shift = cpi->Y1quant_shift[QIndex];
x->block[i].zbin = cpi->Y1zbin[QIndex];
x->block[i].round = cpi->Y1round[QIndex];
x->e_mbd.block[i].dequant = cpi->common.Y1dequant[QIndex];
for (i = 16; i < 24; i++)
{
x->block[i].quant = cpi->UVquant[QIndex];
+ x->block[i].quant_shift = cpi->UVquant_shift[QIndex];
x->block[i].zbin = cpi->UVzbin[QIndex];
x->block[i].round = cpi->UVround[QIndex];
x->e_mbd.block[i].dequant = cpi->common.UVdequant[QIndex];
// Y2
zbin_extra = (cpi->common.Y2dequant[QIndex][0][1] * ((cpi->zbin_over_quant / 2) + cpi->zbin_mode_boost)) >> 7;
x->block[24].quant = cpi->Y2quant[QIndex];
+ x->block[24].quant_shift = cpi->Y2quant_shift[QIndex];
x->block[24].zbin = cpi->Y2zbin[QIndex];
x->block[24].round = cpi->Y2round[QIndex];
x->e_mbd.block[24].dequant = cpi->common.Y2dequant[QIndex];
{
DECLARE_ALIGNED(16, short, Y1quant[QINDEX_RANGE][4][4]);
+ DECLARE_ALIGNED(16, short, Y1quant_shift[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, Y1zbin[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, Y1round[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, Y2quant[QINDEX_RANGE][4][4]);
+ DECLARE_ALIGNED(16, short, Y2quant_shift[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, Y2zbin[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, Y2round[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, UVquant[QINDEX_RANGE][4][4]);
+ DECLARE_ALIGNED(16, short, UVquant_shift[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, UVzbin[QINDEX_RANGE][4][4]);
DECLARE_ALIGNED(16, short, UVround[QINDEX_RANGE][4][4]);
short *zbin_ptr = &b->zbin[0][0];
short *round_ptr = &b->round[0][0];
short *quant_ptr = &b->quant[0][0];
+ short *quant_shift_ptr = &b->quant_shift[0][0];
short *qcoeff_ptr = d->qcoeff;
short *dqcoeff_ptr = d->dqcoeff;
short *dequant_ptr = &d->dequant[0][0];
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
short *zbin_ptr = &b->zbin[0][0];
short *round_ptr = &b->round[0][0];
short *quant_ptr = &b->quant[0][0];
+ short *quant_shift_ptr = &b->quant_shift[0][0];
short *qcoeff_ptr = d->qcoeff;
short *dqcoeff_ptr = d->dqcoeff;
short *dequant_ptr = &d->dequant[0][0];
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