/*
 * 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 "avm_ports/system_state.h"

#include "av2/common/reconintra.h"
#include "av2/common/intra_dip.h"

#include "av2/encoder/encoder.h"
#include "av2/encoder/encodeframe_utils.h"
#include "av2/encoder/partition_strategy.h"
#include "av2/encoder/rdopt.h"

static AVM_INLINE int set_deltaq_rdmult(const AV2_COMP *const cpi,
                                        const MACROBLOCK *const x) {
  const AV2_COMMON *const cm = &cpi->common;
  const CommonQuantParams *quant_params = &cm->quant_params;
  return av2_compute_rd_mult(cpi, quant_params->base_qindex + x->delta_qindex +
                                      quant_params->y_dc_delta_q);
}

void av2_set_ssim_rdmult(const AV2_COMP *const cpi, MvCosts *const mv_costs,
                         const BLOCK_SIZE bsize, const int mi_row,
                         const int mi_col, int *const rdmult) {
  const AV2_COMMON *const cm = &cpi->common;

  const BLOCK_SIZE bsize_base = BLOCK_16X16;
  const int num_mi_w = mi_size_wide[bsize_base];
  const int num_mi_h = mi_size_high[bsize_base];
  const int num_cols = (cm->mi_params.mi_cols + num_mi_w - 1) / num_mi_w;
  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
  const int num_bcols = (mi_size_wide[bsize] + num_mi_w - 1) / num_mi_w;
  const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
  int row, col;
  double num_of_mi = 0.0;
  double geom_mean_of_scale = 0.0;

  assert(cpi->oxcf.tune_cfg.tuning == AVM_TUNE_SSIM);

  avm_clear_system_state();
  for (row = mi_row / num_mi_w;
       row < num_rows && row < mi_row / num_mi_w + num_brows; ++row) {
    for (col = mi_col / num_mi_h;
         col < num_cols && col < mi_col / num_mi_h + num_bcols; ++col) {
      const int index = row * num_cols + col;
      geom_mean_of_scale += log(cpi->ssim_rdmult_scaling_factors[index]);
      num_of_mi += 1.0;
    }
  }
  geom_mean_of_scale = exp(geom_mean_of_scale / num_of_mi);

  *rdmult = (int)((double)(*rdmult) * geom_mean_of_scale + 0.5);
  *rdmult = AVMMAX(*rdmult, 0);
  av2_set_error_per_bit(mv_costs, *rdmult);
  avm_clear_system_state();
}

// Return the end column for the current superblock, in unit of TPL blocks.
static int get_superblock_tpl_column_end(const AV2_COMMON *const cm, int mi_col,
                                         int num_mi_w) {
  // Find the start column of this superblock.
  const int sb_mi_col_start = (mi_col >> cm->mib_size_log2)
                              << cm->mib_size_log2;
  const int sb_mi_col_start_sr = sb_mi_col_start;
  // Width of this superblock in mi units.
  const int sb_mi_width = mi_size_wide[cm->sb_size];
  const int sb_mi_width_sr = sb_mi_width;
  // Superblock end in mi units.
  const int sb_mi_end = sb_mi_col_start_sr + sb_mi_width_sr;
  // Superblock end in TPL units.
  return (sb_mi_end + num_mi_w - 1) / num_mi_w;
}

int av2_get_hier_tpl_rdmult(const AV2_COMP *const cpi, MACROBLOCK *const x,
                            const BLOCK_SIZE bsize, const int mi_row,
                            const int mi_col, int orig_rdmult) {
  const AV2_COMMON *const cm = &cpi->common;
  const GF_GROUP *const gf_group = &cpi->gf_group;
  assert(IMPLIES(cpi->gf_group.size > 0,
                 cpi->gf_group.index < cpi->gf_group.size));
  const int tpl_idx = cpi->gf_group.index;
  const TplDepFrame *tpl_frame = &cpi->tpl_data.tpl_frame[tpl_idx];
  const int deltaq_rdmult = set_deltaq_rdmult(cpi, x);
  if (tpl_frame->is_valid == 0) return deltaq_rdmult;
  if (!is_frame_tpl_eligible(gf_group, gf_group->index)) return deltaq_rdmult;
  if (tpl_idx >= MAX_TPL_FRAME_IDX) return deltaq_rdmult;
  if (cpi->oxcf.q_cfg.aq_mode != NO_AQ) return deltaq_rdmult;

  const int mi_col_sr = mi_col;
  const int mi_cols_sr = av2_pixels_to_mi(cm->width);
  const int block_mi_width_sr = mi_size_wide[bsize];
  const BLOCK_SIZE bsize_base = BLOCK_16X16;
  const int num_mi_w = mi_size_wide[bsize_base];
  const int num_mi_h = mi_size_high[bsize_base];
  const int num_cols = (mi_cols_sr + num_mi_w - 1) / num_mi_w;
  const int num_rows = (cm->mi_params.mi_rows + num_mi_h - 1) / num_mi_h;
  const int num_bcols = (block_mi_width_sr + num_mi_w - 1) / num_mi_w;
  const int num_brows = (mi_size_high[bsize] + num_mi_h - 1) / num_mi_h;
  // This is required because the end col of superblock may be off by 1.
  const int sb_bcol_end = get_superblock_tpl_column_end(cm, mi_col, num_mi_w);
  int row, col;
  double base_block_count = 0.0;
  double geom_mean_of_scale = 0.0;
  avm_clear_system_state();
  for (row = mi_row / num_mi_w;
       row < num_rows && row < mi_row / num_mi_w + num_brows; ++row) {
    for (col = mi_col_sr / num_mi_h;
         col < num_cols && col < mi_col_sr / num_mi_h + num_bcols &&
         col < sb_bcol_end;
         ++col) {
      const int index = row * num_cols + col;
      geom_mean_of_scale += log(cpi->tpl_sb_rdmult_scaling_factors[index]);
      base_block_count += 1.0;
    }
  }
  geom_mean_of_scale = exp(geom_mean_of_scale / base_block_count);
  int rdmult = (int)((double)orig_rdmult * geom_mean_of_scale + 0.5);
  rdmult = AVMMAX(rdmult, 0);
  av2_set_error_per_bit(&x->mv_costs, rdmult);
  avm_clear_system_state();
  if (bsize == cm->sb_size) {
    const int rdmult_sb = set_deltaq_rdmult(cpi, x);
    assert(rdmult_sb == rdmult);
    (void)rdmult_sb;
  }
  return rdmult;
}

static AVM_INLINE void update_filter_type_count(FRAME_COUNTS *counts,
                                                const MACROBLOCKD *xd,
                                                const MB_MODE_INFO *mbmi) {
  const int ctx = av2_get_pred_context_switchable_interp(xd, 0);
  ++counts->switchable_interp[ctx][mbmi->interp_fltr];
}

// This function will copy the best reference mode information from
// MB_MODE_INFO_EXT_FRAME to MB_MODE_INFO_EXT.
static INLINE void copy_mbmi_ext_frame_to_mbmi_ext(
    MB_MODE_INFO_EXT *mbmi_ext,
    const MB_MODE_INFO_EXT_FRAME *const mbmi_ext_best, uint8_t ref_frame_type,
    int skip_mode, PREDICTION_MODE this_mode) {
  if (skip_mode) {
    memcpy(&(mbmi_ext->skip_mvp_candidate_list),
           &(mbmi_ext_best->skip_mvp_candidate_list),
           sizeof(mbmi_ext->skip_mvp_candidate_list));
  }

  MV_REFERENCE_FRAME rf[2];
  av2_set_ref_frame(rf, ref_frame_type);
  if (has_second_drl_by_mode(this_mode, rf)) {
    memcpy(mbmi_ext->ref_mv_stack[rf[0]], mbmi_ext_best->ref_mv_stack[0],
           sizeof(mbmi_ext->ref_mv_stack[0]));
    memcpy(mbmi_ext->weight[rf[0]], mbmi_ext_best->weight[0],
           sizeof(mbmi_ext->weight[0]));
    mbmi_ext->ref_mv_count[rf[0]] = mbmi_ext_best->ref_mv_count[0];
    memcpy(mbmi_ext->ref_mv_stack[rf[1]], mbmi_ext_best->ref_mv_stack[1],
           sizeof(mbmi_ext->ref_mv_stack[0]));
    memcpy(mbmi_ext->weight[rf[1]], mbmi_ext_best->weight[1],
           sizeof(mbmi_ext->weight[0]));
    mbmi_ext->ref_mv_count[rf[1]] = mbmi_ext_best->ref_mv_count[1];
  } else {
    memcpy(mbmi_ext->ref_mv_stack[ref_frame_type],
           mbmi_ext_best->ref_mv_stack[0], sizeof(mbmi_ext->ref_mv_stack[0]));
    memcpy(mbmi_ext->weight[ref_frame_type], mbmi_ext_best->weight[0],
           sizeof(mbmi_ext->weight[0]));
    mbmi_ext->ref_mv_count[ref_frame_type] = mbmi_ext_best->ref_mv_count[0];
  }

  mbmi_ext->mode_context[ref_frame_type] = mbmi_ext_best->mode_context;
  memcpy(mbmi_ext->global_mvs, mbmi_ext_best->global_mvs,
         sizeof(mbmi_ext->global_mvs));

  if (ref_frame_type < INTER_REFS_PER_FRAME) {
    memcpy(mbmi_ext->warp_param_stack[ref_frame_type],
           mbmi_ext_best->warp_param_stack,
           sizeof(mbmi_ext->warp_param_stack[0]));
  }
}

void av2_update_state(const AV2_COMP *const cpi, ThreadData *td,
                      const PICK_MODE_CONTEXT *const ctx, int mi_row,
                      int mi_col, BLOCK_SIZE bsize, RUN_TYPE dry_run) {
  int i, x_idx, y;
  const AV2_COMMON *const cm = &cpi->common;
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const int num_planes = av2_num_planes(cm);
  RD_COUNTS *const rdc = &td->rd_counts;
  MACROBLOCK *const x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
  const MB_MODE_INFO *const mi = &ctx->mic;
  MB_MODE_INFO *const mi_addr = xd->mi[0];
  const struct segmentation *const seg = &cm->seg;
  assert(bsize < BLOCK_SIZES_ALL);
  const int bw = mi_size_wide[mi->sb_type[xd->tree_type == CHROMA_PART]];
  const int bh = mi_size_high[mi->sb_type[xd->tree_type == CHROMA_PART]];
  const int mis = mi_params->mi_stride;
  const int mi_width = mi_size_wide[bsize];
  const int mi_height = mi_size_high[bsize];
  TxfmSearchInfo *txfm_info = &x->txfm_search_info;
  assert(mi->sb_type[xd->tree_type == CHROMA_PART] == bsize);

  *mi_addr = *mi;
  mi_addr->chroma_ref_info = ctx->chroma_ref_info;
  if (is_warp_mode(mi->motion_mode)) update_submi(xd, cm, ctx->submic, bsize);
  if (xd->tree_type != CHROMA_PART)
    copy_mbmi_ext_frame_to_mbmi_ext(x->mbmi_ext, &ctx->mbmi_ext_best,
                                    av2_ref_frame_type(ctx->mic.ref_frame),
                                    mi->skip_mode, ctx->mic.mode);

  for (i = 0; i < num_planes; ++i) {
    const int num_blk_plane =
        (i == AVM_PLANE_Y) ? ctx->num_4x4_blk : ctx->num_4x4_blk_chroma;
    memcpy(txfm_info->blk_skip[i], ctx->blk_skip[i],
           sizeof(*txfm_info->blk_skip[i]) * num_blk_plane);
  }

  txfm_info->skip_txfm = ctx->rd_stats.skip_txfm;
  if (xd->tree_type != CHROMA_PART) {
    xd->tx_type_map = ctx->tx_type_map;
    xd->tx_type_map_stride = mi_size_wide[bsize];
    // If not dry_run, copy the transform type data into the frame level buffer.
    // Encoder will fetch tx types when writing bitstream.
    if (!dry_run) {
      const int grid_idx = get_mi_grid_idx(mi_params, mi_row, mi_col);
      TX_TYPE *const tx_type_map = mi_params->tx_type_map + grid_idx;
      const int mi_stride = mi_params->mi_stride;
      for (int blk_row = 0; blk_row < bh; ++blk_row) {
        av2_copy_array(tx_type_map + blk_row * mi_stride,
                       xd->tx_type_map + blk_row * xd->tx_type_map_stride, bw);
      }
      xd->tx_type_map = tx_type_map;
      xd->tx_type_map_stride = mi_stride;
    }
  }

  if (xd->tree_type != LUMA_PART && xd->is_chroma_ref &&
      is_cctx_allowed(cm, xd)) {
    xd->cctx_type_map = ctx->cctx_type_map;
    const BLOCK_SIZE chroma_bsize = get_bsize_base(xd, mi, AVM_PLANE_U);
    xd->cctx_type_map_stride = mi_size_wide[chroma_bsize];
    // If not dry_run, copy the cctx type data into the frame level buffer.
    // Encoder will fetch cctx types when writing bitstream.
    if (!dry_run) {
      const int mi_stride = mi_params->mi_stride;
      CctxType cur_cctx_type =
          txfm_info->skip_txfm ? CCTX_NONE : xd->cctx_type_map[0];
      const int chroma_bw = mi_size_wide[chroma_bsize];
      const int chroma_bh = mi_size_high[chroma_bsize];
      const int grid_idx =
          get_mi_grid_idx(mi_params, mi->chroma_ref_info.mi_row_chroma_base,
                          mi->chroma_ref_info.mi_col_chroma_base);
      CctxType *const cctx_type_map = mi_params->cctx_type_map + grid_idx;
      for (int blk_row = 0; blk_row < chroma_bh; ++blk_row) {
        memset(&cctx_type_map[blk_row * mi_stride], cur_cctx_type,
               chroma_bw * sizeof(cctx_type_map[0]));
      }
      xd->cctx_type_map = cctx_type_map;
      xd->cctx_type_map_stride = mi_stride;
    }
  }

  // If segmentation in use
  if (seg->enabled) {
    // For in frame complexity AQ copy the segment id from the segment map.
    if (cpi->oxcf.q_cfg.aq_mode == COMPLEXITY_AQ &&
        xd->tree_type != CHROMA_PART) {
      const uint8_t *const map =
          seg->update_map ? cpi->enc_seg.map : cm->last_frame_seg_map;
      mi_addr->segment_id =
          map ? get_segment_id(mi_params, map, bsize, mi_row, mi_col) : 0;
    }
    // Else for cyclic refresh mode update the segment map, set the segment id
    // and then update the quantizer.
    if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ &&
        xd->tree_type != CHROMA_PART) {
      av2_cyclic_refresh_update_segment(cpi, mi_addr, mi_row, mi_col, bsize,
                                        ctx->rd_stats.rate, ctx->rd_stats.dist,
                                        txfm_info->skip_txfm);
    }

    if (mi_addr->uv_mode == UV_CFL_PRED &&
        !is_cfl_allowed(cm->seq_params.enable_cfl_intra, xd) &&
        !is_mhccp_allowed(cm, xd)) {
      mi_addr->uv_mode = UV_DC_PRED;
    }
  }
  for (i = (xd->tree_type == CHROMA_PART); i < num_planes; ++i) {
    p[i].coeff = ctx->coeff[i];
    p[i].qcoeff = ctx->qcoeff[i];
    p[i].dqcoeff = ctx->dqcoeff[i];
    p[i].eobs = ctx->eobs[i];
    p[i].bobs = ctx->bobs[i];
    p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
  }
  for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
  // Restore the coding context of the MB to that that was in place
  // when the mode was picked for it
  // Note: the copying here must match corresponding decoder-side copying in
  // parse_decode_block().
  // TODO(any): Refactor.
  for (y = 0; y < mi_height; y++) {
    for (x_idx = 0; x_idx < mi_width; x_idx++) {
      if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx &&
          (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
        const int mi_idx =
            get_alloc_mi_idx(mi_params, mi_row + y, mi_col + x_idx);
        xd->mi[x_idx + y * mis] = &mi_params->mi_alloc[mi_idx];
        if (xd->tree_type == LUMA_PART) {
          *(xd->mi[x_idx + y * mis]) = *mi_addr;
        } else if (xd->tree_type == CHROMA_PART) {
          xd->mi[x_idx + y * mis]->sb_type[PLANE_TYPE_UV] =
              mi_addr->sb_type[PLANE_TYPE_UV];
          xd->mi[x_idx + y * mis]->uv_mode = mi_addr->uv_mode;
          xd->mi[x_idx + y * mis]->angle_delta[PLANE_TYPE_UV] =
              mi_addr->angle_delta[PLANE_TYPE_UV];
          xd->mi[x_idx + y * mis]->cfl_alpha_signs = mi_addr->cfl_alpha_signs;
          xd->mi[x_idx + y * mis]->cfl_alpha_idx = mi_addr->cfl_alpha_idx;
          xd->mi[x_idx + y * mis]->partition = mi_addr->partition;
          xd->mi[x_idx + y * mis]->chroma_mi_row_start =
              mi_addr->chroma_mi_row_start;
          xd->mi[x_idx + y * mis]->chroma_mi_col_start =
              mi_addr->chroma_mi_col_start;
          xd->mi[x_idx + y * mis]
              ->palette_mode_info.palette_size[PLANE_TYPE_UV] =
              mi_addr->palette_mode_info.palette_size[PLANE_TYPE_UV];
          for (i = PALETTE_MAX_SIZE; i < 3 * PALETTE_MAX_SIZE; i++)
            xd->mi[x_idx + y * mis]->palette_mode_info.palette_colors[i] =
                mi_addr->palette_mode_info.palette_colors[i];
        } else {
          xd->mi[x_idx + y * mis] = mi_addr;
        }
      }
    }
  }

  if (cpi->oxcf.q_cfg.aq_mode)
    av2_init_plane_quantizers(cpi, x, mi_addr->segment_id);

  if (dry_run) return;

  if (mi_addr->ref_frame[0] != INTRA_FRAME) {
    if (cm->features.interp_filter == SWITCHABLE &&
        !is_warp_mode(mi_addr->motion_mode) &&
        !is_nontrans_global_motion(xd, xd->mi[0])) {
      update_filter_type_count(td->counts, xd, mi_addr);
    }

    rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
    rdc->comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
    rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
  }
}

void av2_update_inter_mode_stats(FRAME_CONTEXT *fc, FRAME_COUNTS *counts,
                                 PREDICTION_MODE mode, int16_t mode_context,
                                 const AV2_COMMON *const cm,
                                 const MACROBLOCKD *xd,
                                 const MB_MODE_INFO *mbmi, BLOCK_SIZE bsize

) {
  (void)counts;

  if (is_tip_ref_frame(mbmi->ref_frame[0])) {
    const int tip_pred_index =
        tip_pred_mode_to_index[mode - SINGLE_INTER_MODE_START];
#if CONFIG_ENTROPY_STATS
    ++counts->tip_pred_mode_cnt[tip_pred_index];
#endif  // CONFIG_ENTROPY_STATS
    update_cdf(fc->tip_pred_mode_cdf, tip_pred_index, TIP_PRED_MODES);
    return;
  }

  if (is_warpmv_mode_allowed(cm, mbmi, bsize)) {
    const int16_t iswarpmvmode_ctx = inter_warpmv_mode_ctx(cm, xd, mbmi);
    const int is_warpmv_or_warp_newmv = (mode == WARPMV || mode == WARP_NEWMV);
#if CONFIG_ENTROPY_STATS
    ++counts->inter_warp_cnts[iswarpmvmode_ctx][is_warpmv_or_warp_newmv];
#endif  // CONFIG_ENTROPY_STATS
    update_cdf(fc->inter_warp_mode_cdf[iswarpmvmode_ctx],
               is_warpmv_or_warp_newmv, 2);
    if (is_warpmv_or_warp_newmv) {
      if (is_warp_newmv_allowed(cm, xd, mbmi, bsize)) {
#if CONFIG_ENTROPY_STATS
        ++counts->is_warpmv_or_warp_newmv_cnt[mode == WARPMV];
#endif  // CONFIG_ENTROPY_STATS
        update_cdf(fc->is_warpmv_or_warp_newmv_cdf, mode == WARPMV, 2);
      }
      return;
    }
  }

  const int16_t ismode_ctx = inter_single_mode_ctx(mode_context);
#if CONFIG_ENTROPY_STATS
  ++counts->inter_single_mode[ismode_ctx][mode - SINGLE_INTER_MODE_START];
#endif  // CONFIG_ENTROPY_STATS
  update_cdf(fc->inter_single_mode_cdf[ismode_ctx],
             mode - SINGLE_INTER_MODE_START, INTER_SINGLE_MODES);
}

static void update_palette_cdf(MACROBLOCKD *xd, const MB_MODE_INFO *const mbmi,
                               FRAME_COUNTS *counts) {
  FRAME_CONTEXT *fc = xd->tile_ctx;
  const PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;

  (void)counts;
  if (mbmi->mode == DC_PRED && xd->tree_type != CHROMA_PART) {
    const int n = pmi->palette_size[0];
#if CONFIG_ENTROPY_STATS
    ++counts->palette_y_mode[n > 0];
#endif
    update_cdf(fc->palette_y_mode_cdf, n > 0, 2);
    if (n > 0) {
#if CONFIG_ENTROPY_STATS
      ++counts->palette_y_size[n - PALETTE_MIN_SIZE];
#endif
      update_cdf(fc->palette_y_size_cdf, n - PALETTE_MIN_SIZE, PALETTE_SIZES);
    }
  }
}

static INLINE void update_fsc_cdf(const AV2_COMMON *const cm, MACROBLOCKD *xd,
#if CONFIG_ENTROPY_STATS
                                  FRAME_COUNTS *counts,
#endif  // CONFIG_ENTROPY_STATS
                                  const int intraonly) {
  const MB_MODE_INFO *const mbmi = xd->mi[0];
  const BLOCK_SIZE bsize = mbmi->sb_type[xd->tree_type == CHROMA_PART];
  if (allow_fsc_intra(cm, bsize, mbmi)) {
#if CONFIG_ENTROPY_STATS
    const int ctx = get_fsc_mode_ctx(xd, intraonly);
    ++counts->fsc_mode[ctx][fsc_bsize_groups[bsize]]
                      [mbmi->fsc_mode[xd->tree_type == CHROMA_PART]];
#endif  // CONFIG_ENTROPY_STATS
    avm_cdf_prob *fsc_cdf = get_fsc_mode_cdf(xd, bsize, intraonly);
    update_cdf(fsc_cdf, mbmi->fsc_mode[xd->tree_type == CHROMA_PART],
               FSC_MODES);
  }
}

void av2_sum_intra_stats(const AV2_COMMON *const cm, FRAME_COUNTS *counts,
                         MACROBLOCKD *xd, const MB_MODE_INFO *const mbmi) {
  FRAME_CONTEXT *fc = xd->tile_ctx;
#if CONFIG_ENTROPY_STATS
  int cdf_idx = cm->coef_cdf_category;
#endif
  (void)counts;
  const BLOCK_SIZE bsize = mbmi->sb_type[xd->tree_type == CHROMA_PART];
  if (xd->tree_type != CHROMA_PART) {
    const int intraonly = frame_is_intra_only(cm);
    if (xd->lossless[mbmi->segment_id]) {
      update_cdf(fc->dpcm_cdf, mbmi->use_dpcm_y, 2);
      if (mbmi->use_dpcm_y == 0) {
        const int context = get_y_mode_idx_ctx(xd);
        const int mode_idx = mbmi->y_mode_idx;
        int mode_set_index = mode_idx < FIRST_MODE_COUNT ? 0 : 1;
        mode_set_index += ((mode_idx - FIRST_MODE_COUNT) / SECOND_MODE_COUNT);
#if CONFIG_ENTROPY_STATS
        ++counts->y_mode_set_idx[mode_set_index];
#endif
        update_cdf(fc->y_mode_set_cdf, mode_set_index, INTRA_MODE_SETS);
        if (mode_set_index == 0) {
          int mode_set_low = AVMMIN(mode_idx, LUMA_INTRA_MODE_INDEX_COUNT - 1);
#if CONFIG_ENTROPY_STATS
          ++counts->y_mode_idx[context][mode_set_low];
#endif
          update_cdf(fc->y_mode_idx_cdf[context], mode_set_low,
                     LUMA_INTRA_MODE_INDEX_COUNT);
          if (mode_set_low == (LUMA_INTRA_MODE_INDEX_COUNT - 1)) {
#if CONFIG_ENTROPY_STATS
            ++counts->y_mode_idx_offset[context][mode_idx - mode_set_low];
#endif
            update_cdf(fc->y_mode_idx_offset_cdf[context],
                       mode_idx - mode_set_low, LUMA_INTRA_MODE_OFFSET_COUNT);
          }
        }
      } else {
        update_cdf(fc->dpcm_vert_horz_cdf, mbmi->dpcm_mode_y, 2);
      }
    } else {
      const int context = get_y_mode_idx_ctx(xd);
      const int mode_idx = mbmi->y_mode_idx;
      int mode_set_index = mode_idx < FIRST_MODE_COUNT ? 0 : 1;
      mode_set_index += ((mode_idx - FIRST_MODE_COUNT) / SECOND_MODE_COUNT);
#if CONFIG_ENTROPY_STATS
      ++counts->y_mode_set_idx[mode_set_index];
#endif
      update_cdf(fc->y_mode_set_cdf, mode_set_index, INTRA_MODE_SETS);
      if (mode_set_index == 0) {
        int mode_set_low = AVMMIN(mode_idx, LUMA_INTRA_MODE_INDEX_COUNT - 1);
#if CONFIG_ENTROPY_STATS
        ++counts->y_mode_idx[context][mode_set_low];
#endif
        update_cdf(fc->y_mode_idx_cdf[context], mode_set_low,
                   LUMA_INTRA_MODE_INDEX_COUNT);
        if (mode_set_low == (LUMA_INTRA_MODE_INDEX_COUNT - 1)) {
#if CONFIG_ENTROPY_STATS
          ++counts->y_mode_idx_offset[context][mode_idx - mode_set_low];
#endif
          update_cdf(fc->y_mode_idx_offset_cdf[context],
                     mode_idx - mode_set_low, LUMA_INTRA_MODE_OFFSET_COUNT);
        }
      }
    }

    update_fsc_cdf(cm, xd,
#if CONFIG_ENTROPY_STATS
                   counts,
#endif  // CONFIG_ENTROPY_STATS
                   intraonly);
    if (cm->seq_params.enable_mrls && av2_is_directional_mode(mbmi->mode)) {
      if (xd->lossless[mbmi->segment_id]) {
        if (mbmi->use_dpcm_y == 0) {
          int mrl_ctx = get_mrl_index_ctx(xd->neighbors[0], xd->neighbors[1]);
          update_cdf(fc->mrl_index_cdf[mrl_ctx], mbmi->mrl_index,
                     MRL_LINE_NUMBER);
          if (mbmi->mrl_index) {
            int multi_line_mrl_ctx = get_multi_line_mrl_index_ctx(
                xd->neighbors[0], xd->neighbors[1]);
            update_cdf(fc->multi_line_mrl_cdf[multi_line_mrl_ctx],
                       mbmi->multi_line_mrl, 2);
          }
#if CONFIG_ENTROPY_STATS
          ++counts->mrl_index[mrl_ctx][mbmi->mrl_index];
          if (mbmi->mrl_index) {
            int multi_line_mrl_ctx = get_multi_line_mrl_index_ctx(
                xd->neighbors[0], xd->neighbors[1]);
            ++counts->multi_line_mrl[multi_line_mrl_ctx][mbmi->multi_line_mrl];
          }
#endif  // CONFIG_ENTROPY_STATS
        }
      } else {
        int mrl_ctx = get_mrl_index_ctx(xd->neighbors[0], xd->neighbors[1]);
        update_cdf(fc->mrl_index_cdf[mrl_ctx], mbmi->mrl_index,
                   MRL_LINE_NUMBER);
        if (mbmi->mrl_index) {
          int multi_line_mrl_ctx =
              get_multi_line_mrl_index_ctx(xd->neighbors[0], xd->neighbors[1]);
          update_cdf(fc->multi_line_mrl_cdf[multi_line_mrl_ctx],
                     mbmi->multi_line_mrl, 2);
        }
#if CONFIG_ENTROPY_STATS
        ++counts->mrl_index[mrl_ctx][mbmi->mrl_index];
        if (mbmi->mrl_index) {
          int multi_line_mrl_ctx =
              get_multi_line_mrl_index_ctx(xd->neighbors[0], xd->neighbors[1]);
          ++counts->multi_line_mrl[multi_line_mrl_ctx][mbmi->multi_line_mrl];
        }
#endif  // CONFIG_ENTROPY_STATS
      }
    }
    if (av2_intra_dip_allowed(cm, mbmi)) {
      const int use_intra_dip = mbmi->use_intra_dip;
      int ctx = get_intra_dip_ctx(xd->neighbors[0], xd->neighbors[1], bsize);
#if CONFIG_ENTROPY_STATS
      ++counts->intra_dip[cdf_idx][ctx][use_intra_dip];
      if (use_intra_dip) {
        ++counts->intra_dip_mode_n6[mbmi->intra_dip_mode & 15];
      }
#endif
      avm_cdf_prob *cdf = fc->intra_dip_cdf[ctx];
      update_cdf(cdf, use_intra_dip, 2);
      if (use_intra_dip) {
        int n_modes = av2_intra_dip_modes(bsize);
        avm_cdf_prob *mode_cdf = xd->tile_ctx->intra_dip_mode_n6_cdf;
        update_cdf(mode_cdf, mbmi->intra_dip_mode & 15, n_modes);
      }
    }
  }

  if (!xd->is_chroma_ref) return;
  if (xd->tree_type != LUMA_PART) {
    const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
    const CFL_ALLOWED_TYPE cfl_allowed =
        is_cfl_allowed(cm->seq_params.enable_cfl_intra, xd) ||
        is_mhccp_allowed(cm, xd);
    const int uv_context = av2_is_directional_mode(mbmi->mode) ? 1 : 0;
#if CONFIG_ENTROPY_STATS
    if (cfl_allowed) {
      const int cfl_ctx = get_cfl_ctx(xd);
      ++counts->cfl_mode[cfl_ctx][uv_mode == UV_CFL_PRED];
      if (uv_mode != UV_CFL_PRED) {
        ++counts->uv_mode[uv_context][uv_mode];
      }
    } else {
      ++counts->uv_mode[uv_context][uv_mode];
    }
#endif  // CONFIG_ENTROPY_STATS
    if (cfl_allowed) {
      const int cfl_ctx = get_cfl_ctx(xd);
      update_cdf(fc->cfl_cdf[cfl_ctx], mbmi->uv_mode == UV_CFL_PRED, 2);
      if (mbmi->uv_mode != UV_CFL_PRED) {
        if (xd->lossless[mbmi->segment_id]) {
          update_cdf(fc->dpcm_uv_cdf, mbmi->use_dpcm_uv, 2);
          if (mbmi->use_dpcm_uv == 0) {
            int mode_set_low =
                AVMMIN(mbmi->uv_mode_idx, CHROMA_INTRA_MODE_INDEX_COUNT - 1);
#if CONFIG_ENTROPY_STATS
            ++counts->uv_mode[uv_context][mode_set_low];
#endif
            update_cdf(fc->uv_mode_cdf[uv_context], mode_set_low,
                       CHROMA_INTRA_MODE_INDEX_COUNT);
          } else {
            update_cdf(fc->dpcm_uv_vert_horz_cdf, mbmi->dpcm_mode_uv, 2);
          }
        } else {
          int mode_set_low =
              AVMMIN(mbmi->uv_mode_idx, CHROMA_INTRA_MODE_INDEX_COUNT - 1);
#if CONFIG_ENTROPY_STATS
          ++counts->uv_mode[uv_context][mode_set_low];
#endif
          update_cdf(fc->uv_mode_cdf[uv_context], mode_set_low,
                     CHROMA_INTRA_MODE_INDEX_COUNT);
        }
      }
    } else {
      if (xd->lossless[mbmi->segment_id]) {
        update_cdf(fc->dpcm_uv_cdf, mbmi->use_dpcm_uv, 2);
        if (mbmi->use_dpcm_uv == 0) {
          int mode_set_low =
              AVMMIN(mbmi->uv_mode_idx, CHROMA_INTRA_MODE_INDEX_COUNT - 1);
#if CONFIG_ENTROPY_STATS
          ++counts->uv_mode[uv_context][mode_set_low];
#endif
          update_cdf(fc->uv_mode_cdf[uv_context], mode_set_low,
                     CHROMA_INTRA_MODE_INDEX_COUNT);
        } else {
          update_cdf(fc->dpcm_uv_vert_horz_cdf, mbmi->dpcm_mode_uv, 2);
        }
      } else {
        int mode_set_low =
            AVMMIN(mbmi->uv_mode_idx, CHROMA_INTRA_MODE_INDEX_COUNT - 1);
#if CONFIG_ENTROPY_STATS
        ++counts->uv_mode[uv_context][mode_set_low];
#endif
        update_cdf(fc->uv_mode_cdf[uv_context], mode_set_low,
                   CHROMA_INTRA_MODE_INDEX_COUNT);
      }
    }
    if (mbmi->uv_mode == UV_CFL_PRED) {
#if CONFIG_ENTROPY_STATS
      ++counts->cfl_index[mbmi->cfl_idx];
#endif
      if (is_mhccp_allowed(cm, xd)) {
        update_cdf(fc->cfl_mhccp_cdf, mbmi->cfl_idx == CFL_MULTI_PARAM,
                   CFL_MHCCP_SWITCH_NUM);
        if (mbmi->cfl_idx == CFL_MULTI_PARAM) {
          avm_cdf_prob *filter_dir_cdf = get_mhccp_dir_cdf(xd, bsize);
          update_cdf(filter_dir_cdf, mbmi->mh_dir, MHCCP_MODE_NUM);
        } else {
          update_cdf(fc->cfl_index_cdf, mbmi->cfl_idx, CFL_TYPE_COUNT - 1);
        }
      } else {
        if (cm->seq_params.enable_cfl_intra)
          update_cdf(fc->cfl_index_cdf, mbmi->cfl_idx, CFL_TYPE_COUNT - 1);
      }
    }
    if (uv_mode == UV_CFL_PRED) {
      const int8_t joint_sign = mbmi->cfl_alpha_signs;
      const uint8_t idx = mbmi->cfl_alpha_idx;

#if CONFIG_ENTROPY_STATS
      ++counts->cfl_sign[joint_sign];
#endif
      update_cdf(fc->cfl_sign_cdf, joint_sign, CFL_JOINT_SIGNS);
      if (CFL_SIGN_U(joint_sign) != CFL_SIGN_ZERO) {
        avm_cdf_prob *cdf_u = fc->cfl_alpha_cdf[CFL_CONTEXT_U(joint_sign)];

#if CONFIG_ENTROPY_STATS
        ++counts->cfl_alpha[CFL_CONTEXT_U(joint_sign)][CFL_IDX_U(idx)];
#endif
        update_cdf(cdf_u, CFL_IDX_U(idx), CFL_ALPHABET_SIZE);
      }
      if (CFL_SIGN_V(joint_sign) != CFL_SIGN_ZERO) {
        avm_cdf_prob *cdf_v = fc->cfl_alpha_cdf[CFL_CONTEXT_V(joint_sign)];

#if CONFIG_ENTROPY_STATS
        ++counts->cfl_alpha[CFL_CONTEXT_V(joint_sign)][CFL_IDX_V(idx)];
#endif
        update_cdf(cdf_v, CFL_IDX_V(idx), CFL_ALPHABET_SIZE);
      }
    }
  }
  if (av2_allow_palette(PLANE_TYPE_Y, cm->features.allow_screen_content_tools,
                        bsize)) {
    update_palette_cdf(xd, mbmi, counts);
  }
}

void av2_restore_context(const AV2_COMMON *cm, MACROBLOCK *x,
                         const RD_SEARCH_MACROBLOCK_CONTEXT *ctx, int mi_row,
                         int mi_col, BLOCK_SIZE bsize, const int num_planes) {
  (void)cm;
  MACROBLOCKD *xd = &x->e_mbd;
  int p;
  const int num_4x4_blocks_wide = mi_size_wide[bsize];
  const int num_4x4_blocks_high = mi_size_high[bsize];
  int mi_width = mi_size_wide[bsize];
  int mi_height = mi_size_high[bsize];
  for (p = (xd->tree_type == CHROMA_PART); p < num_planes; p++) {
    int tx_col = mi_col;
    int tx_row = mi_row & MAX_MIB_MASK;
    memcpy(
        xd->above_entropy_context[p] + (tx_col >> xd->plane[p].subsampling_x),
        ctx->a + num_4x4_blocks_wide * p,
        (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide) >>
            xd->plane[p].subsampling_x);
    memcpy(xd->left_entropy_context[p] + (tx_row >> xd->plane[p].subsampling_y),
           ctx->l + num_4x4_blocks_high * p,
           (sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high) >>
               xd->plane[p].subsampling_y);
    memcpy(xd->above_partition_context[p] + mi_col, ctx->sa + mi_width * p,
           sizeof(*xd->above_partition_context[p]) * mi_width);
    memcpy(xd->left_partition_context[p] + (mi_row & MAX_MIB_MASK),
           ctx->sl + mi_height * p,
           sizeof(xd->left_partition_context[p][0]) * mi_height);
  }
  av2_mark_block_as_not_coded(xd, mi_row, mi_col, bsize, cm->sb_size);
}

void av2_save_context(const MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *ctx,
                      int mi_row, int mi_col, BLOCK_SIZE bsize,
                      const int num_planes) {
  const MACROBLOCKD *xd = &x->e_mbd;
  int p;
  int mi_width = mi_size_wide[bsize];
  int mi_height = mi_size_high[bsize];

  // buffer the above/left context information of the block in search.
  for (p = (xd->tree_type == CHROMA_PART); p < num_planes; ++p) {
    int tx_col = mi_col;
    int tx_row = mi_row & MAX_MIB_MASK;
    memcpy(
        ctx->a + mi_width * p,
        xd->above_entropy_context[p] + (tx_col >> xd->plane[p].subsampling_x),
        (sizeof(ENTROPY_CONTEXT) * mi_width) >> xd->plane[p].subsampling_x);
    memcpy(ctx->l + mi_height * p,
           xd->left_entropy_context[p] + (tx_row >> xd->plane[p].subsampling_y),
           (sizeof(ENTROPY_CONTEXT) * mi_height) >> xd->plane[p].subsampling_y);
    memcpy(ctx->sa + mi_width * p, xd->above_partition_context[p] + mi_col,
           sizeof(*xd->above_partition_context[p]) * mi_width);
    memcpy(ctx->sl + mi_height * p,
           xd->left_partition_context[p] + (mi_row & MAX_MIB_MASK),
           sizeof(xd->left_partition_context[p][0]) * mi_height);
  }
}

static void set_partial_sb_partition(const AV2_COMMON *const cm,
                                     MB_MODE_INFO *mi, int bh_in, int bw_in,
                                     int mi_rows_remaining,
                                     int mi_cols_remaining, BLOCK_SIZE bsize,
                                     MB_MODE_INFO **mib) {
  int bh = bh_in;
  int r, c;
  for (r = 0; r < cm->mib_size; r += bh) {
    int bw = bw_in;
    for (c = 0; c < cm->mib_size; c += bw) {
      const int grid_index = get_mi_grid_idx(&cm->mi_params, r, c);
      const int mi_index = get_alloc_mi_idx(&cm->mi_params, r, c);
      mib[grid_index] = mi + mi_index;
      mib[grid_index]->sb_type[PLANE_TYPE_Y] =
          mib[grid_index]->sb_type[PLANE_TYPE_UV] = find_partition_size(
              bsize, mi_rows_remaining - r, mi_cols_remaining - c, &bh, &bw);
    }
  }
}

// This function attempts to set all mode info entries in a given superblock
// to the same block partition size.
// However, at the bottom and right borders of the image the requested size
// may not be allowed in which case this code attempts to choose the largest
// allowable partition.
void av2_set_fixed_partitioning(AV2_COMP *cpi, const TileInfo *const tile,
                                MB_MODE_INFO **mib, int mi_row, int mi_col,
                                BLOCK_SIZE bsize) {
  AV2_COMMON *const cm = &cpi->common;
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  const int mi_rows_remaining = tile->mi_row_end - mi_row;
  const int mi_cols_remaining = tile->mi_col_end - mi_col;
  MB_MODE_INFO *const mi_upper_left =
      mi_params->mi_alloc + get_alloc_mi_idx(mi_params, mi_row, mi_col);
  int bh = mi_size_high[bsize];
  int bw = mi_size_wide[bsize];

  assert(bsize >= mi_params->mi_alloc_bsize &&
         "Attempted to use bsize < mi_params->mi_alloc_bsize");
  assert((mi_rows_remaining > 0) && (mi_cols_remaining > 0));

  // Apply the requested partition size to the SB if it is all "in image"
  if ((mi_cols_remaining >= cm->mib_size) &&
      (mi_rows_remaining >= cm->mib_size)) {
    for (int block_row = 0; block_row < cm->mib_size; block_row += bh) {
      for (int block_col = 0; block_col < cm->mib_size; block_col += bw) {
        const int grid_index = get_mi_grid_idx(mi_params, block_row, block_col);
        const int mi_index = get_alloc_mi_idx(mi_params, block_row, block_col);
        mib[grid_index] = mi_upper_left + mi_index;
        mib[grid_index]->sb_type[PLANE_TYPE_Y] = bsize;
        mib[grid_index]->sb_type[PLANE_TYPE_UV] = bsize;
      }
    }
  } else {
    // Else this is a partial SB.
    set_partial_sb_partition(cm, mi_upper_left, bh, bw, mi_rows_remaining,
                             mi_cols_remaining, bsize, mib);
  }
}

int av2_get_rdmult_delta(AV2_COMP *cpi, BLOCK_SIZE bsize, int mi_row,
                         int mi_col, int orig_rdmult) {
  AV2_COMMON *const cm = &cpi->common;
  const GF_GROUP *const gf_group = &cpi->gf_group;
  assert(IMPLIES(cpi->gf_group.size > 0,
                 cpi->gf_group.index < cpi->gf_group.size));
  const int tpl_idx = cpi->gf_group.index;
  TplParams *const tpl_data = &cpi->tpl_data;
  TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
  TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
  const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
  int tpl_stride = tpl_frame->stride;
  int64_t intra_cost = 0;
  int64_t mc_dep_cost = 0;
  const int mi_wide = mi_size_wide[bsize];
  const int mi_high = mi_size_high[bsize];

  if (tpl_frame->is_valid == 0) return orig_rdmult;

  if (!is_frame_tpl_eligible(gf_group, gf_group->index)) return orig_rdmult;

  if (cpi->gf_group.index >= MAX_TPL_FRAME_IDX) return orig_rdmult;

#ifndef NDEBUG
  int mi_count = 0;
#endif  // NDEBUG
  const int mi_col_sr = mi_col;
  const int mi_col_end_sr = mi_col + mi_wide;
  const int mi_cols_sr = av2_pixels_to_mi(cm->width);
  const int step = 1 << block_mis_log2;
  const int row_step = step;
  const int col_step_sr = step;
  for (int row = mi_row; row < mi_row + mi_high; row += row_step) {
    for (int col = mi_col_sr; col < mi_col_end_sr; col += col_step_sr) {
      if (row >= cm->mi_params.mi_rows || col >= mi_cols_sr) continue;
      TplDepStats *this_stats =
          &tpl_stats[av2_tpl_ptr_pos(row, col, tpl_stride, block_mis_log2)];
      int64_t mc_dep_delta =
          RDCOST(tpl_frame->base_rdmult, this_stats->mc_dep_rate,
                 this_stats->mc_dep_dist);
      intra_cost += this_stats->recrf_dist << RDDIV_BITS;
      mc_dep_cost += (this_stats->recrf_dist << RDDIV_BITS) + mc_dep_delta;
#ifndef NDEBUG
      mi_count++;
#endif  // NDEBUG
    }
  }
  assert(mi_count <= MAX_TPL_BLK_IN_SB * MAX_TPL_BLK_IN_SB);

  avm_clear_system_state();

  double beta = 1.0;
  if (mc_dep_cost > 0 && intra_cost > 0) {
    const double r0 = cpi->rd.r0;
    const double rk = (double)intra_cost / mc_dep_cost;
    beta = (r0 / rk);
  }

  int rdmult = av2_get_adaptive_rdmult(cpi, beta);

  avm_clear_system_state();

  rdmult = AVMMIN(rdmult, orig_rdmult * 3 / 2);
  rdmult = AVMMAX(rdmult, orig_rdmult * 1 / 2);

  rdmult = AVMMAX(1, rdmult);

  return rdmult;
}

// Checks to see if a super block is on a horizontal image edge.
// In most cases this is the "real" edge unless there are formatting
// bars embedded in the stream.
int av2_active_h_edge(const AV2_COMP *cpi, int mi_row, int mi_step) {
  int top_edge = 0;
  int bottom_edge = cpi->common.mi_params.mi_rows;
  int is_active_h_edge = 0;

  if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
      ((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
    is_active_h_edge = 1;
  }
  return is_active_h_edge;
}

// Checks to see if a super block is on a vertical image edge.
// In most cases this is the "real" edge unless there are formatting
// bars embedded in the stream.
int av2_active_v_edge(const AV2_COMP *cpi, int mi_col, int mi_step) {
  int left_edge = 0;
  int right_edge = cpi->common.mi_params.mi_cols;
  int is_active_v_edge = 0;

  if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
      ((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
    is_active_v_edge = 1;
  }
  return is_active_v_edge;
}

void av2_get_tpl_stats_sb(AV2_COMP *cpi, BLOCK_SIZE bsize, int mi_row,
                          int mi_col, SuperBlockEnc *sb_enc) {
  sb_enc->tpl_data_count = 0;

  if (!cpi->oxcf.algo_cfg.enable_tpl_model) return;
  if (cpi->common.current_frame.frame_type == KEY_FRAME) return;
  const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
  if (update_type == INTNL_OVERLAY_UPDATE || update_type == OVERLAY_UPDATE ||
      update_type == KFFLT_OVERLAY_UPDATE)
    return;
  assert(IMPLIES(cpi->gf_group.size > 0,
                 cpi->gf_group.index < cpi->gf_group.size));

  AV2_COMMON *const cm = &cpi->common;
  const int gf_group_index = cpi->gf_group.index;
  TplParams *const tpl_data = &cpi->tpl_data;
  TplDepFrame *tpl_frame = &tpl_data->tpl_frame[gf_group_index];
  TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
  int tpl_stride = tpl_frame->stride;
  const int mi_wide = mi_size_wide[bsize];
  const int mi_high = mi_size_high[bsize];

  if (tpl_frame->is_valid == 0) return;
  if (gf_group_index >= MAX_TPL_FRAME_IDX) return;

  int mi_count = 0;
  int count = 0;
  const int mi_col_sr = mi_col;
  const int mi_col_end_sr = mi_col + mi_wide;
  const int mi_cols_sr = av2_pixels_to_mi(cm->width);
  // TPL store unit size is not the same as the motion estimation unit size.
  // Here always use motion estimation size to avoid getting repetitive inter/
  // intra cost.
  const BLOCK_SIZE tpl_bsize = convert_length_to_bsize(tpl_data->tpl_bsize_1d);
  assert(mi_size_wide[tpl_bsize] == mi_size_high[tpl_bsize]);
  const int row_step = mi_size_high[tpl_bsize];
  const int col_step_sr = mi_size_wide[tpl_bsize];

  // Stride is only based on SB size, and we fill in values for every 16x16
  // block in a SB.
  sb_enc->tpl_stride = (mi_col_end_sr - mi_col_sr) / col_step_sr;

  for (int row = mi_row; row < mi_row + mi_high; row += row_step) {
    for (int col = mi_col_sr; col < mi_col_end_sr; col += col_step_sr) {
      assert(count < MAX_TPL_BLK_IN_SB * MAX_TPL_BLK_IN_SB);
      // Handle partial SB, so that no invalid values are used later.
      if (row >= cm->mi_params.mi_rows || col >= mi_cols_sr) {
        sb_enc->tpl_inter_cost[count] = INT64_MAX;
        sb_enc->tpl_intra_cost[count] = INT64_MAX;
        for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
          sb_enc->tpl_mv[count][i].as_int = INVALID_MV;
        }
        count++;
        continue;
      }

      TplDepStats *this_stats = &tpl_stats[av2_tpl_ptr_pos(
          row, col, tpl_stride, tpl_data->tpl_stats_block_mis_log2)];
      sb_enc->tpl_inter_cost[count] = this_stats->inter_cost;
      sb_enc->tpl_intra_cost[count] = this_stats->intra_cost;
      memcpy(sb_enc->tpl_mv[count], this_stats->mv, sizeof(this_stats->mv));
      mi_count++;
      count++;
    }
  }

  assert(mi_count <= MAX_TPL_BLK_IN_SB * MAX_TPL_BLK_IN_SB);
  sb_enc->tpl_data_count = mi_count;
}

// analysis_type 0: Use mc_dep_cost and intra_cost
// analysis_type 1: Use count of best inter predictor chosen
// analysis_type 2: Use cost reduction from intra to inter for best inter
//                  predictor chosen
int av2_get_q_for_deltaq_objective(AV2_COMP *const cpi, BLOCK_SIZE bsize,
                                   int mi_row, int mi_col) {
  AV2_COMMON *const cm = &cpi->common;
  const GF_GROUP *const gf_group = &cpi->gf_group;
  assert(IMPLIES(cpi->gf_group.size > 0,
                 cpi->gf_group.index < cpi->gf_group.size));
  const int tpl_idx = cpi->gf_group.index;
  TplParams *const tpl_data = &cpi->tpl_data;
  TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
  TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
  const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
  int tpl_stride = tpl_frame->stride;
  int64_t intra_cost = 0;
  int64_t mc_dep_cost = 0;
  const int mi_wide = mi_size_wide[bsize];
  const int mi_high = mi_size_high[bsize];
  const int base_qindex = cm->quant_params.base_qindex;

  if (tpl_frame->is_valid == 0) return base_qindex;

  if (!is_frame_tpl_eligible(gf_group, gf_group->index)) return base_qindex;

  if (cpi->gf_group.index >= MAX_TPL_FRAME_IDX) return base_qindex;

#ifndef NDEBUG
  int mi_count = 0;
#endif  // NDEBUG
  const int mi_col_sr = mi_col;
  const int mi_col_end_sr = mi_col + mi_wide;
  const int mi_cols_sr = av2_pixels_to_mi(cm->width);
  const int step = 1 << block_mis_log2;
  const int row_step = step;
  const int col_step_sr = step;
  for (int row = mi_row; row < mi_row + mi_high; row += row_step) {
    for (int col = mi_col_sr; col < mi_col_end_sr; col += col_step_sr) {
      if (row >= cm->mi_params.mi_rows || col >= mi_cols_sr) continue;
      TplDepStats *this_stats =
          &tpl_stats[av2_tpl_ptr_pos(row, col, tpl_stride, block_mis_log2)];
      int64_t mc_dep_delta =
          RDCOST(tpl_frame->base_rdmult, this_stats->mc_dep_rate,
                 this_stats->mc_dep_dist);
      intra_cost += this_stats->recrf_dist << RDDIV_BITS;
      mc_dep_cost += (this_stats->recrf_dist << RDDIV_BITS) + mc_dep_delta;
#ifndef NDEBUG
      mi_count++;
#endif  // NDEBUG
    }
  }
  assert(mi_count <= MAX_TPL_BLK_IN_SB * MAX_TPL_BLK_IN_SB);

  avm_clear_system_state();

  int offset = 0;
  double beta = 1.0;
  if (mc_dep_cost > 0 && intra_cost > 0) {
    const double r0 = cpi->rd.r0;
    const double rk = (double)intra_cost / mc_dep_cost;
    beta = (r0 / rk);
    assert(beta > 0.0);
  }
  offset = av2_get_deltaq_offset(cpi, base_qindex, beta);
  avm_clear_system_state();

  const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
  offset = AVMMIN(offset, delta_q_info->delta_q_res * 9 - 1);
  offset = AVMMAX(offset, -delta_q_info->delta_q_res * 9 + 1);
  int qindex = cm->quant_params.base_qindex + offset;

  qindex =
      AVMMIN(qindex, cm->seq_params.bit_depth == AVM_BITS_8    ? MAXQ_8_BITS
                     : cm->seq_params.bit_depth == AVM_BITS_10 ? MAXQ_10_BITS
                                                               : MAXQ);
  qindex = AVMMAX(qindex, MINQ);

  return qindex;
}

void av2_reset_simple_motion_tree_partition(SIMPLE_MOTION_DATA_TREE *sms_tree,
                                            BLOCK_SIZE bsize) {
  sms_tree->partitioning = PARTITION_NONE;

  if (bsize >= BLOCK_8X8) {
    BLOCK_SIZE subsize = get_partition_subsize(bsize, PARTITION_SPLIT);
    assert(subsize < BLOCK_SIZES_ALL);
    assert(is_square_block(subsize));
    for (int idx = 0; idx < 4; ++idx)
      av2_reset_simple_motion_tree_partition(sms_tree->split[idx], subsize);
  }
}

// Record the ref frames that have been selected by square partition blocks.
void av2_update_picked_ref_frames_mask(MACROBLOCK *const x, int ref_type,
                                       BLOCK_SIZE bsize, int mib_size,
                                       int mi_row, int mi_col) {
  const int sb_size_mask = mib_size - 1;
  const int mi_row_in_sb = mi_row & sb_size_mask;
  const int mi_col_in_sb = mi_col & sb_size_mask;
  const int mi_size_h = mi_size_high[bsize];
  const int mi_size_w = mi_size_wide[bsize];
  for (int i = mi_row_in_sb; i < mi_row_in_sb + mi_size_h; ++i) {
    for (int j = mi_col_in_sb; j < mi_col_in_sb + mi_size_w; ++j) {
      x->picked_ref_frames_mask[i * mib_size + j] |= 1ULL << ref_type;
    }
  }
}

// Memset the mbmis at the current superblock to 0
void av2_reset_mbmi(const CommonModeInfoParams *const mi_params,
                    BLOCK_SIZE sb_size, int mi_row, int mi_col) {
  // size of sb in unit of mi (BLOCK_4X4)
  const int sb_size_mi = mi_size_wide[sb_size];
  const int mi_alloc_size_1d = mi_size_wide[mi_params->mi_alloc_bsize];
  // size of sb in unit of allocated mi size
  const int sb_size_alloc_mi = mi_size_wide[sb_size] / mi_alloc_size_1d;
  assert(mi_params->mi_alloc_stride % sb_size_alloc_mi == 0 &&
         "mi is not allocated as a multiple of sb!");
  assert(mi_params->mi_stride % sb_size_mi == 0 &&
         "mi_grid_base is not allocated as a multiple of sb!");

  const int mi_rows = mi_size_high[sb_size];
  for (int cur_mi_row = 0; cur_mi_row < mi_rows; cur_mi_row++) {
    assert(get_mi_grid_idx(mi_params, 0, mi_col + mi_alloc_size_1d) <
           mi_params->mi_stride);
    const int mi_grid_idx =
        get_mi_grid_idx(mi_params, mi_row + cur_mi_row, mi_col);
    const int alloc_mi_idx =
        get_alloc_mi_idx(mi_params, mi_row + cur_mi_row, mi_col);
    memset(&mi_params->mi_grid_base[mi_grid_idx], 0,
           sb_size_mi * sizeof(*mi_params->mi_grid_base));
    memset(&mi_params->tx_type_map[mi_grid_idx], 0,
           sb_size_mi * sizeof(*mi_params->tx_type_map));
    memset(&mi_params->submi_grid_base[mi_grid_idx], 0,
           sb_size_mi * sizeof(*mi_params->submi_grid_base));
    memset(&mi_params->cctx_type_map[mi_grid_idx], 0,
           sb_size_mi * sizeof(*mi_params->cctx_type_map));
    if (cur_mi_row % mi_alloc_size_1d == 0) {
      memset(&mi_params->mi_alloc[alloc_mi_idx], 0,
             sb_size_alloc_mi * sizeof(*mi_params->mi_alloc));
      memset(&mi_params->mi_alloc_sub[alloc_mi_idx], 0,
             sb_size_alloc_mi * sizeof(*mi_params->mi_alloc_sub));
    }
  }
}

void av2_backup_sb_state(SB_FIRST_PASS_STATS *sb_fp_stats, const AV2_COMP *cpi,
                         ThreadData *td, const TileDataEnc *tile_data,
                         int mi_row, int mi_col) {
  MACROBLOCK *x = &td->mb;

  const AV2_COMMON *cm = &cpi->common;
  const int num_planes = av2_num_planes(cm);
  const BLOCK_SIZE sb_size = cm->sb_size;
  av2_save_context(x, &sb_fp_stats->x_ctx, mi_row, mi_col, sb_size, num_planes);

  sb_fp_stats->rd_count = td->rd_counts;
  sb_fp_stats->split_count = x->txfm_search_info.txb_split_count;

  sb_fp_stats->fc = *td->counts;

  memcpy(sb_fp_stats->inter_mode_rd_models, tile_data->inter_mode_rd_models,
         sizeof(sb_fp_stats->inter_mode_rd_models));

  memcpy(sb_fp_stats->thresh_freq_fact, x->thresh_freq_fact,
         sizeof(sb_fp_stats->thresh_freq_fact));

  const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
  sb_fp_stats->current_qindex =
      cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex;
  sb_fp_stats->ref_mv_bank = td->mb.e_mbd.ref_mv_bank;
#if WARP_CU_BANK
  sb_fp_stats->warp_param_bank = td->mb.e_mbd.warp_param_bank;
#endif  // WARP_CU_BANK
  sb_fp_stats->min_partition_size = x->sb_enc.min_partition_size;
}

void av2_restore_sb_state(const SB_FIRST_PASS_STATS *sb_fp_stats, AV2_COMP *cpi,
                          ThreadData *td, TileDataEnc *tile_data, int mi_row,
                          int mi_col) {
  MACROBLOCK *x = &td->mb;

  const AV2_COMMON *cm = &cpi->common;
  const int num_planes = av2_num_planes(cm);
  const BLOCK_SIZE sb_size = cm->sb_size;

  av2_restore_context(cm, x, &sb_fp_stats->x_ctx, mi_row, mi_col, sb_size,
                      num_planes);

  td->rd_counts = sb_fp_stats->rd_count;
  x->txfm_search_info.txb_split_count = sb_fp_stats->split_count;

  *td->counts = sb_fp_stats->fc;

  memcpy(tile_data->inter_mode_rd_models, sb_fp_stats->inter_mode_rd_models,
         sizeof(sb_fp_stats->inter_mode_rd_models));
  memcpy(x->thresh_freq_fact, sb_fp_stats->thresh_freq_fact,
         sizeof(sb_fp_stats->thresh_freq_fact));

  const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
  cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex =
      sb_fp_stats->current_qindex;
  x->e_mbd.ref_mv_bank = sb_fp_stats->ref_mv_bank;
#if WARP_CU_BANK
  x->e_mbd.warp_param_bank = sb_fp_stats->warp_param_bank;
#endif  // WARP_CU_BANK
  x->sb_enc.min_partition_size = sb_fp_stats->min_partition_size;
}

// Update the rate costs of some symbols according to the frequency directed
// by speed features
void av2_set_cost_upd_freq(AV2_COMP *cpi, ThreadData *td,
                           const TileInfo *const tile_info, const int mi_row,
                           const int mi_col) {
  AV2_COMMON *const cm = &cpi->common;
  const int num_planes = av2_num_planes(cm);
  MACROBLOCK *const x = &td->mb;
  MACROBLOCKD *const xd = &x->e_mbd;

  switch (cpi->oxcf.cost_upd_freq.coeff) {
    case COST_UPD_TILE:  // Tile level
      if (mi_row != tile_info->mi_row_start) break;
      AVM_FALLTHROUGH_INTENDED;
    case COST_UPD_SBROW:  // SB row level in tile
      if (mi_col != tile_info->mi_col_start) break;
      AVM_FALLTHROUGH_INTENDED;
    case COST_UPD_SB:  // SB level
      if (cpi->sf.inter_sf.disable_sb_level_coeff_cost_upd &&
          mi_col != tile_info->mi_col_start)
        break;
      av2_fill_coeff_costs(&x->coeff_costs, xd->tile_ctx, num_planes);
      break;
    default: assert(0);
  }

  switch (cpi->oxcf.cost_upd_freq.mode) {
    case COST_UPD_TILE:  // Tile level
      if (mi_row != tile_info->mi_row_start) break;
      AVM_FALLTHROUGH_INTENDED;
    case COST_UPD_SBROW:  // SB row level in tile
      if (mi_col != tile_info->mi_col_start) break;
      AVM_FALLTHROUGH_INTENDED;
    case COST_UPD_SB:  // SB level
      av2_fill_mode_rates(cm, &x->mode_costs, xd->tile_ctx);
      break;
    default: assert(0);
  }
  switch (cpi->oxcf.cost_upd_freq.mv) {
    case COST_UPD_OFF: break;
    case COST_UPD_TILE:  // Tile level
      if (mi_row != tile_info->mi_row_start) break;
      AVM_FALLTHROUGH_INTENDED;
    case COST_UPD_SBROW:  // SB row level in tile
      if (mi_col != tile_info->mi_col_start) break;
      AVM_FALLTHROUGH_INTENDED;
    case COST_UPD_SB:  // SB level
      if (cpi->sf.inter_sf.disable_sb_level_mv_cost_upd &&
          mi_col != tile_info->mi_col_start)
        break;
      av2_fill_mv_costs(xd->tile_ctx, cm->features.cur_frame_force_integer_mv,
                        cm->features.fr_mv_precision, &x->mv_costs);
      if (cm->features.allow_intrabc) {
        fill_dv_costs(&x->dv_costs, xd->tile_ctx, &x->mv_costs);
      }
      break;
    default: assert(0);
  }
}
