Store predicted motion vectors Change-Id: I51307a217eeba14dbdaa2522be474530316a4faa
diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h index cf78cbb..4d7f921 100644 --- a/vp10/common/blockd.h +++ b/vp10/common/blockd.h
@@ -79,6 +79,9 @@ typedef struct { PREDICTION_MODE as_mode; int_mv as_mv[2]; // first, second inter predictor motion vectors +#if CONFIG_REF_MV + int_mv pred_mv[2]; +#endif #if CONFIG_EXT_INTER int_mv ref_mv[2]; #endif // CONFIG_EXT_INTER
diff --git a/vp10/common/mv.h b/vp10/common/mv.h index 904d372..4523705 100644 --- a/vp10/common/mv.h +++ b/vp10/common/mv.h
@@ -38,6 +38,7 @@ typedef struct candidate_mv { int_mv this_mv; int_mv comp_mv; + int_mv pred_mv; int weight; } CANDIDATE_MV; #endif
diff --git a/vp10/common/mvref_common.c b/vp10/common/mvref_common.c index 1b7fb7d..5a2def0 100644 --- a/vp10/common/mvref_common.c +++ b/vp10/common/mvref_common.c
@@ -38,6 +38,8 @@ // Add a new item to the list. if (index == *refmv_count) { ref_mv_stack[index].this_mv = this_refmv; + ref_mv_stack[index].pred_mv = + get_sub_block_pred_mv(candidate_mi, ref, col, block); ref_mv_stack[index].weight = 2 * weight; ++(*refmv_count); @@ -63,6 +65,8 @@ // Add a new item to the list. if (index == *refmv_count) { ref_mv_stack[index].this_mv = this_refmv; + ref_mv_stack[index].pred_mv = + get_sub_block_pred_mv(candidate_mi, ref, col, alt_block); ref_mv_stack[index].weight = weight; ++(*refmv_count);
diff --git a/vp10/common/mvref_common.h b/vp10/common/mvref_common.h index b02c0dd..62d85da 100644 --- a/vp10/common/mvref_common.h +++ b/vp10/common/mvref_common.h
@@ -150,6 +150,16 @@ : candidate->mbmi.mv[which_mv]; } +#if CONFIG_REF_MV +static INLINE int_mv get_sub_block_pred_mv(const MODE_INFO *candidate, + int which_mv, + int search_col, int block_idx) { + return block_idx >= 0 && candidate->mbmi.sb_type < BLOCK_8X8 + ? candidate->bmi[idx_n_column_to_subblock[block_idx][search_col == 0]] + .pred_mv[which_mv] + : candidate->mbmi.pred_mv[which_mv]; +} +#endif // Performs mv sign inversion if indicated by the reference frame combination. static INLINE int_mv scale_mv(const MB_MODE_INFO *mbmi, int ref,
diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c index 401298f..f924a6d 100644 --- a/vp10/decoder/decodemv.c +++ b/vp10/decoder/decodemv.c
@@ -891,11 +891,20 @@ static INLINE int assign_mv(VP10_COMMON *cm, MACROBLOCKD *xd, PREDICTION_MODE mode, +#if CONFIG_REF_MV + int block, +#endif int_mv mv[2], int_mv ref_mv[2], int_mv nearest_mv[2], int_mv near_mv[2], int is_compound, int allow_hp, vpx_reader *r) { int i; int ret = 1; +#if CONFIG_REF_MV + MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi; + BLOCK_SIZE bsize = mbmi->sb_type; + int_mv *pred_mv = (bsize >= BLOCK_8X8) ? + mbmi->pred_mv : xd->mi[0]->bmi[block].pred_mv; +#endif switch (mode) { #if CONFIG_EXT_INTER @@ -908,6 +917,10 @@ read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts, allow_hp); ret = ret && is_mv_valid(&mv[i].as_mv); + +#if CONFIG_REF_MV + pred_mv[i].as_int = ref_mv[i].as_int; +#endif } break; } @@ -915,18 +928,36 @@ mv[0].as_int = nearest_mv[0].as_int; if (is_compound) mv[1].as_int = nearest_mv[1].as_int; + +#if CONFIG_REF_MV + pred_mv[0].as_int = nearest_mv[0].as_int; + if (is_compound) + pred_mv[1].as_int = nearest_mv[1].as_int; +#endif break; } case NEARMV: { mv[0].as_int = near_mv[0].as_int; if (is_compound) mv[1].as_int = near_mv[1].as_int; + +#if CONFIG_REF_MV + pred_mv[0].as_int = near_mv[0].as_int; + if (is_compound) + pred_mv[1].as_int = near_mv[1].as_int; +#endif break; } case ZEROMV: { mv[0].as_int = 0; if (is_compound) mv[1].as_int = 0; + +#if CONFIG_REF_MV + pred_mv[0].as_int = 0; + if (is_compound) + pred_mv[1].as_int = 0; +#endif break; } #if CONFIG_EXT_INTER @@ -1284,7 +1315,11 @@ #endif // CONFIG_EXT_INTER } - if (!assign_mv(cm, xd, b_mode, block, + if (!assign_mv(cm, xd, b_mode, +#if CONFIG_REF_MV + j, +#endif + block, #if CONFIG_EXT_INTER ref_mv[mv_idx], #else @@ -1312,7 +1347,11 @@ mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int; mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int; } else { - xd->corrupted |= !assign_mv(cm, xd, mbmi->mode, mbmi->mv, + xd->corrupted |= !assign_mv(cm, xd, mbmi->mode, +#if CONFIG_REF_MV + 0, +#endif + mbmi->mv, #if CONFIG_EXT_INTER mbmi->mode == NEWFROMNEARMV ? nearmv : nearestmv,
diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c index f77a66e..8f6c4c7 100644 --- a/vp10/encoder/rdopt.c +++ b/vp10/encoder/rdopt.c
@@ -3512,6 +3512,20 @@ mic->bmi[i].as_mode = mode; +#if CONFIG_REF_MV + if (mode == NEWMV) { + mic->bmi[i].pred_mv[0].as_int = + mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_int; + if (is_compound) + mic->bmi[i].pred_mv[1].as_int = + mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_int; + } else { + mic->bmi[i].pred_mv[0].as_int = this_mv[0].as_int; + if (is_compound) + mic->bmi[i].pred_mv[1].as_int = this_mv[1].as_int; + } +#endif + for (idy = 0; idy < num_4x4_blocks_high; ++idy) for (idx = 0; idx < num_4x4_blocks_wide; ++idx) memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i])); @@ -5263,6 +5277,13 @@ if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX; mbmi->mv[i].as_int = cur_mv[i].as_int; + +#if CONFIG_REF_MV + if (this_mode != NEWMV) + mbmi->pred_mv[i].as_int = mbmi->mv[i].as_int; + else + mbmi->pred_mv[i].as_int = mbmi_ext->ref_mvs[refs[i]][0].as_int; +#endif } #if CONFIG_REF_MV