Clean-up fb_of_context_type/frame_context_idx

* Move AV1_COMMON.fb_of_context_type[] to AV1_COMP
* Move assignments of fb_of_context_type[] from bitstream to
  finalize_encoded_frame()
* Move the derivation of cm->frame_context_idx to a function
  get_current_frame_ref_type() and use this as a getter instead
* Move show_existing_frame assignment of cm->cur_frame from bitstream to
  finalize_encoded_frame()

This forms part of wider restructuring and refactoring in order to
achieve a clean API separation at the entry to the low-level encoder.

BUG=aomedia:2244

Change-Id: I827ef697d44055c588f9e2da7aaea843dce49319
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index c114148..5a785f7 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -500,8 +500,6 @@
 
   FRAME_CONTEXT *fc;              /* this frame entropy */
   FRAME_CONTEXT *default_frame_context;
-  unsigned int frame_context_idx; /* Context to use/update */
-  int fb_of_context_type[REF_FRAMES];
   int primary_ref_frame;
 
   int error_resilient_mode;
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 1e6dd16..a19069e 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2832,15 +2832,6 @@
   }
   if (!seq_params->reduced_still_picture_hdr) {
     if (encode_show_existing_frame(cm)) {
-      RefCntBuffer *const frame_to_show =
-          cm->ref_frame_map[cpi->existing_fb_idx_to_show];
-
-      if (frame_to_show == NULL || frame_to_show->ref_count < 1) {
-        aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
-                           "Buffer does not contain a reconstructed frame");
-      }
-      assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
-
       aom_wb_write_bit(wb, 1);  // show_existing_frame
       aom_wb_write_literal(wb, cpi->existing_fb_idx_to_show, 3);
 
@@ -2853,13 +2844,6 @@
         int display_frame_id = cm->ref_frame_id[cpi->existing_fb_idx_to_show];
         aom_wb_write_literal(wb, display_frame_id, frame_id_len);
       }
-
-      if (cm->reset_decoder_state && frame_to_show->frame_type != KEY_FRAME) {
-        aom_internal_error(
-            &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
-            "show_existing_frame to reset state on KEY_FRAME only");
-      }
-
       return;
     } else {
       aom_wb_write_bit(wb, 0);  // show_existing_frame
@@ -2967,18 +2951,6 @@
       current_frame->frame_type == INTRA_ONLY_FRAME)
     aom_wb_write_literal(wb, current_frame->refresh_frame_flags, REF_FRAMES);
 
-  // For non-keyframes, we need to update the buffer of reference frame ids.
-  // If more than one frame is refreshed, it doesn't matter which one we pick,
-  // so pick the first.  LST sometimes doesn't refresh any: this is ok
-  if (current_frame->frame_type != KEY_FRAME) {
-    for (int i = 0; i < REF_FRAMES; i++) {
-      if (current_frame->refresh_frame_flags & (1 << i)) {
-        cm->fb_of_context_type[cm->frame_context_idx] = i;
-        break;
-      }
-    }
-  }
-
   if (!frame_is_intra_only(cm) || current_frame->refresh_frame_flags != 0xff) {
     // Write all ref frame order hints if error_resilient_mode == 1
     if (cm->error_resilient_mode &&
@@ -2996,8 +2968,6 @@
     assert(!av1_superres_scaled(cm) || !cm->allow_intrabc);
     if (cm->allow_screen_content_tools && !av1_superres_scaled(cm))
       aom_wb_write_bit(wb, cm->allow_intrabc);
-    // all eight fbs are refreshed, pick one that will live long enough
-    cm->fb_of_context_type[REGULAR_FRAME] = 0;
   } else {
     if (current_frame->frame_type == INTRA_ONLY_FRAME) {
       write_frame_size(cm, frame_size_override_flag, wb);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 2836160..870a7ad 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -367,6 +367,30 @@
   return BLOCK_128X128;
 }
 
+static int get_current_frame_ref_type(const AV1_COMP *const cpi) {
+  const AV1_COMMON *const cm = &cpi->common;
+  const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+  // We choose the reference "type" of this frame from the flags which indicate
+  // which reference frames will be refreshed by it.  More than one of these
+  // flags may be set, so the order here implies an order of precedence.
+
+  if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
+      cm->force_primary_ref_none)
+    return REGULAR_FRAME;
+  else if (gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE)
+    return EXT_ARF_FRAME;
+  else if (cpi->refresh_alt_ref_frame)
+    return ARF_FRAME;
+  else if (cpi->rc.is_src_frame_alt_ref)
+    return OVERLAY_FRAME;
+  else if (cpi->refresh_golden_frame)
+    return GLD_FRAME;
+  else if (cpi->refresh_bwd_ref_frame)
+    return BRF_FRAME;
+  else
+    return REGULAR_FRAME;
+}
+
 static void setup_frame(AV1_COMP *cpi) {
   AV1_COMMON *const cm = &cpi->common;
   // Set up entropy context depending on frame type. The decoder mandates
@@ -380,27 +404,13 @@
       cm->force_primary_ref_none) {
     av1_setup_past_independence(cm);
     for (int i = 0; i < REF_FRAMES; i++) {
-      cm->fb_of_context_type[i] = -1;
+      cpi->fb_of_context_type[i] = -1;
     }
-    cm->fb_of_context_type[REGULAR_FRAME] =
+    cpi->fb_of_context_type[REGULAR_FRAME] =
         cm->show_frame ? get_ref_frame_map_idx(cm, GOLDEN_FRAME)
                        : get_ref_frame_map_idx(cm, ALTREF_FRAME);
-    cm->frame_context_idx = REGULAR_FRAME;
   } else {
-    const GF_GROUP *gf_group = &cpi->twopass.gf_group;
-    if (gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE)
-      cm->frame_context_idx = EXT_ARF_FRAME;
-    else if (cpi->refresh_alt_ref_frame)
-      cm->frame_context_idx = ARF_FRAME;
-    else if (cpi->rc.is_src_frame_alt_ref)
-      cm->frame_context_idx = OVERLAY_FRAME;
-    else if (cpi->refresh_golden_frame)
-      cm->frame_context_idx = GLD_FRAME;
-    else if (cpi->refresh_bwd_ref_frame)
-      cm->frame_context_idx = BRF_FRAME;
-    else
-      cm->frame_context_idx = REGULAR_FRAME;
-    int wanted_fb = cm->fb_of_context_type[cm->frame_context_idx];
+    int wanted_fb = cpi->fb_of_context_type[get_current_frame_ref_type(cpi)];
     for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
       int fb = get_ref_frame_map_idx(cm, ref_frame);
       if (fb == wanted_fb) {
@@ -4582,10 +4592,46 @@
 
 static void finalize_encoded_frame(AV1_COMP *const cpi) {
   AV1_COMMON *const cm = &cpi->common;
+  CurrentFrame *const current_frame = &cm->current_frame;
 
   // This bitfield indicates which reference frame slots will be overwritten by
   // the current frame
-  cm->current_frame.refresh_frame_flags = get_refresh_frame_flags(cpi);
+  current_frame->refresh_frame_flags = get_refresh_frame_flags(cpi);
+
+  if (!encode_show_existing_frame(cm)) {
+    // Refresh fb_of_context_type[]: see encoder.h for explanation
+    if (current_frame->frame_type == KEY_FRAME) {
+      // All ref frames are refreshed, pick one that will live long enough
+      cpi->fb_of_context_type[REGULAR_FRAME] = 0;
+    } else {
+      // If more than one frame is refreshed, it doesn't matter which one we
+      // pick so pick the first.  LST sometimes doesn't refresh any: this is ok
+      const int current_frame_ref_type = get_current_frame_ref_type(cpi);
+      for (int i = 0; i < REF_FRAMES; i++) {
+        if (current_frame->refresh_frame_flags & (1 << i)) {
+          cpi->fb_of_context_type[current_frame_ref_type] = i;
+          break;
+        }
+      }
+    }
+  }
+
+  if (!cm->seq_params.reduced_still_picture_hdr &&
+      encode_show_existing_frame(cm)) {
+    RefCntBuffer *const frame_to_show =
+        cm->ref_frame_map[cpi->existing_fb_idx_to_show];
+
+    if (frame_to_show == NULL || frame_to_show->ref_count < 1) {
+      aom_internal_error(&cm->error, AOM_CODEC_UNSUP_BITSTREAM,
+                         "Buffer does not contain a reconstructed frame");
+    }
+    assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
+    if (cm->reset_decoder_state && frame_to_show->frame_type != KEY_FRAME) {
+      aom_internal_error(
+          &cm->error, AOM_CODEC_UNSUP_BITSTREAM,
+          "show_existing_frame to reset state on KEY_FRAME only");
+    }
+  }
 }
 
 static int encode_with_recode_loop(AV1_COMP *cpi, size_t *size, uint8_t *dest) {
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 29cb51a..d33695b 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -637,6 +637,12 @@
   int refresh_alt2_ref_frame;
   int refresh_alt_ref_frame;
 
+  // For each type of reference frame, this contains the index of a reference
+  // frame buffer for a reference frame of the same type.  We use this to
+  // choose our primary reference frame (which is the most recent reference
+  // frame of the same type as the current frame).
+  int fb_of_context_type[REF_FRAMES];
+
 #if USE_SYMM_MULTI_LAYER
   // When true, a new rule for backward (future) reference frames is in effect:
   // - BWDREF_FRAME is always the closest future frame available