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