diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c index a76d5d869..8035e063d 100644 --- a/vp10/decoder/decodemv.c +++ b/vp10/decoder/decodemv.c @@ -1390,7 +1390,7 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, if (b_mode != ZEROMV && b_mode != ZERO_ZEROMV) { #else - if (b_mode == NEARESTMV || b_mode == NEARMV) { + if (b_mode != ZEROMV) { #endif // CONFIG_EXT_INTER #if CONFIG_REF_MV CANDIDATE_MV ref_mv_stack[2][MAX_REF_MV_STACK_SIZE]; @@ -1411,8 +1411,8 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, #if CONFIG_EXT_INTER mv_ref_list, #endif // CONFIG_EXT_INTER - &nearest_sub8x8[ref], - &near_sub8x8[ref]); + &nearest_sub8x8[ref], + &near_sub8x8[ref]); #if CONFIG_EXT_INTER if (have_newmv_in_inter_mode(b_mode)) { mv_ref_list[0].as_int = nearest_sub8x8[ref].as_int; @@ -1424,8 +1424,13 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi, #endif // CONFIG_EXT_INTER } - for (ref = 0; ref < 2; ++ref) { + for (ref = 0; ref < 1 + is_compound && b_mode != ZEROMV; ++ref) { +#if CONFIG_REF_MV + ref_mv_s8[ref] = nearest_sub8x8[ref]; + lower_mv_precision(&ref_mv_s8[ref].as_mv, allow_hp); +#else ref_mv_s8[ref] = nearestmv[ref]; +#endif } #if CONFIG_EXT_INTER (void)ref_mv_s8; diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c index b685f8aca..4bbe29c16 100644 --- a/vp10/encoder/rdopt.c +++ b/vp10/encoder/rdopt.c @@ -4783,8 +4783,10 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, #endif // CONFIG_EXT_INTER BEST_SEG_INFO *bsi_buf, int filter_idx, int mi_row, int mi_col) { - int i; BEST_SEG_INFO *bsi = bsi_buf + filter_idx; +#if CONFIG_REF_MV + int_mv tmp_ref_mv[2]; +#endif MACROBLOCKD *xd = &x->e_mbd; MODE_INFO *mi = xd->mi[0]; MB_MODE_INFO *mbmi = &mi->mbmi; @@ -4816,8 +4818,20 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, bsi->mvp.as_int = best_ref_mv->as_int; bsi->mvthresh = mvthresh; - for (i = 0; i < 4; i++) - bsi->modes[i] = ZEROMV; + for (idx = 0; idx < 4; ++idx) + bsi->modes[idx] = ZEROMV; + +#if CONFIG_REFMV + for (idx = 0; idx < 4; ++idx) { + for (k = NEARESTMV; k <= NEWMV; ++k) { + bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[0].as_int = INVALID_MV; + bsi->rdstat[idx][INTER_OFFSET(k)].pred_mv[1].as_int = INVALID_MV; + + bsi->rdstat[idx][INTER_OFFSET(k)].mvs[0].as_int = INVALID_MV; + bsi->rdstat[idx][INTER_OFFSET(k)].mvs[1].as_int = INVALID_MV; + } + } +#endif memcpy(t_above, pd->above_context, sizeof(t_above)); memcpy(t_left, pd->left_context, sizeof(t_left)); @@ -4867,6 +4881,13 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, &frame_mv[NEARESTMV][frame], &frame_mv[NEARMV][frame]); +#if CONFIG_REF_MV + tmp_ref_mv[ref] = frame_mv[NEARESTMV][mbmi->ref_frame[ref]]; + lower_mv_precision(&tmp_ref_mv[ref].as_mv, cm->allow_high_precision_mv); + bsi->ref_mv[ref] = &tmp_ref_mv[ref]; + mbmi_ext->ref_mvs[frame][0] = tmp_ref_mv[ref]; +#endif + #if CONFIG_EXT_INTER mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int; mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int; @@ -4911,6 +4932,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, #endif // CONFIG_EXT_INTER const struct buf_2d orig_src = x->plane[0].src; struct buf_2d orig_pre[2]; + int run_rd_check = 0; mode_idx = INTER_OFFSET(this_mode); #if CONFIG_EXT_INTER @@ -4923,6 +4945,55 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, if (!(inter_mode_mask & (1 << this_mode))) continue; +#if CONFIG_REF_MV + run_rd_check = 2; +#if !CONFIG_EXT_INTER + if (filter_idx > 0) { + BEST_SEG_INFO* ref_bsi = bsi_buf; + if (seg_mvs[i][mbmi->ref_frame[0]].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[0].as_int && + ref_bsi->rdstat[i][mode_idx].mvs[0].as_int != INVALID_MV) + if (bsi->ref_mv[0]->as_int == + ref_bsi->rdstat[i][mode_idx].pred_mv[0].as_int) + --run_rd_check; + + if (!has_second_rf) { + --run_rd_check; + } else { + if (seg_mvs[i][mbmi->ref_frame[1]].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[1].as_int && + ref_bsi->rdstat[i][mode_idx].mvs[1].as_int != INVALID_MV) + if (bsi->ref_mv[1]->as_int == + ref_bsi->rdstat[i][mode_idx].pred_mv[1].as_int) + --run_rd_check; + } + + if (run_rd_check != 0 && filter_idx > 1) { + ref_bsi = bsi_buf + 1; + run_rd_check = 2; + + if (seg_mvs[i][mbmi->ref_frame[0]].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[0].as_int && + ref_bsi->rdstat[i][mode_idx].mvs[0].as_int != INVALID_MV) + if (bsi->ref_mv[0]->as_int == + ref_bsi->rdstat[i][mode_idx].pred_mv[0].as_int) + --run_rd_check; + + if (!has_second_rf) { + --run_rd_check; + } else { + if (seg_mvs[i][mbmi->ref_frame[1]].as_int == + ref_bsi->rdstat[i][mode_idx].mvs[1].as_int && + ref_bsi->rdstat[i][mode_idx].mvs[1].as_int != INVALID_MV) + if (bsi->ref_mv[1]->as_int == + ref_bsi->rdstat[i][mode_idx].pred_mv[1].as_int) + --run_rd_check; + } + } + } +#endif // CONFIG_EXT_INTER +#endif // CONFIG_REF_MV + if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, #if CONFIG_REF_MV && CONFIG_EXT_INTER mbmi_ext->compound_mode_context, @@ -4944,7 +5015,8 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV #else this_mode == NEWMV && - seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV + (seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV || + run_rd_check) #endif // CONFIG_EXT_INTER ) { #if CONFIG_EXT_INTER @@ -4969,11 +5041,13 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, bsi->mvp.as_int = bsi->ref_mv[0]->as_int; #else // use previous block's result as next block's MV predictor. +#if !CONFIG_REF_MV if (i > 0) { bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int; if (i == 2) bsi->mvp.as_int = mi->bmi[i - 2].as_mv[0].as_int; } +#endif #endif // CONFIG_EXT_INTER } if (i == 0) @@ -4992,8 +5066,13 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, step_param = cpi->mv_step_param; } +#if CONFIG_REF_MV + mvp_full.row = best_ref_mv->as_mv.row >> 3; + mvp_full.col = best_ref_mv->as_mv.col >> 3; +#else mvp_full.row = bsi->mvp.as_mv.row >> 3; mvp_full.col = bsi->mvp.as_mv.col >> 3; +#endif if (cpi->sf.adaptive_motion_search) { mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3; @@ -5101,7 +5180,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, #else this_mode == NEWMV && #endif // CONFIG_EXT_INTER - mbmi->interp_filter == EIGHTTAP_REGULAR) { + (mbmi->interp_filter == EIGHTTAP_REGULAR || run_rd_check)) { // adjust src pointers mi_buf_shift(x, i); if (cpi->sf.comp_inter_joint_search_thresh <= bsize) { @@ -5219,8 +5298,34 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, if (!subpelmv && have_ref && ref_bsi->rdstat[i][mode_idx].brdcost < INT64_MAX) { +#if CONFIG_REF_MV + bsi->rdstat[i][mode_idx].pred_mv[0].as_int = + bsi->ref_mv[0]->as_int; + + if (has_second_rf) + bsi->rdstat[i][mode_idx].pred_mv[1].as_int = + bsi->ref_mv[1]->as_int; + + bsi->rdstat[i][mode_idx].byrate = + ref_bsi->rdstat[i][mode_idx].byrate; + bsi->rdstat[i][mode_idx].bdist = + ref_bsi->rdstat[i][mode_idx].bdist; + bsi->rdstat[i][mode_idx].bsse = + ref_bsi->rdstat[i][mode_idx].bsse; + bsi->rdstat[i][mode_idx].brate += + ref_bsi->rdstat[i][mode_idx].byrate; + bsi->rdstat[i][mode_idx].eobs = + ref_bsi->rdstat[i][mode_idx].eobs; + memcpy(bsi->rdstat[i][mode_idx].ta, + ref_bsi->rdstat[i][mode_idx].ta, + sizeof(bsi->rdstat[i][mode_idx].ta)); + memcpy(bsi->rdstat[i][mode_idx].tl, + ref_bsi->rdstat[i][mode_idx].tl, + sizeof(bsi->rdstat[i][mode_idx].tl)); +#else memcpy(&bsi->rdstat[i][mode_idx], &ref_bsi->rdstat[i][mode_idx], sizeof(SEG_RDSTAT)); +#endif if (num_4x4_blocks_wide > 1) bsi->rdstat[i + 1][mode_idx].eobs = ref_bsi->rdstat[i + 1][mode_idx].eobs; @@ -5331,23 +5436,24 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x, if (bsi->segment_rd > best_rd) return INT64_MAX; /* set it to the best */ - for (i = 0; i < 4; i++) { - mode_idx = INTER_OFFSET(bsi->modes[i]); - mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int; + for (idx = 0; idx < 4; idx++) { + mode_idx = INTER_OFFSET(bsi->modes[idx]); + mi->bmi[idx].as_mv[0].as_int = bsi->rdstat[idx][mode_idx].mvs[0].as_int; if (has_second_ref(mbmi)) - mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int; + mi->bmi[idx].as_mv[1].as_int = bsi->rdstat[idx][mode_idx].mvs[1].as_int; #if CONFIG_REF_MV - mi->bmi[i].pred_mv_s8[0] = bsi->rdstat[i][mode_idx].pred_mv[0]; + mi->bmi[idx].pred_mv_s8[0] = bsi->rdstat[idx][mode_idx].pred_mv[0]; if (has_second_ref(mbmi)) - mi->bmi[i].pred_mv_s8[1] = bsi->rdstat[i][mode_idx].pred_mv[1]; + mi->bmi[idx].pred_mv_s8[1] = bsi->rdstat[idx][mode_idx].pred_mv[1]; #endif #if CONFIG_EXT_INTER - mi->bmi[i].ref_mv[0].as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int; + mi->bmi[idx].ref_mv[0].as_int = bsi->rdstat[idx][mode_idx].ref_mv[0].as_int; if (has_second_rf) - mi->bmi[i].ref_mv[1].as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int; + mi->bmi[idx].ref_mv[1].as_int = + bsi->rdstat[idx][mode_idx].ref_mv[1].as_int; #endif // CONFIG_EXT_INTER - x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs; - mi->bmi[i].as_mode = bsi->modes[i]; + x->plane[0].eobs[idx] = bsi->rdstat[idx][mode_idx].eobs; + mi->bmi[idx].as_mode = bsi->modes[idx]; } /*