Move frame_type to EncodeFrameParams

In this patch I move all frame_type (i.e. key, S, inter, intra-only)
determining logic above the av1_encode() boundary.  frame_type is now
passed into the low-level encoder as EncodeFrameParams.frame_type and is
not modified below that boundary.  This also means
cm->current_frame.frame_type (including functions like
frame_is_sframe()) should not be used before av1_encode(), as this is a
lower-level variable.

As part of this, calls to av1_tpl_setup_stats() and
av1_rc_get_second_pass_params() are moved to av1_encode_strategy() since
they are used to work out high-level pass2 strategy.

Also, remove the reset_decoder_state variable from the encoder as it
wasn't doing anything useful.  So, move it from AV1_COMMON to Av1Decoder

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: I672c435dfff88bb982ea904b5547e5d3294ef37c
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index e6cd60f..9e9158b 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -378,7 +378,6 @@
   int show_frame;
   int showable_frame;  // frame can be used as show existing frame in future
   int show_existing_frame;
-  int reset_decoder_state;
 
   uint8_t disable_cdf_update;
   int allow_high_precision_mv;
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 2c91f4a..26e91d5 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4854,7 +4854,7 @@
     cm->error_resilient_mode = 1;
   } else {
     cm->show_existing_frame = aom_rb_read_bit(rb);
-    cm->reset_decoder_state = 0;
+    pbi->reset_decoder_state = 0;
 
     if (cm->show_existing_frame) {
       if (pbi->sequence_header_changed) {
@@ -4896,7 +4896,7 @@
       // assign_frame_buffer_p()!
       assert(!cm->cur_frame->raw_frame_buffer.data);
       assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
-      cm->reset_decoder_state = frame_to_show->frame_type == KEY_FRAME;
+      pbi->reset_decoder_state = frame_to_show->frame_type == KEY_FRAME;
       unlock_buffer_pool(pool);
 
       cm->lf.filter_level[0] = 0;
@@ -4906,11 +4906,11 @@
       if (!frame_to_show->showable_frame) {
         aom_merge_corrupted_flag(&xd->corrupted, 1);
       }
-      if (cm->reset_decoder_state) frame_to_show->showable_frame = 0;
+      if (pbi->reset_decoder_state) frame_to_show->showable_frame = 0;
 
       cm->film_grain_params = frame_to_show->film_grain_params;
 
-      if (cm->reset_decoder_state) {
+      if (pbi->reset_decoder_state) {
         show_existing_frame_reset(pbi, existing_frame_idx);
       } else {
         current_frame->refresh_frame_flags = 0;
@@ -5508,7 +5508,7 @@
   if (cm->show_existing_frame) {
     // showing a frame directly
     *p_data_end = data + uncomp_hdr_size;
-    if (cm->reset_decoder_state) {
+    if (pbi->reset_decoder_state) {
       // Use the default frame context values.
       *cm->fc = *cm->default_frame_context;
       if (!cm->fc->initialized)
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index 743f2cf..bff4b7a 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -361,7 +361,7 @@
       assert(IMPLIES(!pbi->hold_ref_buf,
                      cm->current_frame.refresh_frame_flags == 0));
       assert(IMPLIES(!pbi->hold_ref_buf,
-                     cm->show_existing_frame && !cm->reset_decoder_state));
+                     cm->show_existing_frame && !pbi->reset_decoder_state));
 
       // The following two for loops need to release the reference stored in
       // cm->ref_frame_map[ref_index] before transferring the reference stored
@@ -374,7 +374,7 @@
       }
 
       const int check_on_show_existing_frame =
-          !cm->show_existing_frame || cm->reset_decoder_state;
+          !cm->show_existing_frame || pbi->reset_decoder_state;
       for (; ref_index < REF_FRAMES && check_on_show_existing_frame;
            ++ref_index) {
         decrease_ref_count(cm->ref_frame_map[ref_index], pool);
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index 3e9d4c2..467c8a2 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -200,6 +200,7 @@
   int need_resync;   // wait for key/intra-only frame.
   int hold_ref_buf;  // Boolean: whether we are holding reference buffers in
                      // common.next_ref_frame_map.
+  int reset_decoder_state;
 
   int tile_size_bytes;
   int tile_col_size_bytes;
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index 272f170..741ba0c 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -23,6 +23,8 @@
 
 #include "av1/encoder/encoder.h"
 #include "av1/encoder/encode_strategy.h"
+#include "av1/encoder/firstpass.h"
+#include "av1/encoder/tpl_model.h"
 
 static void set_additional_frame_flags(const AV1_COMMON *const cm,
                                        unsigned int *const frame_flags) {
@@ -134,7 +136,7 @@
   AV1_COMMON *const cm = &cpi->common;
 
   if (cpi->ext_use_s_frame) {
-    cm->current_frame.frame_type = S_FRAME;
+    frame_params->frame_type = S_FRAME;
   }
   cm->force_primary_ref_none = cpi->ext_use_primary_ref_none;
 
@@ -156,10 +158,9 @@
   // A keyframe is already error resilient and keyframes with
   // error_resilient_mode interferes with the use of show_existing_frame
   // when forward reference keyframes are enabled.
-  frame_params->error_resilient_mode &=
-      cm->current_frame.frame_type != KEY_FRAME;
+  frame_params->error_resilient_mode &= frame_params->frame_type != KEY_FRAME;
   // For bitstream conformance, s-frames must be error-resilient
-  frame_params->error_resilient_mode |= frame_is_sframe(cm);
+  frame_params->error_resilient_mode |= frame_params->frame_type == S_FRAME;
 }
 
 static int get_ref_frame_flags(const AV1_COMP *const cpi) {
@@ -241,9 +242,9 @@
                        EncodeFrameParams *const frame_params,
                        EncodeFrameResults *const frame_results) {
   if (cpi->oxcf.rc_mode == AOM_CBR) {
-    av1_rc_get_one_pass_cbr_params(cpi);
+    av1_rc_get_one_pass_cbr_params(cpi, frame_params);
   } else {
-    av1_rc_get_one_pass_vbr_params(cpi);
+    av1_rc_get_one_pass_vbr_params(cpi, frame_params);
   }
 
   // Apply external override flags
@@ -270,7 +271,17 @@
 static int Pass1Encode(AV1_COMP *const cpi,
                        const EncodeFrameInput *const frame_input,
                        EncodeFrameParams *const frame_params) {
+  const CurrentFrame *const current_frame = &cpi->common.current_frame;
+
   cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&cpi->oxcf);
+
+  if (!cpi->refresh_alt_ref_frame && (current_frame->frame_number == 0 ||
+                                      (cpi->frame_flags & FRAMEFLAGS_KEY))) {
+    frame_params->frame_type = KEY_FRAME;
+  } else {
+    frame_params->frame_type = INTER_FRAME;
+  }
+
   av1_encode(cpi, NULL, frame_input, frame_params, NULL);
   return AOM_CODEC_OK;
 }
@@ -324,12 +335,33 @@
                         uint8_t *const dest, unsigned int *frame_flags,
                         const EncodeFrameInput *const frame_input) {
   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
+  AV1_COMMON *const cm = &cpi->common;
 
   EncodeFrameParams frame_params;
   EncodeFrameResults frame_results;
   memset(&frame_params, 0, sizeof(frame_params));
   memset(&frame_results, 0, sizeof(frame_results));
 
+  if (oxcf->pass == 2 &&
+      (!cm->show_existing_frame || cpi->rc.is_src_frame_alt_ref)) {
+    // GF_GROUP needs updating for arf overlays as well as non-show-existing
+    av1_rc_get_second_pass_params(cpi, &frame_params);
+  }
+  if (cm->show_existing_frame && frame_params.frame_type != KEY_FRAME) {
+    // Force show-existing frames to be INTER, except forward keyframes
+    frame_params.frame_type = INTER_FRAME;
+  }
+
+  if (!cm->show_existing_frame) {
+    cm->using_qmatrix = cpi->oxcf.using_qm;
+    cm->min_qmlevel = cpi->oxcf.qm_minlevel;
+    cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
+    if (cpi->twopass.gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
+      av1_set_frame_size(cpi, cm->width, cm->height);
+      av1_tpl_setup_stats(cpi, frame_input);
+    }
+  }
+
   frame_params.frame_flags = frame_flags;
 
   // TODO(david.turner@argondesign.com): Move all the encode strategy
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index f0003c5..1037318 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -71,7 +71,6 @@
 #include "av1/encoder/segmentation.h"
 #include "av1/encoder/speed_features.h"
 #include "av1/encoder/temporal_filter.h"
-#include "av1/encoder/tpl_model.h"
 #include "av1/encoder/reconinter_enc.h"
 
 #define DEFAULT_EXPLICIT_ORDER_HINT_BITS 7
@@ -4031,7 +4030,7 @@
   return 0;
 }
 
-static void set_frame_size(AV1_COMP *cpi, int width, int height) {
+void av1_set_frame_size(AV1_COMP *cpi, int width, int height) {
   AV1_COMMON *const cm = &cpi->common;
   const SequenceHeader *const seq_params = &cm->seq_params;
   const int num_planes = av1_num_planes(cm);
@@ -4265,7 +4264,7 @@
 }
 
 // Calculates resize and superres params for next frame
-size_params_type av1_calculate_next_size_params(AV1_COMP *cpi) {
+static size_params_type calculate_next_size_params(AV1_COMP *cpi) {
   const AV1EncoderConfig *oxcf = &cpi->oxcf;
   size_params_type rsz = { oxcf->width, oxcf->height, SCALE_NUMERATOR };
   int resize_denom;
@@ -4299,13 +4298,13 @@
   cm->superres_scale_denominator = rsz->superres_denom;
   av1_calculate_scaled_superres_size(&encode_width, &encode_height,
                                      rsz->superres_denom);
-  set_frame_size(cpi, encode_width, encode_height);
+  av1_set_frame_size(cpi, encode_width, encode_height);
 }
 
 static void setup_frame_size(AV1_COMP *cpi) {
   // Reset superres params from previous frame.
   cpi->common.superres_scale_denominator = SCALE_NUMERATOR;
-  const size_params_type rsz = av1_calculate_next_size_params(cpi);
+  const size_params_type rsz = calculate_next_size_params(cpi);
   setup_frame_size_from_params(cpi, &rsz);
 }
 
@@ -4549,11 +4548,6 @@
     }
     assert(frame_to_show->ref_count > 0);
     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");
-    }
   }
 
   if (!encode_show_existing_frame(cm) &&
@@ -5166,11 +5160,6 @@
   if (encode_show_existing_frame(cm)) {
     // NOTE(zoeliu): In BIDIR_PRED, the existing frame to show is the current
     //               BWDREF_FRAME in the reference frame buffer.
-    if (current_frame->frame_type == KEY_FRAME) {
-      cm->reset_decoder_state = 1;
-    } else {
-      current_frame->frame_type = INTER_FRAME;
-    }
     cm->show_frame = 1;
     cpi->frame_flags = *frame_flags;
 
@@ -5533,6 +5522,7 @@
   cpi->unscaled_last_source = frame_input->last_source;
 
   cm->error_resilient_mode = frame_params->error_resilient_mode;
+  cm->current_frame.frame_type = frame_params->frame_type;
   cpi->ref_frame_flags = frame_params->ref_frame_flags;
   cpi->speed = frame_params->speed;
 
@@ -6070,7 +6060,6 @@
 
   // Initialize fields related to forward keyframes
   cpi->no_show_kf = 0;
-  cm->reset_decoder_state = 0;
 
   cm->show_existing_frame &= allow_show_existing(cpi);
 
@@ -6134,24 +6123,7 @@
     cpi->common.frame_presentation_time = (uint32_t)pts64;
   }
 
-  if (oxcf->pass == 2) {
-    // GF_GROUP needs updating for arf overlays as well as non-show-existing
-    if (!cm->show_existing_frame || cpi->rc.is_src_frame_alt_ref) {
-      av1_rc_get_second_pass_params(cpi);
-    }
-  } else if (oxcf->pass == 1) {
-    setup_frame_size(cpi);
-  }
-
-  if (!cm->show_existing_frame) {
-    cm->using_qmatrix = cpi->oxcf.using_qm;
-    cm->min_qmlevel = cpi->oxcf.qm_minlevel;
-    cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
-    if (cpi->twopass.gf_group.index == 1 && cpi->oxcf.enable_tpl_model) {
-      set_frame_size(cpi, cm->width, cm->height);
-      av1_tpl_setup_stats(cpi, &frame_input);
-    }
-  }
+  if (oxcf->pass == 1) setup_frame_size(cpi);
 
   if (av1_encode_strategy(cpi, size, dest, frame_flags, &frame_input) !=
       AOM_CODEC_OK) {
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 407f986..9a4e533 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -877,8 +877,9 @@
 
 // EncodeFrameParams contains per-frame encoding parameters decided upon by
 // av1_encode_strategy() and passed down to av1_encode()
-typedef struct {
+struct EncodeFrameParams {
   int error_resilient_mode;
+  FRAME_TYPE frame_type;
 
   // This is a bitmask of which reference slots can be used in this frame
   int ref_frame_flags;
@@ -887,7 +888,8 @@
   int speed;
 
   unsigned int *frame_flags;
-} EncodeFrameParams;
+};
+typedef struct EncodeFrameParams EncodeFrameParams;
 
 // EncodeFrameResults contains information about the result of encoding a
 // single frame
@@ -936,6 +938,8 @@
 
 int av1_set_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
 
+void av1_set_frame_size(AV1_COMP *cpi, int width, int height);
+
 int av1_update_entropy(AV1_COMP *cpi, int update);
 
 int av1_set_active_map(AV1_COMP *cpi, unsigned char *map, int rows, int cols);
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 8349ee7..3f50204 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -449,18 +449,6 @@
   return i;
 }
 
-static void set_first_pass_params(AV1_COMP *cpi) {
-  AV1_COMMON *const cm = &cpi->common;
-  if (!cpi->refresh_alt_ref_frame && (cm->current_frame.frame_number == 0 ||
-                                      (cpi->frame_flags & FRAMEFLAGS_KEY))) {
-    cm->current_frame.frame_type = KEY_FRAME;
-  } else {
-    cm->current_frame.frame_type = INTER_FRAME;
-  }
-  // Do not use periodic key frames.
-  cpi->rc.frames_to_key = INT_MAX;
-}
-
 static double raw_motion_error_stdev(int *raw_motion_err_list,
                                      int raw_motion_err_counts) {
   int64_t sum_raw_err = 0;
@@ -558,7 +546,9 @@
   brightness_factor = 0.0;
   neutral_count = 0.0;
 
-  set_first_pass_params(cpi);
+  // Do not use periodic key frames.
+  cpi->rc.frames_to_key = INT_MAX;
+
   av1_set_quantizer(cm, qindex);
 
   av1_setup_block_planes(&x->e_mbd, seq_params->subsampling_x,
@@ -1719,11 +1709,12 @@
   return AOMMIN(max_gf_length_allowed, MAX_GF_INTERVAL);
 }
 
-static void define_customized_gf_group_structure(AV1_COMP *cpi) {
+static void define_customized_gf_group_structure(
+    AV1_COMP *cpi, const EncodeFrameParams *const frame_params) {
   RATE_CONTROL *const rc = &cpi->rc;
   TWO_PASS *const twopass = &cpi->twopass;
   GF_GROUP *const gf_group = &twopass->gf_group;
-  const int key_frame = cpi->common.current_frame.frame_type == KEY_FRAME;
+  const int key_frame = frame_params->frame_type == KEY_FRAME;
 
   assert(rc->baseline_gf_interval >= MIN_GF_INTERVAL &&
          rc->baseline_gf_interval <=
@@ -1794,7 +1785,8 @@
 // result in exactly the same GF group structure as
 // define_customized_gf_group_structure() when rc->baseline_gf_interval == 4
 
-static void define_gf_group_structure(AV1_COMP *cpi) {
+static void define_gf_group_structure(
+    AV1_COMP *cpi, const EncodeFrameParams *const frame_params) {
   RATE_CONTROL *const rc = &cpi->rc;
 
   const int max_pyr_height = cpi->oxcf.gf_max_pyr_height;
@@ -1805,7 +1797,7 @@
   // used the new structure only if extra_arf is allowed
   if (valid_customized_gf_length && rc->source_alt_ref_pending &&
       cpi->extra_arf_allowed > 0) {
-    define_customized_gf_group_structure(cpi);
+    define_customized_gf_group_structure(cpi, frame_params);
     cpi->new_bwdref_update_rule = 1;
     return;
   } else {
@@ -1816,7 +1808,7 @@
   GF_GROUP *const gf_group = &twopass->gf_group;
   int i;
   int frame_index = 0;
-  const int key_frame = cpi->common.current_frame.frame_type == KEY_FRAME;
+  const int key_frame = frame_params->frame_type == KEY_FRAME;
 
   // The use of bi-predictive frames are only enabled when following 3
   // conditions are met:
@@ -2031,25 +2023,24 @@
 static double lvl_budget_factor[MAX_PYRAMID_LVL - 1][MAX_PYRAMID_LVL - 1] = {
   { 1.0, 0.0, 0.0 }, { 0.6, 0.4, 0 }, { 0.45, 0.35, 0.20 }
 };
-static void allocate_gf_group_bits(AV1_COMP *cpi, int64_t gf_group_bits,
-                                   double group_error, int gf_arf_bits) {
+static void allocate_gf_group_bits(
+    AV1_COMP *cpi, int64_t gf_group_bits, double group_error, int gf_arf_bits,
+    const EncodeFrameParams *const frame_params) {
   RATE_CONTROL *const rc = &cpi->rc;
   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
   TWO_PASS *const twopass = &cpi->twopass;
   GF_GROUP *const gf_group = &twopass->gf_group;
   int i;
   int frame_index = 0;
-  int key_frame;
+  const int key_frame = frame_params->frame_type == KEY_FRAME;
   const int max_bits = frame_max_bits(&cpi->rc, &cpi->oxcf);
   int64_t total_group_bits = gf_group_bits;
   int ext_arf_boost[MAX_EXT_ARFS];
 
-  define_gf_group_structure(cpi);
+  define_gf_group_structure(cpi, frame_params);
 
   av1_zero_array(ext_arf_boost, MAX_EXT_ARFS);
 
-  key_frame = cpi->common.current_frame.frame_type == KEY_FRAME;
-
   // For key frames the frame target rate is already set and it
   // is also the golden frame.
   // === [frame_index == 0] ===
@@ -2210,7 +2201,8 @@
 #define ARF_ABS_ZOOM_THRESH 4.4
 
 // Analyse and define a gf/arf group.
-static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame) {
+static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame,
+                            const EncodeFrameParams *const frame_params) {
   AV1_COMMON *const cm = &cpi->common;
   RATE_CONTROL *const rc = &cpi->rc;
   AV1EncoderConfig *const oxcf = &cpi->oxcf;
@@ -2249,14 +2241,15 @@
   int64_t gf_group_bits;
   double gf_group_error_left;
   int gf_arf_bits;
-  const int is_key_frame = frame_is_intra_only(cm);
-  const int arf_active_or_kf = is_key_frame || rc->source_alt_ref_active;
+  const int is_intra_only = frame_params->frame_type == KEY_FRAME ||
+                            frame_params->frame_type == INTRA_ONLY_FRAME;
+  const int arf_active_or_kf = is_intra_only || rc->source_alt_ref_active;
 
   cpi->extra_arf_allowed = 1;
 
   // Reset the GF group data structures unless this is a key
   // frame in which case it will already have been done.
-  if (is_key_frame == 0) {
+  if (!is_intra_only) {
     av1_zero(twopass->gf_group);
   }
 
@@ -2560,20 +2553,21 @@
   // also a key frame in which case it has already been accounted for.
   if (rc->source_alt_ref_pending) {
     gf_group_error_left = gf_group_err - mod_frame_err;
-  } else if (is_key_frame == 0) {
+  } else if (!is_intra_only) {
     gf_group_error_left = gf_group_err - gf_first_frame_err;
   } else {
     gf_group_error_left = gf_group_err;
   }
 
   // Allocate bits to each of the frames in the GF group.
-  allocate_gf_group_bits(cpi, gf_group_bits, gf_group_error_left, gf_arf_bits);
+  allocate_gf_group_bits(cpi, gf_group_bits, gf_group_error_left, gf_arf_bits,
+                         frame_params);
 
   // Reset the file position.
   reset_fpf_position(twopass, start_pos);
 
   // Calculate a section intra ratio used in setting max loop filter.
-  if (cpi->common.current_frame.frame_type != KEY_FRAME) {
+  if (frame_params->frame_type != KEY_FRAME) {
     twopass->section_intra_rating = calculate_section_intra_ratio(
         start_pos, twopass->stats_in_end, rc->baseline_gf_interval);
   }
@@ -2712,7 +2706,6 @@
 
   av1_zero(next_frame);
 
-  cpi->common.current_frame.frame_type = KEY_FRAME;
   rc->frames_since_key = 0;
 
   // Reset the GF group data structures.
@@ -3005,7 +2998,8 @@
           twopass->stats_in->pcnt_inter - twopass->stats_in->pcnt_motion == 1);
 }
 
-void av1_rc_get_second_pass_params(AV1_COMP *cpi) {
+void av1_rc_get_second_pass_params(AV1_COMP *cpi,
+                                   EncodeFrameParams *const frame_params) {
   AV1_COMMON *const cm = &cpi->common;
   CurrentFrame *const current_frame = &cm->current_frame;
   RATE_CONTROL *const rc = &cpi->rc;
@@ -3031,9 +3025,9 @@
 
     if (cpi->no_show_kf) {
       assert(gf_group->update_type[gf_group->index] == ARF_UPDATE);
-      current_frame->frame_type = KEY_FRAME;
+      frame_params->frame_type = KEY_FRAME;
     } else {
-      current_frame->frame_type = INTER_FRAME;
+      frame_params->frame_type = INTER_FRAME;
     }
 
     // Do the firstpass stats indicate that this frame is skippable for the
@@ -3088,16 +3082,17 @@
   if (rc->frames_to_key == 0 || (cpi->frame_flags & FRAMEFLAGS_KEY)) {
     FIRSTPASS_STATS this_frame_copy;
     this_frame_copy = this_frame;
+    frame_params->frame_type = KEY_FRAME;
     // Define next KF group and assign bits to it.
     find_next_key_frame(cpi, &this_frame);
     this_frame = this_frame_copy;
   } else {
-    current_frame->frame_type = INTER_FRAME;
+    frame_params->frame_type = INTER_FRAME;
   }
 
   // Define a new GF/ARF group. (Should always enter here for key frames).
   if (rc->frames_till_gf_update_due == 0) {
-    define_gf_group(cpi, &this_frame);
+    define_gf_group(cpi, &this_frame, frame_params);
 
     rc->frames_till_gf_update_due = rc->baseline_gf_interval;
 
@@ -3125,7 +3120,7 @@
 
   target_rate = gf_group->bit_allocation[gf_group->index];
 
-  if (cpi->common.current_frame.frame_type == KEY_FRAME)
+  if (frame_params->frame_type == KEY_FRAME)
     target_rate = av1_rc_clamp_iframe_target_size(cpi, target_rate);
   else
     target_rate = av1_rc_clamp_pframe_target_size(cpi, target_rate);
diff --git a/av1/encoder/firstpass.h b/av1/encoder/firstpass.h
index 9bb1df5..b61116f 100644
--- a/av1/encoder/firstpass.h
+++ b/av1/encoder/firstpass.h
@@ -171,6 +171,7 @@
 } TWO_PASS;
 
 struct AV1_COMP;
+struct EncodeFrameParams;
 
 void av1_init_first_pass(struct AV1_COMP *cpi);
 void av1_rc_get_first_pass_params(struct AV1_COMP *cpi);
@@ -178,7 +179,8 @@
 void av1_end_first_pass(struct AV1_COMP *cpi);
 
 void av1_init_second_pass(struct AV1_COMP *cpi);
-void av1_rc_get_second_pass_params(struct AV1_COMP *cpi);
+void av1_rc_get_second_pass_params(
+    struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
 void av1_configure_buffer_updates_firstpass(struct AV1_COMP *cpi,
                                             FRAME_UPDATE_TYPE update_type);
 
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index f952b35..e34349a 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1586,7 +1586,8 @@
   return av1_rc_clamp_iframe_target_size(cpi, target);
 }
 
-void av1_rc_get_one_pass_vbr_params(AV1_COMP *cpi) {
+void av1_rc_get_one_pass_vbr_params(AV1_COMP *cpi,
+                                    EncodeFrameParams *const frame_params) {
   AV1_COMMON *const cm = &cpi->common;
   RATE_CONTROL *const rc = &cpi->rc;
   CurrentFrame *const current_frame = &cm->current_frame;
@@ -1600,44 +1601,41 @@
       (current_frame->frame_number == 0 ||
        (cpi->frame_flags & FRAMEFLAGS_KEY) || rc->frames_to_key == 0 ||
        (cpi->oxcf.auto_key && 0))) {
-    current_frame->frame_type = KEY_FRAME;
+    frame_params->frame_type = KEY_FRAME;
     rc->this_key_frame_forced =
         current_frame->frame_number != 0 && rc->frames_to_key == 0;
     rc->frames_to_key = cpi->oxcf.key_freq;
     rc->kf_boost = DEFAULT_KF_BOOST;
     rc->source_alt_ref_active = 0;
   } else {
-    current_frame->frame_type = INTER_FRAME;
+    frame_params->frame_type = INTER_FRAME;
     if (sframe_enabled) {
       if (altref_enabled) {
         if (sframe_mode == 1) {
           // sframe_mode == 1: insert sframe if it matches altref frame.
 
           if (current_frame->frame_number % sframe_dist == 0 &&
-              current_frame->frame_type != KEY_FRAME &&
               current_frame->frame_number != 0 && cpi->refresh_alt_ref_frame) {
-            current_frame->frame_type = S_FRAME;
+            frame_params->frame_type = S_FRAME;
           }
         } else {
           // sframe_mode != 1: if sframe will be inserted at the next available
           // altref frame
 
           if (current_frame->frame_number % sframe_dist == 0 &&
-              current_frame->frame_type != KEY_FRAME &&
               current_frame->frame_number != 0) {
             rc->sframe_due = 1;
           }
 
           if (rc->sframe_due && cpi->refresh_alt_ref_frame) {
-            current_frame->frame_type = S_FRAME;
+            frame_params->frame_type = S_FRAME;
             rc->sframe_due = 0;
           }
         }
       } else {
         if (current_frame->frame_number % sframe_dist == 0 &&
-            current_frame->frame_type != KEY_FRAME &&
             current_frame->frame_number != 0) {
-          current_frame->frame_type = S_FRAME;
+          frame_params->frame_type = S_FRAME;
         }
       }
     }
@@ -1660,7 +1658,7 @@
   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
     av1_cyclic_refresh_update_parameters(cpi);
 
-  if (current_frame->frame_type == KEY_FRAME)
+  if (frame_params->frame_type == KEY_FRAME)
     target = calc_iframe_target_size_one_pass_vbr(cpi);
   else
     target = calc_pframe_target_size_one_pass_vbr(cpi);
@@ -1726,7 +1724,8 @@
   return av1_rc_clamp_iframe_target_size(cpi, target);
 }
 
-void av1_rc_get_one_pass_cbr_params(AV1_COMP *cpi) {
+void av1_rc_get_one_pass_cbr_params(AV1_COMP *cpi,
+                                    EncodeFrameParams *const frame_params) {
   AV1_COMMON *const cm = &cpi->common;
   RATE_CONTROL *const rc = &cpi->rc;
   CurrentFrame *const current_frame = &cm->current_frame;
@@ -1735,14 +1734,14 @@
   if ((current_frame->frame_number == 0 ||
        (cpi->frame_flags & FRAMEFLAGS_KEY) || rc->frames_to_key == 0 ||
        (cpi->oxcf.auto_key && 0))) {
-    current_frame->frame_type = KEY_FRAME;
+    frame_params->frame_type = KEY_FRAME;
     rc->this_key_frame_forced =
         current_frame->frame_number != 0 && rc->frames_to_key == 0;
     rc->frames_to_key = cpi->oxcf.key_freq;
     rc->kf_boost = DEFAULT_KF_BOOST;
     rc->source_alt_ref_active = 0;
   } else {
-    current_frame->frame_type = INTER_FRAME;
+    frame_params->frame_type = INTER_FRAME;
   }
   if (rc->frames_till_gf_update_due == 0) {
     if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
@@ -1763,7 +1762,7 @@
   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
     av1_cyclic_refresh_update_parameters(cpi);
 
-  if (current_frame->frame_type == KEY_FRAME)
+  if (frame_params->frame_type == KEY_FRAME)
     target = calc_iframe_target_size_one_pass_cbr(cpi);
   else
     target = calc_pframe_target_size_one_pass_cbr(cpi);
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 3613555..78c23cf 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -199,8 +199,11 @@
 
 // Functions to set parameters for encoding before the actual
 // encode_frame_to_data_rate() function.
-void av1_rc_get_one_pass_vbr_params(struct AV1_COMP *cpi);
-void av1_rc_get_one_pass_cbr_params(struct AV1_COMP *cpi);
+struct EncodeFrameParams;
+void av1_rc_get_one_pass_vbr_params(
+    struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
+void av1_rc_get_one_pass_cbr_params(
+    struct AV1_COMP *cpi, struct EncodeFrameParams *const frame_params);
 
 // Post encode update of the rate control parameters based
 // on bytes used