/*
 * 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 "av2/encoder/ratectrl.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 is_ras_frame 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->is_ras_frame == 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 FWD_KF_OVERLAY_UPDATE:
    case FWD_KF_SUCCESSOR_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) {
    if (!cpi->oxcf.unit_test_cfg.multi_layers_lag_test ||
        cpi->common.number_mlayers == 1) {
      cpi->rc.frames_since_key++;
      cpi->rc.frames_to_key--;
    } else {
      if (cpi->common.mlayer_id == (int)cpi->common.number_mlayers - 1) {
        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;
      // Continue on the same mlayer.
      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] ==
                    FWD_KF_OVERLAY_UPDATE ||
                gf_group->update_type[cpi->gf_group.index] ==
                    FWD_KF_SUCCESSOR_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;
      // Go to next mlayer
      cpi->common.next_mlayer_id = 1;
    } 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;
      // Go back to mlayer 0
      cpi->common.next_mlayer_id = 0;
    } else {
      // Go to next mlayer
      cpi->common.next_mlayer_id = 1;
    }
  }
}

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) /
      (cpi->oxcf.unit_test_cfg.multi_layers_lag_test
           ? cpi->common.number_mlayers
           : 1);

  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;
      // When S-frames prevent show_existing_frame for overlays, the hidden
      // altref must not be implicitly output to avoid duplicate frames.
      if (cm->implicit_output_picture &&
          (cm->current_frame.frame_type == S_FRAME ||
           cpi->oxcf.tool_cfg.g_error_resilient_mode)) {
        cm->implicit_output_picture = 0;
      }
    }
  }
  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) {
    // When lookahead is exhausted, still disallow show_existing_frame if
    // S-frames are enabled or global error resilient mode is on, since
    // S-frames reset reference frame buffers.
    if (cpi->common.current_frame.frame_type == S_FRAME ||
        cpi->oxcf.tool_cfg.g_error_resilient_mode)
      return 0;
    return 1;
  }

  const int is_s_frame = cpi->oxcf.tool_cfg.g_error_resilient_mode ||
                         (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_multi_layer(
    RefFrameMapPair ref_map_pairs[REF_FRAMES], const int ref_frames,
    int olk_flags_to_keep, int m_layer_id) {
  // First check free space in the same m layer.  Then check for any other not
  // used reference in other layers.  With multiple m layers, this might not be
  // the best decision, but it ensures a somewhat reasonable refresh frame
  // choice.
  int fb_idx = INVALID_IDX;
  for (int idx = 0; idx < ref_frames; ++idx) {
    if (ref_map_pairs[idx].ref_frame_for_inference == -1) {
      if ((olk_flags_to_keep >> idx) & 1u) continue;
      if (ref_map_pairs[idx].mlayer_id >= 0 &&
          m_layer_id != ref_map_pairs[idx].mlayer_id)
        continue;
      fb_idx = idx;
      break;
    }
  }
  if (fb_idx != INVALID_IDX) return fb_idx;
  for (int idx = 0; idx < ref_frames; ++idx) {
    if (ref_map_pairs[idx].ref_frame_for_inference == -1) {
      if ((olk_flags_to_keep >> idx) & 1u) continue;
      fb_idx = idx;
      break;
    }
  }
  return fb_idx;
}

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 is_ras_frame,
                           RefFrameMapPair ref_frame_map_pairs[REF_FRAMES],
                           const int ref_frames, int olk_flags_to_keep,
                           int is_multi_layers_lag_test) {
  // 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 (is_ras_frame == 1 && ref_pair.frame_type == KEY_FRAME) continue;
    if ((olk_flags_to_keep >> map_idx) & 1u) continue;
    const int frame_order = ref_pair.disp_order_removed;
    const int reference_frame_level = ref_pair.pyr_level;

    if (is_multi_layers_lag_test) {
      // For multi layer, need to manage the buffer more flexibly.
      // Keep future frames and one closest previous frames in output order
      if (frame_order > cur_frame_disp - 1) continue;
    } else {
      // 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, int olk_flags_to_keep) {
  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->oxcf.kf_cfg.sframe_type == RAS_FRAME), ref_frame_map_pairs,
      cpi->common.seq_params.ref_frames, olk_flags_to_keep,
      cpi->oxcf.unit_test_cfg.multi_layers_lag_test);
  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]) {
  // 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->no_show_fwd_kf) {
    return (1 << cpi->common.seq_params.ref_frames) - 1;
  }

  if (frame_params->frame_type == S_FRAME ||
      frame_params->frame_type == KEY_FRAME) {
    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] != NULL &&
          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++;
        }
      }
    }
    // For fwd kf, only refresh one buffer. The other buffers will be refreshed
    // on the first regular TU it encounters after the OLK TU.
    if (cpi->no_show_fwd_kf) {
      int refresh_idx = -1;
      for (int i = 0; i < cm->seq_params.ref_frames; ++i) {
        if ((refresh_frame_flags >> i) & 1) {
          // Skip slots containing implicit-output frames that have not
          // been output yet and whose DOH is at least the current
          // frame's DOH. (DOH requirement)
          if (cm->ref_frame_map[i] != NULL &&
              cm->ref_frame_map[i]->implicit_output_picture &&
              !cm->ref_frame_map[i]->frame_output_done &&
              (int)cm->ref_frame_map[i]->display_order_hint >= cur_disp_order) {
            continue;
          }
          refresh_idx = i;
          break;
        }
      }
      assert(refresh_idx >= 0);
      return (1 << refresh_idx);
    }
    return refresh_frame_flags;
  }

  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;
  }

  int olk_flags_to_keep = 0;
  if (cpi->olk_encountered || cpi->common.is_leading_picture) {
    for (int layer = 0; layer <= cpi->common.seq_params.max_mlayer_id;
         layer++) {
      if (cpi->common.olk_refresh_frame_flags[layer] == -1) continue;
      olk_flags_to_keep |= cpi->common.olk_refresh_frame_flags[layer];
    }
  }

  // Protect ref buffer slots containing implicit-output frames with DOH
  // at least the current frame's DOH. (DOH requirement)
  for (int i = 0; i < cpi->common.seq_params.ref_frames; i++) {
    const RefCntBuffer *const buf = cpi->common.ref_frame_map[i];
    if (buf != NULL && buf->implicit_output_picture &&
        !buf->frame_output_done &&
        (int)buf->display_order_hint >= cur_disp_order) {
      olk_flags_to_keep |= (1 << i);
    }
  }

  // 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 {
    if (cpi->oxcf.unit_test_cfg.multi_layers_lag_test) {
      free_fb_index = get_free_ref_map_index_multi_layer(
          ref_frame_map_pairs, cpi->common.seq_params.ref_frames,
          olk_flags_to_keep, cpi->common.mlayer_id);
    } 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, olk_flags_to_keep);
    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->oxcf.kf_cfg.sframe_type,
      ref_frame_map_pairs, cpi->common.seq_params.ref_frames, olk_flags_to_keep,
      cpi->oxcf.unit_test_cfg.multi_layers_lag_test);

  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,
                              int64_t *const time_stamp,
                              int64_t *const time_end) {
  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;
    }
    // When S-frames prevent show_existing_frame for overlays, the overlay
    // will be fully coded and produce its own output. The hidden altref
    // must not be implicitly output, otherwise the decoder outputs both
    // the evicted altref and the overlay, causing duplicate frames.
    if (cm->implicit_output_picture &&
        (cpi->oxcf.kf_cfg.enable_sframe ||
         cpi->oxcf.tool_cfg.g_error_resilient_mode)) {
      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,
                 time_stamp, time_end) != 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;

  if (cm->next_mlayer_id >= 0) {
    cm->mlayer_id = cm->next_mlayer_id;
  }

  // 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 (gf_group->update_type[gf_group->index] == FWD_KF_OVERLAY_UPDATE ||
      gf_group->update_type[gf_group->index] == FWD_KF_SUCCESSOR_UPDATE) {
    // These have to use implicit output since they need to be
    // coded_output_picture OBUs, to be put together with a hidden OLK obu in
    // the same TU.
    cpi->common.implicit_output_picture = 1;
  }

  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)) {
    if (*frame_flags & FRAMEFLAGS_KEY) {
      frame_params.frame_type = KEY_FRAME;
    }
    if (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 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 (gf_group->update_type[gf_group->index] == FWD_KF_OVERLAY_UPDATE ||
      gf_group->update_type[gf_group->index] == FWD_KF_SUCCESSOR_UPDATE) {
    // These have to use implicit output since they need to be
    // coded_output_picture OBUs, to be put together with a hidden OLK obu in
    // the same TU.
    cpi->common.implicit_output_picture = 1;
  }

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

  if (cpi->no_show_fwd_kf && cpi->oxcf.kf_cfg.enable_keyframe_filtering > 1) {
    // An overlay of the fwd kf is going to be added. The fwd kf cannot be
    // directly displayed.
    cm->allow_direct_use = 0;
    cm->implicit_output_picture = 0;
  }

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

  cm->restricted_prediction_switch =
      cpi->oxcf.kf_cfg.enable_sframe && 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) /
      (cpi->oxcf.unit_test_cfg.multi_layers_lag_test
           ? cpi->common.number_mlayers
           : 1);

  // 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.enable_sframe &&
           is_mlayer_transitively_dependent(&cm->seq_params, buf->mlayer_id,
                                            cm->mlayer_id))
              ? (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;
      }
    }
  }

  int ref_flags_to_keep = 0;
  for (int layer = 0; layer <= cm->seq_params.max_mlayer_id; layer++) {
    if (cm->olk_refresh_frame_flags[layer] == -1) continue;
    ref_flags_to_keep |= cm->olk_refresh_frame_flags[layer];
  }
  if (cpi->olk_encountered && ref_flags_to_keep != 0 && 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.
    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;
  }
  int use_olk_ref_only =
      cpi->gf_group.update_type[cpi->gf_group.index] == FWD_KF_OVERLAY_UPDATE ||
      cpi->gf_group.update_type[cpi->gf_group.index] == FWD_KF_SUCCESSOR_UPDATE;
  init_ref_map_pair(&cpi->common, cm->ref_frame_map_pairs,
                    frame_params.frame_type == KEY_FRAME,
                    cpi->is_ras_frame == 1, use_olk_ref_only);

  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.enable_sframe &&
           is_mlayer_transitively_dependent(&cm->seq_params, buf->mlayer_id,
                                            cm->mlayer_id))
              ? (int)buf->display_order_hint_restricted
              : (int)buf->display_order_hint;
      if (frame_order == cur_frame_disp && cm->mlayer_id == buf->mlayer_id) {
        frame_params.fb_idx_for_overlay = frame;
        if (buf->allow_direct_use) {
          // If we have multiple reference frames at the same order hint, use
          // the one that allows direct use.
          break;
        }
      }
    }

    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->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_OPEN_LOOP_KEY but the overlay at the end of
          // the group
          //  pointing an OLK
          frame_params.frame_params_obu_type = OBU_OPEN_LOOP_KEY;
        } 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 CONFIG_MISMATCH_DEBUG
  if (is_stat_consumption_stage(cpi) || has_no_stats_stage(cpi)) {
    mismatch_move_frame_idx_w(
        !frame_params.frame_params_update_type_was_overlay);
  }
#endif  // CONFIG_MISMATCH_DEBUG
  if (denoise_and_encode(cpi, dest, &frame_input, &frame_params, &frame_results,
                         time_stamp, time_end) != 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

  cpi->common.next_mlayer_id = -1;
  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 ||
         gf_group->update_type[gf_index] == FWD_KF_OVERLAY_UPDATE ||
         gf_group->update_type[gf_index] == FWD_KF_SUCCESSOR_UPDATE;
  /*
  return gf_group->update_type[gf_index - 1] == ARF_UPDATE &&
         gf_group->update_type[gf_index] == OVERLAY_UPDATE &&
         frame_since_key == 0;
         */
}
