Integrate motion vector stack into codec

This commit ports the motion vector stack from motion field
analyzer to the encoding and decoding pipeline.

Change-Id: Ie283c1e1a15b4c17a1c7c175ce322bf053bb7840
diff --git a/vp10/common/blockd.h b/vp10/common/blockd.h
index 0ea70d3..eeeb69c 100644
--- a/vp10/common/blockd.h
+++ b/vp10/common/blockd.h
@@ -254,6 +254,11 @@
   // dimension in the unit of 8x8 block of the current block
   uint8_t n8_w, n8_h;
 
+#if CONFIG_REF_MV
+  uint8_t ref_mv_count[MAX_REF_FRAMES];
+  CANDIDATE_MV ref_mv_stack[MAX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
+#endif
+
 #if CONFIG_VP9_HIGHBITDEPTH
   /* Bit depth: 8, 10, 12 */
   int bd;
diff --git a/vp10/common/mv.h b/vp10/common/mv.h
index 4cc2638..289c591 100644
--- a/vp10/common/mv.h
+++ b/vp10/common/mv.h
@@ -34,6 +34,13 @@
   int32_t col;
 } MV32;
 
+#if CONFIG_REF_MV
+typedef struct candidate_mv {
+  int_mv this_mv;
+  int weight;
+} CANDIDATE_MV;
+#endif
+
 static INLINE int is_zero_mv(const MV *mv) {
   return *((const uint32_t *)mv) == 0;
 }
diff --git a/vp10/common/mvref_common.c b/vp10/common/mvref_common.c
index 851f30a..3470643 100644
--- a/vp10/common/mvref_common.c
+++ b/vp10/common/mvref_common.c
@@ -17,7 +17,7 @@
                           const MV_REFERENCE_FRAME ref_frame,
                           int row_offset,
                           CANDIDATE_MV *ref_mv_stack,
-                          int *refmv_count) {
+                          uint8_t *refmv_count) {
   const TileInfo *const tile = &xd->tile;
   int i;
 
@@ -66,7 +66,7 @@
                           const MV_REFERENCE_FRAME ref_frame,
                           int col_offset,
                           CANDIDATE_MV *ref_mv_stack,
-                          int *refmv_count) {
+                          uint8_t *refmv_count) {
   const TileInfo *const tile = &xd->tile;
   int i;
 
@@ -115,7 +115,7 @@
                           const MV_REFERENCE_FRAME ref_frame,
                           int row_offset, int col_offset,
                           CANDIDATE_MV *ref_mv_stack,
-                          int *refmv_count) {
+                          uint8_t *refmv_count) {
   const TileInfo *const tile = &xd->tile;
   POSITION mi_pos;
 
@@ -154,29 +154,30 @@
 
 static void setup_ref_mv_list(const VP10_COMMON *cm, const MACROBLOCKD *xd,
                               MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
+                              uint8_t *refmv_count,
+                              CANDIDATE_MV *ref_mv_stack,
                               int_mv *mv_ref_list,
                               int block, int mi_row, int mi_col,
                               uint8_t *mode_context) {
-  int idx, refmv_count = 0, nearest_refmv_count = 0;
+  int idx, nearest_refmv_count = 0;
   const int bw = num_8x8_blocks_wide_lookup[mi->mbmi.sb_type] << 3;
   const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type] << 3;
 
-  CANDIDATE_MV ref_mv_stack[MAX_REF_MV_STACK_SIZE];
   CANDIDATE_MV tmp_mv;
   int len, nr_len;
 
   (void) mode_context;
 
-  memset(ref_mv_stack, 0, sizeof(ref_mv_stack));
+  *refmv_count = 0;
 
   // Scan the first above row mode info.
   scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -1, ref_mv_stack, &refmv_count);
+                -1, ref_mv_stack, refmv_count);
   // Scan the first left column mode info.
   scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -1, ref_mv_stack, &refmv_count);
+                -1, ref_mv_stack, refmv_count);
 
-  nearest_refmv_count = refmv_count;
+  nearest_refmv_count = *refmv_count;
 
   // Analyze the top-left corner block mode info.
 //  scan_blk_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
@@ -184,22 +185,22 @@
 
   // Scan the second outer area.
   scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -2, ref_mv_stack, &refmv_count);
+                -2, ref_mv_stack, refmv_count);
   scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -2, ref_mv_stack, &refmv_count);
+                -2, ref_mv_stack, refmv_count);
 
   // Scan the third outer area.
   scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -3, ref_mv_stack, &refmv_count);
+                -3, ref_mv_stack, refmv_count);
   scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -3, ref_mv_stack, &refmv_count);
+                -3, ref_mv_stack, refmv_count);
 
   // Scan the fourth outer area.
   scan_row_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -4, ref_mv_stack, &refmv_count);
+                -4, ref_mv_stack, refmv_count);
   // Scan the third left row mode info.
   scan_col_mbmi(cm, xd, mi_row, mi_col, block, ref_frame,
-                -4, ref_mv_stack, &refmv_count);
+                -4, ref_mv_stack, refmv_count);
 
   // Rank the likelihood and assign nearest and near mvs.
   len = nearest_refmv_count;
@@ -216,7 +217,7 @@
     len = nr_len;
   }
 
-  len = refmv_count;
+  len = *refmv_count;
   while (len > nearest_refmv_count) {
     nr_len = nearest_refmv_count;
     for (idx = nearest_refmv_count + 1; idx < len; ++idx) {
@@ -230,7 +231,7 @@
     len = nr_len;
   }
 
-  for (idx = 0; idx < VPXMIN(MAX_MV_REF_CANDIDATES, refmv_count); ++idx) {
+  for (idx = 0; idx < VPXMIN(MAX_MV_REF_CANDIDATES, *refmv_count); ++idx) {
     mv_ref_list[idx].as_int = ref_mv_stack[idx].this_mv.as_int;
     clamp_mv_ref(&mv_ref_list[idx].as_mv, bw, bh, xd);
   }
@@ -373,6 +374,10 @@
 
 void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
                       MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
+#if CONFIG_REF_MV
+                      uint8_t *ref_mv_count,
+                      CANDIDATE_MV *ref_mv_stack,
+#endif
                       int_mv *mv_ref_list,
                       int mi_row, int mi_col,
                       find_mv_refs_sync sync, void *const data,
@@ -381,8 +386,8 @@
                    mi_row, mi_col, sync, data, mode_context);
 
 #if CONFIG_REF_MV
-  setup_ref_mv_list(cm, xd, mi, ref_frame, mv_ref_list, -1,
-                    mi_row, mi_col, mode_context);
+  setup_ref_mv_list(cm, xd, mi, ref_frame, ref_mv_count, ref_mv_stack,
+                    mv_ref_list, -1, mi_row, mi_col, mode_context);
 #endif
 }
 
diff --git a/vp10/common/mvref_common.h b/vp10/common/mvref_common.h
index 410be4c..6b40878 100644
--- a/vp10/common/mvref_common.h
+++ b/vp10/common/mvref_common.h
@@ -24,13 +24,6 @@
   int col;
 } POSITION;
 
-#if CONFIG_REF_MV
-typedef struct candidate_mv {
-  int_mv this_mv;
-  int weight;
-} CANDIDATE_MV;
-#endif
-
 typedef enum {
   BOTH_ZERO = 0,
   ZERO_PLUS_PREDICTED = 1,
@@ -204,10 +197,14 @@
 
 typedef void (*find_mv_refs_sync)(void *const data, int mi_row);
 void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
-                      MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
-                      int_mv *mv_ref_list, int mi_row, int mi_col,
-                      find_mv_refs_sync sync, void *const data,
-                      uint8_t *mode_context);
+                       MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
+#if CONFIG_REF_MV
+                       uint8_t *ref_mv_count,
+                       CANDIDATE_MV *ref_mv_stack,
+#endif
+                       int_mv *mv_ref_list, int mi_row, int mi_col,
+                       find_mv_refs_sync sync, void *const data,
+                       uint8_t *mode_context);
 
 // check a list of motion vectors by sad score using a number rows of pixels
 // above and a number cols of pixels in the left to select the one with best
diff --git a/vp10/decoder/decodemv.c b/vp10/decoder/decodemv.c
index ea21c8b..edc2716 100644
--- a/vp10/decoder/decodemv.c
+++ b/vp10/decoder/decodemv.c
@@ -786,8 +786,13 @@
                          "Reference frame has invalid dimensions");
     vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
                          &ref_buf->sf);
-    vp10_find_mv_refs(cm, xd, mi, frame, ref_mvs[frame],
-                     mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
+    vp10_find_mv_refs(cm, xd, mi, frame,
+#if CONFIG_REF_MV
+                      &xd->ref_mv_count[frame],
+                      xd->ref_mv_stack[frame],
+#endif
+                      ref_mvs[frame],
+                      mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
   }
 
   if (segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
diff --git a/vp10/encoder/block.h b/vp10/encoder/block.h
index 55ec46e..62de0bc 100644
--- a/vp10/encoder/block.h
+++ b/vp10/encoder/block.h
@@ -13,6 +13,9 @@
 
 #include "vp10/common/entropymv.h"
 #include "vp10/common/entropy.h"
+#if CONFIG_REF_MV
+#include "vp10/common/mvref_common.h"
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -50,6 +53,10 @@
 typedef struct {
   int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
   uint8_t mode_context[MAX_REF_FRAMES];
+#if CONFIG_REF_MV
+  uint8_t ref_mv_count[MAX_REF_FRAMES];
+  CANDIDATE_MV ref_mv_stack[MAX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
+#endif
 } MB_MODE_INFO_EXT;
 
 typedef struct {
diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c
index 1f23784..3708214 100644
--- a/vp10/encoder/rdopt.c
+++ b/vp10/encoder/rdopt.c
@@ -3902,8 +3902,13 @@
   vp10_setup_pred_block(xd, yv12_mb[ref_frame], yv12, mi_row, mi_col, sf, sf);
 
   // Gets an initial list of candidate vectors from neighbours and orders them
-  vp10_find_mv_refs(cm, xd, mi, ref_frame, candidates, mi_row, mi_col,
-                   NULL, NULL, mbmi_ext->mode_context);
+  vp10_find_mv_refs(cm, xd, mi, ref_frame,
+#if CONFIG_REF_MV
+                    &mbmi_ext->ref_mv_count[ref_frame],
+                    mbmi_ext->ref_mv_stack[ref_frame],
+#endif
+                    candidates, mi_row, mi_col,
+                    NULL, NULL, mbmi_ext->mode_context);
 
   // Candidate refinement carried out at encoder and decoder
   vp10_find_best_ref_mvs(cm->allow_high_precision_mv, candidates,