Modularize external interface flags in AV1_COMP

This CL groups together external interface flags from AV1_COMP into a
new struct ExternalFlags, adds relevant documentation and cleans up
function interfaces.

BUG=aomedia:2610

Change-Id: I2ea0631cd99276e1da73b1edb9d8816cdb5191ca
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index e701d35..e4f9bdf 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -2399,7 +2399,7 @@
                                           va_list args) {
   const int reference_flag = va_arg(args, int);
 
-  av1_use_as_reference(ctx->cpi, reference_flag);
+  av1_use_as_reference(&ctx->cpi->ext_flags.ref_frame_flags, reference_flag);
   return AOM_CODEC_OK;
 }
 
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index c202fe8..a2b5f55 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -43,6 +43,7 @@
   // NOTE(weitinglin): Should we define another function to take care of
   // cpi->rc.is_$Source_Type to make this function as it is in the comment?
 
+  const ExternalFlags *const ext_flags = &cpi->ext_flags;
   cpi->rc.is_src_frame_alt_ref = 0;
 
   switch (type) {
@@ -96,11 +97,11 @@
     default: assert(0); break;
   }
 
-  if (cpi->ext_refresh_frame_flags_pending &&
+  if (ext_flags->refresh_frame_flags_pending &&
       (!is_stat_generation_stage(cpi))) {
-    frame_params->refresh_golden_frame = cpi->ext_refresh_golden_frame;
-    frame_params->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
-    frame_params->refresh_bwd_ref_frame = cpi->ext_refresh_bwd_ref_frame;
+    frame_params->refresh_golden_frame = ext_flags->refresh_golden_frame;
+    frame_params->refresh_alt_ref_frame = ext_flags->refresh_alt_ref_frame;
+    frame_params->refresh_bwd_ref_frame = ext_flags->refresh_bwd_ref_frame;
   }
 
   if (force_refresh_all) {
@@ -136,16 +137,17 @@
   }
 }
 
-static INLINE int is_frame_droppable(const AV1_COMP *const cpi) {
+static INLINE int is_frame_droppable(const SVC *const svc,
+                                     const ExternalFlags *const ext_flags) {
   // Droppable frame is only used by external refresh flags. VoD setting won't
   // trigger its use case.
-  if (cpi->svc.external_ref_frame_config)
-    return cpi->svc.non_reference_frame;
-  else if (cpi->ext_refresh_frame_flags_pending)
-    return !(cpi->ext_refresh_alt_ref_frame ||
-             cpi->ext_refresh_alt2_ref_frame ||
-             cpi->ext_refresh_bwd_ref_frame || cpi->ext_refresh_golden_frame ||
-             cpi->ext_refresh_last_frame);
+  if (svc->external_ref_frame_config)
+    return svc->non_reference_frame;
+  else if (ext_flags->refresh_frame_flags_pending)
+    return !(ext_flags->refresh_alt_ref_frame ||
+             ext_flags->refresh_alt2_ref_frame ||
+             ext_flags->refresh_bwd_ref_frame ||
+             ext_flags->refresh_golden_frame || ext_flags->refresh_last_frame);
   else
     return 0;
 }
@@ -155,7 +157,8 @@
   // is a work-around to handle the condition when a frame is drop.
   // We should fix the cpi->common.show_frame flag
   // instead of checking the other condition to update the counter properly.
-  if (cpi->common.show_frame || is_frame_droppable(cpi)) {
+  if (cpi->common.show_frame ||
+      is_frame_droppable(&cpi->svc, &cpi->ext_flags)) {
     // Decrement count down till next gf
     if (cpi->rc.frames_till_gf_update_due > 0)
       cpi->rc.frames_till_gf_update_due--;
@@ -179,26 +182,25 @@
   update_gf_group_index(cpi);
 }
 
-static void set_ext_overrides(AV1_COMP *const cpi,
-                              EncodeFrameParams *const frame_params) {
+static void set_ext_overrides(AV1_COMMON *const cm,
+                              EncodeFrameParams *const frame_params,
+                              ExternalFlags *const ext_flags) {
   // Overrides the defaults with the externally supplied values with
   // av1_update_reference() and av1_update_entropy() calls
   // Note: The overrides are valid only for the next frame passed
   // to av1_encode_lowlevel()
 
-  AV1_COMMON *const cm = &cpi->common;
-
-  if (cpi->ext_use_s_frame) {
+  if (ext_flags->use_s_frame) {
     frame_params->frame_type = S_FRAME;
   }
 
-  if (cpi->ext_refresh_frame_context_pending) {
-    cm->features.refresh_frame_context = cpi->ext_refresh_frame_context;
-    cpi->ext_refresh_frame_context_pending = 0;
+  if (ext_flags->refresh_frame_context_pending) {
+    cm->features.refresh_frame_context = ext_flags->refresh_frame_context;
+    ext_flags->refresh_frame_context_pending = 0;
   }
-  cm->features.allow_ref_frame_mvs = cpi->ext_use_ref_frame_mvs;
+  cm->features.allow_ref_frame_mvs = ext_flags->use_ref_frame_mvs;
 
-  frame_params->error_resilient_mode = cpi->ext_use_error_resilient;
+  frame_params->error_resilient_mode = ext_flags->use_error_resilient;
   // 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.
@@ -235,7 +237,7 @@
   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->use_svc ||
-      cpi->ext_use_primary_ref_none) {
+      cpi->ext_flags.use_primary_ref_none) {
     return PRIMARY_REF_NONE;
   }
 
@@ -268,7 +270,7 @@
       get_current_frame_ref_type(cpi, frame_params);
 
   if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
-      cpi->ext_use_primary_ref_none) {
+      cpi->ext_flags.use_primary_ref_none) {
     for (int i = 0; i < REF_FRAMES; i++) {
       fb_of_context_type[i] = -1;
     }
@@ -638,7 +640,7 @@
   // expressed than converting the frame update type.
   if (frame_is_sframe(cm)) frame_update_type = KEY_FRAME;
 
-  if (is_frame_droppable(cpi)) return;
+  if (is_frame_droppable(&cpi->svc, &cpi->ext_flags)) return;
 
   switch (frame_update_type) {
     case KEY_FRAME:
@@ -725,7 +727,8 @@
                                 FRAME_UPDATE_TYPE frame_update_type,
                                 const RefBufferStack *const ref_buffer_stack) {
   const AV1_COMMON *const cm = &cpi->common;
-
+  const ExternalFlags *const ext_flags = &cpi->ext_flags;
+  const SVC *const svc = &cpi->svc;
   // Switch frames and shown key-frames overwrite all reference slots
   if ((frame_params->frame_type == KEY_FRAME && frame_params->show_frame) ||
       frame_params->frame_type == S_FRAME)
@@ -739,16 +742,15 @@
     return 0;
   }
 
-  if (is_frame_droppable(cpi)) return 0;
+  if (is_frame_droppable(svc, ext_flags)) return 0;
 
   int refresh_mask = 0;
 
-  if (cpi->ext_refresh_frame_flags_pending) {
-    if (cpi->svc.external_ref_frame_config) {
+  if (ext_flags->refresh_frame_flags_pending) {
+    if (svc->external_ref_frame_config) {
       for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
-        int ref_frame_map_idx = cpi->svc.ref_idx[i];
-        refresh_mask |= cpi->svc.refresh[ref_frame_map_idx]
-                        << ref_frame_map_idx;
+        int ref_frame_map_idx = svc->ref_idx[i];
+        refresh_mask |= svc->refresh[ref_frame_map_idx] << ref_frame_map_idx;
       }
       return refresh_mask;
     }
@@ -757,28 +759,28 @@
     // order to preserve the behaviour of the flag overrides.
     int ref_frame_map_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
     if (ref_frame_map_idx != INVALID_IDX)
-      refresh_mask |= cpi->ext_refresh_last_frame << ref_frame_map_idx;
+      refresh_mask |= ext_flags->refresh_last_frame << ref_frame_map_idx;
 
     ref_frame_map_idx = get_ref_frame_map_idx(cm, EXTREF_FRAME);
     if (ref_frame_map_idx != INVALID_IDX)
-      refresh_mask |= cpi->ext_refresh_bwd_ref_frame << ref_frame_map_idx;
+      refresh_mask |= ext_flags->refresh_bwd_ref_frame << ref_frame_map_idx;
 
     ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF2_FRAME);
     if (ref_frame_map_idx != INVALID_IDX)
-      refresh_mask |= cpi->ext_refresh_alt2_ref_frame << ref_frame_map_idx;
+      refresh_mask |= ext_flags->refresh_alt2_ref_frame << ref_frame_map_idx;
 
     if (frame_update_type == OVERLAY_UPDATE) {
       ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
       if (ref_frame_map_idx != INVALID_IDX)
-        refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
+        refresh_mask |= ext_flags->refresh_golden_frame << ref_frame_map_idx;
     } else {
       ref_frame_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
       if (ref_frame_map_idx != INVALID_IDX)
-        refresh_mask |= cpi->ext_refresh_golden_frame << ref_frame_map_idx;
+        refresh_mask |= ext_flags->refresh_golden_frame << ref_frame_map_idx;
 
       ref_frame_map_idx = get_ref_frame_map_idx(cm, ALTREF_FRAME);
       if (ref_frame_map_idx != INVALID_IDX)
-        refresh_mask |= cpi->ext_refresh_alt_ref_frame << ref_frame_map_idx;
+        refresh_mask |= ext_flags->refresh_alt_ref_frame << ref_frame_map_idx;
     }
     return refresh_mask;
   }
@@ -1047,6 +1049,7 @@
   const AV1EncoderConfig *const oxcf = &cpi->oxcf;
   AV1_COMMON *const cm = &cpi->common;
   GF_GROUP *gf_group = &cpi->gf_group;
+  ExternalFlags *const ext_flags = &cpi->ext_flags;
 
   EncodeFrameInput frame_input;
   EncodeFrameParams frame_params;
@@ -1196,7 +1199,8 @@
 #endif
   }
 
-  if (!is_stat_generation_stage(cpi)) set_ext_overrides(cpi, &frame_params);
+  if (!is_stat_generation_stage(cpi))
+    set_ext_overrides(cm, &frame_params, ext_flags);
 
   // Shown keyframes and S frames refresh all reference buffers
   const int force_refresh_all =
@@ -1211,7 +1215,7 @@
     const RefCntBuffer *ref_frames[INTER_REFS_PER_FRAME];
     const YV12_BUFFER_CONFIG *ref_frame_buf[INTER_REFS_PER_FRAME];
 
-    if (!cpi->ext_refresh_frame_flags_pending) {
+    if (!ext_flags->refresh_frame_flags_pending) {
       av1_get_ref_frames(cpi, &cpi->ref_buffer_stack);
     } else if (cpi->svc.external_ref_frame_config) {
       for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++)
@@ -1224,7 +1228,8 @@
       ref_frame_buf[i] = ref_frames[i] != NULL ? &ref_frames[i]->buf : NULL;
     }
     // Work out which reference frame slots may be used.
-    frame_params.ref_frame_flags = get_ref_frame_flags(cpi, ref_frame_buf);
+    frame_params.ref_frame_flags = get_ref_frame_flags(
+        &cpi->sf, ref_frame_buf, ext_flags->ref_frame_flags);
 
     frame_params.primary_ref_frame =
         choose_primary_ref_frame(cpi, &frame_params);
@@ -1286,7 +1291,7 @@
     // First pass doesn't modify reference buffer assignment or produce frame
     // flags
     update_frame_flags(cpi, frame_flags);
-    if (!cpi->ext_refresh_frame_flags_pending) {
+    if (!ext_flags->refresh_frame_flags_pending) {
       int ref_map_index =
           av1_get_refresh_ref_frame_map(cm->current_frame.refresh_frame_flags);
       av1_update_ref_frame_map(cpi, frame_update_type, cm->show_existing_frame,
@@ -1319,7 +1324,7 @@
 
   // Leave a signal for a higher level caller about if this frame is droppable
   if (*size > 0) {
-    cpi->droppable = is_frame_droppable(cpi);
+    cpi->droppable = is_frame_droppable(&cpi->svc, ext_flags);
   }
 
   if (cpi->use_svc) av1_save_layer_context(cpi);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 32e552f..93eefca 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -615,7 +615,7 @@
   // context 1 for ALTREF frames and context 0 for the others.
 
   if (frame_is_intra_only(cm) || cm->features.error_resilient_mode ||
-      cpi->ext_use_primary_ref_none) {
+      cpi->ext_flags.use_primary_ref_none) {
     av1_setup_past_independence(cm);
   }
 
@@ -2951,8 +2951,8 @@
   set_tile_info(cpi);
 
   if (!cpi->svc.external_ref_frame_config)
-    cpi->ext_refresh_frame_flags_pending = 0;
-  cpi->ext_refresh_frame_context_pending = 0;
+    cpi->ext_flags.refresh_frame_flags_pending = 0;
+  cpi->ext_flags.refresh_frame_context_pending = 0;
 
 #if CONFIG_AV1_HIGHBITDEPTH
   highbd_set_var_fns(cpi);
@@ -3701,10 +3701,10 @@
   aom_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
 }
 
-int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags) {
+int av1_use_as_reference(int *ext_ref_frame_flags, int ref_frame_flags) {
   if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
 
-  cpi->ext_ref_frame_flags = ref_frame_flags;
+  *ext_ref_frame_flags = ref_frame_flags;
   return 0;
 }
 
@@ -3732,9 +3732,10 @@
   }
 }
 
-int av1_update_entropy(AV1_COMP *cpi, int update) {
-  cpi->ext_refresh_frame_context = update;
-  cpi->ext_refresh_frame_context_pending = 1;
+int av1_update_entropy(bool *ext_refresh_frame_context,
+                       bool *ext_refresh_frame_context_pending, bool update) {
+  *ext_refresh_frame_context = update;
+  *ext_refresh_frame_context_pending = 1;
   return 0;
 }
 
@@ -7026,17 +7027,18 @@
   return AOM_CODEC_OK;
 }
 
-static void svc_set_updates_external_ref_frame_config(AV1_COMP *cpi) {
-  cpi->ext_refresh_frame_flags_pending = 1;
-  cpi->ext_refresh_last_frame = cpi->svc.refresh[cpi->svc.ref_idx[0]];
-  cpi->ext_refresh_golden_frame = cpi->svc.refresh[cpi->svc.ref_idx[3]];
-  cpi->ext_refresh_bwd_ref_frame = cpi->svc.refresh[cpi->svc.ref_idx[4]];
-  cpi->ext_refresh_alt2_ref_frame = cpi->svc.refresh[cpi->svc.ref_idx[5]];
-  cpi->ext_refresh_alt_ref_frame = cpi->svc.refresh[cpi->svc.ref_idx[6]];
-  cpi->svc.non_reference_frame = 1;
+static void svc_set_updates_external_ref_frame_config(
+    ExternalFlags *const ext_flags, SVC *const svc) {
+  ext_flags->refresh_frame_flags_pending = 1;
+  ext_flags->refresh_last_frame = svc->refresh[svc->ref_idx[0]];
+  ext_flags->refresh_golden_frame = svc->refresh[svc->ref_idx[3]];
+  ext_flags->refresh_bwd_ref_frame = svc->refresh[svc->ref_idx[4]];
+  ext_flags->refresh_alt2_ref_frame = svc->refresh[svc->ref_idx[5]];
+  ext_flags->refresh_alt_ref_frame = svc->refresh[svc->ref_idx[6]];
+  svc->non_reference_frame = 1;
   for (int i = 0; i < REF_FRAMES; i++) {
-    if (cpi->svc.refresh[i] == 1) {
-      cpi->svc.non_reference_frame = 0;
+    if (svc->refresh[i] == 1) {
+      svc->non_reference_frame = 0;
       break;
     }
   }
@@ -7058,7 +7060,9 @@
   // ensure that there is not conflict between the two. In AV1 encoder, the
   // priority rank for 7 reference frames are: LAST, ALTREF, LAST2, LAST3,
   // GOLDEN, BWDREF, ALTREF2.
-  cpi->ext_ref_frame_flags = AOM_REFFRAME_ALL;
+
+  ExternalFlags *const ext_flags = &cpi->ext_flags;
+  ext_flags->ref_frame_flags = AOM_REFFRAME_ALL;
   if (flags &
       (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_LAST2 | AOM_EFLAG_NO_REF_LAST3 |
        AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF | AOM_EFLAG_NO_REF_BWD |
@@ -7080,11 +7084,11 @@
       if (flags & AOM_EFLAG_NO_REF_ARF2) ref ^= AOM_ALT2_FLAG;
     }
 
-    av1_use_as_reference(cpi, ref);
+    av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
   } else {
     if (cpi->svc.external_ref_frame_config) {
       int ref = svc_set_references_external_ref_frame_config(cpi);
-      av1_use_as_reference(cpi, ref);
+      av1_use_as_reference(&ext_flags->ref_frame_flags, ref);
     }
   }
 
@@ -7103,29 +7107,31 @@
       upd ^= AOM_ALT2_FLAG;
     }
 
-    cpi->ext_refresh_last_frame = (upd & AOM_LAST_FLAG) != 0;
-    cpi->ext_refresh_golden_frame = (upd & AOM_GOLD_FLAG) != 0;
-    cpi->ext_refresh_alt_ref_frame = (upd & AOM_ALT_FLAG) != 0;
-    cpi->ext_refresh_bwd_ref_frame = (upd & AOM_BWD_FLAG) != 0;
-    cpi->ext_refresh_alt2_ref_frame = (upd & AOM_ALT2_FLAG) != 0;
-    cpi->ext_refresh_frame_flags_pending = 1;
+    ext_flags->refresh_last_frame = (upd & AOM_LAST_FLAG) != 0;
+    ext_flags->refresh_golden_frame = (upd & AOM_GOLD_FLAG) != 0;
+    ext_flags->refresh_alt_ref_frame = (upd & AOM_ALT_FLAG) != 0;
+    ext_flags->refresh_bwd_ref_frame = (upd & AOM_BWD_FLAG) != 0;
+    ext_flags->refresh_alt2_ref_frame = (upd & AOM_ALT2_FLAG) != 0;
+    ext_flags->refresh_frame_flags_pending = 1;
   } else {
     if (cpi->svc.external_ref_frame_config)
-      svc_set_updates_external_ref_frame_config(cpi);
+      svc_set_updates_external_ref_frame_config(ext_flags, &cpi->svc);
     else
-      cpi->ext_refresh_frame_flags_pending = 0;
+      ext_flags->refresh_frame_flags_pending = 0;
   }
 
-  cpi->ext_use_ref_frame_mvs = cpi->oxcf.allow_ref_frame_mvs &
-                               ((flags & AOM_EFLAG_NO_REF_FRAME_MVS) == 0);
-  cpi->ext_use_error_resilient = cpi->oxcf.error_resilient_mode |
-                                 ((flags & AOM_EFLAG_ERROR_RESILIENT) != 0);
-  cpi->ext_use_s_frame =
+  ext_flags->use_ref_frame_mvs = cpi->oxcf.allow_ref_frame_mvs &
+                                 ((flags & AOM_EFLAG_NO_REF_FRAME_MVS) == 0);
+  ext_flags->use_error_resilient = cpi->oxcf.error_resilient_mode |
+                                   ((flags & AOM_EFLAG_ERROR_RESILIENT) != 0);
+  ext_flags->use_s_frame =
       cpi->oxcf.s_frame_mode | ((flags & AOM_EFLAG_SET_S_FRAME) != 0);
-  cpi->ext_use_primary_ref_none = (flags & AOM_EFLAG_SET_PRIMARY_REF_NONE) != 0;
+  ext_flags->use_primary_ref_none =
+      (flags & AOM_EFLAG_SET_PRIMARY_REF_NONE) != 0;
 
   if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
-    av1_update_entropy(cpi, 0);
+    av1_update_entropy(&ext_flags->refresh_frame_context,
+                       &ext_flags->refresh_frame_context_pending, 0);
   }
 }
 
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 0de8b2b..4a3cb4f 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -958,6 +958,43 @@
 } WinnerModeParams;
 
 typedef struct {
+  // Bit mask to disable certain reference frame types.
+  int ref_frame_flags;
+
+  // Flags to determine which reference buffers are refreshed by this frame.
+  // When set, the encoder will update the particular reference frame buffer
+  // with the contents of the current frame.
+  bool refresh_last_frame;
+  bool refresh_golden_frame;
+  bool refresh_bwd_ref_frame;
+  bool refresh_alt2_ref_frame;
+  bool refresh_alt_ref_frame;
+
+  // Flag to indicate that updation of refresh frame flags from external
+  // interface is pending.
+  bool refresh_frame_flags_pending;
+
+  // Flag to enable the updation of frame contexts at the end of a frame decode.
+  bool refresh_frame_context;
+
+  // Flag to indicate that updation of refresh_frame_context from external
+  // interface is pending.
+  bool refresh_frame_context_pending;
+
+  // Flag to enable temporal MV prediction.
+  bool use_ref_frame_mvs;
+
+  // Flag to code the frame as error-resilient.
+  bool use_error_resilient;
+
+  // Flag to code the frame as s-frame.
+  bool use_s_frame;
+
+  // Flag to set the frame's primary_ref_frame to PRIMARY_REF_NONE.
+  bool use_primary_ref_none;
+} ExternalFlags;
+
+typedef struct {
   int arf_stack[FRAME_BUFFERS];
   int arf_stack_size;
   int lst_stack[FRAME_BUFFERS];
@@ -1071,19 +1108,8 @@
   // frame of the same type as the current frame).
   int fb_of_context_type[REF_FRAMES];
 
-  int ext_refresh_frame_flags_pending;
-  int ext_refresh_last_frame;
-  int ext_refresh_golden_frame;
-  int ext_refresh_bwd_ref_frame;
-  int ext_refresh_alt2_ref_frame;
-  int ext_refresh_alt_ref_frame;
-
-  int ext_refresh_frame_context_pending;
-  int ext_refresh_frame_context;
-  int ext_use_ref_frame_mvs;
-  int ext_use_error_resilient;
-  int ext_use_s_frame;
-  int ext_use_primary_ref_none;
+  // Flags signalled by the external interface at frame level.
+  ExternalFlags ext_flags;
 
   YV12_BUFFER_CONFIG last_frame_uf;
   YV12_BUFFER_CONFIG trial_frame_rst;
@@ -1110,7 +1136,6 @@
   struct aom_codec_pkt_list *output_pkt_list;
 
   int ref_frame_flags;
-  int ext_ref_frame_flags;
 
   // speed is passed as a per-frame parameter into the encoder
   int speed;
@@ -1396,7 +1421,7 @@
                                        YV12_BUFFER_CONFIG *new_frame,
                                        YV12_BUFFER_CONFIG *sd);
 
-int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags);
+int av1_use_as_reference(int *ext_ref_frame_flags, int ref_frame_flags);
 
 int av1_copy_reference_enc(AV1_COMP *cpi, int idx, YV12_BUFFER_CONFIG *sd);
 
@@ -1406,7 +1431,8 @@
 
 void av1_set_frame_size(AV1_COMP *cpi, int width, int height);
 
-int av1_update_entropy(AV1_COMP *cpi, int update);
+int av1_update_entropy(bool *ext_refresh_frame_context,
+                       bool *ext_refresh_frame_context_pending, bool update);
 
 int av1_set_active_map(AV1_COMP *cpi, unsigned char *map, int rows, int cols);
 
@@ -1731,22 +1757,23 @@
       ALTREF2_FRAME, LAST2_FRAME,  LAST3_FRAME,
     };
 
-static INLINE int get_ref_frame_flags(const AV1_COMP *const cpi,
-                                      const YV12_BUFFER_CONFIG **ref_frames) {
-  // cpi->ext_ref_frame_flags allows certain reference types to be disabled
-  // by the external interface.  These are set by av1_apply_encoding_flags().
-  // Start with what the external interface allows, then suppress any reference
-  // types which we have found to be duplicates.
-  int flags = cpi->ext_ref_frame_flags;
+static INLINE int get_ref_frame_flags(const SPEED_FEATURES *const sf,
+                                      const YV12_BUFFER_CONFIG **ref_frames,
+                                      const int ext_ref_frame_flags) {
+  // cpi->ext_flags.ref_frame_flags allows certain reference types to be
+  // disabled by the external interface.  These are set by
+  // av1_apply_encoding_flags(). Start with what the external interface allows,
+  // then suppress any reference types which we have found to be duplicates.
+  int flags = ext_ref_frame_flags;
 
   for (int i = 1; i < INTER_REFS_PER_FRAME; ++i) {
     const YV12_BUFFER_CONFIG *const this_ref = ref_frames[i];
     // If this_ref has appeared before, mark the corresponding ref frame as
     // invalid. For nonrd mode, only disable GOLDEN_FRAME if it's the same
     // as LAST_FRAME or ALTREF_FRAME (if ALTREF is being used in nonrd).
-    int index = (cpi->sf.rt_sf.use_nonrd_pick_mode &&
+    int index = (sf->rt_sf.use_nonrd_pick_mode &&
                  ref_frame_priority_order[i] == GOLDEN_FRAME)
-                    ? (1 + cpi->sf.rt_sf.use_nonrd_altref_frame)
+                    ? (1 + sf->rt_sf.use_nonrd_altref_frame)
                     : i;
     for (int j = 0; j < index; ++j) {
       if (this_ref == ref_frames[j]) {
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 144d9e0..eec48bd 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1957,6 +1957,8 @@
 
 static void set_reference_structure_one_pass_rt(AV1_COMP *cpi, int gf_update) {
   AV1_COMMON *const cm = &cpi->common;
+  ExternalFlags *const ext_flags = &cpi->ext_flags;
+  SVC *const svc = &cpi->svc;
   // Specify the reference prediction structure, for 1 layer nonrd mode.
   // Current structue is to use 3 references (LAST, GOLDEN, ALTREF),
   // where ALT_REF always behind current by lag_alt frames, and GOLDEN is
@@ -1968,18 +1970,18 @@
   int last_idx_refresh = 0;
   int gld_idx = 0;
   int alt_ref_idx = 0;
-  cpi->ext_refresh_frame_flags_pending = 1;
-  cpi->svc.external_ref_frame_config = 1;
-  cpi->ext_ref_frame_flags = 0;
-  cpi->ext_refresh_last_frame = 1;
-  cpi->ext_refresh_golden_frame = 0;
-  cpi->ext_refresh_alt_ref_frame = 0;
-  for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) cpi->svc.ref_idx[i] = 7;
-  for (int i = 0; i < REF_FRAMES; ++i) cpi->svc.refresh[i] = 0;
+  ext_flags->refresh_frame_flags_pending = 1;
+  svc->external_ref_frame_config = 1;
+  ext_flags->ref_frame_flags = 0;
+  ext_flags->refresh_last_frame = 1;
+  ext_flags->refresh_golden_frame = 0;
+  ext_flags->refresh_alt_ref_frame = 0;
+  for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) svc->ref_idx[i] = 7;
+  for (int i = 0; i < REF_FRAMES; ++i) svc->refresh[i] = 0;
   // Always reference LAST, GOLDEN, ALTREF
-  cpi->ext_ref_frame_flags ^= AOM_LAST_FLAG;
-  cpi->ext_ref_frame_flags ^= AOM_GOLD_FLAG;
-  cpi->ext_ref_frame_flags ^= AOM_ALT_FLAG;
+  ext_flags->ref_frame_flags ^= AOM_LAST_FLAG;
+  ext_flags->ref_frame_flags ^= AOM_GOLD_FLAG;
+  ext_flags->ref_frame_flags ^= AOM_ALT_FLAG;
   const int sh = 7 - gld_fixed_slot;
   // Moving index slot for last: 0 - (sh - 1).
   if (cm->current_frame.frame_number > 1)
@@ -1997,16 +1999,16 @@
   // Moving index for alt_ref, lag behind LAST by lag_alt frames.
   if (cm->current_frame.frame_number > lag_alt)
     alt_ref_idx = ((cm->current_frame.frame_number - lag_alt) % sh);
-  cpi->svc.ref_idx[0] = last_idx;          // LAST
-  cpi->svc.ref_idx[1] = last_idx_refresh;  // LAST2 (for refresh of last).
-  cpi->svc.ref_idx[3] = gld_idx;           // GOLDEN
-  cpi->svc.ref_idx[6] = alt_ref_idx;       // ALT_REF
+  svc->ref_idx[0] = last_idx;          // LAST
+  svc->ref_idx[1] = last_idx_refresh;  // LAST2 (for refresh of last).
+  svc->ref_idx[3] = gld_idx;           // GOLDEN
+  svc->ref_idx[6] = alt_ref_idx;       // ALT_REF
   // Refresh this slot, which will become LAST on next frame.
-  cpi->svc.refresh[last_idx_refresh] = 1;
+  svc->refresh[last_idx_refresh] = 1;
   // Update GOLDEN on period for fixed slot case.
   if (gld_fixed_slot && gf_update) {
-    cpi->ext_refresh_golden_frame = 1;
-    cpi->svc.refresh[gld_idx] = 1;
+    ext_flags->refresh_golden_frame = 1;
+    svc->refresh[gld_idx] = 1;
   }
 }
 
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index af192f6..1736750 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -715,7 +715,8 @@
   }
 
   // Work out which reference frame slots may be used.
-  ref_frame_flags = get_ref_frame_flags(cpi, ref_frames_ordered);
+  ref_frame_flags = get_ref_frame_flags(&cpi->sf, ref_frames_ordered,
+                                        cpi->ext_flags.ref_frame_flags);
 
   enforce_max_ref_frames(cpi, &ref_frame_flags);