Add frame index to the decoded frames

Add frame index to the deocded frames. Store such information to
the reference frame buffer pool. This design allows each frame
to know its index in natural order, as well as its reference
frames positions.

Change-Id: I5bb36928dc5750a4fdcc582dca0d244d6482f400
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index 3793aa6..8f6232e 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -1033,6 +1033,47 @@
   }
 }
 
+#if CONFIG_MFMV
+void av1_setup_frame_buf_refs(AV1_COMMON *cm) {
+  cm->cur_frame->cur_frame_offset = cm->frame_offset;
+  int alt_buf_idx = cm->frame_refs[ALTREF_FRAME - LAST_FRAME].idx;
+  int lst_buf_idx = cm->frame_refs[LAST_FRAME - LAST_FRAME].idx;
+  int gld_buf_idx = cm->frame_refs[GOLDEN_FRAME - LAST_FRAME].idx;
+
+#if CONFIG_EXT_REFS
+  int lst2_buf_idx = cm->frame_refs[LAST2_FRAME - LAST_FRAME].idx;
+  int lst3_buf_idx = cm->frame_refs[LAST3_FRAME - LAST_FRAME].idx;
+  int bwd_buf_idx = cm->frame_refs[BWDREF_FRAME - LAST_FRAME].idx;
+#endif
+
+  if (alt_buf_idx >= 0)
+    cm->cur_frame->alt_frame_offset =
+        cm->buffer_pool->frame_bufs[alt_buf_idx].cur_frame_offset;
+
+  if (lst_buf_idx >= 0)
+    cm->cur_frame->lst_frame_offset =
+        cm->buffer_pool->frame_bufs[lst_buf_idx].cur_frame_offset;
+
+  if (gld_buf_idx >= 0)
+    cm->cur_frame->gld_frame_offset =
+        cm->buffer_pool->frame_bufs[gld_buf_idx].cur_frame_offset;
+
+#if CONFIG_EXT_REFS
+  if (lst2_buf_idx >= 0)
+    cm->cur_frame->lst2_frame_offset =
+        cm->buffer_pool->frame_bufs[lst2_buf_idx].cur_frame_offset;
+
+  if (lst3_buf_idx >= 0)
+    cm->cur_frame->lst3_frame_offset =
+        cm->buffer_pool->frame_bufs[lst3_buf_idx].cur_frame_offset;
+
+  if (bwd_buf_idx >= 0)
+    cm->cur_frame->bwd_frame_offset =
+        cm->buffer_pool->frame_bufs[bwd_buf_idx].cur_frame_offset;
+#endif
+}
+#endif
+
 #if CONFIG_WARPED_MOTION
 #if WARPED_MOTION_SORT_SAMPLES
 static INLINE void record_samples(MB_MODE_INFO *mbmi, int *pts, int *pts_inref,
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h
index 4dc2350..05d7584 100644
--- a/av1/common/mvref_common.h
+++ b/av1/common/mvref_common.h
@@ -379,6 +379,10 @@
   return 0;
 }
 
+#if CONFIG_MFMV
+void av1_setup_frame_buf_refs(AV1_COMMON *cm);
+#endif
+
 typedef void (*find_mv_refs_sync)(void *const data, int mi_row);
 void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
                       MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index a5006f0..e077556 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -119,6 +119,20 @@
 
 typedef struct {
   int ref_count;
+
+#if CONFIG_MFMV
+  int cur_frame_offset;
+  int lst_frame_offset;
+  int alt_frame_offset;
+  int gld_frame_offset;
+
+#if CONFIG_EXT_REFS
+  int lst2_frame_offset;
+  int lst3_frame_offset;
+  int bwd_frame_offset;
+#endif
+#endif
+
   MV_REF *mvs;
   int mi_rows;
   int mi_cols;
@@ -375,6 +389,10 @@
 #endif
   FRAME_COUNTS counts;
 
+#if CONFIG_MFMV
+  unsigned int frame_offset;
+#endif
+
   unsigned int current_video_frame;
   BITSTREAM_PROFILE profile;
 
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 432a641..18663cc 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -44,6 +44,7 @@
 #include "av1/common/entropymode.h"
 #include "av1/common/entropymv.h"
 #include "av1/common/idct.h"
+#include "av1/common/mvref_common.h"
 #include "av1/common/pred_common.h"
 #include "av1/common/quant_common.h"
 #include "av1/common/reconinter.h"
@@ -4564,6 +4565,15 @@
       }
     }
   }
+
+#if CONFIG_MFMV
+  if (cm->show_frame == 0) {
+    cm->frame_offset = cm->current_video_frame + aom_rb_read_literal(rb, 4);
+  } else {
+    cm->frame_offset = cm->current_video_frame;
+  }
+#endif
+
 #if CONFIG_TEMPMV_SIGNALING
   cm->cur_frame->intra_only = cm->frame_type == KEY_FRAME || cm->intra_only;
 #endif
@@ -5275,6 +5285,10 @@
                            (cm->last_frame_type != KEY_FRAME);
 #endif  // CONFIG_TEMPMV_SIGNALING
 
+#if CONFIG_MFMV
+  av1_setup_frame_buf_refs(cm);
+#endif
+
   av1_setup_block_planes(xd, cm->subsampling_x, cm->subsampling_y);
 #if CONFIG_NO_FRAME_CONTEXT_SIGNALING
   if (cm->error_resilient_mode || frame_is_intra_only(cm)) {
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 54ad2df..cbb78da 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -4443,6 +4443,21 @@
     }
   }
 
+#if CONFIG_MFMV
+  if (cm->show_frame == 0) {
+    int arf_offset = AOMMIN(
+        (MAX_GF_INTERVAL - 1),
+        cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]);
+#if CONFIG_EXT_REFS
+    int brf_offset =
+        cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index];
+
+    arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
+#endif
+    aom_wb_write_literal(wb, arf_offset, 4);
+  }
+#endif
+
 #if CONFIG_REFERENCE_BUFFER
   cm->refresh_mask = cm->frame_type == KEY_FRAME ? 0xFF : get_refresh_mask(cpi);
 #endif
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 501c536..64f40ac 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -5299,6 +5299,23 @@
   av1_zero(x->blk_skip_drl);
 #endif
 
+#if CONFIG_MFMV
+  if (cm->show_frame == 0) {
+    int arf_offset = AOMMIN(
+        (MAX_GF_INTERVAL - 1),
+        cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]);
+#if CONFIG_EXT_REFS
+    int brf_offset =
+        cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index];
+    arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
+#endif
+    cm->frame_offset = cm->current_video_frame + arf_offset;
+  } else {
+    cm->frame_offset = cm->current_video_frame;
+  }
+  av1_setup_frame_buf_refs(cm);
+#endif
+
   {
     struct aom_usec_timer emr_timer;
     aom_usec_timer_start(&emr_timer);