From 795c6dd2c9e3b17923a275bbd593d68112a4dba6 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Fri, 28 Oct 2011 15:27:23 +0100 Subject: Segmentation Entropy and tweaks. Some correction for entropy impact of segment signaled (EOB and ref frame) Other slight tweaks. Derf VBR average gain now over 1% (best over 7%) One YT test clip has gains of circa 30% (VBR) There is still an issue with noisy clips where making the background static and coded with 0,0 can have a negative effect, especially at low Q. This is probably because of the loss of smoothing by fractional pixel filters. Change-Id: I7a225613c98067b96f8fc7a7e36f95d465b2b834 --- vp8/encoder/bitstream.c | 30 ++++++++++++++++++++++-------- vp8/encoder/encodeframe.c | 17 ++++++++--------- vp8/encoder/onyx_if.c | 21 ++++++++++++++++----- vp8/encoder/tokenize.c | 22 ++++++++++++++++++++-- 4 files changed, 66 insertions(+), 24 deletions(-) (limited to 'vp8') diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 395ffa79d..7df367f11 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -929,12 +929,19 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) if (pc->mb_no_coeff_skip) { - prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count); + // Divide by 0 check. 0 case possible with segment features + if ( (cpi->skip_false_count + cpi->skip_true_count) ) + { + prob_skip_false = cpi->skip_false_count * 256 / + (cpi->skip_false_count + cpi->skip_true_count); - if (prob_skip_false <= 1) - prob_skip_false = 1; + if (prob_skip_false <= 1) + prob_skip_false = 1; - if (prob_skip_false > 255) + if (prob_skip_false > 255) + prob_skip_false = 255; + } + else prob_skip_false = 255; cpi->prob_skip_false = prob_skip_false; @@ -1192,12 +1199,19 @@ static void write_kfmodes(VP8_COMP *cpi) if (c->mb_no_coeff_skip) { - prob_skip_false = cpi->skip_false_count * 256 / (cpi->skip_false_count + cpi->skip_true_count); + // Divide by 0 check. 0 case possible with segment features + if ( (cpi->skip_false_count + cpi->skip_true_count) ) + { + prob_skip_false = cpi->skip_false_count * 256 / + (cpi->skip_false_count + cpi->skip_true_count); - if (prob_skip_false <= 1) - prob_skip_false = 1; + if (prob_skip_false <= 1) + prob_skip_false = 1; - if (prob_skip_false >= 255) + if (prob_skip_false > 255) + prob_skip_false = 255; + } + else prob_skip_false = 255; cpi->prob_skip_false = prob_skip_false; diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index a6e47f240..ec679846e 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -716,7 +716,7 @@ void encode_mb_row(VP8_COMP *cpi, #endif - // Count of last ref frame 0,0 useage + // Count of last ref frame 0,0 usage if ((xd->mode_info_context->mbmi.mode == ZEROMV) && (xd->mode_info_context->mbmi.ref_frame == LAST_FRAME)) cpi->inter_zz_count ++; @@ -758,7 +758,7 @@ void encode_mb_row(VP8_COMP *cpi, cpi->tplist[mb_row].stop = *tp; - // Increment pointer into gf useage flags structure. + // Increment pointer into gf usage flags structure. x->gf_active_ptr++; // Increment the activity mask pointers. @@ -1014,7 +1014,7 @@ void vp8_encode_frame(VP8_COMP *cpi) &cpi->common.rtcd.subpix, bilinear16x16); } - // Reset frame count of inter 0,0 motion vector useage. + // Reset frame count of inter 0,0 motion vector usage. cpi->inter_zz_count = 0; vpx_memset(segment_counts, 0, sizeof(segment_counts)); @@ -1320,7 +1320,7 @@ void vp8_encode_frame(VP8_COMP *cpi) } #endif - // Adjust the projected reference frame useage probability numbers to reflect + // Adjust the projected reference frame usage probability numbers to reflect // what we have just seen. This may be usefull when we make multiple itterations // of the recode loop rather than continuing to use values from the previous frame. if ((cm->frame_type != KEY_FRAME) && !cm->refresh_alt_ref_frame && !cm->refresh_golden_frame) @@ -1710,11 +1710,10 @@ int vp8cx_encode_inter_macroblock vp8_update_zbin_extra(cpi, x); } -#if 0 -//#if CONFIG_SEGFEATURES - // Test code using segment 1 only. - // Dont increment count if ref frame coded at segment level - if ( (xd->mode_info_context->mbmi.segment_id != 1) ) +#if CONFIG_SEGFEATURES + // Dont increment usage count if ref frame coded at segment level + if ( !segfeature_active( xd, xd->mode_info_context->mbmi.segment_id, + SEG_LVL_REF_FRAME ) ) cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame]++; #else cpi->count_mb_ref_frame_usage[xd->mode_info_context->mbmi.ref_frame] ++; diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index c6547cf4a..35b45673c 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -480,6 +480,10 @@ static void init_seg_features(VP8_COMP *cpi) VP8_COMMON *cm = &cpi->common; MACROBLOCKD *xd = &cpi->mb.e_mbd; + int high_q = ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && + (cpi->cq_target_quality > 16 ) ) || + (cpi->ni_av_qi > 32); + // For now at least dont enable seg features alongside cyclic refresh. if ( cpi->cyclic_refresh_mode_enabled || (cpi->pass != 2) ) @@ -557,14 +561,12 @@ static void init_seg_features(VP8_COMP *cpi) enable_segfeature(xd, 1, SEG_LVL_ALT_Q); enable_segfeature(xd, 1, SEG_LVL_ALT_LF); - if ( ( (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY) && - (cpi->cq_target_quality > 56 ) ) || - (cpi->ni_av_qi > 64) ) + if ( high_q ) { xd->segment_feature_data[1] - [SEG_LVL_REF_FRAME] = LAST_FRAME; + [SEG_LVL_REF_FRAME] = ALTREF_FRAME; xd->segment_feature_data[1][SEG_LVL_MODE] = ZEROMV; - xd->segment_feature_data[1][SEG_LVL_EOB] = 15; + xd->segment_feature_data[1][SEG_LVL_EOB] = 0; enable_segfeature(xd, 1, SEG_LVL_REF_FRAME); enable_segfeature(xd, 1, SEG_LVL_MODE); @@ -602,6 +604,15 @@ static void init_seg_features(VP8_COMP *cpi) xd->segment_feature_data[1][SEG_LVL_REF_FRAME] = ALTREF_FRAME; xd->segment_feature_data[1][SEG_LVL_MODE] = ZEROMV; + // Skip all MBs if high Q + if ( high_q ) + { + enable_segfeature(xd, 0, SEG_LVL_EOB); + enable_segfeature(xd, 1, SEG_LVL_EOB); + xd->segment_feature_data[0][SEG_LVL_EOB] = 0; + xd->segment_feature_data[1][SEG_LVL_EOB] = 0; + } + // Enable data udpate xd->update_mb_segmentation_data = 1; } diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c index c9fb624f3..138f99447 100644 --- a/vp8/encoder/tokenize.c +++ b/vp8/encoder/tokenize.c @@ -491,6 +491,24 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) int has_y2_block; int b; +#if CONFIG_SEGFEATURES + // If the MB is going to be skipped because of a segment level flag + // exclude this from the skip count stats used to calculate the + // transmitted skip probability; + int skip_inc; + int segment_id = x->mode_info_context->mbmi.segment_id; + + if ( !segfeature_active( x, segment_id, SEG_LVL_EOB ) || + (x->segment_feature_data[segment_id][SEG_LVL_EOB] != 0) ) + { + skip_inc = 1; + } + else + skip_inc = 0; +#else + int skip_inc = 1; +#endif + has_y2_block = (x->mode_info_context->mbmi.mode != B_PRED #if CONFIG_I8X8 && x->mode_info_context->mbmi.mode != I8X8_PRED @@ -508,7 +526,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) if (x->mode_info_context->mbmi.mb_skip_coeff) { - cpi->skip_true_count++; + cpi->skip_true_count += skip_inc; if (!cpi->common.mb_no_coeff_skip) { @@ -527,7 +545,7 @@ void vp8_tokenize_mb(VP8_COMP *cpi, MACROBLOCKD *x, TOKENEXTRA **t) return; } - cpi->skip_false_count++; + cpi->skip_false_count += skip_inc; plane_type = 3; if(has_y2_block) -- cgit v1.2.3