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 */