/*
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
 *
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. 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 www.aomedia.org/license/patent.
 */

#include <limits.h>
#include <math.h>

#include "av1/common/pred_common.h"
#include "av1/common/seg_common.h"
#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/encoder_utils.h"
#include "av1/encoder/ratectrl.h"
#include "av1/encoder/segmentation.h"
#include "av1/encoder/tokenize.h"
#include "aom_dsp/aom_dsp_common.h"

CYCLIC_REFRESH *av1_cyclic_refresh_alloc(int mi_rows, int mi_cols) {
  CYCLIC_REFRESH *const cr = aom_calloc(1, sizeof(*cr));
  if (cr == NULL) return NULL;

  cr->map = aom_calloc(mi_rows * mi_cols, sizeof(*cr->map));
  cr->counter_encode_maxq_scene_change = 0;
  cr->percent_refresh_adjustment = 5;
  cr->rate_ratio_qdelta_adjustment = 0.25;
  if (cr->map == NULL) {
    av1_cyclic_refresh_free(cr);
    return NULL;
  }
  return cr;
}

void av1_cyclic_refresh_free(CYCLIC_REFRESH *cr) {
  if (cr != NULL) {
    aom_free(cr->map);
    aom_free(cr);
  }
}

// Check if this coding block, of size bsize, should be considered for refresh
// (lower-qp coding). Decision can be based on various factors, such as
// size of the coding block (i.e., below min_block size rejected), coding
// mode, and rate/distortion.
static int candidate_refresh_aq(const CYCLIC_REFRESH *cr,
                                const MB_MODE_INFO *mbmi, int64_t rate,
                                int64_t dist, BLOCK_SIZE bsize,
                                int noise_level) {
  MV mv = mbmi->mv[0].as_mv;
  int is_compound = has_second_ref(mbmi);
  // Reject the block for lower-qp coding for non-compound mode if
  // projected distortion is above the threshold, and any of the following
  // is true:
  // 1) mode uses large mv
  // 2) mode is an intra-mode
  // Otherwise accept for refresh.
  if (!is_compound && dist > cr->thresh_dist_sb &&
      (mv.row > cr->motion_thresh || mv.row < -cr->motion_thresh ||
       mv.col > cr->motion_thresh || mv.col < -cr->motion_thresh ||
       !is_inter_block(mbmi)))
    return CR_SEGMENT_ID_BASE;
  else if ((is_compound && noise_level < kMedium) ||
           (bsize >= BLOCK_16X16 && rate < cr->thresh_rate_sb &&
            is_inter_block(mbmi) && mbmi->mv[0].as_int == 0 &&
            cr->rate_boost_fac > 10))
    // More aggressive delta-q for bigger blocks with zero motion.
    return CR_SEGMENT_ID_BOOST2;
  else
    return CR_SEGMENT_ID_BOOST1;
}

// Compute delta-q for the segment.
static int compute_deltaq(const AV1_COMP *cpi, int q, double rate_factor) {
  const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  int deltaq = av1_compute_qdelta_by_rate(
      cpi, cpi->common.current_frame.frame_type, q, rate_factor);
  if ((-deltaq) > cr->max_qdelta_perc * q / 100) {
    deltaq = -cr->max_qdelta_perc * q / 100;
  }
  return deltaq;
}

int av1_cyclic_refresh_estimate_bits_at_q(const AV1_COMP *cpi,
                                          double correction_factor) {
  const AV1_COMMON *const cm = &cpi->common;
  const int base_qindex = cm->quant_params.base_qindex;
  const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  const int mbs = cm->mi_params.MBs;
  const int num4x4bl = mbs << 4;
  // Weight for non-base segments: use actual number of blocks refreshed in
  // previous/just encoded frame. Note number of blocks here is in 4x4 units.
  double weight_segment1 = (double)cr->actual_num_seg1_blocks / num4x4bl;
  double weight_segment2 = (double)cr->actual_num_seg2_blocks / num4x4bl;
  if (cpi->rc.rtc_external_ratectrl) {
    weight_segment1 = (double)(cr->percent_refresh * cm->mi_params.mi_rows *
                               cm->mi_params.mi_cols / 100) /
                      num4x4bl;
    weight_segment2 = 0;
  }
  // Take segment weighted average for estimated bits.
  const int estimated_bits = (int)round(
      (1.0 - weight_segment1 - weight_segment2) *
          av1_estimate_bits_at_q(cpi, base_qindex, correction_factor) +
      weight_segment1 *
          av1_estimate_bits_at_q(cpi, base_qindex + cr->qindex_delta[1],
                                 correction_factor) +
      weight_segment2 *
          av1_estimate_bits_at_q(cpi, base_qindex + cr->qindex_delta[2],
                                 correction_factor));
  return estimated_bits;
}

int av1_cyclic_refresh_rc_bits_per_mb(const AV1_COMP *cpi, int i,
                                      double correction_factor) {
  const AV1_COMMON *const cm = &cpi->common;
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  int bits_per_mb;
  int num4x4bl = cm->mi_params.MBs << 4;
  // Weight for segment prior to encoding: take the average of the target
  // number for the frame to be encoded and the actual from the previous frame.
  double weight_segment =
      (double)((cr->target_num_seg_blocks + cr->actual_num_seg1_blocks +
                cr->actual_num_seg2_blocks) >>
               1) /
      num4x4bl;
  if (cpi->rc.rtc_external_ratectrl) {
    weight_segment = (double)((cr->target_num_seg_blocks +
                               cr->percent_refresh * cm->mi_params.mi_rows *
                                   cm->mi_params.mi_cols / 100) >>
                              1) /
                     num4x4bl;
  }
  // Compute delta-q corresponding to qindex i.
  int deltaq = compute_deltaq(cpi, i, cr->rate_ratio_qdelta);
  const int accurate_estimate = cpi->sf.hl_sf.accurate_bit_estimate;
  // Take segment weighted average for bits per mb.
  bits_per_mb = (int)round(
      (1.0 - weight_segment) *
          av1_rc_bits_per_mb(cpi, cm->current_frame.frame_type, i,
                             correction_factor, accurate_estimate) +
      weight_segment * av1_rc_bits_per_mb(cpi, cm->current_frame.frame_type,
                                          i + deltaq, correction_factor,
                                          accurate_estimate));
  return bits_per_mb;
}

void av1_cyclic_reset_segment_skip(const AV1_COMP *cpi, MACROBLOCK *const x,
                                   int mi_row, int mi_col, BLOCK_SIZE bsize,
                                   RUN_TYPE dry_run) {
  int cdf_num;
  const AV1_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *const mbmi = xd->mi[0];
  const int prev_segment_id = mbmi->segment_id;
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int xmis = AOMMIN(cm->mi_params.mi_cols - mi_col, bw);
  const int ymis = AOMMIN(cm->mi_params.mi_rows - mi_row, bh);

  assert(cm->seg.enabled);

  if (!cr->skip_over4x4) {
    mbmi->segment_id =
        av1_get_spatial_seg_pred(cm, xd, &cdf_num, cr->skip_over4x4);
    if (prev_segment_id != mbmi->segment_id) {
      const int block_index = mi_row * cm->mi_params.mi_cols + mi_col;
      const int mi_stride = cm->mi_params.mi_cols;
      const uint8_t segment_id = mbmi->segment_id;
      for (int mi_y = 0; mi_y < ymis; mi_y++) {
        const int map_offset = block_index + mi_y * mi_stride;
        memset(&cr->map[map_offset], 0, xmis);
        memset(&cpi->enc_seg.map[map_offset], segment_id, xmis);
        memset(&cm->cur_frame->seg_map[map_offset], segment_id, xmis);
      }
    }
  }
  if (!dry_run) {
    if (cyclic_refresh_segment_id(prev_segment_id) == CR_SEGMENT_ID_BOOST1)
      x->actual_num_seg1_blocks -= xmis * ymis;
    else if (cyclic_refresh_segment_id(prev_segment_id) == CR_SEGMENT_ID_BOOST2)
      x->actual_num_seg2_blocks -= xmis * ymis;
  }
}

void av1_cyclic_refresh_update_segment(const AV1_COMP *cpi, MACROBLOCK *const x,
                                       int mi_row, int mi_col, BLOCK_SIZE bsize,
                                       int64_t rate, int64_t dist, int skip,
                                       RUN_TYPE dry_run) {
  const AV1_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *const mbmi = xd->mi[0];
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int xmis = AOMMIN(cm->mi_params.mi_cols - mi_col, bw);
  const int ymis = AOMMIN(cm->mi_params.mi_rows - mi_row, bh);
  const int block_index = mi_row * cm->mi_params.mi_cols + mi_col;
  int noise_level = 0;
  if (cpi->noise_estimate.enabled) noise_level = cpi->noise_estimate.level;
  const int refresh_this_block =
      candidate_refresh_aq(cr, mbmi, rate, dist, bsize, noise_level);
  int sh = cpi->cyclic_refresh->skip_over4x4 ? 2 : 1;
  // Default is to not update the refresh map.
  int new_map_value = cr->map[block_index];

  // If this block is labeled for refresh, check if we should reset the
  // segment_id.
  if (cyclic_refresh_segment_id_boosted(mbmi->segment_id)) {
    mbmi->segment_id = refresh_this_block;
    // Reset segment_id if will be skipped.
    if (skip) mbmi->segment_id = CR_SEGMENT_ID_BASE;
  }
  const uint8_t segment_id = mbmi->segment_id;

  // Update the cyclic refresh map, to be used for setting segmentation map
  // for the next frame. If the block  will be refreshed this frame, mark it
  // as clean. The magnitude of the -ve influences how long before we consider
  // it for refresh again.
  if (cyclic_refresh_segment_id_boosted(segment_id)) {
    new_map_value = -cr->time_for_refresh;
  } else if (refresh_this_block) {
    // Else if it is accepted as candidate for refresh, and has not already
    // been refreshed (marked as 1) then mark it as a candidate for cleanup
    // for future time (marked as 0), otherwise don't update it.
    if (cr->map[block_index] == 1) new_map_value = 0;
  } else {
    // Leave it marked as block that is not candidate for refresh.
    new_map_value = 1;
  }

  // Update entries in the cyclic refresh map with new_map_value, and
  // copy mbmi->segment_id into global segmentation map.
  const int mi_stride = cm->mi_params.mi_cols;
  for (int mi_y = 0; mi_y < ymis; mi_y += sh) {
    const int map_offset = block_index + mi_y * mi_stride;
    memset(&cr->map[map_offset], new_map_value, xmis);
    memset(&cpi->enc_seg.map[map_offset], segment_id, xmis);
    memset(&cm->cur_frame->seg_map[map_offset], segment_id, xmis);
  }

  // Accumulate cyclic refresh update counters.
  if (!dry_run) {
    if (cyclic_refresh_segment_id(segment_id) == CR_SEGMENT_ID_BOOST1)
      x->actual_num_seg1_blocks += xmis * ymis;
    else if (cyclic_refresh_segment_id(segment_id) == CR_SEGMENT_ID_BOOST2)
      x->actual_num_seg2_blocks += xmis * ymis;
  }
}

// Initializes counters used for cyclic refresh.
void av1_init_cyclic_refresh_counters(MACROBLOCK *const x) {
  x->actual_num_seg1_blocks = 0;
  x->actual_num_seg2_blocks = 0;
}

// Accumulate cyclic refresh counters.
void av1_accumulate_cyclic_refresh_counters(
    CYCLIC_REFRESH *const cyclic_refresh, const MACROBLOCK *const x) {
  cyclic_refresh->actual_num_seg1_blocks += x->actual_num_seg1_blocks;
  cyclic_refresh->actual_num_seg2_blocks += x->actual_num_seg2_blocks;
}

void av1_cyclic_refresh_set_golden_update(AV1_COMP *const cpi) {
  RATE_CONTROL *const rc = &cpi->rc;
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  // Set minimum gf_interval for GF update to a multiple of the refresh period,
  // with some max limit. Depending on past encoding stats, GF flag may be
  // reset and update may not occur until next baseline_gf_interval.
  const int gf_length_mult[2] = { 8, 4 };
  if (cr->percent_refresh > 0)
    p_rc->baseline_gf_interval =
        AOMMIN(gf_length_mult[cpi->sf.rt_sf.gf_length_lvl] *
                   (100 / cr->percent_refresh),
               MAX_GF_INTERVAL_RT);
  else
    p_rc->baseline_gf_interval = FIXED_GF_INTERVAL_RT;
  if (rc->avg_frame_low_motion && rc->avg_frame_low_motion < 40)
    p_rc->baseline_gf_interval = 16;
}

// Update the segmentation map, and related quantities: cyclic refresh map,
// refresh sb_index, and target number of blocks to be refreshed.
// The map is set to either 0/CR_SEGMENT_ID_BASE (no refresh) or to
// 1/CR_SEGMENT_ID_BOOST1 (refresh) for each superblock.
// Blocks labeled as BOOST1 may later get set to BOOST2 (during the
// encoding of the superblock).
static void cyclic_refresh_update_map(AV1_COMP *const cpi) {
  AV1_COMMON *const cm = &cpi->common;
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  unsigned char *const seg_map = cpi->enc_seg.map;
  unsigned char *const active_map_4x4 = cpi->active_map.map;
  int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame;
  int xmis, ymis, x, y;
  uint64_t sb_sad = 0;
  uint64_t thresh_sad_low = 0;
  uint64_t thresh_sad = INT64_MAX;
  const int mi_rows = mi_params->mi_rows, mi_cols = mi_params->mi_cols;
  const int mi_stride = mi_cols;
  // Don't set seg_map to 0 if active_maps is enabled. Active_maps will set
  // seg_map to either 7 or 0 (AM_SEGMENT_ID_INACTIVE/ACTIVE), and cyclic
  // refresh set below (segment 1 or 2) will only be set for ACTIVE blocks.
  if (!cpi->active_map.enabled) {
    memset(seg_map, CR_SEGMENT_ID_BASE, mi_rows * mi_cols);
  }
  sb_cols = (mi_cols + cm->seq_params->mib_size - 1) / cm->seq_params->mib_size;
  sb_rows = (mi_rows + cm->seq_params->mib_size - 1) / cm->seq_params->mib_size;
  sbs_in_frame = sb_cols * sb_rows;
  // Number of target blocks to get the q delta (segment 1).
  block_count = cr->percent_refresh * mi_rows * mi_cols / 100;
  // Set the segmentation map: cycle through the superblocks, starting at
  // cr->mb_index, and stopping when either block_count blocks have been found
  // to be refreshed, or we have passed through whole frame.
  if (cr->sb_index >= sbs_in_frame) cr->sb_index = 0;
  assert(cr->sb_index < sbs_in_frame);
  i = cr->sb_index;
  cr->last_sb_index = cr->sb_index;
  cr->target_num_seg_blocks = 0;
  do {
    int sum_map = 0;
    // Get the mi_row/mi_col corresponding to superblock index i.
    int sb_row_index = (i / sb_cols);
    int sb_col_index = i - sb_row_index * sb_cols;
    int mi_row = sb_row_index * cm->seq_params->mib_size;
    int mi_col = sb_col_index * cm->seq_params->mib_size;
    assert(mi_row >= 0 && mi_row < mi_rows);
    assert(mi_col >= 0 && mi_col < mi_cols);
    bl_index = mi_row * mi_stride + mi_col;
    // Loop through all MI blocks in superblock and update map.
    xmis = AOMMIN(mi_cols - mi_col, cm->seq_params->mib_size);
    ymis = AOMMIN(mi_rows - mi_row, cm->seq_params->mib_size);
    if (cr->use_block_sad_scene_det && cpi->rc.frames_since_key > 30 &&
        cr->counter_encode_maxq_scene_change > 30 &&
        cpi->src_sad_blk_64x64 != NULL &&
        cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
      sb_sad = cpi->src_sad_blk_64x64[sb_col_index + sb_cols * sb_row_index];
      int scale = (cm->width * cm->height < 640 * 360) ? 6 : 8;
      int scale_low = 2;
      thresh_sad = (scale * 64 * 64);
      thresh_sad_low = (scale_low * 64 * 64);
      // For temporal layers: the base temporal layer (temporal_layer_id = 0)
      // has larger frame separation (2 or 4 frames apart), so use larger sad
      // thresholds to compensate for larger frame sad. The larger thresholds
      // also increase the amount of refresh, which is needed for the base
      // temporal layer.
      if (cpi->svc.number_temporal_layers > 1 &&
          cpi->svc.temporal_layer_id == 0) {
        thresh_sad <<= 4;
        thresh_sad_low <<= 2;
      }
    }
    // cr_map only needed at 8x8 blocks.
    for (y = 0; y < ymis; y += 2) {
      for (x = 0; x < xmis; x += 2) {
        const int bl_index2 = bl_index + y * mi_stride + x;
        // If the block is as a candidate for clean up then mark it
        // for possible boost/refresh (segment 1). The segment id may get
        // reset to 0 later if block gets coded anything other than low motion.
        // If the block_sad (sb_sad) is very low label it for refresh anyway.
        // If active_maps is enabled, only allow for setting on ACTIVE blocks.
        if ((cr->map[bl_index2] == 0 || sb_sad < thresh_sad_low) &&
            (!cpi->active_map.enabled ||
             active_map_4x4[bl_index2] == AM_SEGMENT_ID_ACTIVE)) {
          sum_map += 4;
        } else if (cr->map[bl_index2] < 0) {
          cr->map[bl_index2]++;
        }
      }
    }
    // Enforce constant segment over superblock.
    // If segment is at least half of superblock, set to 1.
    // Enforce that block sad (sb_sad) is not too high.
    if (sum_map >= (xmis * ymis) >> 1 && sb_sad < thresh_sad) {
      set_segment_id(seg_map, bl_index, xmis, ymis, mi_stride,
                     CR_SEGMENT_ID_BOOST1);
      cr->target_num_seg_blocks += xmis * ymis;
    }
    i++;
    if (i == sbs_in_frame) {
      i = 0;
    }
  } while (cr->target_num_seg_blocks < block_count && i != cr->sb_index);
  cr->sb_index = i;
  if (cr->target_num_seg_blocks == 0) {
    // Disable segmentation, seg_map is already set to 0 above.
    // Don't disable if active_map is being used.
    if (!cpi->active_map.enabled) av1_disable_segmentation(&cm->seg);
  }
}

static int is_scene_change_detected(AV1_COMP *const cpi) {
  return cpi->rc.high_source_sad;
}

// Set cyclic refresh parameters.
void av1_cyclic_refresh_update_parameters(AV1_COMP *const cpi) {
  // TODO(marpan): Parameters need to be tuned.
  const RATE_CONTROL *const rc = &cpi->rc;
  const PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
  const AV1_COMMON *const cm = &cpi->common;
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  SVC *const svc = &cpi->svc;
  const int qp_thresh = AOMMAX(16, rc->best_quality + 4);
  const int qp_max_thresh = 118 * MAXQ >> 7;
  const int scene_change_detected = is_scene_change_detected(cpi);
  const int is_screen_content =
      (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN);

  // A scene change or key frame marks the start of a cyclic refresh cycle.
  const int frames_since_scene_change =
      (cpi->ppi->use_svc || !is_screen_content)
          ? cpi->rc.frames_since_key
          : AOMMIN(cpi->rc.frames_since_key,
                   cr->counter_encode_maxq_scene_change);

  // Cases to reset the cyclic refresh adjustment parameters.
  if (frame_is_intra_only(cm) || scene_change_detected ||
      cpi->ppi->rtc_ref.bias_recovery_frame) {
    // Reset adaptive elements for intra only frames and scene changes.
    cr->percent_refresh_adjustment = 5;
    cr->rate_ratio_qdelta_adjustment = 0.25;
  }

  // Although this segment feature for RTC is only used for
  // blocks >= 8X8, for more efficient coding of the seg map
  // cur_frame->seg_map needs to set at 4x4 along with the
  // function av1_cyclic_reset_segment_skip(). Skipping over
  // 4x4 will therefore have small bdrate loss (~0.2%), so
  // we use it only for speed > 9 for now.
  cr->skip_over4x4 = (cpi->oxcf.speed > 9) ? 1 : 0;

  // should we enable cyclic refresh on this frame.
  cr->apply_cyclic_refresh = 1;
  if (frame_is_intra_only(cm) || is_lossless_requested(&cpi->oxcf.rc_cfg) ||
      cpi->rc.high_motion_screen_content || scene_change_detected ||
      svc->temporal_layer_id > 0 ||
      svc->prev_number_spatial_layers != svc->number_spatial_layers ||
      p_rc->avg_frame_qindex[INTER_FRAME] < qp_thresh ||
      (svc->number_spatial_layers > 1 &&
       svc->layer_context[svc->temporal_layer_id].is_key_frame) ||
      (frames_since_scene_change > 20 &&
       p_rc->avg_frame_qindex[INTER_FRAME] > qp_max_thresh) ||
      (rc->avg_frame_low_motion && rc->avg_frame_low_motion < 30 &&
       frames_since_scene_change > 40) ||
      cpi->ppi->rtc_ref.bias_recovery_frame) {
    cr->apply_cyclic_refresh = 0;
    return;
  }

  // Increase the amount of refresh for #temporal_layers > 2
  if (svc->number_temporal_layers > 2)
    cr->percent_refresh = 15;
  else
    cr->percent_refresh = 10 + cr->percent_refresh_adjustment;

  if (cpi->active_map.enabled) {
    // Scale down the percent_refresh to target the active blocks only.
    cr->percent_refresh =
        cr->percent_refresh * (100 - cpi->rc.percent_blocks_inactive) / 100;
    if (cr->percent_refresh == 0) {
      cr->apply_cyclic_refresh = 0;
    }
  }

  cr->max_qdelta_perc = 60;
  cr->time_for_refresh = 0;
  cr->use_block_sad_scene_det =
      (cpi->oxcf.tune_cfg.content != AOM_CONTENT_SCREEN &&
       cm->seq_params->sb_size == BLOCK_64X64)
          ? 1
          : 0;
  cr->motion_thresh = 32;
  cr->rate_boost_fac =
      (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN) ? 10 : 15;

  // Use larger delta-qp (increase rate_ratio_qdelta) for first few
  // refresh cycles after a key frame (svc) or scene change (non svc).
  // For non svc screen content, after a scene change gradually reduce
  // this boost and supress it further if either of the previous two
  // frames overshot.
  if (cr->percent_refresh > 0) {
    if (cpi->ppi->use_svc || !is_screen_content) {
      if (frames_since_scene_change <
          ((4 * svc->number_temporal_layers) * (100 / cr->percent_refresh))) {
        cr->rate_ratio_qdelta = 3.0 + cr->rate_ratio_qdelta_adjustment;
      } else {
        cr->rate_ratio_qdelta = 2.25 + cr->rate_ratio_qdelta_adjustment;
      }
    } else {
      double distance_from_sc_factor =
          AOMMIN(0.75, (int)(frames_since_scene_change / 10) * 0.1);
      cr->rate_ratio_qdelta =
          3.0 + cr->rate_ratio_qdelta_adjustment - distance_from_sc_factor;
      if ((frames_since_scene_change < 10) &&
          ((cpi->rc.rc_1_frame < 0) || (cpi->rc.rc_2_frame < 0))) {
        cr->rate_ratio_qdelta -= 0.25;
      }
    }
  } else {
    cr->rate_ratio_qdelta = 2.25 + cr->rate_ratio_qdelta_adjustment;
  }
  // Adjust some parameters for low resolutions.
  if (cm->width * cm->height <= 352 * 288) {
    if (cpi->svc.number_temporal_layers > 1) {
      cr->motion_thresh = 32;
      cr->rate_boost_fac = 13;
    } else {
      if (rc->avg_frame_bandwidth < 3000) {
        cr->motion_thresh = 16;
        cr->rate_boost_fac = 13;
      } else {
        cr->max_qdelta_perc = 50;
        cr->rate_ratio_qdelta = AOMMAX(cr->rate_ratio_qdelta, 2.0);
      }
    }
  }
  if (cpi->oxcf.rc_cfg.mode == AOM_VBR) {
    // To be adjusted for VBR mode, e.g., based on gf period and boost.
    // For now use smaller qp-delta (than CBR), no second boosted seg, and
    // turn-off (no refresh) on golden refresh (since it's already boosted).
    cr->percent_refresh = 10;
    cr->rate_ratio_qdelta = 1.5;
    cr->rate_boost_fac = 10;
    if (cpi->refresh_frame.golden_frame) {
      cr->percent_refresh = 0;
      cr->rate_ratio_qdelta = 1.0;
    }
  }
  if (rc->rtc_external_ratectrl) {
    cr->actual_num_seg1_blocks = cr->percent_refresh * cm->mi_params.mi_rows *
                                 cm->mi_params.mi_cols / 100;
    cr->actual_num_seg2_blocks = 0;
  }
}

// Setup cyclic background refresh: set delta q and segmentation map.
void av1_cyclic_refresh_setup(AV1_COMP *const cpi) {
  AV1_COMMON *const cm = &cpi->common;
  const RATE_CONTROL *const rc = &cpi->rc;
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  struct segmentation *const seg = &cm->seg;
  const int scene_change_detected = is_scene_change_detected(cpi);
  const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
  const int boost_index = AOMMIN(15, (cpi->ppi->p_rc.gfu_boost / 100));
  const int layer_depth = AOMMIN(gf_group->layer_depth[cpi->gf_frame_index], 6);
  const FRAME_TYPE frame_type = cm->current_frame.frame_type;

  // Set resolution_change flag: for svc only set it when the
  // number of spatial layers has not changed.
  const int resolution_change =
      cm->prev_frame &&
      (cm->width != cm->prev_frame->width ||
       cm->height != cm->prev_frame->height) &&
      cpi->svc.prev_number_spatial_layers == cpi->svc.number_spatial_layers;

  if (resolution_change) av1_cyclic_refresh_reset_resize(cpi);
  if (!cr->apply_cyclic_refresh) {
    // Don't disable and set seg_map to 0 if active_maps is enabled, unless
    // whole frame is set as inactive (since we only apply cyclic_refresh to
    // active blocks).
    if (!cpi->active_map.enabled || cpi->rc.percent_blocks_inactive == 100) {
      unsigned char *const seg_map = cpi->enc_seg.map;
      memset(seg_map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
      av1_disable_segmentation(&cm->seg);
    }
    if (frame_is_intra_only(cm) || scene_change_detected ||
        cpi->ppi->rtc_ref.bias_recovery_frame) {
      cr->sb_index = 0;
      cr->last_sb_index = 0;
      cr->counter_encode_maxq_scene_change = 0;
      cr->actual_num_seg1_blocks = 0;
      cr->actual_num_seg2_blocks = 0;
    }
    return;
  } else {
    cr->counter_encode_maxq_scene_change++;
    const double q = av1_convert_qindex_to_q(cm->quant_params.base_qindex,
                                             cm->seq_params->bit_depth);
    // Set rate threshold to some multiple (set to 2 for now) of the target
    // rate (target is given by sb64_target_rate and scaled by 256).
    cr->thresh_rate_sb = ((int64_t)(rc->sb64_target_rate) << 8) << 2;
    // Distortion threshold, quadratic in Q, scale factor to be adjusted.
    // q will not exceed 457, so (q * q) is within 32bit; see:
    // av1_convert_qindex_to_q(), av1_ac_quant(), ac_qlookup*[].
    cr->thresh_dist_sb = ((int64_t)(q * q)) << 2;
    // For low-resoln or lower speeds, the rate/dist thresholds need to be
    // tuned/updated.
    if (cpi->oxcf.speed <= 7 || (cm->width * cm->height < 640 * 360)) {
      cr->thresh_dist_sb = 0;
      cr->thresh_rate_sb = INT64_MAX;
    }
    // Set up segmentation.
    av1_enable_segmentation(&cm->seg);
    if (!cpi->active_map.enabled) {
      // Clear down the segment map, only if active_maps is not enabled.
      av1_clearall_segfeatures(seg);
    }

    // Note: setting temporal_update has no effect, as the seg-map coding method
    // (temporal or spatial) is determined in
    // av1_choose_segmap_coding_method(),
    // based on the coding cost of each method. For error_resilient mode on the
    // last_frame_seg_map is set to 0, so if temporal coding is used, it is
    // relative to 0 previous map.
    // seg->temporal_update = 0;

    // Segment BASE "Q" feature is disabled so it defaults to the baseline Q.
    av1_disable_segfeature(seg, CR_SEGMENT_ID_BASE, SEG_LVL_ALT_Q);
    // Use segment BOOST1 for in-frame Q adjustment.
    av1_enable_segfeature(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q);
    // Use segment BOOST2 for more aggressive in-frame Q adjustment.
    av1_enable_segfeature(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q);

    // Set the q delta for segment BOOST1.
    const CommonQuantParams *const quant_params = &cm->quant_params;
    int qindex_delta =
        compute_deltaq(cpi, quant_params->base_qindex, cr->rate_ratio_qdelta);
    cr->qindex_delta[1] = qindex_delta;

    // Compute rd-mult for segment BOOST1.
    const int qindex2 = clamp(
        quant_params->base_qindex + quant_params->y_dc_delta_q + qindex_delta,
        0, MAXQ);
    cr->rdmult = av1_compute_rd_mult(
        qindex2, cm->seq_params->bit_depth,
        cpi->ppi->gf_group.update_type[cpi->gf_frame_index], layer_depth,
        boost_index, frame_type, cpi->oxcf.q_cfg.use_fixed_qp_offsets,
        is_stat_consumption_stage(cpi));

    av1_set_segdata(seg, CR_SEGMENT_ID_BOOST1, SEG_LVL_ALT_Q, qindex_delta);

    // Set a more aggressive (higher) q delta for segment BOOST2.
    qindex_delta = compute_deltaq(
        cpi, quant_params->base_qindex,
        AOMMIN(CR_MAX_RATE_TARGET_RATIO,
               0.1 * cr->rate_boost_fac * cr->rate_ratio_qdelta));
    cr->qindex_delta[2] = qindex_delta;
    av1_set_segdata(seg, CR_SEGMENT_ID_BOOST2, SEG_LVL_ALT_Q, qindex_delta);

    // Update the segmentation and refresh map.
    cyclic_refresh_update_map(cpi);
  }
}

int av1_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr) {
  return cr->rdmult;
}

void av1_cyclic_refresh_reset_resize(AV1_COMP *const cpi) {
  const AV1_COMMON *const cm = &cpi->common;
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  memset(cr->map, 0, cm->mi_params.mi_rows * cm->mi_params.mi_cols);
  cr->sb_index = 0;
  cr->last_sb_index = 0;
  cpi->refresh_frame.golden_frame = true;
  cr->apply_cyclic_refresh = 0;
  cr->counter_encode_maxq_scene_change = 0;
  cr->percent_refresh_adjustment = 5;
  cr->rate_ratio_qdelta_adjustment = 0.25;
}

int av1_cyclic_refresh_disable_lf_cdef(AV1_COMP *const cpi) {
  CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
  const int qindex = cpi->common.quant_params.base_qindex;
  if (cpi->active_map.enabled &&
      cpi->rc.percent_blocks_inactive >
          cpi->sf.rt_sf.thresh_active_maps_skip_lf_cdef)
    return 1;
  if (cpi->rc.frames_since_key > 30 && cr->percent_refresh > 0 &&
      cr->counter_encode_maxq_scene_change > 300 / cr->percent_refresh &&
      cpi->rc.frame_source_sad < 1000 &&
      qindex < 7 * (cpi->rc.worst_quality >> 3))
    return 1;
  // More aggressive skip.
  else if (cpi->sf.rt_sf.skip_lf_screen > 1 && !cpi->rc.high_source_sad &&
           cpi->rc.frame_source_sad < 50000 && qindex < cpi->rc.worst_quality)
    return 1;
  return 0;
}
