From: Paul Wilkins Date: Wed, 8 Feb 2012 15:52:07 +0000 (+0000) Subject: Changes to coding of dual_pred flag. X-Git-Tag: v1.3.0~1217^2~380^2~69 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=59a200f1ea73d2327746fff3d35a05aec10e436f;p=libvpx Changes to coding of dual_pred flag. Further use of common prediction functions and experiments with alternate contexts based on mode and reference frame. For the Derf set using reference frame as basis of context gives +0.18% Overall Psnr and +0.08 SSIM Change-Id: Ie7eb76f329f74c9c698614f01ece31de0b6bfc9e --- diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c index affdae4ba..810c11d2f 100644 --- a/vp8/common/pred_common.c +++ b/vp8/common/pred_common.c @@ -39,10 +39,27 @@ unsigned char get_pred_context( VP8_COMMON *const cm, break; case PRED_DUAL: - // Second ref not INTRA indicates use of dual pred in neighbour - pred_context = - ((m - 1)->mbmi.second_ref_frame != INTRA_FRAME) + - ((m - cm->mode_info_stride)->mbmi.second_ref_frame != INTRA_FRAME); + // Context based on use of dual pred flag by neighbours + //pred_context = + // ((m - 1)->mbmi.second_ref_frame != INTRA_FRAME) + + // ((m - cm->mode_info_stride)->mbmi.second_ref_frame != INTRA_FRAME); + + // Context based on mode + //if ( m->mbmi.mode == ZEROMV ) + // pred_context = 0; + //else if ( (m->mbmi.mode == NEARESTMV) || (m->mbmi.mode == NEARMV) ) + // pred_context = 1; + //else + // pred_context = 2; + + // Context based on reference frame + if ( m->mbmi.ref_frame == LAST_FRAME ) + pred_context = 0; + else if ( m->mbmi.ref_frame == GOLDEN_FRAME ) + pred_context = 1; + else + pred_context = 2; + break; #endif @@ -79,7 +96,9 @@ vp8_prob get_pred_prob( VP8_COMMON *const cm, break; case PRED_DUAL: - // Second ref non zero indicates use of dual pred in neighbour + // In keeping with convention elsewhre the probability returned is + // the probability of a "0" outcome which in this case means the + // probability of dual pred off. pred_probability = cm->prob_dualpred[pred_context]; break; #endif diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index d027b03b4..2d4bb4bad 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1057,8 +1057,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) int row, col; int prob_skip_false = 0; + #if CONFIG_DUALPRED +#if !CONFIG_COMPRED int prob_dual_pred[3]; +#endif #endif /* CONFIG_DUALPRED */ // Values used in prediction model coding @@ -1111,8 +1114,20 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) { +#if CONFIG_COMPRED + pc->prob_dualpred[i] = cpi->single_pred_count[i] * 255 / + (cpi->single_pred_count[i] + cpi->dual_pred_count[i]); + if (pc->prob_dualpred[i] < 1) + pc->prob_dualpred[i] = 1; + } + else + { + pc->prob_dualpred[i] = 128; + } + vp8_write_literal(w, pc->prob_dualpred[i], 8); +#else prob_dual_pred[i] = cpi->single_pred_count[i] * 256 / - (cpi->single_pred_count[i] + cpi->dual_pred_count[i]); + (cpi->single_pred_count[i] + cpi->dual_pred_count[i]); if (prob_dual_pred[i] < 1) prob_dual_pred[i] = 1; else if (prob_dual_pred[i] > 255) @@ -1123,9 +1138,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) prob_dual_pred[i] = 128; } vp8_write_literal(w, prob_dual_pred[i], 8); - -#if CONFIG_COMPRED - pc->prob_dualpred[i] = prob_dual_pred[i]; #endif } } @@ -1457,7 +1469,9 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) int prob_skip_false = 0; #if CONFIG_DUALPRED +#if !CONFIG_COMPRED int prob_dual_pred[3]; +#endif #endif /* CONFIG_DUALPRED */ // Values used in prediction model coding @@ -1507,8 +1521,20 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) { +#if CONFIG_COMPRED + pc->prob_dualpred[i] = cpi->single_pred_count[i] * 255 / + (cpi->single_pred_count[i] + cpi->dual_pred_count[i]); + if (pc->prob_dualpred[i] < 1) + pc->prob_dualpred[i] = 1; + } + else + { + pc->prob_dualpred[i] = 128; + } + vp8_write_literal(w, pc->prob_dualpred[i], 8); +#else prob_dual_pred[i] = cpi->single_pred_count[i] * 256 / - (cpi->single_pred_count[i] + cpi->dual_pred_count[i]); + (cpi->single_pred_count[i] + cpi->dual_pred_count[i]); if (prob_dual_pred[i] < 1) prob_dual_pred[i] = 1; else if (prob_dual_pred[i] > 255) @@ -1519,9 +1545,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) prob_dual_pred[i] = 128; } vp8_write_literal(w, prob_dual_pred[i], 8); - -#if CONFIG_COMPRED - pc->prob_dualpred[i] = prob_dual_pred[i]; #endif } } diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 388d8a6bb..b12a41aa0 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -1811,13 +1811,21 @@ int vp8cx_encode_inter_macroblock if (x->e_mbd.mode_info_context->mbmi.ref_frame && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) { - MB_MODE_INFO *t = &x->e_mbd.mode_info_context[-cpi->common.mode_info_stride].mbmi; + unsigned char pred_context; + +#if CONFIG_COMPRED + pred_context = get_pred_context( cm, xd, PRED_DUAL ); +#else + MB_MODE_INFO *t = &x->e_mbd.mode_info_context + [-cpi->common.mode_info_stride].mbmi; MB_MODE_INFO *l = &x->e_mbd.mode_info_context[-1].mbmi; - int cnt = (t->second_ref_frame != INTRA_FRAME) + (l->second_ref_frame != INTRA_FRAME); - if (x->e_mbd.mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) - cpi->single_pred_count[cnt]++; + pred_context = (t->second_ref_frame != INTRA_FRAME) + + (l->second_ref_frame != INTRA_FRAME); +#endif + if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME) + cpi->single_pred_count[pred_context]++; else - cpi->dual_pred_count[cnt]++; + cpi->dual_pred_count[pred_context]++; } #endif /* CONFIG_DUALPRED */