From 87254e0b7b862c93926fa82e814376357d8c3c32 Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Thu, 19 May 2011 11:04:03 -0400 Subject: [PATCH] Move quantizer init functions to quantize.c Group related functions together. Change-Id: I92fd779225b75a7204650f1decb713142c655d71 --- vp8/encoder/encodeframe.c | 364 ---------------------------------------- vp8/encoder/onyx_if.c | 43 +---- vp8/encoder/onyx_int.h | 2 +- vp8/encoder/quantize.c | 418 +++++++++++++++++++++++++++++++++++++++++++++- vp8/encoder/quantize.h | 7 + 5 files changed, 427 insertions(+), 407 deletions(-) diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 6e5282b..a1533e6 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -60,370 +60,6 @@ unsigned int uv_modes[4] = {0, 0, 0, 0}; unsigned int b_modes[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; #endif -static const int qrounding_factors[129] = -{ - 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 -}; - -static const int qzbin_factors[129] = -{ - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80 -}; - -static const int qrounding_factors_y2[129] = -{ - 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 -}; - -static const int qzbin_factors_y2[129] = -{ - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, - 80 -}; - -#define EXACT_QUANT -#ifdef EXACT_QUANT -static void vp8cx_invert_quant(int improved_quant, short *quant, - unsigned char *shift, short d) -{ - if(improved_quant) - { - 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; - } - else - { - *quant = (1 << 16) / d; - *shift = 0; - } -} - -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}; - - for (Q = 0; Q < QINDEX_RANGE; Q++) - { - // dc values - quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q); - cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val; - vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0, - cpi->Y1quant_shift[Q] + 0, quant_val); - cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.Y1dequant[Q][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_fast[Q][0] = (1 << 16) / quant_val; - vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0, - cpi->Y2quant_shift[Q] + 0, quant_val); - cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; - cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7; - cpi->common.Y2dequant[Q][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_fast[Q][0] = (1 << 16) / quant_val; - vp8cx_invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0, - cpi->UVquant_shift[Q] + 0, quant_val); - cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;; - cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.UVdequant[Q][0] = quant_val; - cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7; - - // all the ac values = ; - for (i = 1; i < 16; i++) - { - int rc = vp8_default_zig_zag1d[i]; - - quant_val = vp8_ac_yquant(Q); - cpi->Y1quant_fast[Q][rc] = (1 << 16) / quant_val; - vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + rc, - cpi->Y1quant_shift[Q] + rc, quant_val); - cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.Y1dequant[Q][rc] = 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_fast[Q][rc] = (1 << 16) / quant_val; - vp8cx_invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + rc, - cpi->Y2quant_shift[Q] + rc, quant_val); - cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; - cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7; - cpi->common.Y2dequant[Q][rc] = 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_fast[Q][rc] = (1 << 16) / quant_val; - vp8cx_invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + rc, - cpi->UVquant_shift[Q] + rc, quant_val); - cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.UVdequant[Q][rc] = quant_val; - cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7; - } - } -} -#else -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}; - - for (Q = 0; Q < QINDEX_RANGE; Q++) - { - // dc values - quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q); - cpi->Y1quant[Q][0] = (1 << 16) / quant_val; - cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.Y1dequant[Q][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] = (1 << 16) / quant_val; - cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; - cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7; - cpi->common.Y2dequant[Q][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] = (1 << 16) / quant_val; - cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;; - cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.UVdequant[Q][0] = quant_val; - cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7; - - // all the ac values = ; - for (i = 1; i < 16; i++) - { - int rc = vp8_default_zig_zag1d[i]; - - quant_val = vp8_ac_yquant(Q); - cpi->Y1quant[Q][rc] = (1 << 16) / quant_val; - cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.Y1dequant[Q][rc] = 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][rc] = (1 << 16) / quant_val; - cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; - cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7; - cpi->common.Y2dequant[Q][rc] = 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][rc] = (1 << 16) / quant_val; - cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; - cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; - cpi->common.UVdequant[Q][rc] = quant_val; - cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7; - } - } -} -#endif -void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x) -{ - int i; - int QIndex; - MACROBLOCKD *xd = &x->e_mbd; - int zbin_extra; - - // Select the baseline MB Q index. - if (xd->segmentation_enabled) - { - // Abs Value - if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA) - - QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; - // Delta Value - else - { - QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; - QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; // Clamp to valid range - } - } - else - QIndex = cpi->common.base_qindex; - - // Y - zbin_extra = ( cpi->common.Y1dequant[QIndex][1] * - ( cpi->zbin_over_quant + - cpi->zbin_mode_boost + - x->act_zbin_adj ) ) >> 7; - - for (i = 0; i < 16; i++) - { - x->block[i].quant = cpi->Y1quant[QIndex]; - x->block[i].quant_fast = cpi->Y1quant_fast[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]; - x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex]; - x->block[i].zbin_extra = (short)zbin_extra; - } - - // UV - zbin_extra = ( cpi->common.UVdequant[QIndex][1] * - ( cpi->zbin_over_quant + - cpi->zbin_mode_boost + - x->act_zbin_adj ) ) >> 7; - - for (i = 16; i < 24; i++) - { - x->block[i].quant = cpi->UVquant[QIndex]; - x->block[i].quant_fast = cpi->UVquant_fast[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]; - x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex]; - x->block[i].zbin_extra = (short)zbin_extra; - } - - // Y2 - zbin_extra = ( cpi->common.Y2dequant[QIndex][1] * - ( (cpi->zbin_over_quant / 2) + - cpi->zbin_mode_boost + - x->act_zbin_adj ) ) >> 7; - - x->block[24].quant_fast = cpi->Y2quant_fast[QIndex]; - 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]; - x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex]; - x->block[24].zbin_extra = (short)zbin_extra; - - /* save this macroblock QIndex for vp8_update_zbin_extra() */ - x->q_index = QIndex; -} -void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x) -{ - int i; - int QIndex = x->q_index; - int zbin_extra; - - // Y - zbin_extra = ( cpi->common.Y1dequant[QIndex][1] * - ( cpi->zbin_over_quant + - cpi->zbin_mode_boost + - x->act_zbin_adj ) ) >> 7; - for (i = 0; i < 16; i++) - { - x->block[i].zbin_extra = (short)zbin_extra; - } - - // UV - zbin_extra = ( cpi->common.UVdequant[QIndex][1] * - ( cpi->zbin_over_quant + - cpi->zbin_mode_boost + - x->act_zbin_adj ) ) >> 7; - - for (i = 16; i < 24; i++) - { - x->block[i].zbin_extra = (short)zbin_extra; - } - - // Y2 - zbin_extra = ( cpi->common.Y2dequant[QIndex][1] * - ( (cpi->zbin_over_quant / 2) + - cpi->zbin_mode_boost + - x->act_zbin_adj ) ) >> 7; - - x->block[24].zbin_extra = (short)zbin_extra; -} - -void vp8cx_frame_init_quantizer(VP8_COMP *cpi) -{ - // Clear Zbin mode boost for default case - cpi->zbin_mode_boost = 0; - - // MB level quantizer setup - vp8cx_mb_init_quantizer(cpi, &cpi->mb); -} - /* activity_avg must be positive, or flat regions could get a zero weight * (infinite lambda), which confounds analysis. diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 2a77235..fc7a863 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2653,45 +2653,6 @@ static void resize_key_frame(VP8_COMP *cpi) } -static void set_quantizer(VP8_COMP *cpi, int Q) -{ - VP8_COMMON *cm = &cpi->common; - MACROBLOCKD *mbd = &cpi->mb.e_mbd; - int update = 0; - int new_delta_q; - cm->base_qindex = Q; - - /* if any of the delta_q values are changing update flag has to be set */ - /* currently only y2dc_delta_q may change */ - - cm->y1dc_delta_q = 0; - cm->y2ac_delta_q = 0; - cm->uvdc_delta_q = 0; - cm->uvac_delta_q = 0; - - if (Q < 4) - { - new_delta_q = 4-Q; - } - else - new_delta_q = 0; - - update |= cm->y2dc_delta_q != new_delta_q; - cm->y2dc_delta_q = new_delta_q; - - - // Set Segment specific quatizers - mbd->segment_feature_data[MB_LVL_ALT_Q][0] = cpi->segment_feature_data[MB_LVL_ALT_Q][0]; - mbd->segment_feature_data[MB_LVL_ALT_Q][1] = cpi->segment_feature_data[MB_LVL_ALT_Q][1]; - mbd->segment_feature_data[MB_LVL_ALT_Q][2] = cpi->segment_feature_data[MB_LVL_ALT_Q][2]; - mbd->segment_feature_data[MB_LVL_ALT_Q][3] = cpi->segment_feature_data[MB_LVL_ALT_Q][3]; - - /* quantizer has to be reinitialized for any delta_q changes */ - if(update) - vp8cx_init_quantizer(cpi); - -} - static void update_alt_ref_frame_and_stats(VP8_COMP *cpi) { VP8_COMMON *cm = &cpi->common; @@ -3034,7 +2995,7 @@ static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, (void) size; (void) dest; (void) frame_flags; - set_quantizer(cpi, 26); + vp8_set_quantizer(cpi, 26); scale_and_extend_source(cpi->un_scaled_source, cpi); vp8_first_pass(cpi); @@ -3694,7 +3655,7 @@ static void encode_frame_to_data_rate Q = 127; */ - set_quantizer(cpi, Q); + vp8_set_quantizer(cpi, Q); this_q = Q; // setup skip prob for costing in mode/mv decision diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 8b17178..e18d468 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -240,7 +240,7 @@ enum BLOCK_MAX_SEGMENTS }; -typedef struct +typedef struct VP8_COMP { DECLARE_ALIGNED(16, short, Y1quant[QINDEX_RANGE][16]); diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 86ed267..49e8e1b 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -12,8 +12,9 @@ #include #include "vpx_mem/vpx_mem.h" +#include "onyx_int.h" #include "quantize.h" -#include "vp8/common/entropy.h" +#include "vp8/common/quant_common.h" #define EXACT_QUANT @@ -299,3 +300,418 @@ void vp8_quantize_mbuv(MACROBLOCK *x) for (i = 16; i < 24; i++) x->quantize_b(&x->block[i], &x->e_mbd.block[i]); } + + +static const int qrounding_factors[129] = +{ + 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 +}; + + +static const int qzbin_factors[129] = +{ + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80 +}; + + +static const int qrounding_factors_y2[129] = +{ + 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 +}; + + +static const int qzbin_factors_y2[129] = +{ + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80 +}; + + +#define EXACT_QUANT +#ifdef EXACT_QUANT +static void invert_quant(int improved_quant, short *quant, + unsigned char *shift, short d) +{ + if(improved_quant) + { + 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; + } + else + { + *quant = (1 << 16) / d; + *shift = 0; + } +} + + +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}; + + for (Q = 0; Q < QINDEX_RANGE; Q++) + { + // dc values + quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q); + cpi->Y1quant_fast[Q][0] = (1 << 16) / quant_val; + invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + 0, + cpi->Y1quant_shift[Q] + 0, quant_val); + cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; + cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.Y1dequant[Q][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_fast[Q][0] = (1 << 16) / quant_val; + invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + 0, + cpi->Y2quant_shift[Q] + 0, quant_val); + cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; + cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7; + cpi->common.Y2dequant[Q][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_fast[Q][0] = (1 << 16) / quant_val; + invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + 0, + cpi->UVquant_shift[Q] + 0, quant_val); + cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;; + cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.UVdequant[Q][0] = quant_val; + cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7; + + // all the ac values = ; + for (i = 1; i < 16; i++) + { + int rc = vp8_default_zig_zag1d[i]; + + quant_val = vp8_ac_yquant(Q); + cpi->Y1quant_fast[Q][rc] = (1 << 16) / quant_val; + invert_quant(cpi->sf.improved_quant, cpi->Y1quant[Q] + rc, + cpi->Y1quant_shift[Q] + rc, quant_val); + cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; + cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.Y1dequant[Q][rc] = 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_fast[Q][rc] = (1 << 16) / quant_val; + invert_quant(cpi->sf.improved_quant, cpi->Y2quant[Q] + rc, + cpi->Y2quant_shift[Q] + rc, quant_val); + cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; + cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7; + cpi->common.Y2dequant[Q][rc] = 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_fast[Q][rc] = (1 << 16) / quant_val; + invert_quant(cpi->sf.improved_quant, cpi->UVquant[Q] + rc, + cpi->UVquant_shift[Q] + rc, quant_val); + cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; + cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.UVdequant[Q][rc] = quant_val; + cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7; + } + } +} +#else +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}; + + for (Q = 0; Q < QINDEX_RANGE; Q++) + { + // dc values + quant_val = vp8_dc_quant(Q, cpi->common.y1dc_delta_q); + cpi->Y1quant[Q][0] = (1 << 16) / quant_val; + cpi->Y1zbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; + cpi->Y1round[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.Y1dequant[Q][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] = (1 << 16) / quant_val; + cpi->Y2zbin[Q][0] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; + cpi->Y2round[Q][0] = (qrounding_factors_y2[Q] * quant_val) >> 7; + cpi->common.Y2dequant[Q][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] = (1 << 16) / quant_val; + cpi->UVzbin[Q][0] = ((qzbin_factors[Q] * quant_val) + 64) >> 7;; + cpi->UVround[Q][0] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.UVdequant[Q][0] = quant_val; + cpi->zrun_zbin_boost_uv[Q][0] = (quant_val * zbin_boost[0]) >> 7; + + // all the ac values = ; + for (i = 1; i < 16; i++) + { + int rc = vp8_default_zig_zag1d[i]; + + quant_val = vp8_ac_yquant(Q); + cpi->Y1quant[Q][rc] = (1 << 16) / quant_val; + cpi->Y1zbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; + cpi->Y1round[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.Y1dequant[Q][rc] = 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][rc] = (1 << 16) / quant_val; + cpi->Y2zbin[Q][rc] = ((qzbin_factors_y2[Q] * quant_val) + 64) >> 7; + cpi->Y2round[Q][rc] = (qrounding_factors_y2[Q] * quant_val) >> 7; + cpi->common.Y2dequant[Q][rc] = 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][rc] = (1 << 16) / quant_val; + cpi->UVzbin[Q][rc] = ((qzbin_factors[Q] * quant_val) + 64) >> 7; + cpi->UVround[Q][rc] = (qrounding_factors[Q] * quant_val) >> 7; + cpi->common.UVdequant[Q][rc] = quant_val; + cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7; + } + } +} +#endif + + +void vp8cx_mb_init_quantizer(VP8_COMP *cpi, MACROBLOCK *x) +{ + int i; + int QIndex; + MACROBLOCKD *xd = &x->e_mbd; + int zbin_extra; + + // Select the baseline MB Q index. + if (xd->segmentation_enabled) + { + // Abs Value + if (xd->mb_segement_abs_delta == SEGMENT_ABSDATA) + + QIndex = xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; + // Delta Value + else + { + QIndex = cpi->common.base_qindex + xd->segment_feature_data[MB_LVL_ALT_Q][xd->mode_info_context->mbmi.segment_id]; + QIndex = (QIndex >= 0) ? ((QIndex <= MAXQ) ? QIndex : MAXQ) : 0; // Clamp to valid range + } + } + else + QIndex = cpi->common.base_qindex; + + // Y + zbin_extra = ( cpi->common.Y1dequant[QIndex][1] * + ( cpi->zbin_over_quant + + cpi->zbin_mode_boost + + x->act_zbin_adj ) ) >> 7; + + for (i = 0; i < 16; i++) + { + x->block[i].quant = cpi->Y1quant[QIndex]; + x->block[i].quant_fast = cpi->Y1quant_fast[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]; + x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_y1[QIndex]; + x->block[i].zbin_extra = (short)zbin_extra; + } + + // UV + zbin_extra = ( cpi->common.UVdequant[QIndex][1] * + ( cpi->zbin_over_quant + + cpi->zbin_mode_boost + + x->act_zbin_adj ) ) >> 7; + + for (i = 16; i < 24; i++) + { + x->block[i].quant = cpi->UVquant[QIndex]; + x->block[i].quant_fast = cpi->UVquant_fast[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]; + x->block[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[QIndex]; + x->block[i].zbin_extra = (short)zbin_extra; + } + + // Y2 + zbin_extra = ( cpi->common.Y2dequant[QIndex][1] * + ( (cpi->zbin_over_quant / 2) + + cpi->zbin_mode_boost + + x->act_zbin_adj ) ) >> 7; + + x->block[24].quant_fast = cpi->Y2quant_fast[QIndex]; + 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]; + x->block[24].zrun_zbin_boost = cpi->zrun_zbin_boost_y2[QIndex]; + x->block[24].zbin_extra = (short)zbin_extra; + + /* save this macroblock QIndex for vp8_update_zbin_extra() */ + x->q_index = QIndex; +} + + +void vp8_update_zbin_extra(VP8_COMP *cpi, MACROBLOCK *x) +{ + int i; + int QIndex = x->q_index; + int zbin_extra; + + // Y + zbin_extra = ( cpi->common.Y1dequant[QIndex][1] * + ( cpi->zbin_over_quant + + cpi->zbin_mode_boost + + x->act_zbin_adj ) ) >> 7; + for (i = 0; i < 16; i++) + { + x->block[i].zbin_extra = (short)zbin_extra; + } + + // UV + zbin_extra = ( cpi->common.UVdequant[QIndex][1] * + ( cpi->zbin_over_quant + + cpi->zbin_mode_boost + + x->act_zbin_adj ) ) >> 7; + + for (i = 16; i < 24; i++) + { + x->block[i].zbin_extra = (short)zbin_extra; + } + + // Y2 + zbin_extra = ( cpi->common.Y2dequant[QIndex][1] * + ( (cpi->zbin_over_quant / 2) + + cpi->zbin_mode_boost + + x->act_zbin_adj ) ) >> 7; + + x->block[24].zbin_extra = (short)zbin_extra; +} + + +void vp8cx_frame_init_quantizer(VP8_COMP *cpi) +{ + // Clear Zbin mode boost for default case + cpi->zbin_mode_boost = 0; + + // MB level quantizer setup + vp8cx_mb_init_quantizer(cpi, &cpi->mb); +} + + +void vp8_set_quantizer(struct VP8_COMP *cpi, int Q) +{ + VP8_COMMON *cm = &cpi->common; + MACROBLOCKD *mbd = &cpi->mb.e_mbd; + int update = 0; + int new_delta_q; + cm->base_qindex = Q; + + /* if any of the delta_q values are changing update flag has to be set */ + /* currently only y2dc_delta_q may change */ + + cm->y1dc_delta_q = 0; + cm->y2ac_delta_q = 0; + cm->uvdc_delta_q = 0; + cm->uvac_delta_q = 0; + + if (Q < 4) + { + new_delta_q = 4-Q; + } + else + new_delta_q = 0; + + update |= cm->y2dc_delta_q != new_delta_q; + cm->y2dc_delta_q = new_delta_q; + + + // Set Segment specific quatizers + mbd->segment_feature_data[MB_LVL_ALT_Q][0] = cpi->segment_feature_data[MB_LVL_ALT_Q][0]; + mbd->segment_feature_data[MB_LVL_ALT_Q][1] = cpi->segment_feature_data[MB_LVL_ALT_Q][1]; + mbd->segment_feature_data[MB_LVL_ALT_Q][2] = cpi->segment_feature_data[MB_LVL_ALT_Q][2]; + mbd->segment_feature_data[MB_LVL_ALT_Q][3] = cpi->segment_feature_data[MB_LVL_ALT_Q][3]; + + /* quantizer has to be reinitialized for any delta_q changes */ + if(update) + vp8cx_init_quantizer(cpi); + +} diff --git a/vp8/encoder/quantize.h b/vp8/encoder/quantize.h index e4c32a5..d9a0410 100644 --- a/vp8/encoder/quantize.h +++ b/vp8/encoder/quantize.h @@ -55,4 +55,11 @@ extern void vp8_quantize_mb(MACROBLOCK *x); extern void vp8_quantize_mbuv(MACROBLOCK *x); extern void vp8_quantize_mby(MACROBLOCK *x); +struct VP8_COMP; +extern void vp8_set_quantizer(struct VP8_COMP *cpi, int Q); +extern void vp8cx_frame_init_quantizer(struct VP8_COMP *cpi); +extern void vp8_update_zbin_extra(struct VP8_COMP *cpi, MACROBLOCK *x); +extern void vp8cx_mb_init_quantizer(struct VP8_COMP *cpi, MACROBLOCK *x); +extern void vp8cx_init_quantizer(struct VP8_COMP *cpi); + #endif -- 2.7.4