/*
 * Copyright (c) 2019, 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 <assert.h>
#include <math.h>

#include "av1/encoder/encoder.h"
#include "av1/encoder/encoder_alloc.h"

static void swap_ptr(void *a, void *b) {
  void **a_p = (void **)a;
  void **b_p = (void **)b;
  void *c = *a_p;
  *a_p = *b_p;
  *b_p = c;
}

void av1_init_layer_context(AV1_COMP *const cpi) {
  AV1_COMMON *const cm = &cpi->common;
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
  SVC *const svc = &cpi->svc;
  int mi_rows = cpi->common.mi_params.mi_rows;
  int mi_cols = cpi->common.mi_params.mi_cols;
  svc->base_framerate = 30.0;
  svc->current_superframe = 0;
  svc->force_zero_mode_spatial_ref = 1;
  svc->num_encoded_top_layer = 0;
  svc->use_flexible_mode = 0;
  svc->has_lower_quality_layer = 0;

  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
      int layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
      RATE_CONTROL *const lrc = &lc->rc;
      PRIMARY_RATE_CONTROL *const lp_rc = &lc->p_rc;
      lrc->ni_av_qi = oxcf->rc_cfg.worst_allowed_q;
      lp_rc->total_actual_bits = 0;
      lrc->ni_tot_qi = 0;
      lp_rc->tot_q = 0.0;
      lp_rc->avg_q = 0.0;
      lp_rc->ni_frames = 0;
      lrc->decimation_count = 0;
      lrc->decimation_factor = 0;
      lrc->worst_quality = av1_quantizer_to_qindex(lc->max_q);
      lrc->best_quality = av1_quantizer_to_qindex(lc->min_q);
      lrc->rtc_external_ratectrl = 0;
      for (int i = 0; i < RATE_FACTOR_LEVELS; ++i) {
        lp_rc->rate_correction_factors[i] = 1.0;
      }
      lc->target_bandwidth = lc->layer_target_bitrate;
      lp_rc->last_q[INTER_FRAME] = lrc->worst_quality;
      lp_rc->avg_frame_qindex[INTER_FRAME] = lrc->worst_quality;
      lp_rc->avg_frame_qindex[KEY_FRAME] = lrc->worst_quality;
      lp_rc->buffer_level =
          oxcf->rc_cfg.starting_buffer_level_ms * lc->target_bandwidth / 1000;
      lp_rc->bits_off_target = lp_rc->buffer_level;
      // Initialize the cyclic refresh parameters. If spatial layers are used
      // (i.e., ss_number_layers > 1), these need to be updated per spatial
      // layer. Cyclic refresh is only applied on base temporal layer.
      if (svc->number_spatial_layers > 1 && tl == 0) {
        lc->sb_index = 0;
        lc->actual_num_seg1_blocks = 0;
        lc->actual_num_seg2_blocks = 0;
        lc->counter_encode_maxq_scene_change = 0;
        aom_free(lc->map);
        CHECK_MEM_ERROR(cm, lc->map,
                        aom_calloc(mi_rows * mi_cols, sizeof(*lc->map)));
      }
    }
    svc->downsample_filter_type[sl] = BILINEAR;
    svc->downsample_filter_phase[sl] = 8;
    svc->last_layer_dropped[sl] = false;
    svc->drop_spatial_layer[sl] = false;
  }
  if (svc->number_spatial_layers == 3) {
    svc->downsample_filter_type[0] = EIGHTTAP_SMOOTH;
  }
}

bool av1_alloc_layer_context(AV1_COMP *cpi, int num_layers) {
  SVC *const svc = &cpi->svc;
  if (svc->layer_context == NULL || svc->num_allocated_layers < num_layers) {
    assert(num_layers > 1);
    aom_free(svc->layer_context);
    svc->num_allocated_layers = 0;
    svc->layer_context =
        (LAYER_CONTEXT *)aom_calloc(num_layers, sizeof(*svc->layer_context));
    if (svc->layer_context == NULL) return false;
    svc->num_allocated_layers = num_layers;
  }
  return true;
}

// Update the layer context from a change_config() call.
void av1_update_layer_context_change_config(AV1_COMP *const cpi,
                                            const int64_t target_bandwidth) {
  const RATE_CONTROL *const rc = &cpi->rc;
  const PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
  AV1_COMMON *const cm = &cpi->common;
  SVC *const svc = &cpi->svc;
  int layer = 0;
  int64_t spatial_layer_target = 0;
  float bitrate_alloc = 1.0;
  const int mi_rows = cm->mi_params.mi_rows;
  const int mi_cols = cm->mi_params.mi_cols;
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
      layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
      svc->layer_context[layer].target_bandwidth = lc->layer_target_bitrate;
    }
    spatial_layer_target = svc->layer_context[layer].target_bandwidth;
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
      LAYER_CONTEXT *const lc =
          &svc->layer_context[sl * svc->number_temporal_layers + tl];
      RATE_CONTROL *const lrc = &lc->rc;
      PRIMARY_RATE_CONTROL *const lp_rc = &lc->p_rc;
      lc->spatial_layer_target_bandwidth = spatial_layer_target;
      if (target_bandwidth != 0) {
        bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth;
      }
      lp_rc->starting_buffer_level =
          (int64_t)(p_rc->starting_buffer_level * bitrate_alloc);
      lp_rc->optimal_buffer_level =
          (int64_t)(p_rc->optimal_buffer_level * bitrate_alloc);
      lp_rc->maximum_buffer_size =
          (int64_t)(p_rc->maximum_buffer_size * bitrate_alloc);
      lp_rc->bits_off_target =
          AOMMIN(lp_rc->bits_off_target, lp_rc->maximum_buffer_size);
      lp_rc->buffer_level =
          AOMMIN(lp_rc->buffer_level, lp_rc->maximum_buffer_size);
      lc->framerate = cpi->framerate / lc->framerate_factor;
      lrc->avg_frame_bandwidth =
          (int)round(lc->target_bandwidth / lc->framerate);
      lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
      lrc->rtc_external_ratectrl = rc->rtc_external_ratectrl;
      lrc->worst_quality = av1_quantizer_to_qindex(lc->max_q);
      lrc->best_quality = av1_quantizer_to_qindex(lc->min_q);
      if (rc->use_external_qp_one_pass) {
        lrc->worst_quality = rc->worst_quality;
        lrc->best_quality = rc->best_quality;
      }
      // Reset the cyclic refresh parameters, if needed (map is NULL),
      // or number of spatial layers has changed.
      // Cyclic refresh is only applied on base temporal layer.
      if (svc->number_spatial_layers > 1 && tl == 0 &&
          (lc->map == NULL ||
           svc->prev_number_spatial_layers != svc->number_spatial_layers)) {
        lc->sb_index = 0;
        lc->actual_num_seg1_blocks = 0;
        lc->actual_num_seg2_blocks = 0;
        lc->counter_encode_maxq_scene_change = 0;
        aom_free(lc->map);
        CHECK_MEM_ERROR(cm, lc->map,
                        aom_calloc(mi_rows * mi_cols, sizeof(*lc->map)));
      }
    }
  }
}

/*!\brief Return layer context for current layer.
 *
 * \ingroup rate_control
 * \param[in]       cpi   Top level encoder structure
 *
 * \return LAYER_CONTEXT for current layer.
 */
static LAYER_CONTEXT *get_layer_context(AV1_COMP *const cpi) {
  return &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
                                     cpi->svc.number_temporal_layers +
                                 cpi->svc.temporal_layer_id];
}

void av1_update_temporal_layer_framerate(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
  RATE_CONTROL *const lrc = &lc->rc;
  const int tl = svc->temporal_layer_id;
  lc->framerate = cpi->framerate / lc->framerate_factor;
  lrc->avg_frame_bandwidth = (int)round(lc->target_bandwidth / lc->framerate);
  lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
  // Update the average layer frame size (non-cumulative per-frame-bw).
  if (tl == 0) {
    lc->avg_frame_size = lrc->avg_frame_bandwidth;
  } else {
    int prev_layer = svc->spatial_layer_id * svc->number_temporal_layers +
                     svc->temporal_layer_id - 1;
    LAYER_CONTEXT *const lcprev = &svc->layer_context[prev_layer];
    const double prev_layer_framerate =
        cpi->framerate / lcprev->framerate_factor;
    const int64_t prev_layer_target_bandwidth = lcprev->layer_target_bitrate;
    if (lc->framerate > prev_layer_framerate) {
      lc->avg_frame_size =
          (int)round((lc->target_bandwidth - prev_layer_target_bandwidth) /
                     (lc->framerate - prev_layer_framerate));
    } else {
      lc->avg_frame_size = (int)round(lc->target_bandwidth / lc->framerate);
    }
  }
}

bool av1_check_ref_is_low_spatial_res_super_frame(AV1_COMP *const cpi,
                                                  int ref_frame) {
  SVC *svc = &cpi->svc;
  RTC_REF *const rtc_ref = &cpi->ppi->rtc_ref;
  int ref_frame_idx = rtc_ref->ref_idx[ref_frame - 1];
  return rtc_ref->buffer_time_index[ref_frame_idx] == svc->current_superframe &&
         rtc_ref->buffer_spatial_layer[ref_frame_idx] <=
             svc->spatial_layer_id - 1;
}

void av1_restore_layer_context(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  RTC_REF *const rtc_ref = &cpi->ppi->rtc_ref;
  const AV1_COMMON *const cm = &cpi->common;
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
  const int old_frame_since_key = cpi->rc.frames_since_key;
  const int old_frame_to_key = cpi->rc.frames_to_key;
  const int max_consec_drop = cpi->rc.max_consec_drop;
  // Restore layer rate control.
  cpi->rc = lc->rc;
  cpi->ppi->p_rc = lc->p_rc;
  cpi->oxcf.rc_cfg.target_bandwidth = lc->target_bandwidth;
  cpi->gf_frame_index = 0;
  cpi->mv_search_params.max_mv_magnitude = lc->max_mv_magnitude;
  if (cpi->mv_search_params.max_mv_magnitude == 0)
    cpi->mv_search_params.max_mv_magnitude = AOMMAX(cm->width, cm->height);
  // Reset the frames_since_key and frames_to_key counters to their values
  // before the layer restore. Keep these defined for the stream (not layer).
  cpi->rc.frames_since_key = old_frame_since_key;
  cpi->rc.frames_to_key = old_frame_to_key;
  // Reset to value before the layer restore.
  cpi->rc.max_consec_drop = max_consec_drop;
  // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
  // for the base temporal layer.
  if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ &&
      svc->number_spatial_layers > 1 && svc->temporal_layer_id == 0) {
    CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
    swap_ptr(&cr->map, &lc->map);
    cr->sb_index = lc->sb_index;
    cr->actual_num_seg1_blocks = lc->actual_num_seg1_blocks;
    cr->actual_num_seg2_blocks = lc->actual_num_seg2_blocks;
    cr->counter_encode_maxq_scene_change = lc->counter_encode_maxq_scene_change;
  }
  svc->skip_mvsearch_last = 0;
  svc->skip_mvsearch_gf = 0;
  svc->skip_mvsearch_altref = 0;
  // For each reference (LAST/GOLDEN) set the skip_mvsearch_last/gf frame flags.
  // This is to skip searching mv for that reference if it was last
  // refreshed (i.e., buffer slot holding that reference was refreshed) on the
  // previous spatial layer(s) at the same time (current_superframe).
  if (rtc_ref->set_ref_frame_config && svc->force_zero_mode_spatial_ref &&
      cpi->sf.rt_sf.use_nonrd_pick_mode) {
    if (av1_check_ref_is_low_spatial_res_super_frame(cpi, LAST_FRAME)) {
      svc->skip_mvsearch_last = 1;
    }
    if (av1_check_ref_is_low_spatial_res_super_frame(cpi, GOLDEN_FRAME)) {
      svc->skip_mvsearch_gf = 1;
    }
    if (av1_check_ref_is_low_spatial_res_super_frame(cpi, ALTREF_FRAME)) {
      svc->skip_mvsearch_altref = 1;
    }
  }
}

void av1_svc_update_buffer_slot_refreshed(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  RTC_REF *const rtc_ref = &cpi->ppi->rtc_ref;
  const unsigned int current_frame =
      cpi->ppi->use_svc ? svc->current_superframe
                        : cpi->common.current_frame.frame_number;
  // For any buffer slot that is refreshed, update it with
  // the spatial_layer_id and the current_superframe.
  if (cpi->common.current_frame.frame_type == KEY_FRAME) {
    // All slots are refreshed on KEY.
    for (unsigned int i = 0; i < REF_FRAMES; i++) {
      rtc_ref->buffer_time_index[i] = current_frame;
      rtc_ref->buffer_spatial_layer[i] = svc->spatial_layer_id;
    }
  } else if (rtc_ref->set_ref_frame_config) {
    for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
      const int ref_frame_map_idx = rtc_ref->ref_idx[i];
      if (cpi->ppi->rtc_ref.refresh[ref_frame_map_idx]) {
        rtc_ref->buffer_time_index[ref_frame_map_idx] = current_frame;
        rtc_ref->buffer_spatial_layer[ref_frame_map_idx] =
            svc->spatial_layer_id;
      }
    }
  }
}

void av1_save_layer_context(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  const AV1_COMMON *const cm = &cpi->common;
  LAYER_CONTEXT *lc = get_layer_context(cpi);
  lc->rc = cpi->rc;
  lc->p_rc = cpi->ppi->p_rc;
  lc->target_bandwidth = (int)cpi->oxcf.rc_cfg.target_bandwidth;
  lc->group_index = cpi->gf_frame_index;
  lc->max_mv_magnitude = cpi->mv_search_params.max_mv_magnitude;
  if (svc->spatial_layer_id == 0) svc->base_framerate = cpi->framerate;
  // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
  // for the base temporal layer.
  if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ &&
      cpi->svc.number_spatial_layers > 1 && svc->temporal_layer_id == 0) {
    CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
    signed char *temp = lc->map;
    lc->map = cr->map;
    cr->map = temp;
    lc->sb_index = cr->sb_index;
    lc->actual_num_seg1_blocks = cr->actual_num_seg1_blocks;
    lc->actual_num_seg2_blocks = cr->actual_num_seg2_blocks;
    lc->counter_encode_maxq_scene_change = cr->counter_encode_maxq_scene_change;
  }
  av1_svc_update_buffer_slot_refreshed(cpi);
  for (unsigned int i = 0; i < REF_FRAMES; i++) {
    if (frame_is_intra_only(cm) ||
        cm->current_frame.refresh_frame_flags & (1 << i)) {
      svc->spatial_layer_fb[i] = svc->spatial_layer_id;
      svc->temporal_layer_fb[i] = svc->temporal_layer_id;
    }
  }
  if (svc->spatial_layer_id == svc->number_spatial_layers - 1) {
    svc->current_superframe++;
    // Reset drop flag to false for next superframe.
    for (int sl = 0; sl < svc->number_spatial_layers; sl++)
      svc->drop_spatial_layer[sl] = false;
  }
}

int av1_svc_primary_ref_frame(const AV1_COMP *const cpi) {
  const SVC *const svc = &cpi->svc;
  const AV1_COMMON *const cm = &cpi->common;
  int fb_idx = -1;
  int primary_ref_frame = PRIMARY_REF_NONE;
  if (cpi->svc.number_spatial_layers > 1 ||
      cpi->svc.number_temporal_layers > 1) {
    // Set the primary_ref_frame to LAST_FRAME if that buffer slot for LAST
    // was last updated on a lower temporal layer (or base TL0) and for the
    // same spatial layer. For RTC patterns this allows for continued decoding
    // when set of enhancement layers are dropped (continued decoding starting
    // at next base TL0), so error_resilience can be off/0 for all layers.
    fb_idx = get_ref_frame_map_idx(cm, LAST_FRAME);
    if (svc->spatial_layer_fb[fb_idx] == svc->spatial_layer_id &&
        (svc->temporal_layer_fb[fb_idx] < svc->temporal_layer_id ||
         svc->temporal_layer_fb[fb_idx] == 0)) {
      primary_ref_frame = 0;  // LAST_FRAME: ref_frame - LAST_FRAME
    }
  } else if (cpi->ppi->rtc_ref.set_ref_frame_config) {
    const ExternalFlags *const ext_flags = &cpi->ext_flags;
    int flags = ext_flags->ref_frame_flags;
    if (flags & AOM_LAST_FLAG) {
      primary_ref_frame = 0;  // LAST_FRAME: ref_frame - LAST_FRAME
    } else if (flags & AOM_GOLD_FLAG) {
      primary_ref_frame = GOLDEN_FRAME - LAST_FRAME;
    } else if (flags & AOM_ALT_FLAG) {
      primary_ref_frame = ALTREF_FRAME - LAST_FRAME;
    }
  }
  return primary_ref_frame;
}

void av1_free_svc_cyclic_refresh(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
      int layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
      aom_free(lc->map);
      lc->map = NULL;
    }
  }
}

void av1_svc_reset_temporal_layers(AV1_COMP *const cpi, int is_key) {
  SVC *const svc = &cpi->svc;
  LAYER_CONTEXT *lc = NULL;
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
      lc = &cpi->svc.layer_context[sl * svc->number_temporal_layers + tl];
      if (is_key) lc->frames_from_key_frame = 0;
    }
  }
  av1_update_temporal_layer_framerate(cpi);
  av1_restore_layer_context(cpi);
}

void av1_get_layer_resolution(const int width_org, const int height_org,
                              const int num, const int den, int *width_out,
                              int *height_out) {
  int w, h;
  if (width_out == NULL || height_out == NULL || den == 0) return;
  if (den == 1 && num == 1) {
    *width_out = width_org;
    *height_out = height_org;
    return;
  }
  w = width_org * num / den;
  h = height_org * num / den;
  // Make height and width even.
  w += w % 2;
  h += h % 2;
  *width_out = w;
  *height_out = h;
}

void av1_one_pass_cbr_svc_start_layer(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  AV1_COMMON *const cm = &cpi->common;
  LAYER_CONTEXT *lc = NULL;
  int width = 0, height = 0;
  lc = &svc->layer_context[svc->spatial_layer_id * svc->number_temporal_layers +
                           svc->temporal_layer_id];
  // Set the lower quality layer flag.
  svc->has_lower_quality_layer = 0;
  if (cpi->svc.spatial_layer_id > 0) {
    const LAYER_CONTEXT *lc_prev =
        &svc->layer_context[(svc->spatial_layer_id - 1) *
                                svc->number_temporal_layers +
                            svc->temporal_layer_id];
    if (lc_prev->scaling_factor_den == 1 && lc_prev->scaling_factor_num == 1)
      svc->has_lower_quality_layer = 1;
  }
  av1_get_layer_resolution(cpi->oxcf.frm_dim_cfg.width,
                           cpi->oxcf.frm_dim_cfg.height, lc->scaling_factor_num,
                           lc->scaling_factor_den, &width, &height);
  // Use Eightap_smooth for low resolutions.
  if (width * height <= 320 * 240)
    svc->downsample_filter_type[svc->spatial_layer_id] = EIGHTTAP_SMOOTH;

  cm->width = width;
  cm->height = height;
  alloc_mb_mode_info_buffers(cpi);
  av1_update_frame_size(cpi);
  if (svc->spatial_layer_id == svc->number_spatial_layers - 1) {
    svc->mi_cols_full_resoln = cm->mi_params.mi_cols;
    svc->mi_rows_full_resoln = cm->mi_params.mi_rows;
  }
}

enum {
  SVC_LAST_FRAME = 0,
  SVC_LAST2_FRAME,
  SVC_LAST3_FRAME,
  SVC_GOLDEN_FRAME,
  SVC_BWDREF_FRAME,
  SVC_ALTREF2_FRAME,
  SVC_ALTREF_FRAME
};

// For fixed svc mode: fixed pattern is set based on the number of
// spatial and temporal layers, and the ksvc_fixed_mode.
void av1_set_svc_fixed_mode(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  RTC_REF *const rtc_ref = &cpi->ppi->rtc_ref;
  int i;
  assert(svc->use_flexible_mode == 0);
  // Fixed SVC mode only supports at most 3 spatial or temporal layers.
  assert(svc->number_spatial_layers >= 1 && svc->number_spatial_layers <= 3 &&
         svc->number_temporal_layers >= 1 && svc->number_temporal_layers <= 3);
  rtc_ref->set_ref_frame_config = 1;
  int superframe_cnt = svc->current_superframe;
  // Set the reference map buffer idx for the 7 references:
  // LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), GOLDEN_FRAME(3),
  // BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6).
  for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = i;
  for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->reference[i] = 0;
  for (i = 0; i < REF_FRAMES; i++) rtc_ref->refresh[i] = 0;
  // Always reference LAST, and reference GOLDEN on SL > 0.
  // For KSVC: GOLDEN reference will be removed on INTER_FRAMES later
  // when frame_type is set.
  rtc_ref->reference[SVC_LAST_FRAME] = 1;
  if (svc->spatial_layer_id > 0) rtc_ref->reference[SVC_GOLDEN_FRAME] = 1;
  if (svc->temporal_layer_id == 0) {
    // Base temporal layer.
    if (svc->spatial_layer_id == 0) {
      // Set all buffer_idx to 0. Update slot 0 (LAST).
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 0;
      rtc_ref->refresh[0] = 1;
    } else if (svc->spatial_layer_id == 1) {
      // Set buffer_idx for LAST to slot 1, GOLDEN (and all other refs) to
      // slot 0. Update slot 1 (LAST).
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 0;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 1;
      rtc_ref->refresh[1] = 1;
    } else if (svc->spatial_layer_id == 2) {
      // Set buffer_idx for LAST to slot 2, GOLDEN (and all other refs) to
      // slot 1. Update slot 2 (LAST).
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 1;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 2;
      rtc_ref->refresh[2] = 1;
    }
  } else if (svc->temporal_layer_id == 2 && (superframe_cnt - 1) % 4 == 0) {
    // First top temporal enhancement layer.
    if (svc->spatial_layer_id == 0) {
      // Reference LAST (slot 0).
      // Set GOLDEN to slot 3 and update slot 3.
      // Set all other buffer_idx to slot 0.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 0;
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
        rtc_ref->ref_idx[SVC_GOLDEN_FRAME] = 3;
        rtc_ref->refresh[3] = 1;
      }
    } else if (svc->spatial_layer_id == 1) {
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1,
      // GOLDEN (and all other refs) to slot 3.
      // Set LAST2 to slot 4 and Update slot 4.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 3;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 1;
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
        rtc_ref->ref_idx[SVC_LAST2_FRAME] = 4;
        rtc_ref->refresh[4] = 1;
      }
    } else if (svc->spatial_layer_id == 2) {
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2,
      // GOLDEN (and all other refs) to slot 4.
      // No update.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 4;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 2;
    }
  } else if (svc->temporal_layer_id == 1) {
    // Middle temporal enhancement layer.
    if (svc->spatial_layer_id == 0) {
      // Reference LAST.
      // Set all buffer_idx to 0.
      // Set GOLDEN to slot 5 and update slot 5.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 0;
      if (svc->temporal_layer_id < svc->number_temporal_layers - 1 ||
          svc->spatial_layer_id < svc->number_spatial_layers - 1) {
        rtc_ref->ref_idx[SVC_GOLDEN_FRAME] = 5;
        rtc_ref->refresh[5] = 1;
      }
    } else if (svc->spatial_layer_id == 1) {
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1,
      // GOLDEN (and all other refs) to slot 5.
      // Set LAST3 to slot 6 and update slot 6.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 5;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 1;
      if (svc->temporal_layer_id < svc->number_temporal_layers - 1 ||
          svc->spatial_layer_id < svc->number_spatial_layers - 1) {
        rtc_ref->ref_idx[SVC_LAST3_FRAME] = 6;
        rtc_ref->refresh[6] = 1;
      }
    } else if (svc->spatial_layer_id == 2) {
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2,
      // GOLDEN (and all other refs) to slot 6.
      // Set LAST3 to slot 7 and update slot 7.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 6;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 2;
      if (svc->temporal_layer_id < svc->number_temporal_layers - 1) {
        rtc_ref->ref_idx[SVC_LAST3_FRAME] = 7;
        rtc_ref->refresh[7] = 1;
      }
    }
  } else if (svc->temporal_layer_id == 2 && (superframe_cnt - 3) % 4 == 0) {
    // Second top temporal enhancement layer.
    if (svc->spatial_layer_id == 0) {
      // Set LAST to slot 5 and reference LAST.
      // Set GOLDEN to slot 3 and update slot 3.
      // Set all other buffer_idx to 0.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 0;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 5;
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
        rtc_ref->ref_idx[SVC_GOLDEN_FRAME] = 3;
        rtc_ref->refresh[3] = 1;
      }
    } else if (svc->spatial_layer_id == 1) {
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 6,
      // GOLDEN to slot 3. Set LAST2 to slot 4 and update slot 4.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 0;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 6;
      rtc_ref->ref_idx[SVC_GOLDEN_FRAME] = 3;
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
        rtc_ref->ref_idx[SVC_LAST2_FRAME] = 4;
        rtc_ref->refresh[4] = 1;
      }
    } else if (svc->spatial_layer_id == 2) {
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 7,
      // GOLDEN to slot 4. No update.
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) rtc_ref->ref_idx[i] = 0;
      rtc_ref->ref_idx[SVC_LAST_FRAME] = 7;
      rtc_ref->ref_idx[SVC_GOLDEN_FRAME] = 4;
    }
  }
}

void av1_svc_check_reset_layer_rc_flag(AV1_COMP *const cpi) {
  SVC *const svc = &cpi->svc;
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
    // Check for reset based on avg_frame_bandwidth for spatial layer sl.
    // If avg_frame_bandwidth for top temporal layer is not set
    // (because enhancement layer was inactive), use the base TL0
    int layer = LAYER_IDS_TO_IDX(sl, svc->number_temporal_layers - 1,
                                 svc->number_temporal_layers);
    LAYER_CONTEXT *lc = &svc->layer_context[layer];
    RATE_CONTROL *lrc = &lc->rc;
    int avg_frame_bandwidth = lrc->avg_frame_bandwidth;
    int prev_avg_frame_bandwidth = lrc->prev_avg_frame_bandwidth;
    if (avg_frame_bandwidth == 0 || prev_avg_frame_bandwidth == 0) {
      // Use base TL0.
      layer = LAYER_IDS_TO_IDX(sl, 0, svc->number_temporal_layers);
      lc = &svc->layer_context[layer];
      lrc = &lc->rc;
      avg_frame_bandwidth = lrc->avg_frame_bandwidth;
      prev_avg_frame_bandwidth = lrc->prev_avg_frame_bandwidth;
    }
    if (avg_frame_bandwidth > (3 * prev_avg_frame_bandwidth >> 1) ||
        avg_frame_bandwidth < (prev_avg_frame_bandwidth >> 1)) {
      // Reset for all temporal layers with spatial layer sl.
      for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
        int layer2 = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
        LAYER_CONTEXT *lc2 = &svc->layer_context[layer2];
        RATE_CONTROL *lrc2 = &lc2->rc;
        PRIMARY_RATE_CONTROL *lp_rc2 = &lc2->p_rc;
        PRIMARY_RATE_CONTROL *const lp_rc = &lc2->p_rc;
        lrc2->rc_1_frame = 0;
        lrc2->rc_2_frame = 0;
        lp_rc2->bits_off_target = lp_rc->optimal_buffer_level;
        lp_rc2->buffer_level = lp_rc->optimal_buffer_level;
      }
    }
  }
}

void av1_svc_set_last_source(AV1_COMP *const cpi, EncodeFrameInput *frame_input,
                             YV12_BUFFER_CONFIG *prev_source) {
  frame_input->last_source = prev_source != NULL ? prev_source : NULL;
  if (!cpi->ppi->use_svc && cpi->rc.prev_frame_is_dropped &&
      cpi->rc.frame_number_encoded > 0) {
    frame_input->last_source = &cpi->svc.source_last_TL0;
  } else {
    RTC_REF *const rtc_ref = &cpi->ppi->rtc_ref;
    if (cpi->svc.spatial_layer_id == 0) {
      // For base spatial layer: if the LAST reference (index 0) is not
      // the previous (super)frame set the last_source to the source
      // corresponding to the last TL0, otherwise keep it at prev_source.
      // Always use source_last_TL0 if previous base TL0 was dropped.
      if (cpi->svc.current_superframe > 0) {
        const int buffslot_last = rtc_ref->ref_idx[0];
        // Check if previous frame was dropped on base TL0 layer.
        const int layer =
            LAYER_IDS_TO_IDX(0, 0, cpi->svc.number_temporal_layers);
        LAYER_CONTEXT *lc = &cpi->svc.layer_context[layer];
        RATE_CONTROL *lrc = &lc->rc;
        if (lrc->prev_frame_is_dropped ||
            rtc_ref->buffer_time_index[buffslot_last] <
                cpi->svc.current_superframe - 1) {
          frame_input->last_source = &cpi->svc.source_last_TL0;
        }
      }
    } else if (cpi->svc.spatial_layer_id > 0) {
      // For spatial enhancement layers: the previous source (prev_source)
      // corresponds to the lower spatial layer (which is the same source so
      // we can't use that), so always set the last_source to the source of the
      // last TL0.
      if (cpi->svc.current_superframe > 0)
        frame_input->last_source = &cpi->svc.source_last_TL0;
      else
        frame_input->last_source = NULL;
    }
  }
}

int av1_svc_get_min_ref_dist(const AV1_COMP *cpi) {
  RTC_REF *const rtc_ref = &cpi->ppi->rtc_ref;
  int min_dist = INT_MAX;
  const unsigned int current_frame_num =
      cpi->ppi->use_svc ? cpi->svc.current_superframe
                        : cpi->common.current_frame.frame_number;
  for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
    if (cpi->ppi->rtc_ref.reference[i]) {
      const int ref_frame_map_idx = rtc_ref->ref_idx[i];
      const int dist =
          current_frame_num - rtc_ref->buffer_time_index[ref_frame_map_idx];
      if (dist < min_dist) min_dist = dist;
    }
  }
  return min_dist;
}

void av1_svc_set_reference_was_previous(AV1_COMP *cpi) {
  RTC_REF *const rtc_ref = &cpi->ppi->rtc_ref;
  // Check if the encoded frame had some reference that was the
  // previous frame.
  const unsigned int current_frame =
      cpi->ppi->use_svc ? cpi->svc.current_superframe
                        : cpi->common.current_frame.frame_number;
  rtc_ref->reference_was_previous_frame = true;
  if (current_frame > 0) {
    rtc_ref->reference_was_previous_frame = false;
    for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
      if (rtc_ref->reference[i]) {
        const int ref_frame_map_idx = rtc_ref->ref_idx[i];
        if (rtc_ref->buffer_time_index[ref_frame_map_idx] == current_frame - 1)
          rtc_ref->reference_was_previous_frame = true;
      }
    }
  }
}
