diff --git a/vp8/common/quant_common.c b/vp8/common/quant_common.c index d9a7592683a57e91a24d85679d73b33c169ba882..8b6a96f9f37faa465752a174e3f7d554e919fdc0 100644 --- a/vp8/common/quant_common.c +++ b/vp8/common/quant_common.c @@ -37,7 +37,7 @@ static const int ac_qlookup[QINDEX_RANGE] = 213, 217, 221, 225, 229, 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284, }; #else -static const int dc_qlookup[QINDEX_RANGE] = +static int dc_qlookup[QINDEX_RANGE] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 38, 40, 42, 44, 47, @@ -49,7 +49,7 @@ static const int dc_qlookup[QINDEX_RANGE] = 464, 483, 496, 507, 520, 529, 540, 551, 570, 585, 604, 624, 645, 667, 692, 718, }; -static const int ac_qlookup[QINDEX_RANGE] = +static int ac_qlookup[QINDEX_RANGE] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 51, @@ -62,6 +62,40 @@ static const int ac_qlookup[QINDEX_RANGE] = }; #endif +#if CONFIG_EXTEND_QRANGE +#define ACDC_MIN 4 +void vp8_init_quant_tables() +{ + int i; + int current_val = 4; + int last_val = 4; + int ac_val; + int dc_max; + + // Not active by default for now. + return; + + for ( i = 0; i < QINDEX_RANGE; i++ ) + { + ac_qlookup[i] = current_val; + current_val = (int)((double)current_val * 1.042); + if ( current_val == last_val ) + current_val++; + last_val = current_val; + + ac_val = ac_qlookup[i]; + dc_max = (int)(((double)ac_val * 0.75) + 0.5); + dc_qlookup[i] = (0.000000305 * ac_val * ac_val * ac_val) + + (-0.00065 * ac_val * ac_val) + + (0.9 * ac_val) + 0.5; + if ( dc_qlookup[i] > dc_max ) + dc_qlookup[i] = dc_max; + if ( dc_qlookup[i] < ACDC_MIN ) + dc_qlookup[i] = ACDC_MIN; + } +} +#endif + int vp8_dc_quant(int QIndex, int Delta) { int retval; @@ -140,7 +174,9 @@ int vp8_ac2quant(int QIndex, int Delta) if (retval < 8) retval = 8; #else - retval = ac_qlookup[ QIndex ]; + retval = (ac_qlookup[ QIndex ] * 775) / 1000; + if (retval < 4) + retval = 4; #endif return retval; } diff --git a/vp8/common/quant_common.h b/vp8/common/quant_common.h index cb64d8eb8d878cc20025fe185add3668544422f8..ea0383b3c84f723defa39f66ccfe1878c0f7abff 100644 --- a/vp8/common/quant_common.h +++ b/vp8/common/quant_common.h @@ -13,6 +13,9 @@ #include "blockd.h" #include "onyxc_int.h" +#if CONFIG_EXTEND_QRANGE +extern void vp8_init_quant_tables(); +#endif extern int vp8_ac_yquant(int QIndex); extern int vp8_dc_quant(int QIndex, int Delta); extern int vp8_dc2quant(int QIndex, int Delta); diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index 39df72d07b8debf5edb3fc5dee2dbfe9c2572f58..f103bd78864b1a12eb45059796a12aba922a9580 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -123,6 +123,9 @@ void vp8dx_initialize() if (!init_done) { vp8_initialize_common(); +#if CONFIG_EXTEND_QRANGE + vp8_init_quant_tables(); +#endif vp8_scale_machine_specific_config(); init_done = 1; } diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index d7abbaaaf8bbf0129a07388ccb8d2db0f4ff9eaa..265c2dd4cdf0c048331c649812315be7c135219d 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -195,6 +195,8 @@ int calculate_minq_index( double maxq, if ( minqtarget <= vp8_convert_qindex_to_q(i) ) return i; } + if ( i == QINDEX_RANGE ) + return QINDEX_RANGE-1; } void init_minq_luts() { @@ -251,9 +253,11 @@ void vp8_initialize() vp8_initialize_common(); //vp8_dmachine_specific_config(); vp8_tokenize_initialize(); +#if CONFIG_EXTEND_QRANGE + vp8_init_quant_tables(); +#endif vp8_init_me_luts(); init_minq_luts(); - init_done = 1; } } @@ -467,7 +471,7 @@ static void init_seg_features(VP8_COMP *cpi) xd->update_mb_segmentation_map = 1; xd->update_mb_segmentation_data = 1; - set_segdata( xd, 1, SEG_LVL_ALT_Q, -(2+(cpi->ni_av_qi >> 3)) ); + set_segdata( xd, 1, SEG_LVL_ALT_Q, -(3+(cpi->ni_av_qi >> 3)) ); set_segdata( xd, 1, SEG_LVL_ALT_LF, -2 ); enable_segfeature(xd, 1, SEG_LVL_ALT_Q); @@ -3281,12 +3285,30 @@ static int decide_key_frame(VP8_COMP *cpi) return code_key_frame; } -#if !CONFIG_EXTEND_QRANGE + +/*#if !CONFIG_EXTEND_QRANGE #define FIRSTPASS_QINDEX 26 #else #define FIRSTPASS_QINDEX 49 -#endif +#endif*/ +int find_fp_qindex() +{ + int i; + + for ( i = 0; i < QINDEX_RANGE; i++ ) + { + if ( vp8_convert_qindex_to_q(i) >= 30.0 ) + { + break; + } + } + + if ( i == QINDEX_RANGE ) + i--; + + return i; +} #if !(CONFIG_REALTIME_ONLY) static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, unsigned int *frame_flags) @@ -3294,7 +3316,9 @@ static void Pass1Encode(VP8_COMP *cpi, unsigned long *size, unsigned char *dest, (void) size; (void) dest; (void) frame_flags; - vp8_set_quantizer(cpi, FIRSTPASS_QINDEX); + + + vp8_set_quantizer(cpi, find_fp_qindex()); scale_and_extend_source(cpi->un_scaled_source, cpi); vp8_first_pass(cpi); diff --git a/vp8/encoder/quantize.c b/vp8/encoder/quantize.c index 8bbc0d0a546db000b62eb21235b7044d09e424af..2e2a8dcbf58f43fb7ea730a10e359f43e821d954 100644 --- a/vp8/encoder/quantize.c +++ b/vp8/encoder/quantize.c @@ -934,94 +934,6 @@ void vp8_fast_quantize_b_pair_c(BLOCK *b1, BLOCK *b2, BLOCKD *d1, BLOCKD *d2) } -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, @@ -1054,6 +966,13 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) int zbin_boost[16] = {0, 0, 8, 10, 12, 14, 16, 20, 24, 28, 32, 36, 40, 44, 44, 44}; + int qrounding_factor = 48; +#if CONFIG_EXTEND_QRANGE + int qzbin_factor = (vp8_dc_quant(Q,0) < 148) ? 84 : 80; +#else + int qzbin_factor = (vp8_dc_quant(Q,0) < 37) ? 84: 80; +#endif + for (Q = 0; Q < QINDEX_RANGE; Q++) { // dc values @@ -1061,8 +980,8 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) 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->Y1zbin[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; + 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; @@ -1070,8 +989,8 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) 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->Y2zbin[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7; + 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; @@ -1079,8 +998,8 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) 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->UVzbin[Q][0] = ((qzbin_factor * quant_val) + 64) >> 7;; + 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; @@ -1093,8 +1012,8 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) 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->Y1zbin[Q][rc] = ((qzbin_factor * quant_val) + 64) >> 7; + cpi->Y1round[Q][rc] = (qrounding_factor * quant_val) >> 7; cpi->common.Y1dequant[Q][rc] = quant_val; cpi->zrun_zbin_boost_y1[Q][i] = (quant_val * zbin_boost[i]) >> 7; @@ -1102,8 +1021,8 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) 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->Y2zbin[Q][rc] = ((qzbin_factor * quant_val) + 64) >> 7; + cpi->Y2round[Q][rc] = (qrounding_factor * quant_val) >> 7; cpi->common.Y2dequant[Q][rc] = quant_val; cpi->zrun_zbin_boost_y2[Q][i] = (quant_val * zbin_boost[i]) >> 7; @@ -1111,8 +1030,8 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) 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->UVzbin[Q][rc] = ((qzbin_factor * quant_val) + 64) >> 7; + cpi->UVround[Q][rc] = (qrounding_factor * quant_val) >> 7; cpi->common.UVdequant[Q][rc] = quant_val; cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7; } @@ -1124,30 +1043,35 @@ 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 qrounding_factor = 48; +#if CONFIG_EXTEND_QRANGE + int qzbin_factor = vp8_dc_quant(Q,0) < 148 ) ? 84: 80; +#else + int qzbin_factor = vp8_dc_quant(Q,0) < 37 ) ? 84: 80; +#endif 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->Y1zbin[Q][0] = ((qzbin_factors * quant_val) + 64) >> 7; + 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; 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->Y2zbin[Q][0] = ((qzbin_factors * quant_val) + 64) >> 7; + 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; 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->UVzbin[Q][0] = ((qzbin_factors * quant_val) + 64) >> 7;; + 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; @@ -1158,22 +1082,22 @@ void vp8cx_init_quantizer(VP8_COMP *cpi) 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->Y1zbin[Q][rc] = ((qzbin_factors * quant_val) + 64) >> 7; + cpi->Y1round[Q][rc] = (qrounding_factor * 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->Y2zbin[Q][rc] = ((qzbin_factors * quant_val) + 64) >> 7; + cpi->Y2round[Q][rc] = (qrounding_factors * 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->UVzbin[Q][rc] = ((qzbin_factors * quant_val) + 64) >> 7; + cpi->UVround[Q][rc] = (qrounding_factors * quant_val) >> 7; cpi->common.UVdequant[Q][rc] = quant_val; cpi->zrun_zbin_boost_uv[Q][i] = (quant_val * zbin_boost[i]) >> 7; } diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index a3dab72f60acc3fda780d8d863127bd2edc83670..ff0018be5a3ba51c39fa681403e9217ffba03bad 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -236,28 +236,23 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex) (cpi->RDMULT * rd_iifactor[cpi->twopass.next_iiratio]) >> 4; } -#if !CONFIG_EXTEND_QRANGE -#else if (cpi->RDMULT < 7) cpi->RDMULT = 7; -#endif + cpi->mb.errorperbit = (cpi->RDMULT / 110); cpi->mb.errorperbit += (cpi->mb.errorperbit==0); -#if CONFIG_EXTEND_QRANGE - if(cpi->mb.errorperbit<1) - cpi->mb.errorperbit=1; -#endif vp8_set_speed_features(cpi); - q = (int)pow(vp8_dc_quant(QIndex,0), 1.25); - - if (q < 8) - q = 8; - #if CONFIG_EXTEND_QRANGE + q = (int)pow(vp8_dc_quant(QIndex,0)>>2, 1.25); + q = q << 2; cpi->RDMULT *= 16; +#else + q = (int)pow(vp8_dc_quant(QIndex,0), 1.25); #endif + if (q < 8) + q = 8; if (cpi->RDMULT > 1000) {