/*
 * 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 &&
          (cpi->oxcf.kf_cfg.enable_sframe ||
           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->oxcf.kf_cfg.enable_sframe ||
        cpi->oxcf.tool_cfg.g_error_resilient_mode)
      return 0;
    return 1;
  }

  const int is_s_frame = cpi->oxcf.kf_cfg.enable_sframe ||
                         cpi->oxcf.tool_cfg.g_error_resilient_mode ||
                         (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) {
  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) !=
      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 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 (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 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) /
      (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.sframe_dist != 0 &&
           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.sframe_dist != 0 &&
           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 (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

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