From 82b865da9475586341949664d5468a93237867a8 Mon Sep 17 00:00:00 2001 From: Paul Wilkins Date: Thu, 2 Feb 2012 17:30:27 +0000 Subject: [PATCH] Coding the hybrid dual prediction signal. Initial modifications to make limited use of common prediction functions. The only functional change thus far is that updates to the probabilities are no longer "damped". This was a testing convenience but in fact seems to help by a little over 0.1% over the derf set. Change-Id: I8b82907d9d6b6a4a075728b60b31ce93392a5f2e --- vp8/common/pred_common.c | 15 +++++-- vp8/decoder/decodemv.c | 13 ++++-- vp8/encoder/bitstream.c | 97 ++++++++++++++++++++++++++++------------ vp8/encoder/rdopt.c | 10 +++++ 4 files changed, 100 insertions(+), 35 deletions(-) diff --git a/vp8/common/pred_common.c b/vp8/common/pred_common.c index bda140058..affdae4ba 100644 --- a/vp8/common/pred_common.c +++ b/vp8/common/pred_common.c @@ -33,11 +33,17 @@ unsigned char get_pred_context( VP8_COMMON *const cm, #if CONFIG_COMPRED - case PRED_REF: pred_context = (m - 1)->mbmi.ref_predicted + (m - cm->mode_info_stride)->mbmi.ref_predicted; 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); + break; #endif default: @@ -68,10 +74,14 @@ vp8_prob get_pred_prob( VP8_COMMON *const cm, break; #if CONFIG_COMPRED - case PRED_REF: pred_probability = cm->ref_pred_probs[pred_context]; break; + + case PRED_DUAL: + // Second ref non zero indicates use of dual pred in neighbour + pred_probability = cm->prob_dualpred[pred_context]; + break; #endif default: @@ -276,7 +286,6 @@ void compute_mod_refprobs( VP8_COMMON *const cm ) int gfarf_count; int gf_count; int arf_count; - int i; intra_count = cm->prob_intra_coded; inter_count = (255 - intra_count); diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 78139655c..7925c34da 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -839,11 +839,16 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, mb_to_bottom_edge); propagate_mv: /* same MV throughout */ + #if CONFIG_DUALPRED - if (pbi->common.dual_pred_mode == DUAL_PREDICTION_ONLY || - (pbi->common.dual_pred_mode == HYBRID_PREDICTION && - vp8_read(bc, cm->prob_dualpred[(mi[-1].mbmi.second_ref_frame != INTRA_FRAME) + - (mi[-mis].mbmi.second_ref_frame != INTRA_FRAME)]))) + if ( cm->dual_pred_mode == DUAL_PREDICTION_ONLY || + (cm->dual_pred_mode == HYBRID_PREDICTION && +#if CONFIG_COMPRED + vp8_read(bc, get_pred_prob( cm, xd, PRED_DUAL ))) ) +#else + vp8_read(bc, cm->prob_dualpred[(mi[-1].mbmi.second_ref_frame != INTRA_FRAME) + + (mi[-mis].mbmi.second_ref_frame != INTRA_FRAME)]))) +#endif { mbmi->second_ref_frame = mbmi->ref_frame + 1; if (mbmi->second_ref_frame == 4) diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 99f3df9dc..e7028da9e 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1109,21 +1109,26 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { vp8_write(w, 1, 128); vp8_write(w, 1, 128); - for (i = 0; i < 3; i++) { - if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) + for (i = 0; i < 3; i++) { - prob_dual_pred[i] = cpi->single_pred_count[i] * 256 / - (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) - prob_dual_pred[i] = 255; - } - else - { - prob_dual_pred[i] = 128; - } - vp8_write_literal(w, prob_dual_pred[i], 8); + if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) + { + prob_dual_pred[i] = cpi->single_pred_count[i] * 256 / + (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) + prob_dual_pred[i] = 255; + } + else + { + 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 } } else if (cpi->common.dual_pred_mode == SINGLE_PREDICTION_ONLY) @@ -1315,10 +1320,17 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #if CONFIG_DUALPRED if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { +#if CONFIG_COMPRED + vp8_write(w, + mi->second_ref_frame != INTRA_FRAME, + get_pred_prob( pc, xd, PRED_DUAL ) ); +#else + int t = m[-mis].mbmi.second_ref_frame != INTRA_FRAME; int l = m[-1 ].mbmi.second_ref_frame != INTRA_FRAME; vp8_write(w, mi->second_ref_frame != INTRA_FRAME, prob_dual_pred[t + l]); +#endif } if (mi->second_ref_frame) { @@ -1386,10 +1398,17 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #if CONFIG_DUALPRED if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { +#if CONFIG_COMPRED + + vp8_write(w, + mi->second_ref_frame != INTRA_FRAME, + get_pred_prob( pc, xd, PRED_DUAL ) ); +#else int t = m[-mis].mbmi.second_ref_frame != INTRA_FRAME; int l = m[-1 ].mbmi.second_ref_frame != INTRA_FRAME; vp8_write(w, mi->second_ref_frame != INTRA_FRAME, prob_dual_pred[t + l]); +#endif } #endif /* CONFIG_DUALPRED */ break; @@ -1416,6 +1435,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) cpi->mb.partition_info += mis + (1- (pc->mb_cols & 0x1)); } +#if !CONFIG_COMPRED #if CONFIG_DUALPRED if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { @@ -1424,6 +1444,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) pc->prob_dualpred[2] = (prob_dual_pred[2] + pc->prob_dualpred[2] + 1) >> 1; } #endif /* CONFIG_DUALPRED */ +#endif } #else static void pack_inter_mode_mvs(VP8_COMP *const cpi) @@ -1448,6 +1469,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) int mb_row = -1; int prob_skip_false = 0; + #if CONFIG_DUALPRED int prob_dual_pred[3]; #endif /* CONFIG_DUALPRED */ @@ -1495,21 +1517,26 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) { vp8_write(w, 1, 128); vp8_write(w, 1, 128); - for (i = 0; i < 3; i++) { - if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) + for (i = 0; i < 3; i++) { - prob_dual_pred[i] = cpi->single_pred_count[i] * 256 / - (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) - prob_dual_pred[i] = 255; - } - else - { - prob_dual_pred[i] = 128; - } - vp8_write_literal(w, prob_dual_pred[i], 8); + if (cpi->single_pred_count[i] + cpi->dual_pred_count[i]) + { + prob_dual_pred[i] = cpi->single_pred_count[i] * 256 / + (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) + prob_dual_pred[i] = 255; + } + else + { + 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 } } else if (cpi->common.dual_pred_mode == SINGLE_PREDICTION_ONLY) @@ -1681,10 +1708,16 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #if CONFIG_DUALPRED if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { +#if CONFIG_COMPRED + + vp8_write(w, mi->second_ref_frame != INTRA_FRAME, + get_pred_prob( pc, xd, PRED_DUAL ) ); +#else int t = m[-mis].mbmi.second_ref_frame != INTRA_FRAME; int l = m[-1 ].mbmi.second_ref_frame != INTRA_FRAME; vp8_write(w, mi->second_ref_frame != INTRA_FRAME, prob_dual_pred[t + l]); +#endif } if (mi->second_ref_frame) { @@ -1751,10 +1784,16 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) #if CONFIG_DUALPRED if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { +#if CONFIG_COMPRED + + vp8_write(w, mi->second_ref_frame != INTRA_FRAME, + get_pred_prob( pc, xd, PRED_DUAL ) ); +#else int t = m[-mis].mbmi.second_ref_frame != INTRA_FRAME; int l = m[-1 ].mbmi.second_ref_frame != INTRA_FRAME; vp8_write(w, mi->second_ref_frame != INTRA_FRAME, prob_dual_pred[t + l]); +#endif } #endif /* CONFIG_DUALPRED */ break; @@ -1779,6 +1818,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) cpi->mb.partition_info++; } +#if !CONFIG_COMPRED #if CONFIG_DUALPRED if (cpi->common.dual_pred_mode == HYBRID_PREDICTION) { @@ -1787,6 +1827,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi) pc->prob_dualpred[2] = (prob_dual_pred[2] + pc->prob_dualpred[2] + 1) >> 1; } #endif /* CONFIG_DUALPRED */ +#endif } #endif // CONFIG_SUPERBLOCKS diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 094ad4a21..ff57c58e9 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -2628,12 +2628,17 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int vp8_build_inter16x16_predictors_mby(&x->e_mbd); #if CONFIG_DUALPRED +#if CONFIG_COMPRED + dualmode_cost = + vp8_cost_bit( get_pred_prob( cm, xd, PRED_DUAL ), 0 ); +#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); dualmode_cost = vp8_cost_bit(cm->prob_dualpred[cnt], 0); } +#endif #endif /* CONFIG_DUALPRED */ if (cpi->active_map_enabled && x->active_ptr[0] == 0) { @@ -2788,12 +2793,17 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int /* We don't include the cost of the second reference here, because there are only * three options: Last/Golden, ARF/Last or Golden/ARF, or in other words if you * present them in that order, the second one is always known if the first is known */ +#if CONFIG_COMPRED + dualmode_cost = + vp8_cost_bit( get_pred_prob( cm, xd, PRED_DUAL ), 1 ); +#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); dualmode_cost = vp8_cost_bit(cm->prob_dualpred[cnt], 1); } +#endif } #endif /* CONFIG_DUALPRED */ -- 2.40.0