diff options
Diffstat (limited to 'vp8/encoder/quantize.c')
-rw-r--r-- | vp8/encoder/quantize.c | 196 |
1 files changed, 178 insertions, 18 deletions
diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 78892fc3f..81b4d12b3 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -302,15 +302,93 @@ void vp8_quantize_mb_8x8(MACROBLOCK *x) { void vp8_quantize_mbuv_8x8(MACROBLOCK *x) { int i; - for (i = 16; i < 24; i ++) { + for (i = 16; i < 24; i ++) x->e_mbd.block[i].eob = 0; - } for (i = 16; i < 24; i += 4) x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]); } + +#if CONFIG_TX16X16 +void vp8_quantize_mby_16x16(MACROBLOCK *x) { + int i; + for (i = 0; i < 16; i++) + x->e_mbd.block[i].eob = 0; + x->e_mbd.block[24].eob = 0; + x->quantize_b_16x16(&x->block[0], &x->e_mbd.block[0]); +} + +void vp8_quantize_mb_16x16(MACROBLOCK *x) { + int i; + for(i = 0; i < 25; i++) + x->e_mbd.block[i].eob = 0; + x->quantize_b_16x16(&x->block[0], &x->e_mbd.block[0]); + for (i = 16; i < 24; i += 4) + x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]); +} + +// U and V should use 8x8 +void vp8_quantize_mbuv_16x16(MACROBLOCK *x) { + int i; + + for(i = 16; i < 24; i++) + x->e_mbd.block[i].eob = 0; + for (i = 16; i < 24; i += 4) + x->quantize_b_8x8(&x->block[i], &x->e_mbd.block[i]); +} + +void vp8_regular_quantize_b_16x16(BLOCK *b, BLOCKD *d) { + int i, rc, eob; + int zbin; + int x, y, z, sz; + short *zbin_boost_ptr = b->zrun_zbin_boost_16x16; + short *coeff_ptr = b->coeff; + short *zbin_ptr = b->zbin_16x16; + short *round_ptr = b->round; + short *quant_ptr = b->quant; + unsigned char *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, 256*sizeof(short)); + vpx_memset(dqcoeff_ptr, 0, 256*sizeof(short)); + + eob = -1; + for (i = 0; i < b->eob_max_offset_16x16; i++) { + rc = vp8_default_zig_zag1d_16x16[i]; + z = coeff_ptr[rc]; + + zbin = (zbin_ptr[rc!=0] + *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 += (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]; // dequantized value + + if (y) { + eob = i; // last nonzero coeffs + zbin_boost_ptr = b->zrun_zbin_boost_16x16; + } + } + } + + d->eob = eob + 1; +} +#endif + + + /* quantize_b_pair function pointer in MACROBLOCK structure is set to one of * these two C functions if corresponding optimized routine is not available. * NEON optimized version implements currently the fast quantization for pair @@ -337,20 +415,39 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) { int i; int quant_val; int Q; - int zbin_boost[16] = { 0, 0, 8, 10, 12, 14, 16, 20, - 24, 28, 32, 36, 40, 44, 44, 44 - }; - - int zbin_boost_8x8[64] = { 0, 0, 0, 8, 8, 8, 10, 12, - 14, 16, 18, 20, 22, 24, 26, 28, - 30, 32, 34, 36, 38, 40, 42, 44, - 46, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48 - }; - + static const int zbin_boost[16] = { 0, 0, 8, 10, 12, 14, 16, 20, + 24, 28, 32, 36, 40, 44, 44, 44 + }; + + static const int zbin_boost_8x8[64] = { 0, 0, 0, 8, 8, 8, 10, 12, + 14, 16, 18, 20, 22, 24, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, + 46, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48 + }; +#if CONFIG_TX16X16 + static const int zbin_boost_16x16[256] = { + 0, 0, 0, 8, 8, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + }; +#endif int qrounding_factor = 48; @@ -372,33 +469,52 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) { cpi->Y1quant_shift[Q] + 0, quant_val); cpi->Y1zbin[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; cpi->Y1zbin_8x8[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; +#if CONFIG_TX16X16 + cpi->Y1zbin_16x16[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; +#endif cpi->Y1round[Q][0] = (qrounding_factor * quant_val) >> 7; cpi->common.Y1dequant[Q][0] = quant_val; cpi->zrun_zbin_boost_y1[Q][0] = (quant_val * zbin_boost[0]) >> 7; cpi->zrun_zbin_boost_y1_8x8[Q][0] = ((quant_val * zbin_boost_8x8[0]) + 64) >> 7; +#if CONFIG_TX16X16 + cpi->zrun_zbin_boost_y1_16x16[Q][0] = ((quant_val * zbin_boost_16x16[0]) + 64) >> 7; +#endif + quant_val = vp8_dc2quant(Q, cpi->common.y2dc_delta_q); invert_quant(cpi->Y2quant[Q] + 0, cpi->Y2quant_shift[Q] + 0, quant_val); cpi->Y2zbin[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; cpi->Y2zbin_8x8[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; +#if CONFIG_TX16X16 + cpi->Y2zbin_16x16[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; +#endif cpi->Y2round[Q][0] = (qrounding_factor * quant_val) >> 7; cpi->common.Y2dequant[Q][0] = quant_val; cpi->zrun_zbin_boost_y2[Q][0] = (quant_val * zbin_boost[0]) >> 7; cpi->zrun_zbin_boost_y2_8x8[Q][0] = ((quant_val * zbin_boost_8x8[0]) + 64) >> 7; +#if CONFIG_TX16X16 + cpi->zrun_zbin_boost_y2_16x16[Q][0] = ((quant_val * zbin_boost_16x16[0]) + 64) >> 7; +#endif quant_val = vp8_dc_uv_quant(Q, cpi->common.uvdc_delta_q); invert_quant(cpi->UVquant[Q] + 0, cpi->UVquant_shift[Q] + 0, quant_val); - cpi->UVzbin[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7;; - cpi->UVzbin_8x8[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7;; + cpi->UVzbin[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; + cpi->UVzbin_8x8[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; +#if CONFIG_TX16X16 + cpi->UVzbin_16x16[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; +#endif cpi->UVround[Q][0] = (qrounding_factor * quant_val) >> 7; cpi->common.UVdequant[Q][0] = quant_val; cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7; cpi->zrun_zbin_boost_uv_8x8[Q][0] = ((quant_val * zbin_boost_8x8[0]) + 64) >> 7; +#if CONFIG_TX16X16 + cpi->zrun_zbin_boost_uv_16x16[Q][0] = ((quant_val * zbin_boost_16x16[0]) + 64) >> 7; +#endif // all the 4x4 ac values =; for (i = 1; i < 16; i++) { @@ -453,6 +569,25 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) { cpi->zrun_zbin_boost_uv_8x8[Q][i] = ((quant_val * zbin_boost_8x8[i]) + 64) >> 7; } + +#if CONFIG_TX16X16 + // 16x16 structures. Same comment above applies. + for (i = 1; i < 256; i++) { + int rc = vp8_default_zig_zag1d_16x16[i]; + + quant_val = vp8_ac_yquant(Q); + cpi->Y1zbin_16x16[Q][rc] = ((qzbin_factor * quant_val) + 64) >> 7; + cpi->zrun_zbin_boost_y1_16x16[Q][i] = ((quant_val * zbin_boost_16x16[i]) + 64) >> 7; + + quant_val = vp8_ac2quant(Q, cpi->common.y2ac_delta_q); + cpi->Y2zbin_16x16[Q][rc] = ((qzbin_factor * quant_val) + 64) >> 7; + cpi->zrun_zbin_boost_y2_16x16[Q][i] = ((quant_val * zbin_boost_16x16[i]) + 64) >> 7; + + quant_val = vp8_ac_uv_quant(Q, cpi->common.uvac_delta_q); + cpi->UVzbin_16x16[Q][rc] = ((qzbin_factor * quant_val) + 64) >> 7; + cpi->zrun_zbin_boost_uv_16x16[Q][i] = ((quant_val * zbin_boost_16x16[i]) + 64) >> 7; + } +#endif } } @@ -491,10 +626,16 @@ void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x) { x->block[i].quant_shift = cpi->Y1quant_shift[QIndex]; x->block[i].zbin = cpi->Y1zbin[QIndex]; x->block[i].zbin_8x8 = cpi->Y1zbin_8x8[QIndex]; +#if CONFIG_TX16X16 + x->block[i].zbin_16x16 = cpi->Y1zbin_16x16[QIndex]; +#endif x->block[i].round = cpi->Y1round[QIndex]; x->e_mbd.block[i].dequant = cpi->common.Y1dequant[QIndex]; x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex]; x->block[i].zrun_zbin_boost_8x8 = cpi->zrun_zbin_boost_y1_8x8[QIndex]; +#if CONFIG_TX16X16 + x->block[i].zrun_zbin_boost_16x16 = cpi->zrun_zbin_boost_y1_16x16[QIndex]; +#endif x->block[i].zbin_extra = (short)zbin_extra; // Segment max eob offset feature. @@ -503,9 +644,16 @@ void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x) { get_segdata(xd, segment_id, SEG_LVL_EOB); x->block[i].eob_max_offset_8x8 = get_segdata(xd, segment_id, SEG_LVL_EOB); +#if CONFIG_TX16X16 + x->block[i].eob_max_offset_16x16 = + get_segdata(xd, segment_id, SEG_LVL_EOB); +#endif } else { x->block[i].eob_max_offset = 16; x->block[i].eob_max_offset_8x8 = 64; +#if CONFIG_TX16X16 + x->block[i].eob_max_offset_16x16 = 256; +#endif } } @@ -520,10 +668,16 @@ void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x) { x->block[i].quant_shift = cpi->UVquant_shift[QIndex]; x->block[i].zbin = cpi->UVzbin[QIndex]; x->block[i].zbin_8x8 = cpi->UVzbin_8x8[QIndex]; +#if CONFIG_TX16X16 + x->block[i].zbin_16x16 = cpi->UVzbin_16x16[QIndex]; +#endif x->block[i].round = cpi->UVround[QIndex]; x->e_mbd.block[i].dequant = cpi->common.UVdequant[QIndex]; x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex]; x->block[i].zrun_zbin_boost_8x8 = cpi->zrun_zbin_boost_uv_8x8[QIndex]; +#if CONFIG_TX16X16 + x->block[i].zrun_zbin_boost_16x16 = cpi->zrun_zbin_boost_uv_16x16[QIndex]; +#endif x->block[i].zbin_extra = (short)zbin_extra; @@ -549,10 +703,16 @@ void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x) { x->block[24].quant_shift = cpi->Y2quant_shift[QIndex]; x->block[24].zbin = cpi->Y2zbin[QIndex]; x->block[24].zbin_8x8 = cpi->Y2zbin_8x8[QIndex]; +#if CONFIG_TX16X16 + x->block[24].zbin_16x16 = cpi->Y2zbin_16x16[QIndex]; +#endif x->block[24].round = cpi->Y2round[QIndex]; x->e_mbd.block[24].dequant = cpi->common.Y2dequant[QIndex]; x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex]; x->block[24].zrun_zbin_boost_8x8 = cpi->zrun_zbin_boost_y2_8x8[QIndex]; +#if CONFIG_TX16X16 + x->block[24].zrun_zbin_boost_16x16 = cpi->zrun_zbin_boost_y2_16x16[QIndex]; +#endif x->block[24].zbin_extra = (short)zbin_extra; // TBD perhaps not use for Y2 |