primary_ref_frame order_offset to EncodeFrameParams

primary_ref_frame was set in setup_frame() called by
encode_with_recode_loop().  The determination was made using
fb_of_context_type[] which was setup in setup_frame() and
finalize_encoded_frame(). This patch moves the determination to
choose_primary_ref_frame() called by av1_encode_strategy().
fb_of_context_type[] is now updated by update_fb_of_context_type(), also
called by av1_encode_strategy.  primary_ref_frame is passed to the low
level encoder as part of EncodeFrameParams (and copied to its previous
location in av1_encode()).

Remove cm->force_primary_ref_none and just directly access
cpi->ext_use_primary_ref_none

Add order_offset to EncodeFrameParams, used by av1_encode() to calculate
the order_hint for this frame.  order_offset is now calculated in
encode_strategy.c

Move the resetting of frame_number to 0 upon shown-keyframe to
av1_encode() so it happens before order_hint is calculated.

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: I04c786a7d4389dcc8173c3a6ba3d58e217be3035
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 9e9158b..56f823e 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -501,7 +501,6 @@
   int primary_ref_frame;
 
   int error_resilient_mode;
-  int force_primary_ref_none;
 
   int tile_cols, tile_rows;
 
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 46ae166..92afca6 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -138,7 +138,6 @@
   if (cpi->ext_use_s_frame) {
     frame_params->frame_type = S_FRAME;
   }
-  cm->force_primary_ref_none = cpi->ext_use_primary_ref_none;
 
   if (cpi->ext_refresh_frame_context_pending) {
     cm->refresh_frame_context = cpi->ext_refresh_frame_context;
@@ -237,6 +236,109 @@
   return flags;
 }
 
+static int get_current_frame_ref_type(
+    const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
+  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.
+
+  const int intra_only = frame_params->frame_type == KEY_FRAME ||
+                         frame_params->frame_type == INTRA_ONLY_FRAME;
+  if (intra_only || frame_params->error_resilient_mode ||
+      cpi->ext_use_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 int choose_primary_ref_frame(
+    const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params) {
+  const AV1_COMMON *const cm = &cpi->common;
+
+  const int intra_only = frame_params->frame_type == KEY_FRAME ||
+                         frame_params->frame_type == INTRA_ONLY_FRAME;
+  if (intra_only || frame_params->error_resilient_mode ||
+      cpi->ext_use_primary_ref_none) {
+    return PRIMARY_REF_NONE;
+  }
+
+  // Find the most recent reference frame with the same reference type as the
+  // current frame
+  const FRAME_CONTEXT_INDEX current_ref_type =
+      get_current_frame_ref_type(cpi, frame_params);
+  int wanted_fb = cpi->fb_of_context_type[current_ref_type];
+
+  int primary_ref_frame = PRIMARY_REF_NONE;
+  for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
+    if (get_ref_frame_map_idx(cm, ref_frame) == wanted_fb) {
+      primary_ref_frame = ref_frame - LAST_FRAME;
+    }
+  }
+  return primary_ref_frame;
+}
+
+static void update_fb_of_context_type(
+    const AV1_COMP *const cpi, const EncodeFrameParams *const frame_params,
+    int *const fb_of_context_type) {
+  const AV1_COMMON *const cm = &cpi->common;
+
+  if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
+      cpi->ext_use_primary_ref_none) {
+    for (int i = 0; i < REF_FRAMES; i++) {
+      fb_of_context_type[i] = -1;
+    }
+    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);
+  }
+
+  if (!encode_show_existing_frame(cm)) {
+    // Refresh fb_of_context_type[]: see encoder.h for explanation
+    // Note that we want the value of refresh_frame_flags for the frame that
+    // just happened.  If we call get_refresh_frame_flags now we will get a
+    // different answer, because update_reference_frames() has happened.
+    if (cm->current_frame.frame_type == KEY_FRAME) {
+      // All ref frames are refreshed, pick one that will live long enough
+      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, frame_params);
+      for (int i = 0; i < REF_FRAMES; i++) {
+        if (cm->current_frame.refresh_frame_flags & (1 << i)) {
+          fb_of_context_type[current_frame_ref_type] = i;
+          break;
+        }
+      }
+    }
+  }
+}
+
+static int get_order_offset(const AV1_COMP *const cpi) {
+  // shown frame by definition has order offset 0
+  // show_existing_frame ignores order_offset and simply takes the order_hint
+  // from the reference frame being shown.
+  if (cpi->common.show_frame || cpi->common.show_existing_frame) return 0;
+
+  const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+  const int arf_offset =
+      AOMMIN((MAX_GF_INTERVAL - 1), gf_group->arf_src_offset[gf_group->index]);
+  const int brf_offset = gf_group->brf_src_offset[gf_group->index];
+  return AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
+}
+
 int av1_encode_strategy(AV1_COMP *const cpi, size_t *const size,
                         uint8_t *const dest, unsigned int *frame_flags,
                         const EncodeFrameInput *const frame_input) {
@@ -314,6 +416,12 @@
     frame_params.ref_frame_flags = get_ref_frame_flags(cpi);
   }
 
+  if (oxcf->pass == 0 || oxcf->pass == 2) {
+    frame_params.primary_ref_frame =
+        choose_primary_ref_frame(cpi, &frame_params);
+    frame_params.order_offset = get_order_offset(cpi);
+  }
+
   if (av1_encode(cpi, dest, frame_input, &frame_params, &frame_results) !=
       AOM_CODEC_OK) {
     return AOM_CODEC_ERROR;
@@ -332,6 +440,7 @@
   }
 
   if (oxcf->pass == 0 || oxcf->pass == 2) {
+    update_fb_of_context_type(cpi, &frame_params, cpi->fb_of_context_type);
     set_additional_frame_flags(cm, frame_params.frame_flags);
     update_rc_counts(cpi);
     check_show_existing_frame(cpi);  // Is next frame a show_existing frame?
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index f06cf25..7271c37 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -6418,20 +6418,6 @@
   // rather than the potential full set of 16 transforms
   cm->reduced_tx_set_used = cpi->oxcf.reduced_tx_type_set;
 
-  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]);
-    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);
-    current_frame->order_hint = current_frame->frame_number + arf_offset;
-  } else {
-    current_frame->order_hint = current_frame->frame_number;
-  }
-  current_frame->order_hint %=
-      (1 << (cm->seq_params.order_hint_info.order_hint_bits_minus_1 + 1));
-
   // Make sure segment_id is no larger than last_active_segid.
   if (cm->seg.enabled && cm->seg.update_map) {
     const int mi_rows = cm->mi_rows;
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 1037318..c3418c6 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -370,30 +370,6 @@
   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
@@ -402,24 +378,9 @@
   // other inter-frames the encoder currently uses only two contexts;
   // context 1 for ALTREF frames and context 0 for the others.
 
-  cm->primary_ref_frame = PRIMARY_REF_NONE;
   if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
-      cm->force_primary_ref_none) {
+      cpi->ext_use_primary_ref_none) {
     av1_setup_past_independence(cm);
-    for (int i = 0; i < REF_FRAMES; i++) {
-      cpi->fb_of_context_type[i] = -1;
-    }
-    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);
-  } else {
-    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) {
-        cm->primary_ref_frame = ref_frame - LAST_FRAME;
-      }
-    }
   }
 
   if (cm->current_frame.frame_type == KEY_FRAME && cm->show_frame) {
@@ -4519,24 +4480,6 @@
   // the current frame
   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 =
@@ -5149,10 +5092,6 @@
   cm->allow_warped_motion =
       cpi->oxcf.allow_warped_motion && frame_might_allow_warped_motion(cm);
 
-  // Reset the frame packet stamp index.
-  if (current_frame->frame_type == KEY_FRAME && cm->show_frame)
-    current_frame->frame_number = 0;
-
   cm->last_frame_type = current_frame->frame_type;
   if (cpi->oxcf.pass == 2 && cpi->sf.adaptive_interp_filter_search)
     cpi->sf.interp_filter_search_mask = setup_interp_filter_search_mask(cpi);
@@ -5181,9 +5120,6 @@
 
     cpi->seq_params_locked = 1;
 
-    // Update current frame offset.
-    current_frame->order_hint = cm->cur_frame->order_hint;
-
 #if DUMP_RECON_FRAMES == 1
     // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
     dump_filtered_recon_frames(cpi);
@@ -5516,16 +5452,30 @@
                const EncodeFrameParams *const frame_params,
                EncodeFrameResults *const frame_results) {
   AV1_COMMON *const cm = &cpi->common;
+  CurrentFrame *const current_frame = &cm->current_frame;
 
   cpi->unscaled_source = frame_input->source;
   cpi->source = frame_input->source;
   cpi->unscaled_last_source = frame_input->last_source;
 
   cm->error_resilient_mode = frame_params->error_resilient_mode;
+  cm->primary_ref_frame = frame_params->primary_ref_frame;
   cm->current_frame.frame_type = frame_params->frame_type;
   cpi->ref_frame_flags = frame_params->ref_frame_flags;
   cpi->speed = frame_params->speed;
 
+  if (current_frame->frame_type == KEY_FRAME && cm->show_frame)
+    current_frame->frame_number = 0;
+
+  if (cm->show_existing_frame) {
+    current_frame->order_hint = cm->cur_frame->order_hint;
+  } else {
+    current_frame->order_hint =
+        current_frame->frame_number + frame_params->order_offset;
+    current_frame->order_hint %=
+        (1 << (cm->seq_params.order_hint_info.order_hint_bits_minus_1 + 1));
+  }
+
   if (cpi->oxcf.pass == 1) {
     av1_first_pass(cpi, frame_input->ts_duration);
   } else if (cpi->oxcf.pass == 0 || cpi->oxcf.pass == 2) {
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 2b4ef11..251a917 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -883,6 +883,8 @@
 struct EncodeFrameParams {
   int error_resilient_mode;
   FRAME_TYPE frame_type;
+  int primary_ref_frame;
+  int order_offset;
 
   // This is a bitmask of which reference slots can be used in this frame
   int ref_frame_flags;