/*
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
 *
 * This source code is subject to the terms of the BSD 3-Clause Clear License
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
 * License was not distributed with this source code in the LICENSE file, you
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
 * Alliance for Open Media Patent License 1.0 was not distributed with this
 * source code in the PATENTS file, you can obtain it at
 * aomedia.org/license/patent-license/.
 */

#include <stdint.h>

#include "config/avm_config.h"
#include "config/avm_scale_rtcd.h"

#include "avm/avm_codec.h"
#include "avm/avm_encoder.h"

#include "avm_ports/system_state.h"

#if CONFIG_MISMATCH_DEBUG
#include "avm_util/debug_util.h"
#endif  // CONFIG_MISMATCH_DEBUG

#include "av2/common/av2_common_int.h"
#include "av2/common/bru.h"
#include "av2/common/reconinter.h"

#include "av2/encoder/encoder.h"
#include "av2/encoder/encode_strategy.h"
#include "av2/encoder/encodeframe.h"
#include "av2/encoder/firstpass.h"
#include "av2/encoder/gop_structure.h"
#include "av2/encoder/pass2_strategy.h"
#include "av2/encoder/temporal_filter.h"
#include "av2/encoder/tpl_model.h"
#include "av2/encoder/encoder_utils.h"

#if CONFIG_TUNE_VMAF
#include "av2/encoder/tune_vmaf.h"
#endif

// Get the subgop config corresponding to the current frame within the
// gf group
const SubGOPStepCfg *get_subgop_step(const GF_GROUP *const gf_group,
                                     int index) {
  const SubGOPCfg *subgop_cfg = gf_group->subgop_cfg;
  if (subgop_cfg == NULL) return NULL;
  const int is_first_gop = (gf_group->update_type[0] == KF_UPDATE);
  const int offset =
      gf_group->has_overlay_for_key_frame ? 2 : (is_first_gop ? 1 : 0);
  return &subgop_cfg->step[index - offset];
}

void av2_get_ref_frames_enc(AV2_COMP *const cpi, int cur_frame_disp,
                            RefFrameMapPair *ref_frame_map_pairs) {
  AV2_COMMON *const cm = &cpi->common;
  assert(cm->seq_params.enable_explicit_ref_frame_map || frame_is_sframe(cm));
  // With explicit_ref_frame_map or switch_frame_mode on, an encoder-only
  // ranking scheme can be implemented here. For now, av2_get_ref_frames is used
  // as a placeholder.
  // Do a dry run to obtain variables in resolution independent reference
  // mapping that will be used in write_frame_size_with_refs
  if (cpi->switch_frame_mode == 1) {
    av2_get_ref_frames(cm, cur_frame_disp, 0, 1, ref_frame_map_pairs);
    av2_get_ref_frames(cm, cur_frame_disp, 1, 1, ref_frame_map_pairs);
  } else {
    av2_get_ref_frames(cm, cur_frame_disp, 0, 0, ref_frame_map_pairs);
    av2_get_ref_frames(cm, cur_frame_disp, 1, 0, ref_frame_map_pairs);
  }

  // if BRU ref frame is not in the top n_refs list, swap bru ref to the last of
  // top_n
  enc_bru_swap_ref(cm);
}

void av2_set_seq_seg_info(SequenceHeader *seq_params,
                          struct segmentation *seg) {
  SegmentationInfoSyntax *seg_params = &seq_params->seg_params;
  seg_params->allow_seg_info_change = 1;
  const int max_seg_num = seg->enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8;
  for (int i = 0; i < max_seg_num; i++) {
    seg_params->feature_mask[i] = seg->feature_mask[i];
    for (int j = 0; j < SEG_LVL_MAX; j++) {
      seg_params->feature_data[i][j] = seg->feature_data[i][j];
    }
  }
  seg_params->segid_preskip = seg->segid_preskip;
  seg_params->last_active_segid = seg->last_active_segid;
  seg_params->enable_ext_seg = seq_params->enable_ext_seg;
}

void av2_configure_buffer_updates(AV2_COMP *const cpi,
                                  const FRAME_UPDATE_TYPE type) {
  // 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?

  cpi->rc.is_src_frame_alt_ref = 0;

  switch (type) {
    case OVERLAY_UPDATE:
    case KFFLT_OVERLAY_UPDATE:
    case INTNL_OVERLAY_UPDATE: cpi->rc.is_src_frame_alt_ref = 1; break;

    case KF_UPDATE:
    case LF_UPDATE:
    case GF_UPDATE:
    case ARF_UPDATE:
    case KFFLT_UPDATE:
    case INTNL_ARF_UPDATE: break;

    default: assert(0); break;
  }
}

static void set_additional_frame_flags(const AV2_COMMON *const cm,
                                       unsigned int *const frame_flags) {
  if (frame_is_intra_only(cm)) {
    *frame_flags |= FRAMEFLAGS_INTRAONLY;
  }
  if (frame_is_sframe(cm) && !cm->restricted_prediction_switch) {
    *frame_flags |= FRAMEFLAGS_SWITCH;
  }
  if (cm->film_grain_params.apply_grain) {
    *frame_flags |= FRAMEFLAGS_HAS_FILM_GRAIN_PARAMS;
  }
}

static INLINE void update_keyframe_counters(AV2_COMP *cpi) {
  if (cpi->common.immediate_output_picture) {
    cpi->rc.frames_since_key++;
    cpi->rc.frames_to_key--;
  }
}

static INLINE int is_frame_droppable(
    const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags) {
  // Droppable frame is only used by external refresh flags. VoD setting won't
  // trigger its use case.
  if (ext_refresh_frame_flags->update_pending)
    return ext_refresh_frame_flags->all_ref_frames == 0;
  else
    return 0;
}

static INLINE void update_frames_till_gf_update(AV2_COMP *cpi) {
  // TODO(weitinglin): Updating this counter for is_frame_droppable
  // is a work-around to handle the condition when a frame is drop.
  // We should fix the cpi->common.immediate_output_picture flag
  // instead of checking the other condition to update the counter properly.
  if (cpi->common.immediate_output_picture ||
      is_frame_droppable(&cpi->ext_flags.refresh_frame)) {
    // Decrement count down till next gf
    if (cpi->rc.frames_till_gf_update_due > 0)
      cpi->rc.frames_till_gf_update_due--;
  }
}

static INLINE void update_gf_group_index(AV2_COMP *cpi) {
  // Increment the gf group index ready for the next frame. If this is
  // a show_existing_frame with a source other than altref, or if it is not
  // a displayed forward keyframe, the index was incremented when it was
  // originally encoded.
  if (!cpi->oxcf.unit_test_cfg.multi_layers_lag_test ||
      cpi->common.number_mlayers == 1) {
    ++cpi->gf_group.index;
  } else {
    // To be updated based on the (multi_layers) tests for nonzero lag.
    // The current test is for fixed GOP with keyframe_filtering off.
    GF_GROUP *const gf_group = &cpi->gf_group;
    if (gf_group->update_type[cpi->gf_group.index] == ARF_UPDATE ||
        gf_group->update_type[cpi->gf_group.index] == INTNL_ARF_UPDATE ||
        gf_group->update_type[cpi->gf_group.index] == KFFLT_UPDATE) {
      ++gf_group->index;
      if (cpi->common.mlayer_id == 0) gf_group->arf_update_counter++;
    } else if (cpi->common.mlayer_id == 0 && cpi->gf_group.index > 0 &&
               gf_group->update_type[cpi->gf_group.index] == LF_UPDATE &&
               (gf_group->update_type[cpi->gf_group.index - 1] == ARF_UPDATE ||
                gf_group->update_type[cpi->gf_group.index - 1] ==
                    INTNL_ARF_UPDATE ||
                gf_group->update_type[cpi->gf_group.index - 1] ==
                    OVERLAY_UPDATE ||
                gf_group->update_type[cpi->gf_group.index - 1] ==
                    INTNL_OVERLAY_UPDATE ||
                gf_group->update_type[cpi->gf_group.index - 1] ==
                    KFFLT_OVERLAY_UPDATE)) {
      // This willl force the next encode_call to encode ARFs followed by LF
      // at the next ml layer.
      gf_group->index = gf_group->index - gf_group->arf_update_counter;
      gf_group->arf_update_counter = 0;
    } else if ((unsigned int)cpi->common.mlayer_id ==
               cpi->common.number_mlayers - 1) {
      // Every regular frame is encoded with same source up to number_mlayers.
      ++gf_group->index;
    }
  }
}

static void update_rc_counts(AV2_COMP *cpi) {
  update_keyframe_counters(cpi);
  update_frames_till_gf_update(cpi);
  update_gf_group_index(cpi);
}

static void set_ext_overrides(AV2_COMMON *const cm,
                              EncodeFrameParams *const frame_params,
                              ExternalFlags *const ext_flags) {
  // Overrides the defaults with the externally supplied values with
  // av2_update_reference() and av2_update_entropy() calls
  // Note: The overrides are valid only for the next frame passed
  // to av2_encode_lowlevel()

  if (ext_flags->use_s_frame) {
    frame_params->frame_type = S_FRAME;
  }

  cm->features.allow_ref_frame_mvs = ext_flags->use_ref_frame_mvs;
}

// Map the subgop cfg reference list to actual reference buffers. Disable
// any reference frames that are not listed in the sub gop.
static void get_gop_cfg_enabled_refs(AV2_COMP *const cpi, int *ref_frame_flags,
                                     int order_offset) {
  GF_GROUP gf_group = cpi->gf_group;
  // The current display index stored has not yet been updated. We must add
  // The order offset to get the correct value here.
  const int cur_frame_disp =
      cpi->common.current_frame.frame_number + order_offset;

  const SubGOPStepCfg *step_gop_cfg =
      get_subgop_step(&gf_group, gf_group.index);
  assert(step_gop_cfg != NULL);
  // No references specified
  if (step_gop_cfg->num_references < 0) return;

  // Mask to indicate whether or not each ref is allowed by the GOP config
  int ref_frame_used[INTER_REFS_PER_FRAME] = { 0 };
  // Structures to hash each reference frame based on its pyramid level. This
  // will allow us to match the pyramid levels specified in the cfg to the best
  // reference frame index.
  int n_references[MAX_ARF_LAYERS + 1] = { 0 };
  int references[MAX_ARF_LAYERS + 1][INTER_REFS_PER_FRAME] = { { 0 } };
  int disp_orders[MAX_ARF_LAYERS + 1][INTER_REFS_PER_FRAME] = { { 0 } };

  int frame_level = -1;
  // Loop over each reference frame and hash it based on its pyramid level
  for (int frame = 0; frame < INTER_REFS_PER_FRAME; frame++) {
    // Get reference frame buffer
    const RefCntBuffer *const buf = get_ref_frame_buf(&cpi->common, frame);
    if (buf == NULL) continue;
    if (buf->is_restricted) continue;
    const int frame_order = (int)buf->display_order_hint;
    frame_level = buf->pyramid_level;

    // Sometimes a frame index is in multiple reference buffers.
    // Do not add a frame to the pyramid list multiple times.
    int found = 0;
    for (int r = 0; r < n_references[frame_level]; r++) {
      if (frame_order == disp_orders[frame_level][r]) {
        found = 1;
        break;
      }
    }
    // If this is an unseen frame, map its display order and ref buffer
    // index to its level in the pyramid
    if (!found) {
      int n_refs = n_references[frame_level]++;
      disp_orders[frame_level][n_refs] = frame_order;
      references[frame_level][n_refs] = frame;
    }
  }

  // For each reference specified in the step_gop_cfg, map it to a reference
  // buffer based on pyramid level if possible.
  for (int i = 0; i < step_gop_cfg->num_references; i++) {
    const int level = step_gop_cfg->references[i];
    const int abs_level = abs(level);
    int best_frame = -1;
    int best_frame_index = -1;
    int best_disp_order = INT_MAX;
    for (int ref = 0; ref < n_references[abs_level]; ref++) {
      const int disp_order = disp_orders[abs_level][ref];
      const int cur_order_diff = cur_frame_disp - disp_order;
      // This frame has already been used
      if (disp_order < 0) continue;
      // This frame is in the wrong direction
      if ((cur_order_diff < 0) != (level < 0)) continue;
      // Store this frame if it is the closest in display order to the current
      // frame so far
      if (abs(cur_order_diff) < abs(best_disp_order - cur_frame_disp)) {
        best_frame = references[abs_level][ref];
        best_frame_index = ref;
        best_disp_order = disp_order;
      }
    }
    update_subgop_ref_stats(&cpi->subgop_stats,
                            cpi->oxcf.unit_test_cfg.enable_subgop_stats, i,
                            (best_frame < 0) ? 0 : 1, level, best_disp_order,
                            (int)step_gop_cfg->num_references);
    if (best_frame == -1) {
      if (cpi->print_per_frame_stats) {
        fprintf(stderr,
                "Warning [Subgop cfg]: "
                "Level %d ref for frame %d not found\n",
                level, step_gop_cfg->disp_frame_idx);
      }
    } else {
      ref_frame_used[best_frame] = 1;
      disp_orders[abs_level][best_frame_index] = -1;
    }
  }

  // Avoid using references that were not specified by the cfg
  for (int frame = 0; frame < INTER_REFS_PER_FRAME; frame++)
    if (!ref_frame_used[frame]) *ref_frame_flags &= ~(1 << (frame));
}

static void bru_lookahead_update(AV2_COMP *const cpi,
                                 const int bru_ref_buf_offset,
                                 struct lookahead_entry **bru_ref_source) {
  if (cpi->common.seq_params.enable_bru) {
    AV2_COMMON *const cm = &cpi->common;
    const int n_refs = cm->ref_frames_info.num_total_refs;
    if (n_refs >= BRU_ENC_LOOKAHEAD_DIST_MINUS_1 + BRU_ENC_REF_DELAY)
      *bru_ref_source = av2_lookahead_peek(cpi->lookahead, bru_ref_buf_offset,
                                           cpi->compressor_stage);
  }
}

static void init_bru_frame(AV2_COMMON *const cm) {
  // bru skip mode update ref
  if (cm->bru.enabled) {
    int bru_ref_idx = cm->bru.update_ref_idx;
    RefCntBuffer *ref_buf = get_ref_frame_buf(cm, bru_ref_idx);
    if (!ref_buf) {
      cm->bru.enabled = 0;  // disable if no valid ref
    }
    if (!cm->bru.enabled) {
      cm->bru.update_ref_idx = -1;
      cm->bru.explicit_ref_idx = -1;
    }
  }
}

static void adjust_frame_rate(AV2_COMP *cpi, int64_t ts_start, int64_t ts_end) {
  TimeStamps *time_stamps = &cpi->time_stamps;
  int64_t this_duration;
  int step = 0;

  // Clear down mmx registers
  avm_clear_system_state();

  if (ts_start == time_stamps->first_ever) {
    this_duration = ts_end - ts_start;
    step = 1;
  } else {
    int64_t last_duration =
        time_stamps->prev_end_seen - time_stamps->prev_start_seen;

    this_duration = ts_end - time_stamps->prev_end_seen;

    // do a step update if the duration changes by 10%
    if (last_duration)
      step = (int)((this_duration - last_duration) * 10 / last_duration);
  }

  if (this_duration) {
    if (step) {
      av2_new_framerate(cpi, 10000000.0 / this_duration);
    } else {
      // Average this frame's rate into the last second's average
      // frame rate. If we haven't seen 1 second yet, then average
      // over the whole interval seen.
      const double interval =
          AVMMIN((double)(ts_end - time_stamps->first_ever), 10000000.0);
      double avg_duration = 10000000.0 / cpi->framerate;
      avg_duration *= (interval - avg_duration + this_duration);
      avg_duration /= interval;

      av2_new_framerate(cpi, 10000000.0 / avg_duration);
    }
  }
  time_stamps->prev_start_seen = ts_start;
  time_stamps->prev_end_seen = ts_end;
}

// Determine whether there is a forced keyframe pending in the lookahead buffer
int get_forced_keyframe_position(struct lookahead_ctx *lookahead,
                                 const int up_to_index,
                                 const COMPRESSOR_STAGE compressor_stage) {
  /* If the forced kf is not available or if the current frame is
   * forced kf, then return -1. Else return the position of the
   * forced kf.
   */
  for (int i = 0; i <= up_to_index; i++) {
    const struct lookahead_entry *e =
        av2_lookahead_peek(lookahead, i, compressor_stage);
    if (e == NULL) {
      // We have reached the end of the lookahead buffer and not early-returned
      // so there isn't a forced key-frame pending.
      return -1;
    } else if (e->flags == AVM_EFLAG_FORCE_KF) {
      return (i > 0) ? i : -1;
    } else {
      continue;
    }
  }
  return -1;  // Never reached
}

// Check if we should encode an ARF or internal ARF.  If not, try a LAST
// Do some setup associated with the chosen source
// temporal_filtered, flush, and frame_update_type are outputs.
// Return the frame source, or NULL if we couldn't find one
static struct lookahead_entry *choose_frame_source(
    AV2_COMP *const cpi, int *const flush, struct lookahead_entry **last_source,
    int bru_ref_buf_offset, struct lookahead_entry **bru_ref_source,
    EncodeFrameParams *const frame_params) {
  AV2_COMMON *const cm = &cpi->common;
  const GF_GROUP *const gf_group = &cpi->gf_group;
  struct lookahead_entry *source = NULL;

  // Source index in lookahead buffer.
  int src_index = gf_group->arf_src_offset[gf_group->index];

  // TODO(Aasaipriya): Forced key frames need to be fixed when rc_mode != AVM_Q
  if (src_index &&
      (get_forced_keyframe_position(cpi->lookahead, src_index,
                                    cpi->compressor_stage) != -1) &&
      cpi->oxcf.rc_cfg.mode != AVM_Q) {
    src_index = 0;
    *flush = 1;
  }

  // If the current frame is arf, then we should not pop from the lookahead
  // buffer. If the current frame is not arf, then pop it. This assumes the
  // first frame in the GF group is not arf. May need to change if it is not
  // true.
  int pop_lookahead = (src_index == 0);
  // If this is a key frame and keyframe filtering is enabled with overlay,
  // then do not pop.
  if (pop_lookahead && cpi->oxcf.kf_cfg.enable_keyframe_filtering > 1 &&
      gf_group->update_type[gf_group->index] == KFFLT_UPDATE &&
      !is_stat_generation_stage(cpi) && cpi->lookahead) {
    if (cpi->lookahead->read_ctxs[cpi->compressor_stage].sz &&
        (*flush ||
         cpi->lookahead->read_ctxs[cpi->compressor_stage].sz ==
             cpi->lookahead->read_ctxs[cpi->compressor_stage].pop_sz)) {
      pop_lookahead = 0;
    }
  }
  frame_params->immediate_output_picture = pop_lookahead;
  if (pop_lookahead) {
    // show frame, pop from buffer
    // Get last frame source.
    if (cm->current_frame.frame_number > 0) {
      *last_source =
          av2_lookahead_peek(cpi->lookahead, -1, cpi->compressor_stage);
    }
    if (cpi->common.seq_params.enable_bru) {
      bru_lookahead_update(cpi, bru_ref_buf_offset, bru_ref_source);
    }
    // Read in the source frame.
    source = av2_lookahead_pop(cpi->lookahead, *flush, cpi->compressor_stage);
  } else {
    // no show frames are arf frames
    source =
        av2_lookahead_peek(cpi->lookahead, src_index, cpi->compressor_stage);
    if (source != NULL) {
      cm->allow_direct_use = 1;
      if (gf_group->update_type[gf_group->index] == KFFLT_UPDATE)
        cm->allow_direct_use = 0;

      cm->implicit_output_picture = cm->allow_direct_use;
    }
  }
  return source;
}

// Don't allow a show_existing_frame to coincide with an error resilient or
// S-Frame. An exception can be made in the case of a keyframe, since it does
// not depend on any previous frames.
static int allow_show_existing(const AV2_COMP *const cpi,
                               unsigned int frame_flags) {
  if (cpi->common.current_frame.frame_number == 0) return 0;

  const struct lookahead_entry *lookahead_src =
      av2_lookahead_peek(cpi->lookahead, 0, cpi->compressor_stage);
  if (lookahead_src == NULL) return 1;

  const int is_s_frame = cpi->oxcf.kf_cfg.enable_sframe ||
                         (lookahead_src->flags & AVM_EFLAG_SET_S_FRAME);
  const int is_key_frame =
      (cpi->rc.frames_to_key == 0) || (frame_flags & FRAMEFLAGS_KEY);
  return !is_s_frame || is_key_frame;
}

// Update frame_flags to tell the encoder's caller what sort of frame was
// encoded.
static void update_frame_flags(const AV2_COMMON *const cm,
                               unsigned int *frame_flags) {
  if (cm->current_frame.frame_type == KEY_FRAME) {
    *frame_flags |= FRAMEFLAGS_KEY;
  } else {
    *frame_flags &= ~FRAMEFLAGS_KEY;
  }
}

#define DUMP_REF_FRAME_IMAGES 0

#if DUMP_REF_FRAME_IMAGES == 1
static int dump_one_image(AV2_COMMON *cm,
                          const YV12_BUFFER_CONFIG *const ref_buf,
                          char *file_name) {
  int h;
  FILE *f_ref = NULL;

  if (ref_buf == NULL) {
    printf("Frame data buffer is NULL.\n");
    return AVM_CODEC_MEM_ERROR;
  }

  if ((f_ref = fopen(file_name, "wb")) == NULL) {
    printf("Unable to open file %s to write.\n", file_name);
    return AVM_CODEC_MEM_ERROR;
  }

  // --- Y ---
  for (h = 0; h < cm->height; ++h) {
    fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
  }
  // --- U ---
  for (h = 0; h < (cm->height >> 1); ++h) {
    fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
           f_ref);
  }
  // --- V ---
  for (h = 0; h < (cm->height >> 1); ++h) {
    fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
           f_ref);
  }

  fclose(f_ref);

  return AVM_CODEC_OK;
}

static void dump_ref_frame_images(AV2_COMP *cpi) {
  AV2_COMMON *const cm = &cpi->common;
  MV_REFERENCE_FRAME ref_frame;

  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
    char file_name[256] = "";
    snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
             cm->current_frame.frame_number, ref_frame);
    dump_one_image(cm, get_ref_frame_yv12_buf(cpi, ref_frame), file_name);
  }
}
#endif  // DUMP_REF_FRAME_IMAGES == 1

int av2_get_refresh_ref_frame_map(AV2_COMMON *cm, int refresh_frame_flags) {
  int ref_map_index = INVALID_IDX;
  for (ref_map_index = 0; ref_map_index < cm->seq_params.ref_frames;
       ++ref_map_index) {
    if ((refresh_frame_flags >> ref_map_index) & 1) break;
  }

  return ref_map_index;
}

int use_subgop_cfg(const GF_GROUP *const gf_group, int gf_index) {
  if (gf_index < 0) return 0;
  if (gf_group->subgop_cfg == NULL) return 0;
  if (gf_index == 1) return !gf_group->has_overlay_for_key_frame;
  return 1;
}

static int get_free_ref_map_index(RefFrameMapPair ref_map_pairs[REF_FRAMES],
                                  const int ref_frames) {
  for (int idx = 0; idx < ref_frames; ++idx)
    if (ref_map_pairs[idx].ref_frame_for_inference == -1) return idx;
  return INVALID_IDX;
}

static int get_refresh_idx(int update_arf, int refresh_level,
                           int cur_frame_disp, int switch_frame_mode,
                           RefFrameMapPair ref_frame_map_pairs[REF_FRAMES],
                           const int ref_frames) {
  // refresh_level = -1
  int arf_count = 0;
  int oldest_arf_order = INT32_MAX;
  int oldest_arf_idx = -1;

  int oldest_frame_order = INT32_MAX;
  int oldest_idx = -1;

  int oldest_ref_level_order = INT32_MAX;
  int oldest_ref_level_idx = -1;
  for (int map_idx = 0; map_idx < ref_frames; map_idx++) {
    RefFrameMapPair ref_pair = ref_frame_map_pairs[map_idx];
    if (ref_pair.ref_frame_for_inference == -1) continue;
    if (switch_frame_mode == 1 && ref_pair.frame_type == KEY_FRAME) continue;
    const int frame_order = ref_pair.disp_order_removed;
    const int reference_frame_level = ref_pair.pyr_level;
    // Keep future frames and three closest previous frames in output order
    if (frame_order > cur_frame_disp - 3) continue;
    // Keep track of the oldest reference frame matching the specified
    // refresh level from the subgop cfg
    if (refresh_level > 0 && refresh_level == reference_frame_level) {
      if (frame_order < oldest_ref_level_order) {
        oldest_ref_level_order = frame_order;
        oldest_ref_level_idx = map_idx;
      }
    }
    // Keep track of the oldest level 1 frame if the current frame is level also
    // 1
    if (reference_frame_level == 1) {
      // If there are more than 2 level 1 frames in the reference list,
      // discard the oldest
      if (frame_order < oldest_arf_order) {
        oldest_arf_order = frame_order;
        oldest_arf_idx = map_idx;
      }
      arf_count++;
      continue;
    }

    // Update the overall oldest reference frame
    if (frame_order < oldest_frame_order) {
      oldest_frame_order = frame_order;
      oldest_idx = map_idx;
    }
  }
  if (oldest_ref_level_idx > -1) return oldest_ref_level_idx;
  if (update_arf && arf_count > 2) return oldest_arf_idx;
  if (oldest_idx >= 0) return oldest_idx;
  if (oldest_arf_idx >= 0) return oldest_arf_idx;
  assert(0 && "No valid refresh index found");
  return -1;
}

static int get_refresh_frame_flags_subgop_cfg(
    const AV2_COMP *const cpi, int gf_index, int cur_disp_order,
    RefFrameMapPair ref_frame_map_pairs[REF_FRAMES], int refresh_mask,
    int free_fb_index) {
  const SubGOPStepCfg *step_gop_cfg = get_subgop_step(&cpi->gf_group, gf_index);
  assert(step_gop_cfg != NULL);
  const int pyr_level = step_gop_cfg->pyr_level;
  const FRAME_TYPE_CODE type_code = step_gop_cfg->type_code;
  const int refresh_level = step_gop_cfg->refresh;
  if (refresh_level == 0) return 0;

  // No refresh necessary for these frame types
  if (type_code == FRAME_TYPE_INO_REPEAT ||
      type_code == FRAME_TYPE_INO_SHOWEXISTING)
    return refresh_mask;
  // If there is an open slot, refresh that one instead of replacing a reference
  if (free_fb_index != INVALID_IDX) {
    refresh_mask = 1 << free_fb_index;
    return refresh_mask;
  }

  const int update_arf = type_code == FRAME_TYPE_OOO_FILTERED && pyr_level == 1;
  const int refresh_idx = get_refresh_idx(
      update_arf, refresh_level, cur_disp_order, cpi->switch_frame_mode,
      ref_frame_map_pairs, cpi->common.seq_params.ref_frames);
  return 1 << refresh_idx;
}

int av2_get_refresh_frame_flags(
    AV2_COMP *const cpi, const EncodeFrameParams *const frame_params,
    FRAME_UPDATE_TYPE frame_update_type, int gf_index, int cur_disp_order,
    RefFrameMapPair ref_frame_map_pairs[REF_FRAMES]) {
  if (cpi->switch_frame_mode == 1) {
    AV2_COMMON *const cm = &cpi->common;
    int refresh_frame_flags = (1 << cpi->common.seq_params.ref_frames) - 1;
    cm->num_ref_key_frames = 0;
    for (int i = 0; i < cm->seq_params.ref_frames; i++) {
      if (cm->ref_frame_map[i]->long_term_id >= 0) {
        int new_long_term_id = 1;
        refresh_frame_flags &= ~(1 << i);
        for (int j = 0; j < cm->num_ref_key_frames; j++) {
          if (cm->ref_frame_map[i]->long_term_id == cm->ref_long_term_ids[j])
            new_long_term_id = 0;
        }
        if (new_long_term_id) {
          cm->ref_long_term_ids[cm->num_ref_key_frames] =
              cm->ref_frame_map[i]->long_term_id;
          cm->num_ref_key_frames++;
        }
      }
    }
    return refresh_frame_flags;
  }

  // Switch frames and shown key-frames overwrite all reference slots
  if ((av2_is_shown_keyframe(cpi, frame_params->frame_type) &&
       cpi->common.seq_params.max_mlayer_id == 0) ||
      (cpi->oxcf.kf_cfg.sframe_mode != 0 &&
       frame_params->frame_type == S_FRAME)) {
    return (1 << cpi->common.seq_params.ref_frames) - 1;
  }

  if (frame_params->duplicate_existing_frame) {
    return 0;
  }

  const int refresh_mask = 0;
  const ExtRefreshFrameFlagsInfo *const ext_refresh_frame_flags =
      &cpi->ext_flags.refresh_frame;

  if (is_frame_droppable(ext_refresh_frame_flags)) return 0;

  if (ext_refresh_frame_flags->update_pending) {
    return refresh_mask;
  }

  if (cpi->oxcf.unit_test_cfg.use_buffer_refresh_multi_layers_test) {
    // This logic is currently only used with the control
    // AV2E_SET_ENABLE_BUFFER_REFRESH_TEST.
    int refresh_mask_control = 0;
    for (int i = 0; i < cpi->common.seq_params.ref_frames; i++) {
      refresh_mask_control |=
          cpi->oxcf.unit_test_cfg.buffer_refresh_multi_layers_test[i] << i;
    }
    return refresh_mask_control;
  }

  // BRU frame, refresh flag is set to refresh BRU ref frame
  int free_fb_index = INVALID_IDX;
  if (cpi->common.bru.enabled) {
    const int bru_disp_order = cpi->common.bru.ref_disp_order;
    assert(bru_disp_order >= 0);
    for (int idx = 0; idx < cpi->common.seq_params.ref_frames; ++idx) {
      if (ref_frame_map_pairs[idx].disp_order == bru_disp_order) {
        free_fb_index = idx;  // get the first one
        break;
      }
    }
  } else {
    free_fb_index = get_free_ref_map_index(ref_frame_map_pairs,
                                           cpi->common.seq_params.ref_frames);
  }
  if (use_subgop_cfg(&cpi->gf_group, gf_index)) {
    const int mask = get_refresh_frame_flags_subgop_cfg(
        cpi, gf_index, cur_disp_order, ref_frame_map_pairs, refresh_mask,
        free_fb_index);
    return mask;
  }
  // No refresh necessary for these frame types
  if (frame_update_type == OVERLAY_UPDATE ||
      frame_update_type == KFFLT_OVERLAY_UPDATE ||
      frame_update_type == INTNL_OVERLAY_UPDATE) {
    return refresh_mask;
  }

  // If there is an open slot, refresh that one instead of replacing a reference
  if (free_fb_index != INVALID_IDX) {
    return 1 << free_fb_index;
  }

  const int update_arf = frame_update_type == ARF_UPDATE;
  const int refresh_idx =
      get_refresh_idx(update_arf, -1, cur_disp_order, cpi->switch_frame_mode,
                      ref_frame_map_pairs, cpi->common.seq_params.ref_frames);

  return 1 << refresh_idx;
}

void setup_mi(AV2_COMP *const cpi, YV12_BUFFER_CONFIG *src) {
  AV2_COMMON *const cm = &cpi->common;
  const int num_planes = av2_num_planes(cm);
  MACROBLOCK *const x = &cpi->td.mb;
  MACROBLOCKD *const xd = &x->e_mbd;

  av2_setup_src_planes(x, src, 0, 0, num_planes, NULL);

  av2_setup_block_planes(xd, cm->seq_params.subsampling_x,
                         cm->seq_params.subsampling_y, num_planes);

  set_mi_offsets(&cm->mi_params, xd, 0, 0, 0, 0);
}

// Apply temporal filtering to source frames and encode the filtered frame.
// If the current frame does not require filtering, this function is identical
// to av2_encode() except that tpl is not performed.
static int denoise_and_encode(AV2_COMP *const cpi, uint8_t *const dest,
                              EncodeFrameInput *const frame_input,
                              EncodeFrameParams *const frame_params,
                              EncodeFrameResults *const frame_results) {
  const AV2EncoderConfig *const oxcf = &cpi->oxcf;
  AV2_COMMON *const cm = &cpi->common;
  const GF_GROUP *const gf_group = &cpi->gf_group;

  cm->cur_frame->allow_direct_use = 0;

  // Decide whether to apply temporal filtering to the source frame.
  int apply_filtering = 0;
  int arf_src_index = -1;
  if (frame_params->frame_type == KEY_FRAME) {
    // Decide whether it is allowed to perform key frame filtering
    int allow_kf_filtering =
        oxcf->kf_cfg.enable_keyframe_filtering &&
        !is_stat_generation_stage(cpi) &&
        has_enough_frames_for_key_filtering(cpi->rc.frames_to_key,
                                            oxcf->algo_cfg.arnr_max_frames,
                                            oxcf->gf_cfg.lag_in_frames) &&
        (!is_lossless_requested(&oxcf->rc_cfg) ||
         oxcf->kf_cfg.enable_keyframe_filtering > 1);

    if (allow_kf_filtering) {
      const double y_noise_level = av2_estimate_noise_from_single_plane(
          frame_input->source, 0, cm->seq_params.bit_depth);
      apply_filtering = y_noise_level > 0;
    } else {
      apply_filtering = 0;
    }
    // If we are doing kf filtering, set up a few things.
    if (apply_filtering) {
      MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
      av2_init_mi_buffers(&cm->mi_params);
      setup_mi(cpi, frame_input->source);
      av2_init_macroblockd(cm, xd);
      memset(cpi->mbmi_ext_info.frame_base, 0,
             cpi->mbmi_ext_info.alloc_size *
                 sizeof(*cpi->mbmi_ext_info.frame_base));

      av2_set_speed_features_framesize_independent(cpi, oxcf->speed);
      av2_set_speed_features_framesize_dependent(cpi, oxcf->speed);
      av2_set_rd_speed_thresholds(cpi);
      av2_setup_frame_buf_refs(cm);
      av2_setup_frame_sign_bias(cm);
      av2_frame_init_quantizer(cpi);
      av2_setup_past_independence(cm);

      if (!frame_params->immediate_output_picture && cpi->no_show_fwd_kf) {
        // fwd kf
        arf_src_index = -1 * gf_group->arf_src_offset[gf_group->index];
      } else if (!frame_params->immediate_output_picture) {
        arf_src_index = 0;
      } else {
        arf_src_index = -1;
      }
    }
  } else if (get_frame_update_type(&cpi->gf_group) == ARF_UPDATE ||
             get_frame_update_type(&cpi->gf_group) == KFFLT_UPDATE ||
             get_frame_update_type(&cpi->gf_group) == INTNL_ARF_UPDATE) {
    // ARF
    apply_filtering = oxcf->algo_cfg.arnr_max_frames > 0;
#if !CONFIG_MIXED_LOSSLESS_ENCODE
    if (is_lossless_requested(&oxcf->rc_cfg)) {
#endif  //! CONFIG_MIXED_LOSSLESS_ENCODE
      // Turn off temporal filtering if overlay is off.
      // Also, turn off temporal filtering for internal ARF if overlay is on,
      // since overlay is not supported for this frame, and without overlay,
      // the frame cannot become lossless after temporal filtering.
      apply_filtering &=
          (oxcf->algo_cfg.enable_overlay &
           (get_frame_update_type(&cpi->gf_group) != INTNL_ARF_UPDATE));
#if !CONFIG_MIXED_LOSSLESS_ENCODE
    }
#endif  //! CONFIG_MIXED_LOSSLESS_ENCODE
    if (gf_group->is_user_specified) {
      apply_filtering &= gf_group->is_filtered[gf_group->index];
    }
    if (apply_filtering) {
      arf_src_index = gf_group->arf_src_offset[gf_group->index];
    }
  }
  // Save the pointer to the original source image.
  YV12_BUFFER_CONFIG *source_buffer = frame_input->source;
  // apply filtering to frame
  int show_existing_alt_ref = 0;
  if (apply_filtering) {
    // TODO(bohanli): figure out why we need frame_type in cm here.
    cm->current_frame.frame_type = frame_params->frame_type;
    const int code_arf =
        av2_temporal_filter(cpi, arf_src_index, &show_existing_alt_ref);

    cm->implicit_output_picture = cm->allow_direct_use;
    if (cpi->oxcf.ref_frm_cfg.add_sef_for_hidden_frames) {
      cm->implicit_output_picture = 0;
    }

    if (code_arf) {
      avm_extend_frame_borders(&cpi->alt_ref_buffer, av2_num_planes(cm), 0);
      frame_input->source = &cpi->alt_ref_buffer;
      avm_copy_metadata_to_frame_buffer(frame_input->source,
                                        source_buffer->metadata);
    }
  }

  cm->cur_frame->allow_direct_use = cm->allow_direct_use;

  // perform tpl after filtering
  int allow_tpl = oxcf->gf_cfg.lag_in_frames > 1 &&
                  !is_stat_generation_stage(cpi) &&
                  oxcf->algo_cfg.enable_tpl_model;
  if (frame_params->frame_type == KEY_FRAME) {
    // Don't do tpl for fwd key frames
    allow_tpl = allow_tpl && !cpi->sf.tpl_sf.disable_filtered_key_tpl &&
                !cpi->no_show_fwd_kf;
  } else {
    // Do tpl after ARF is filtered, or if no ARF, at the second frame of GF
    // group.
    // TODO(bohanli): if no ARF, just do it at the first frame.
    int gf_index = gf_group->index;
    allow_tpl = allow_tpl && (gf_group->update_type[gf_index] == ARF_UPDATE ||
                              gf_group->update_type[gf_index] == GF_UPDATE);
    if (allow_tpl) {
      // Need to set the size for TPL for ARF
      // TODO(bohanli): Why is this? what part of it is necessary?
      av2_set_frame_size(cpi, cm->width, cm->height);
    }
  }

  if (gf_group->index == 0) av2_init_tpl_stats(&cpi->tpl_data);
  if (allow_tpl) av2_tpl_setup_stats(cpi, 0, frame_params, frame_input);
  if (av2_encode(cpi, dest, frame_input, frame_params, frame_results) !=
      AVM_CODEC_OK) {
    return AVM_CODEC_ERROR;
  }

  // Set frame_input source to true source for psnr calculation.
  if (apply_filtering && is_psnr_calc_enabled(cpi)) {
    cpi->source = av2_scale_if_required(cm, source_buffer, &cpi->scaled_source,
                                        cm->features.interp_filter, 0, false);
    cpi->unscaled_source = source_buffer;
  }

  return AVM_CODEC_OK;
}

int av2_encode_strategy(AV2_COMP *const cpi, size_t *const size,
                        uint8_t *const dest, unsigned int *frame_flags,
                        int64_t *const time_stamp, int64_t *const time_end,
                        const avm_rational64_t *const timestamp_ratio,
                        int flush) {
  AV2EncoderConfig *const oxcf = &cpi->oxcf;
  AV2_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;
  EncodeFrameResults frame_results;
  memset(&frame_input, 0, sizeof(frame_input));
  memset(&frame_params, 0, sizeof(frame_params));
  memset(&frame_results, 0, sizeof(frame_results));
  cm->bru.update_ref_idx = -1;
  cm->bru.explicit_ref_idx = -1;
  cm->bru.ref_disp_order = -1;

  // Check if we need to stuff more src frames
  if (flush == 0) {
    int srcbuf_size =
        av2_lookahead_depth(cpi->lookahead, cpi->compressor_stage);
    int pop_size = av2_lookahead_pop_sz(cpi->lookahead, cpi->compressor_stage);

    // Continue buffering look ahead buffer.
    if (srcbuf_size < pop_size) return -1;
  }

  if (!av2_lookahead_peek(cpi->lookahead, 0, cpi->compressor_stage)) {
    if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
      av2_end_first_pass(cpi); /* get last stats packet */
      cpi->twopass.first_pass_done = 1;
    }
    return -1;
  }

  if (!is_stat_generation_stage(cpi)) {
    frame_params.frame_params_obu_type = NUM_OBU_TYPES;
    av2_get_second_pass_params(cpi, &frame_params);
  }

  frame_params.duplicate_existing_frame = 0;
  if (cpi->oxcf.unit_test_cfg.sef_with_order_hint_test) {
    frame_params.duplicate_existing_frame =
        (gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE &&
         oxcf->gf_cfg.lag_in_frames != 0);
  }
  struct lookahead_entry *source = NULL;
  struct lookahead_entry *last_source = NULL;
  struct lookahead_entry *bru_ref_source = NULL;
  source = choose_frame_source(cpi, &flush, &last_source,
                               -(BRU_ENC_LOOKAHEAD_DIST_MINUS_1 + 1),
                               &bru_ref_source, &frame_params);
  if (frame_params.frame_type == S_FRAME)
    cpi->common.immediate_output_picture = 1;
  if (cpi->oxcf.ref_frm_cfg.add_sef_for_hidden_frames) {
    cpi->common.implicit_output_picture = 0;
  }

  if (source == NULL) {  // If no source was found, we can't encode a frame.
    if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
      av2_end_first_pass(cpi); /* get last stats packet */
      cpi->twopass.first_pass_done = 1;
    }
    return -1;
  }
  // Source may be changed if temporal filtered later.
  frame_input.source = &source->img;
  frame_input.last_source = last_source != NULL ? &last_source->img : NULL;
  // prepare bru ref source
  frame_input.bru_ref_source =
      bru_ref_source != NULL ? &bru_ref_source->img : NULL;
  if (bru_ref_source) {
    cpi->common.bru.update_ref_idx = bru_ref_source->disp_order_hint;
    cpi->common.bru.ref_disp_order = bru_ref_source->disp_order_hint;
  }
  frame_input.ts_duration = source->ts_end - source->ts_start;
  // Save unfiltered source. It is used in av2_get_second_pass_params().
  cpi->unfiltered_source = frame_input.source;

  *time_stamp = source->ts_start;
  *time_end = source->ts_end;
  if (source->ts_start < cpi->time_stamps.first_ever) {
    cpi->time_stamps.first_ever = source->ts_start;
    cpi->time_stamps.prev_end_seen = source->ts_start;
  }

  if (!is_stat_generation_stage(cpi) &&
      cpi->tpl_data.tpl_stats_pool[0] == NULL) {
    setup_tpl_buffers(cm, &cpi->tpl_data, cpi->oxcf.algo_cfg.enable_tpl_model,
                      oxcf->gf_cfg.lag_in_frames);
  }

  av2_apply_encoding_flags(cpi, source->flags);
  *frame_flags = (source->flags & AVM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;

  // Shown frames and arf-overlay frames need frame-rate considering
  if (frame_params.immediate_output_picture)
    adjust_frame_rate(cpi, source->ts_start, source->ts_end);
  if (!frame_params.duplicate_existing_frame) {
    if (cpi->film_grain_table) {
      cm->seq_params.film_grain_params_present = avm_film_grain_table_lookup(
          cpi->film_grain_table, *time_stamp, *time_end, 0 /* =erase */,
          &cm->film_grain_params);
    }
    // only one operating point supported now
    const int64_t pts64 = ticks_to_timebase_units(timestamp_ratio, *time_stamp);
    if (pts64 < 0 || pts64 > UINT32_MAX) return AVM_CODEC_ERROR;
  }
  FRAME_UPDATE_TYPE frame_update_type = get_frame_update_type(gf_group);

  if (cpi->oxcf.unit_test_cfg.multi_layers_lag_test &&
      cm->number_tlayers == 2) {
    if (frame_update_type == LF_UPDATE)
      cm->tlayer_id = 1;
    else
      cm->tlayer_id = 0;
  }

  // TODO(david.turner@argondesign.com): Move all the encode strategy
  // (largely near av2_get_compressed_data) in here

  // TODO(david.turner@argondesign.com): Change all the encode strategy to
  // modify frame_params instead of cm or cpi.

  // Per-frame encode speed.  In theory this can vary, but things may have
  // been written assuming speed-level will not change within a sequence, so
  // this parameter should be used with caution.
  frame_params.speed = oxcf->speed;

  // Work out some encoding parameters specific to the pass:
  if (has_no_stats_stage(cpi) && oxcf->q_cfg.aq_mode == CYCLIC_REFRESH_AQ) {
    av2_cyclic_refresh_update_parameters(cpi, frame_params.frame_type);
  } else if (is_stat_generation_stage(cpi)) {
    cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(&oxcf->rc_cfg);
    const int kf_requested = (cm->current_frame.frame_number == 0 ||
                              (*frame_flags & FRAMEFLAGS_KEY));
    if (kf_requested && frame_update_type != OVERLAY_UPDATE &&
        frame_update_type != KFFLT_OVERLAY_UPDATE &&
        frame_update_type != INTNL_OVERLAY_UPDATE) {
      frame_params.frame_type = KEY_FRAME;
    } else {
      frame_params.frame_type = INTER_FRAME;
    }
  } else if (is_stat_consumption_stage(cpi)) {
#if CONFIG_MISMATCH_DEBUG
    mismatch_move_frame_idx_w(
        !frame_params.frame_params_update_type_was_overlay);
#endif  // CONFIG_MISMATCH_DEBUG
#if TXCOEFF_COST_TIMER
    cm->txcoeff_cost_timer = 0;
    cm->txcoeff_cost_count = 0;
#endif
  }
  if (frame_params.frame_type == KEY_FRAME) {
    source->disp_order_hint = 0;
  }
  if (cpi->oxcf.ref_frm_cfg.add_sef_for_hidden_frames) {
    cm->implicit_output_picture = 0;
  }

  if (frame_params.frame_type == KEY_FRAME && !cpi->no_show_fwd_kf) {
    cm->allow_direct_use = 0;
    cm->implicit_output_picture = 0;
  }

#if CONFIG_MISMATCH_DEBUG
  if (has_no_stats_stage(cpi)) {
    mismatch_move_frame_idx_w(
        !frame_params.frame_params_update_type_was_overlay);
  }
#endif  // CONFIG_MISMATCH_DEBUG

  if (!is_stat_generation_stage(cpi))
    set_ext_overrides(cm, &frame_params, ext_flags);

  cm->restricted_prediction_switch =
      cpi->oxcf.kf_cfg.sframe_dist != 0 && cpi->oxcf.kf_cfg.sframe_mode == 0;

  av2_configure_buffer_updates(cpi, frame_update_type);

  const int order_offset = gf_group->arf_src_offset[gf_group->index];
  const int cur_frame_disp =
      cpi->common.current_frame.frame_number + order_offset;

  // Here, if tlayer_id is set to a non-zero value (pry_level),
  // tlayer_id affects reference list construction in both encoder and decoder.
  // Otherwise (if tlayer_id is set to 0), tlayer_id does not change the
  // reference frame list construction.
  cm->current_frame.order_hint = cur_frame_disp;
  cm->current_frame.display_order_hint = cur_frame_disp;
  cm->current_frame.display_order_hint_restricted = cur_frame_disp;
  cm->current_frame.pyramid_level = get_true_pyr_level(
      cpi->gf_group.layer_depth[cpi->gf_group.index],
      cm->current_frame.frame_type == KEY_FRAME, cpi->gf_group.max_layer_depth,
      cpi->gf_group.update_type[cpi->gf_group.index] == KFFLT_OVERLAY_UPDATE);

  cm->current_frame.tlayer_id = cm->tlayer_id;
  cm->current_frame.mlayer_id = cm->mlayer_id;

  int is_olk_overlay = 0;
  if ((cpi->gf_group.update_type[cpi->gf_group.index] == OVERLAY_UPDATE ||
       cpi->gf_group.update_type[cpi->gf_group.index] ==
           KFFLT_OVERLAY_UPDATE) &&
      cm->olk_refresh_frame_flags[cm->mlayer_id] != INVALID_IDX) {
    for (int frame = 0; frame < cm->seq_params.ref_frames; frame++) {
      const RefCntBuffer *const buf = cm->ref_frame_map[frame];
      if (buf == NULL) continue;
      const int frame_order = cpi->oxcf.kf_cfg.sframe_dist != 0
                                  ? (int)buf->display_order_hint_restricted
                                  : (int)buf->display_order_hint;
      if (frame_order == cur_frame_disp) {
        is_olk_overlay =
            (cm->olk_refresh_frame_flags[cm->mlayer_id] >> frame) & 1;
      }
    }
  }
  if (cpi->olk_encountered &&
      cm->olk_refresh_frame_flags[cm->mlayer_id] != INVALID_IDX &&
      is_olk_overlay) {
    assert(cpi->gf_group.update_type[cpi->gf_group.index] == OVERLAY_UPDATE ||
           cpi->gf_group.update_type[cpi->gf_group.index] ==
               KFFLT_OVERLAY_UPDATE);

    // This is an OLK KF overlay. We need to clear all references except for the
    // OLK.
    int ref_flags_to_keep = 0;
    for (int layer = 0; layer <= cm->seq_params.max_mlayer_id; layer++) {
      ref_flags_to_keep |= cm->olk_refresh_frame_flags[cm->mlayer_id];
    }
    for (int ref_index = 0; ref_index < cm->seq_params.ref_frames;
         ref_index++) {
      if (!((ref_flags_to_keep >> ref_index) & 1u) &&
          (cm->ref_frame_map[ref_index] == NULL ||
           cm->ref_frame_map[ref_index]->long_term_id == -1)) {
        if (cm->ref_frame_map[ref_index] != NULL) {
          --cm->ref_frame_map[ref_index]->ref_count;
          cm->ref_frame_map[ref_index] = NULL;
        }
      }
    }

    // Set gf_state flag so the next gf group knows that the OLK has been
    // encoded
    cpi->gf_state.olk_overlay_last = 1;
  }
  init_ref_map_pair(&cpi->common, cm->ref_frame_map_pairs,
                    frame_params.frame_type == KEY_FRAME,
                    cpi->switch_frame_mode == 1);

  if (!is_stat_generation_stage(cpi)) {
    cm->current_frame.frame_type = frame_params.frame_type;
    // get last frame idx as bru frame
    cm->bru.enabled = cpi->oxcf.tool_cfg.enable_bru > 0 &&
                      (frame_params.frame_type == INTER_FRAME);
    cm->bru.frame_inactive_flag = 0;
    if (cm->bru.enabled) {
      int n_future = 0;
      for (int i = 0; i < REF_FRAMES; i++) {
        const RefCntBuffer *const buf = cm->ref_frame_map[i];
        if (buf) {
          int ref_disp = (int)buf->display_order_hint;
          const int disp_diff = get_relative_dist(
              &cm->seq_params.order_hint_info, cur_frame_disp, ref_disp);
          if (disp_diff < 0) {
            n_future++;
            break;
          }
        }
      }
      if (n_future > 0) {
        cm->bru.enabled = 0;
      }
    }
    if (cm->bru.enabled && frame_input.bru_ref_source != NULL &&
        !frame_is_intra_only(&cpi->common)) {
      active_region_detection(cpi, frame_input.source,
                              frame_input.bru_ref_source);
      //  disable bru if
      //  1. too many active regions
      //  2. active ratio too large > 50%
      const int num_active_region = bru_get_num_of_active_region(&cpi->common);
      if (num_active_region > MAX_ACTIVE_REGION) {
        cm->bru.blocks_skipped = 0;
      } else if (cm->bru.blocks_skipped * 100 / cm->bru.total_units <
                 BRU_OFF_RATIO) {
        cm->bru.blocks_skipped = 0;
      }
      if (cm->bru.blocks_skipped == 0) {
        cm->bru.enabled = 0;
        cm->bru.update_ref_idx = -1;
      }
      cm->bru.frame_inactive_flag =
          (cm->bru.blocks_skipped == cm->bru.total_units);
    } else {
      cm->bru.enabled = 0;
      cm->bru.update_ref_idx = -1;
    }
    // clean up active sb queue if any left over
    // it may happen if encoder decide not using BRU for lots of active sbs
    // exists
    if (cm->bru.enabled == 0 && cm->bru.active_mode_map) {
      memset(cm->bru.active_mode_map, 2, sizeof(uint8_t) * cm->bru.total_units);
      // Note: enc_act_sb_queue is now local to active_region_detection(),
      // so no global cleanup needed here
    } else {
      cm->features.tip_frame_mode = TIP_FRAME_DISABLED;
    }
    if (cm->seq_params.enable_explicit_ref_frame_map || frame_is_sframe(cm)) {
      av2_get_ref_frames_enc(cpi, cur_frame_disp, cm->ref_frame_map_pairs);
    } else {
      // Derive reference mapping in a resolution independent manner, to
      // generate parameters (num_total_refs_res_indep and
      // remapped_ref_idx_res_indep) needed in write_frame_size_with_refs.
      av2_get_ref_frames(cm, cur_frame_disp, 0, 0, cm->ref_frame_map_pairs);
      // Derive the reference mapping excluding frames of invalid resolutions
      av2_get_ref_frames(cm, cur_frame_disp, 1, 0, cm->ref_frame_map_pairs);
    }
    if (!cm->seq_params.enable_explicit_ref_frame_map && cm->bru.enabled) {
      const int num_past_refs = cm->ref_frames_info.num_past_refs;
      if (cm->bru.ref_disp_order >= 0) {
        cm->bru.update_ref_idx = -1;
        cm->bru.explicit_ref_idx = -1;
        for (int i = 0; i < num_past_refs; i++) {
          const int ref_list_order =
              cm->ref_frame_map[cm->remapped_ref_idx[i]]->display_order_hint;
          if (ref_list_order == cm->bru.ref_disp_order) {
            cm->bru.update_ref_idx = i;
            cm->bru.explicit_ref_idx = cm->remapped_ref_idx[i];
            break;
          }
        }
      }
      if (cm->bru.update_ref_idx < 0) {
        init_bru_params(cm);
      }
    }
    if (cm->bru.frame_inactive_flag) {
      const RefCntBuffer *bru_ref_buf =
          get_ref_frame_buf(cm, cm->bru.update_ref_idx);
      cm->quant_params.base_qindex = bru_ref_buf->base_qindex;
      if (av2_num_planes(cm) > 1) {
        cm->quant_params.u_ac_delta_q = bru_ref_buf->u_ac_delta_q;
        cm->quant_params.v_ac_delta_q = bru_ref_buf->v_ac_delta_q;
      } else {
        cm->quant_params.v_ac_delta_q = cm->quant_params.u_ac_delta_q = 0;
      }
      cm->cur_frame->base_qindex = cm->quant_params.base_qindex;
      cm->cur_frame->u_ac_delta_q = cm->quant_params.u_ac_delta_q;
      cm->cur_frame->v_ac_delta_q = cm->quant_params.v_ac_delta_q;
    }
    cm->ref_frames_info.num_same_ref_compound =
        AVMMIN(cm->seq_params.num_same_ref_compound,
               cm->ref_frames_info.num_total_refs);
    cm->cur_frame->num_ref_frames = cm->ref_frames_info.num_total_refs;

    // ref_frame_flags is defined based on the external flag
    // max-reference-frames.
    frame_params.ref_frame_flags =
        (1 << cpi->common.ref_frames_info.num_total_refs) - 1;

    frame_params.order_offset = gf_group->arf_src_offset[gf_group->index];

    if (!is_stat_generation_stage(cpi) &&
        use_subgop_cfg(&cpi->gf_group, cpi->gf_group.index) &&
        (frame_update_type != KF_UPDATE && frame_update_type != KFFLT_UPDATE)) {
      get_gop_cfg_enabled_refs(cpi, &frame_params.ref_frame_flags,
                               frame_params.order_offset);
    }

    frame_params.refresh_frame_flags = av2_get_refresh_frame_flags(
        cpi, &frame_params, frame_update_type, cpi->gf_group.index,
        cur_frame_disp, cm->ref_frame_map_pairs);
    frame_params.fb_idx_for_overlay = INVALID_IDX;

    for (int frame = 0; frame < cm->seq_params.ref_frames; frame++) {
      const RefCntBuffer *const buf = cm->ref_frame_map[frame];
      if (buf == NULL) continue;
      const int frame_order = cpi->oxcf.kf_cfg.sframe_dist != 0
                                  ? (int)buf->display_order_hint_restricted
                                  : (int)buf->display_order_hint;
      if (frame_order == cur_frame_disp)
        frame_params.fb_idx_for_overlay = frame;
    }

    if (!is_stat_generation_stage(cpi)) {
      int allow_direct_use = 0;
      if (frame_params.fb_idx_for_overlay != INVALID_IDX)
        allow_direct_use = cm->ref_frame_map[frame_params.fb_idx_for_overlay]
                               ->allow_direct_use;

      // If this is a forward keyframe, mark as a show_existing_frame
      // TODO(bohanli): find a consistent condition for fwd keyframes
      if (oxcf->kf_cfg.fwd_kf_enabled &&
          (gf_group->index == (gf_group->size - 1)) &&
          (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE ||
           gf_group->update_type[gf_group->index] == KFFLT_OVERLAY_UPDATE) &&
          gf_group->arf_index >= 0 && cpi->rc.frames_to_key == 0) {
        if (allow_direct_use) {
          frame_params.frame_params_update_type_was_overlay = 1;
          // NOTE: this is NOT OBU_OLK but the overlay at the end of the group
          //  pointing an OLK
          frame_params.frame_params_obu_type = OBU_OLK;
        } else {
          // This is a olk kf overlay, but not show_existing
          frame_params.frame_params_update_type_was_overlay = 0;
        }
      } else {
        frame_params.frame_params_update_type_was_overlay =
            (allow_direct_use &&
             (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE ||
              gf_group->update_type[gf_group->index] ==
                  KFFLT_OVERLAY_UPDATE)) ||
            gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE;
      }
      frame_params.frame_params_update_type_was_overlay &=
          allow_show_existing(cpi, *frame_flags);
    } else {
      frame_params.frame_params_update_type_was_overlay = 0;
    }
  }

  // The way frame_params->remapped_ref_idx is setup is a placeholder.
  // Currently, reference buffer assignment is done by update_ref_frame_map()
  // which is called by high-level strategy AFTER encoding a frame.  It
  // modifies cm->remapped_ref_idx.  If you want to use an alternative method
  // to determine reference buffer assignment, just put your assignments into
  // frame_params->remapped_ref_idx here and they will be used when encoding
  // this frame.  If frame_params->remapped_ref_idx is setup independently of
  // cm->remapped_ref_idx then update_ref_frame_map() will have no effect.
  memcpy(frame_params.remapped_ref_idx, cm->remapped_ref_idx,
         INTER_REFS_PER_FRAME * sizeof(*cm->remapped_ref_idx));
  init_bru_frame(cm);

  cpi->td.mb.delta_qindex = 0;
  if (!frame_params.duplicate_existing_frame) {
    cm->quant_params.using_qmatrix = oxcf->q_cfg.using_qm;
    av2_set_lr_tools(cm->seq_params.lr_tools_disable_mask[0], 0, &cm->features);
    av2_set_lr_tools(cm->seq_params.lr_tools_disable_mask[1], 1, &cm->features);
    av2_set_lr_tools(cm->seq_params.lr_tools_disable_mask[1], 2, &cm->features);
  }
  if (cm->quant_params.using_qmatrix) {
    if (oxcf->q_cfg.using_qm && oxcf->q_cfg.user_defined_qmatrix) {
      for (int qm_id = 0; qm_id < NUM_CUSTOM_QMS; qm_id++) {
        if (cpi->use_user_defined_qm[qm_id]) {
          av2_qm_frame_update(&cm->quant_params,
                              cm->seq_params.monochrome ? 1 : 3, qm_id,
                              cpi->user_defined_qm_list[qm_id]);
        }
      }
    }
  }
  if (denoise_and_encode(cpi, dest, &frame_input, &frame_params,
                         &frame_results) != AVM_CODEC_OK) {
    return AVM_CODEC_ERROR;
  }

  if (!is_stat_generation_stage(cpi)) {
    // First pass doesn't modify reference buffer assignment or produce frame
    // flags
    update_frame_flags(&cpi->common, frame_flags);
  }

  if (!is_stat_generation_stage(cpi)) {
#if TXCOEFF_COST_TIMER
    cm->cum_txcoeff_cost_timer += cm->txcoeff_cost_timer;
    fprintf(stderr,
            "\ntxb coeff cost block number: %ld, frame time: %ld, cum time %ld "
            "in us\n",
            cm->txcoeff_cost_count, cm->txcoeff_cost_timer,
            cm->cum_txcoeff_cost_timer);
#endif
    if (!has_no_stats_stage(cpi)) av2_twopass_postencode_update(cpi);
  }

#if CONFIG_TUNE_VMAF
  if (!is_stat_generation_stage(cpi) &&
      (oxcf->tune_cfg.tuning >= AVM_TUNE_VMAF_WITH_PREPROCESSING &&
       oxcf->tune_cfg.tuning <= AVM_TUNE_VMAF_NEG_MAX_GAIN)) {
    av2_update_vmaf_curve(cpi);
  }
#endif

  if (!is_stat_generation_stage(cpi)) {
    set_additional_frame_flags(cm, frame_flags);
    update_rc_counts(cpi);
  }

  // Unpack frame_results:
  *size = frame_results.size;

  // Leave a signal for a higher level caller about if this frame is droppable
  if (*size > 0) {
    cpi->droppable = is_frame_droppable(&ext_flags->refresh_frame);
  }

  return AVM_CODEC_OK;
}

// Determine whether a frame is a keyframe arf. Will return 0 for fwd kf arf.
// Note it depends on frame_since_key and gf_group, therefore should be called
// after the gf group is defined, or otherwise a keyframe arf may still return
// 0.
int av2_check_keyframe_arf(int gf_index, GF_GROUP *gf_group,
                           int frame_since_key) {
  if (gf_index >= gf_group->size) return 0;
  (void)frame_since_key;
  return gf_group->update_type[gf_index] == KFFLT_UPDATE;
  /*
  return gf_group->update_type[gf_index] == ARF_UPDATE &&
         gf_group->update_type[gf_index + 1] == OVERLAY_UPDATE &&
         frame_since_key == 0;
         */
}

// Determine whether a frame is a keyframe overlay (will also return 0 for fwd
// kf overlays).
int av2_check_keyframe_overlay(int gf_index, GF_GROUP *gf_group,
                               int frame_since_key) {
  if (gf_index < 1) return 0;
  (void)frame_since_key;
  return gf_group->update_type[gf_index] == KFFLT_OVERLAY_UPDATE;
  /*
  return gf_group->update_type[gf_index - 1] == ARF_UPDATE &&
         gf_group->update_type[gf_index] == OVERLAY_UPDATE &&
         frame_since_key == 0;
         */
}
