/*
 * Copyright (c) 2021, 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 "av1/ratectrl_rtc.h"

#include <memory>
#include <new>

#include "aom/aom_encoder.h"
#include "aom/aomcx.h"
#include "aom/internal/aom_codec_internal.h"
#include "aom_dsp/aom_dsp_common.h"
#include "aom_mem/aom_mem.h"
#include "av1/common/common.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/encoder_utils.h"
#include "av1/encoder/pickcdef.h"
#include "av1/encoder/picklpf.h"
#include "av1/encoder/ratectrl.h"
#include "av1/encoder/rc_utils.h"
#include "av1/encoder/svc_layercontext.h"

namespace {

void AomAV1RateControlRtcConfigInitDefault(AomAV1RateControlRtcConfig *config) {
  if (config == nullptr) return;
  config->width = 1280;
  config->height = 720;
  config->is_screen = false;
  config->max_quantizer = 63;
  config->min_quantizer = 2;
  config->target_bandwidth = 1000;
  config->buf_initial_sz = 600;
  config->buf_optimal_sz = 600;
  config->buf_sz = 1000;
  config->undershoot_pct = 50;
  config->overshoot_pct = 50;
  config->max_intra_bitrate_pct = 50;
  config->max_inter_bitrate_pct = 0;
  config->frame_drop_thresh = 0;
  config->max_consec_drop_ms = 0;
  config->framerate = 30.0;
  av1_zero(config->layer_target_bitrate);
  config->layer_target_bitrate[0] = static_cast<int>(config->target_bandwidth);
  av1_zero(config->ts_rate_decimator);
  config->ts_rate_decimator[0] = 1;
  config->aq_mode = 0;
  config->ss_number_layers = 1;
  config->ts_number_layers = 1;
  av1_zero(config->max_quantizers);
  av1_zero(config->min_quantizers);
  av1_zero(config->scaling_factor_num);
  av1_zero(config->scaling_factor_den);
  config->max_quantizers[0] = config->max_quantizer;
  config->min_quantizers[0] = config->min_quantizer;
  config->scaling_factor_num[0] = 1;
  config->scaling_factor_den[0] = 1;
  config->bit_depth = 8;
}

}  // namespace

AomAV1RateControlRtcConfig::AomAV1RateControlRtcConfig() {
  AomAV1RateControlRtcConfigInitDefault(this);
}

namespace aom {

// Creates a setjmp target using `CPI->common.error->jmp` and sets
// `CPI->common.error->setjmp = 1`. Returns false on longjmp. This should be
// accompanied by a call to DISABLE_SETJMP using the same CPI before going out
// of scope.
#define ENABLE_SETJMP(CPI)                                      \
  do {                                                          \
    struct aom_internal_error_info *const enable_setjmp_error = \
        (CPI)->common.error;                                    \
    if (setjmp(enable_setjmp_error->jmp)) {                     \
      enable_setjmp_error->setjmp = 0;                          \
      return false;                                             \
    }                                                           \
    enable_setjmp_error->setjmp = 1;                            \
  } while (0)

// Sets CPI->common.error->setjmp = 0.
#define DISABLE_SETJMP(CPI)                                     \
  do {                                                          \
    struct aom_internal_error_info *const enable_setjmp_error = \
        (CPI)->common.error;                                    \
    enable_setjmp_error->setjmp = 0;                            \
  } while (0)

std::unique_ptr<AV1RateControlRTC> AV1RateControlRTC::Create(
    const AV1RateControlRtcConfig &cfg) {
  std::unique_ptr<AV1RateControlRTC> rc_api(new (std::nothrow)
                                                AV1RateControlRTC());
  if (!rc_api) return nullptr;
  rc_api->cpi_ = static_cast<AV1_COMP *>(aom_memalign(32, sizeof(*cpi_)));
  if (!rc_api->cpi_) return nullptr;
  av1_zero(*rc_api->cpi_);
  rc_api->cpi_->ppi =
      static_cast<AV1_PRIMARY *>(aom_memalign(32, sizeof(AV1_PRIMARY)));
  if (!rc_api->cpi_->ppi) return nullptr;
  av1_zero(*rc_api->cpi_->ppi);
  rc_api->cpi_->common.error = &rc_api->cpi_->ppi->error;
  rc_api->cpi_->common.seq_params = &rc_api->cpi_->ppi->seq_params;
  av1_zero(*rc_api->cpi_->common.seq_params);
  if (!rc_api->InitRateControl(cfg)) return nullptr;
  if (cfg.aq_mode) {
    AV1_COMP *const cpi = rc_api->cpi_;
    cpi->enc_seg.map = static_cast<uint8_t *>(aom_calloc(
        cpi->common.mi_params.mi_rows * cpi->common.mi_params.mi_cols,
        sizeof(*cpi->enc_seg.map)));
    if (!cpi->enc_seg.map) return nullptr;
    cpi->cyclic_refresh = av1_cyclic_refresh_alloc(
        cpi->common.mi_params.mi_rows, cpi->common.mi_params.mi_cols);
    if (!cpi->cyclic_refresh) return nullptr;
  }
  rc_api->rc_is_valid_ = true;
  return rc_api;
}

AV1RateControlRTC::~AV1RateControlRTC() {
  if (cpi_) {
    if (cpi_->svc.number_spatial_layers > 1 ||
        cpi_->svc.number_temporal_layers > 1) {
      for (int sl = 0; sl < cpi_->svc.number_spatial_layers; sl++) {
        for (int tl = 0; tl < cpi_->svc.number_temporal_layers; tl++) {
          int layer =
              LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers);
          LAYER_CONTEXT *const lc = &cpi_->svc.layer_context[layer];
          aom_free(lc->map);
        }
      }
    }
    aom_free(cpi_->svc.layer_context);
    cpi_->svc.layer_context = nullptr;

    if (cpi_->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ) {
      aom_free(cpi_->enc_seg.map);
      cpi_->enc_seg.map = nullptr;
      av1_cyclic_refresh_free(cpi_->cyclic_refresh);
    }
    aom_free(cpi_->ppi);
    aom_free(cpi_);
  }
}

bool AV1RateControlRTC::InitRateControl(const AV1RateControlRtcConfig &rc_cfg) {
  AV1_COMMON *cm = &cpi_->common;
  AV1EncoderConfig *oxcf = &cpi_->oxcf;
  RATE_CONTROL *const rc = &cpi_->rc;
  const int bit_depth = rc_cfg.bit_depth == 0 ? 8 : rc_cfg.bit_depth;
  if (bit_depth != 8 && bit_depth != 10 && bit_depth != 12) return false;
  cm->seq_params->profile = (bit_depth == 12) ? PROFILE_2 : PROFILE_0;
  cm->seq_params->bit_depth = static_cast<aom_bit_depth_t>(bit_depth);
  cm->show_frame = 1;
  oxcf->profile = cm->seq_params->profile;
  oxcf->mode = REALTIME;
  oxcf->rc_cfg.mode = AOM_CBR;
  oxcf->pass = AOM_RC_ONE_PASS;
  oxcf->q_cfg.aq_mode = rc_cfg.aq_mode ? CYCLIC_REFRESH_AQ : NO_AQ;
  oxcf->tune_cfg.content = AOM_CONTENT_DEFAULT;
  oxcf->rc_cfg.drop_frames_water_mark = rc_cfg.frame_drop_thresh;
  if (rc_cfg.max_consec_drop_ms > 0) {
    rc->max_consec_drop = saturate_cast_double_to_int(
        ceil(cpi_->framerate * rc_cfg.max_consec_drop_ms / 1000));
  }
  cpi_->svc.framedrop_mode = AOM_FULL_SUPERFRAME_DROP;
  oxcf->tool_cfg.bit_depth = cm->seq_params->bit_depth;
  oxcf->tool_cfg.superblock_size = AOM_SUPERBLOCK_SIZE_DYNAMIC;
  oxcf->algo_cfg.loopfilter_control = LOOPFILTER_ALL;
  cm->current_frame.frame_number = 0;
  cpi_->ppi->p_rc.kf_boost = DEFAULT_KF_BOOST_RT;
  for (auto &lvl_idx : oxcf->target_seq_level_idx) lvl_idx = SEQ_LEVEL_MAX;

  memcpy(cpi_->ppi->level_params.target_seq_level_idx,
         oxcf->target_seq_level_idx, sizeof(oxcf->target_seq_level_idx));
  if (!UpdateRateControl(rc_cfg)) return false;
  set_sb_size(cm->seq_params,
              av1_select_sb_size(oxcf, cm->width, cm->height,
                                 cpi_->svc.number_spatial_layers));
  cpi_->ppi->use_svc = cpi_->svc.number_spatial_layers > 1 ||
                       cpi_->svc.number_temporal_layers > 1;
  av1_primary_rc_init(oxcf, &cpi_->ppi->p_rc);
  rc->rc_1_frame = 0;
  rc->rc_2_frame = 0;
  av1_rc_init_minq_luts();
  av1_rc_init(oxcf, rc);
  // Enable external rate control.
  cpi_->rc.rtc_external_ratectrl = 1;
  cpi_->sf.rt_sf.use_nonrd_pick_mode = 1;
  rc_is_valid_ = true;
  return true;
}

bool AV1RateControlRTC::UpdateRateControl(
    const AV1RateControlRtcConfig &rc_cfg) {
  if (rc_cfg.ss_number_layers < 1 ||
      rc_cfg.ss_number_layers > AOM_MAX_SS_LAYERS ||
      rc_cfg.ts_number_layers < 1 ||
      rc_cfg.ts_number_layers > AOM_MAX_TS_LAYERS) {
    rc_is_valid_ = false;
    return false;
  }
  if (rc_cfg.bit_depth != 0 &&
      rc_cfg.bit_depth !=
          static_cast<int>(cpi_->common.seq_params->bit_depth)) {
    rc_is_valid_ = false;
    return false;
  }
  if (cpi_->svc.number_spatial_layers != rc_cfg.ss_number_layers ||
      cpi_->svc.number_temporal_layers != rc_cfg.ts_number_layers)
    av1_free_svc_cyclic_refresh(cpi_);
  const int num_layers = rc_cfg.ss_number_layers * rc_cfg.ts_number_layers;
  if (num_layers > 1 && !av1_alloc_layer_context(cpi_, num_layers)) {
    rc_is_valid_ = false;
    return false;
  }
  AV1_COMMON *cm = &cpi_->common;
  AV1EncoderConfig *oxcf = &cpi_->oxcf;
  RATE_CONTROL *const rc = &cpi_->rc;
  if (oxcf->frm_dim_cfg.width && oxcf->frm_dim_cfg.height &&
      (rc_cfg.width > oxcf->frm_dim_cfg.width ||
       rc_cfg.height > oxcf->frm_dim_cfg.height)) {
    rc_is_valid_ = false;
    return false;
  }
  initial_width_ = rc_cfg.width;
  initial_height_ = rc_cfg.height;
  cm->width = rc_cfg.width;
  cm->height = rc_cfg.height;
  oxcf->frm_dim_cfg.width = rc_cfg.width;
  oxcf->frm_dim_cfg.height = rc_cfg.height;
  oxcf->rc_cfg.worst_allowed_q = av1_quantizer_to_qindex(rc_cfg.max_quantizer);
  oxcf->rc_cfg.best_allowed_q = av1_quantizer_to_qindex(rc_cfg.min_quantizer);
  rc->worst_quality = oxcf->rc_cfg.worst_allowed_q;
  rc->best_quality = oxcf->rc_cfg.best_allowed_q;
  oxcf->input_cfg.init_framerate = rc_cfg.framerate;
  oxcf->rc_cfg.target_bandwidth = rc_cfg.target_bandwidth > INT64_MAX / 1000
                                      ? INT64_MAX
                                      : 1000 * rc_cfg.target_bandwidth;
  oxcf->rc_cfg.starting_buffer_level_ms = rc_cfg.buf_initial_sz;
  oxcf->rc_cfg.optimal_buffer_level_ms = rc_cfg.buf_optimal_sz;
  oxcf->rc_cfg.maximum_buffer_size_ms = rc_cfg.buf_sz;
  oxcf->rc_cfg.under_shoot_pct = rc_cfg.undershoot_pct;
  oxcf->rc_cfg.over_shoot_pct = rc_cfg.overshoot_pct;
  oxcf->rc_cfg.drop_frames_water_mark = rc_cfg.frame_drop_thresh;
  if (rc_cfg.max_consec_drop_ms > 0) {
    rc->max_consec_drop = saturate_cast_double_to_int(
        ceil(cpi_->framerate * rc_cfg.max_consec_drop_ms / 1000));
  }
  oxcf->rc_cfg.max_intra_bitrate_pct = rc_cfg.max_intra_bitrate_pct;
  oxcf->rc_cfg.max_inter_bitrate_pct = rc_cfg.max_inter_bitrate_pct;
  cpi_->framerate = rc_cfg.framerate;
  if (rc_cfg.is_screen) {
    cpi_->oxcf.tune_cfg.content = AOM_CONTENT_SCREEN;
    cpi_->is_screen_content_type = 1;
  }
  cpi_->svc.number_spatial_layers = rc_cfg.ss_number_layers;
  cpi_->svc.number_temporal_layers = rc_cfg.ts_number_layers;
  set_primary_rc_buffer_sizes(oxcf, cpi_->ppi);
  enc_set_mb_mi(&cm->mi_params, cm->width, cm->height, BLOCK_8X8);
  av1_new_framerate(cpi_, cpi_->framerate);
  if (cpi_->svc.number_temporal_layers > 1 ||
      cpi_->svc.number_spatial_layers > 1) {
    volatile int64_t target_bandwidth_svc = 0;
    for (int sl = 0; sl < cpi_->svc.number_spatial_layers; ++sl) {
      for (int tl = 0; tl < cpi_->svc.number_temporal_layers; ++tl) {
        const int layer =
            LAYER_IDS_TO_IDX(sl, tl, cpi_->svc.number_temporal_layers);
        LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
        RATE_CONTROL *const lrc = &lc->rc;
        lc->layer_target_bitrate = 1000 * rc_cfg.layer_target_bitrate[layer];
        if (rc_cfg.max_quantizers[layer] > 63 ||
            rc_cfg.min_quantizers[layer] < 0 ||
            rc_cfg.min_quantizers[layer] > rc_cfg.max_quantizers[layer]) {
          rc_is_valid_ = false;
          return false;
        }
        lc->max_q = rc_cfg.max_quantizers[layer];
        lc->min_q = rc_cfg.min_quantizers[layer];
        lrc->worst_quality =
            av1_quantizer_to_qindex(rc_cfg.max_quantizers[layer]);
        lrc->best_quality =
            av1_quantizer_to_qindex(rc_cfg.min_quantizers[layer]);
        // spatial scaling (scaling_factor_num[]/den[]) is always to a lower
        // resolution, so den must be >= num.
        if (rc_cfg.scaling_factor_den[sl] < rc_cfg.scaling_factor_num[sl]) {
          rc_is_valid_ = false;
          return false;
        }
        lc->scaling_factor_num = AOMMAX(1, rc_cfg.scaling_factor_num[sl]);
        lc->scaling_factor_den = AOMMAX(1, rc_cfg.scaling_factor_den[sl]);
        lc->framerate_factor = rc_cfg.ts_rate_decimator[tl];
        if (tl == cpi_->svc.number_temporal_layers - 1)
          target_bandwidth_svc += lc->layer_target_bitrate;
      }
    }

    ENABLE_SETJMP(cpi_);
    if (cm->current_frame.frame_number == 0) {
      av1_init_layer_context(cpi_);
    }
    // This is needed to initialize external RC flag in layer context structure.
    cpi_->rc.rtc_external_ratectrl = 1;
    av1_update_layer_context_change_config(cpi_, target_bandwidth_svc);
    DISABLE_SETJMP(cpi_);
  }
  check_reset_rc_flag(cpi_);
  rc_is_valid_ = true;
  return true;
}

FrameDropDecision AV1RateControlRTC::ComputeQP(
    const AV1FrameParamsRTC &frame_params) {
  if (!rc_is_valid_) return kFrameDropDecisionDrop;
  if (frame_params.spatial_layer_id < 0 ||
      frame_params.spatial_layer_id >= cpi_->svc.number_spatial_layers ||
      frame_params.temporal_layer_id < 0 ||
      frame_params.temporal_layer_id >= cpi_->svc.number_temporal_layers ||
      initial_width_ == 0 || initial_height_ == 0) {
    return kFrameDropDecisionDrop;
  }
  AV1_COMMON *const cm = &cpi_->common;
  int width, height;
  GF_GROUP *const gf_group = &cpi_->ppi->gf_group;
  cpi_->svc.spatial_layer_id = frame_params.spatial_layer_id;
  cpi_->svc.temporal_layer_id = frame_params.temporal_layer_id;
  if (cpi_->svc.number_spatial_layers > 1) {
    const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id,
                                       cpi_->svc.temporal_layer_id,
                                       cpi_->svc.number_temporal_layers);
    LAYER_CONTEXT *lc = &cpi_->svc.layer_context[layer];
    av1_get_layer_resolution(initial_width_, initial_height_,
                             lc->scaling_factor_num, lc->scaling_factor_den,
                             &width, &height);
    cm->width = width;
    cm->height = height;
  }
  enc_set_mb_mi(&cm->mi_params, cm->width, cm->height, BLOCK_8X8);
  cm->current_frame.frame_type = frame_params.frame_type;
  cpi_->refresh_frame.golden_frame =
      (cm->current_frame.frame_type == KEY_FRAME) ? 1 : 0;
  cpi_->sf.rt_sf.use_nonrd_pick_mode = 1;

  if (frame_params.frame_type == kKeyFrame) {
    gf_group->update_type[cpi_->gf_frame_index] = KF_UPDATE;
    gf_group->frame_type[cpi_->gf_frame_index] = KEY_FRAME;
    gf_group->refbuf_state[cpi_->gf_frame_index] = REFBUF_RESET;
    if (cpi_->ppi->use_svc) {
      const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id,
                                         cpi_->svc.temporal_layer_id,
                                         cpi_->svc.number_temporal_layers);
      if (cm->current_frame.frame_number > 0)
        av1_svc_reset_temporal_layers(cpi_, 1);
      cpi_->svc.layer_context[layer].is_key_frame = 1;
    }
  } else {
    gf_group->update_type[cpi_->gf_frame_index] = LF_UPDATE;
    gf_group->frame_type[cpi_->gf_frame_index] = INTER_FRAME;
    gf_group->refbuf_state[cpi_->gf_frame_index] = REFBUF_UPDATE;
    if (cpi_->ppi->use_svc) {
      const int layer = LAYER_IDS_TO_IDX(cpi_->svc.spatial_layer_id,
                                         cpi_->svc.temporal_layer_id,
                                         cpi_->svc.number_temporal_layers);
      cpi_->svc.layer_context[layer].is_key_frame = 0;
    }
  }
  if (cpi_->svc.number_spatial_layers > 1 ||
      cpi_->svc.number_temporal_layers > 1) {
    av1_update_temporal_layer_framerate(cpi_);
    av1_restore_layer_context(cpi_);
  }
  int target = 0;
  if (cpi_->oxcf.rc_cfg.mode == AOM_CBR) {
    if (cpi_->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ)
      av1_cyclic_refresh_update_parameters(cpi_);
    if (frame_is_intra_only(cm)) {
      target = av1_calc_iframe_target_size_one_pass_cbr(cpi_);
      cpi_->common.current_frame.frame_number = 0;
    } else {
      target = av1_calc_pframe_target_size_one_pass_cbr(
          cpi_, gf_group->update_type[cpi_->gf_frame_index]);
    }
  }
  av1_rc_set_frame_target(cpi_, target, cm->width, cm->height);
  // Always drop for spatial enhancement layer if layer bandwidth is 0.
  // Otherwise check for frame-dropping based on buffer level in
  // av1_rc_drop_frame().
  if ((cpi_->svc.spatial_layer_id > 0 &&
       cpi_->oxcf.rc_cfg.target_bandwidth == 0) ||
      av1_rc_drop_frame(cpi_)) {
    cpi_->is_dropped_frame = true;
    av1_rc_postencode_update_drop_frame(cpi_);
    if (cpi_->svc.spatial_layer_id == cpi_->svc.number_spatial_layers - 1)
      cpi_->rc.frames_since_key++;
    if (cpi_->svc.number_spatial_layers > 1 ||
        cpi_->svc.number_temporal_layers > 1) {
      av1_save_layer_context(cpi_);
    }
    cpi_->frame_index_set.show_frame_count++;
    cpi_->common.current_frame.frame_number++;
    return kFrameDropDecisionDrop;
  }
  int bottom_index = 0, top_index = 0;
  cpi_->common.quant_params.base_qindex =
      av1_rc_pick_q_and_bounds(cpi_, cm->width, cm->height,
                               cpi_->gf_frame_index, &bottom_index, &top_index);
  if (cpi_->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ)
    av1_cyclic_refresh_setup(cpi_);
  return kFrameDropDecisionOk;
}

int AV1RateControlRTC::GetQP() const {
  if (rc_is_valid_) return cpi_->common.quant_params.base_qindex;
  return 0;
}

AV1LoopfilterLevel AV1RateControlRTC::GetLoopfilterLevel() const {
  AV1LoopfilterLevel lpf_level;
  if (rc_is_valid_) {
    av1_pick_filter_level(nullptr, cpi_, LPF_PICK_FROM_Q);
    lpf_level.filter_level[0] = cpi_->common.lf.filter_level[0];
    lpf_level.filter_level[1] = cpi_->common.lf.filter_level[1];
    lpf_level.filter_level_u = cpi_->common.lf.filter_level_u;
    lpf_level.filter_level_v = cpi_->common.lf.filter_level_v;
  } else {
    lpf_level.filter_level[0] = 0;
    lpf_level.filter_level[1] = 0;
    lpf_level.filter_level_u = 0;
    lpf_level.filter_level_v = 0;
  }
  return lpf_level;
}

AV1CdefInfo AV1RateControlRTC::GetCdefInfo() const {
  AV1CdefInfo cdef_level;
  if (rc_is_valid_) {
    av1_pick_cdef_from_qp(&cpi_->common, /*skip_cdef=*/0,
                          /*is_screen_content=*/0,
                          /*avoid_uv_cdef=*/false);
    cdef_level.cdef_strength_y = cpi_->common.cdef_info.cdef_strengths[0];
    cdef_level.cdef_strength_uv = cpi_->common.cdef_info.cdef_uv_strengths[0];
    cdef_level.damping = cpi_->common.cdef_info.cdef_damping;
  } else {
    cdef_level.cdef_strength_y = 0;
    cdef_level.cdef_strength_uv = 0;
    cdef_level.damping = 0;
  }
  return cdef_level;
}

bool AV1RateControlRTC::GetSegmentationData(
    AV1SegmentationData *segmentation_data) const {
  if (!rc_is_valid_) return false;
  if (cpi_->oxcf.q_cfg.aq_mode == 0) {
    return false;
  }
  // Don't update the segmentation map if cyclic refresh is not enabled.
  if (!cpi_->cyclic_refresh->apply_cyclic_refresh) {
    return false;
  }
  segmentation_data->segmentation_map = cpi_->enc_seg.map;
  segmentation_data->segmentation_map_size =
      cpi_->common.mi_params.mi_rows * cpi_->common.mi_params.mi_cols;
  segmentation_data->delta_q = cpi_->cyclic_refresh->qindex_delta;
  segmentation_data->delta_q_size = 3u;
  return true;
}

void AV1RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) {
  if (!rc_is_valid_) return;
  cpi_->common.current_frame.frame_number++;
  av1_rc_postencode_update(cpi_, encoded_frame_size);
  if (cpi_->svc.spatial_layer_id == cpi_->svc.number_spatial_layers - 1) {
    cpi_->svc.prev_number_spatial_layers = cpi_->svc.number_spatial_layers;
    cpi_->rc.frames_since_key++;
  }
  if (cpi_->svc.number_spatial_layers > 1 ||
      cpi_->svc.number_temporal_layers > 1)
    av1_save_layer_context(cpi_);
}
}  // namespace aom

extern "C" {

AomAV1RateControlRTC *av1_ratecontrol_rtc_create(
    const AomAV1RateControlRtcConfig *rc_cfg) {
  if (rc_cfg == nullptr) return nullptr;
  return reinterpret_cast<AomAV1RateControlRTC *>(
      aom::AV1RateControlRTC::Create(*rc_cfg).release());
}

void av1_ratecontrol_rtc_destroy(AomAV1RateControlRTC *controller) {
  delete reinterpret_cast<aom::AV1RateControlRTC *>(controller);
}

bool av1_ratecontrol_rtc_update(
    AomAV1RateControlRTC *controller,
    const struct AomAV1RateControlRtcConfig *rc_cfg) {
  if (controller == nullptr || rc_cfg == nullptr) return false;

  return reinterpret_cast<aom::AV1RateControlRTC *>(controller)
      ->UpdateRateControl(*rc_cfg);
}

int av1_ratecontrol_rtc_get_qp(const AomAV1RateControlRTC *controller) {
  if (controller == nullptr) return 0;
  return reinterpret_cast<const aom::AV1RateControlRTC *>(controller)->GetQP();
}

AomAV1LoopfilterLevel av1_ratecontrol_rtc_get_loop_filter_level(
    const AomAV1RateControlRTC *controller) {
  if (controller == nullptr) {
    return { { 0, 0 }, 0, 0 };
  }
  return reinterpret_cast<const aom::AV1RateControlRTC *>(controller)
      ->GetLoopfilterLevel();
}

AomFrameDropDecision av1_ratecontrol_rtc_compute_qp(
    AomAV1RateControlRTC *controller,
    const AomAV1FrameParamsRTC *frame_params) {
  if (controller == nullptr || frame_params == nullptr)
    return kAomFrameDropDecisionOk;
  return reinterpret_cast<aom::AV1RateControlRTC *>(controller)
      ->ComputeQP(*frame_params);
}

void av1_ratecontrol_rtc_post_encode_update(AomAV1RateControlRTC *controller,
                                            uint64_t encoded_frame_size) {
  if (controller == nullptr) return;
  reinterpret_cast<aom::AV1RateControlRTC *>(controller)
      ->PostEncodeUpdate(encoded_frame_size);
}

bool av1_ratecontrol_rtc_get_segmentation(
    const AomAV1RateControlRTC *controller,
    AomAV1SegmentationData *segmentation_data) {
  if (controller == nullptr || segmentation_data == nullptr) return false;

  return reinterpret_cast<const aom::AV1RateControlRTC *>(controller)
      ->GetSegmentationData(segmentation_data);
}

AomAV1CdefInfo av1_ratecontrol_rtc_get_cdef_info(
    const AomAV1RateControlRTC *controller) {
  if (controller == nullptr) {
    return { 0, 0, 0 };
  }
  return reinterpret_cast<const aom::AV1RateControlRTC *>(controller)
      ->GetCdefInfo();
}

void av1_ratecontrol_rtc_init_ratecontrol_config(
    AomAV1RateControlRtcConfig *config) {
  AomAV1RateControlRtcConfigInitDefault(config);
}

}  // extern "C"
