Use arf stacks to monitor the reference frame map

Monitor the reference frame map use case using the arf stacks.

Change-Id: I337e5fe20a356da70db0fdc18cbaeb167c325eed
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 79b1519..8b36b8c 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -756,6 +756,45 @@
 }
 #endif  // DUMP_REF_FRAME_IMAGES == 1
 
+static int get_refresh_ref_frame_map(AV1_COMMON *const cm) {
+  int refresh_frame_flags = cm->current_frame.refresh_frame_flags;
+  int ref_map_index = INVALID_IDX;
+
+  for (ref_map_index = 0; ref_map_index < REF_FRAMES; ++ref_map_index)
+    if ((refresh_frame_flags >> ref_map_index) & 1) break;
+
+  return ref_map_index;
+}
+
+static void update_arf_stack(AV1_COMP *cpi, int ref_map_index) {
+  if (cpi->arf_stack_size >= 0) {
+    if (cpi->arf_stack[0] == ref_map_index)
+      stack_pop(cpi->arf_stack, &cpi->arf_stack_size);
+  }
+
+  if (cpi->lst_stack_size) {
+    for (int i = cpi->lst_stack_size - 1; i >= 0; --i) {
+      if (cpi->lst_stack[i] == ref_map_index) {
+        for (int idx = i; idx < cpi->lst_stack_size - 1; ++idx)
+          cpi->lst_stack[idx] = cpi->lst_stack[idx + 1];
+        cpi->lst_stack[i] = INVALID_IDX;
+        --cpi->lst_stack_size;
+      }
+    }
+  }
+
+  if (cpi->gld_stack_size) {
+    for (int i = cpi->gld_stack_size - 1; i >= 0; --i) {
+      if (cpi->gld_stack[i] == ref_map_index) {
+        for (int idx = i; idx < cpi->gld_stack_size - 1; ++idx)
+          cpi->gld_stack[idx] = cpi->gld_stack[idx + 1];
+        cpi->gld_stack[i] = INVALID_IDX;
+        --cpi->gld_stack_size;
+      }
+    }
+  }
+}
+
 // Assign new_ref in the new mapping to point at the reference buffer pointed at
 // by old_ref in the old_map.  The new mapping is stored in *new_map, while the
 // old map comes from cm->remapped_ref_idx[].
@@ -773,10 +812,48 @@
                                  FRAME_UPDATE_TYPE frame_update_type) {
   AV1_COMMON *const cm = &cpi->common;
 
+  int ref_map_index = get_refresh_ref_frame_map(cm);
+
   if (cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) {
     stack_reset(cpi->lst_stack, &cpi->lst_stack_size);
     stack_reset(cpi->gld_stack, &cpi->gld_stack_size);
     stack_reset(cpi->arf_stack, &cpi->arf_stack_size);
+
+    stack_push(cpi->gld_stack, &cpi->gld_stack_size, ref_map_index);
+  } else {
+    switch (frame_update_type) {
+      case GF_UPDATE:
+        update_arf_stack(cpi, ref_map_index);
+        stack_push(cpi->gld_stack, &cpi->gld_stack_size, ref_map_index);
+        break;
+      case LF_UPDATE:
+        update_arf_stack(cpi, ref_map_index);
+        stack_push(cpi->lst_stack, &cpi->lst_stack_size, ref_map_index);
+        break;
+      case ARF_UPDATE:
+      case INTNL_ARF_UPDATE:
+        update_arf_stack(cpi, ref_map_index);
+        stack_push(cpi->arf_stack, &cpi->arf_stack_size, ref_map_index);
+        break;
+      case OVERLAY_UPDATE:
+        if (cpi->preserve_arf_as_gld) {
+          ref_map_index = stack_pop(cpi->arf_stack, &cpi->arf_stack_size);
+          stack_push(cpi->gld_stack, &cpi->gld_stack_size, ref_map_index);
+        } else {
+          stack_pop(cpi->arf_stack, &cpi->arf_stack_size);
+          update_arf_stack(cpi, ref_map_index);
+          stack_push(cpi->gld_stack, &cpi->gld_stack_size, ref_map_index);
+        }
+        break;
+      case INTNL_OVERLAY_UPDATE:
+        ref_map_index = stack_pop(cpi->arf_stack, &cpi->arf_stack_size);
+        if (cpi->gf_group.layer_depth[cpi->gf_group.index] == 2)
+          stack_push(cpi->gld_stack, &cpi->gld_stack_size, ref_map_index);
+        else
+          stack_push(cpi->lst_stack, &cpi->lst_stack_size, ref_map_index);
+        break;
+      default: assert(0 && "unknown type");
+    }
   }
 
   // If check_frame_refs_short_signaling() decided to set
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 5bbed8b..72f0757 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -1151,6 +1151,8 @@
 }
 
 static INLINE int stack_pop(int *stack, int *stack_size) {
+  if (*stack_size <= 0) return -1;
+
   int item = stack[0];
   for (int i = 0; i < *stack_size; ++i) stack[i] = stack[i + 1];
   --*stack_size;