/*
 * 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 "gtest/gtest.h"
#include "test/codec_factory.h"
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
#include "test/util.h"

namespace {

constexpr size_t kNumFrames = 450;

const int kTemporalId3Layer[4] = { 0, 2, 1, 2 };
const int kTemporalId2Layer[2] = { 0, 1 };
const int kTemporalRateAllocation3Layer[3] = { 50, 70, 100 };
const int kTemporalRateAllocation2Layer[2] = { 60, 100 };
const int kSpatialLayerBitrate[3] = { 200, 500, 900 };

// Parameter: aq mode: 0 and 3
class RcInterfaceTest : public ::libaom_test::EncoderTest,
                        public ::libaom_test::CodecTestWithParam<int> {
 public:
  RcInterfaceTest()
      : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)), key_interval_(3000),
        encoder_exit_(false), layer_frame_cnt_(0), superframe_cnt_(0),
        frame_cnt_(0), dynamic_temporal_layers_(false),
        dynamic_spatial_layers_(false), num_drops_(0), max_consec_drop_ms_(0),
        frame_drop_thresh_(0) {
    memset(&svc_params_, 0, sizeof(svc_params_));
    memset(&layer_id_, 0, sizeof(layer_id_));
    memset(&frame_params_, 0, sizeof(frame_params_));
    frame_params_.frame_type = aom::kKeyFrame;
  }

  ~RcInterfaceTest() override = default;

 protected:
  void SetUp() override { InitializeConfig(::libaom_test::kRealTime); }

  int GetNumSpatialLayers() override { return rc_cfg_.ss_number_layers; }

  void PreEncodeFrameHook(libaom_test::VideoSource *video,
                          libaom_test::Encoder *encoder) override {
    int key_int = key_interval_;
    const int use_svc =
        rc_cfg_.ss_number_layers > 1 || rc_cfg_.ts_number_layers > 1;
    encoder->Control(AV1E_SET_RTC_EXTERNAL_RC, 1);
    if (video->frame() == 0 && layer_frame_cnt_ == 0) {
      encoder->Control(AOME_SET_CPUUSED, 7);
      encoder->Control(AV1E_SET_AQ_MODE, aq_mode_);
      encoder->Control(AV1E_SET_ENABLE_ORDER_HINT, 0);
      if (rc_cfg_.is_screen) {
        encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN);
      } else {
        encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT);
      }
      encoder->Control(AOME_SET_MAX_INTRA_BITRATE_PCT,
                       rc_cfg_.max_intra_bitrate_pct);
      if (use_svc) encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
      encoder->Control(AV1E_SET_MAX_CONSEC_FRAME_DROP_MS_CBR,
                       max_consec_drop_ms_);
    }
    // SVC specific settings
    if (use_svc) {
      frame_params_.spatial_layer_id =
          layer_frame_cnt_ % rc_cfg_.ss_number_layers;
      if (rc_cfg_.ts_number_layers == 3)
        frame_params_.temporal_layer_id =
            kTemporalId3Layer[superframe_cnt_ % 4];
      else if (rc_cfg_.ts_number_layers == 2)
        frame_params_.temporal_layer_id =
            kTemporalId2Layer[superframe_cnt_ % 2];
      else
        frame_params_.temporal_layer_id = 0;
      layer_id_.spatial_layer_id = frame_params_.spatial_layer_id;
      layer_id_.temporal_layer_id = frame_params_.temporal_layer_id;
      encoder->Control(AV1E_SET_SVC_LAYER_ID, &layer_id_);
      key_int = key_interval_ * rc_cfg_.ss_number_layers;
    }
    frame_params_.frame_type =
        layer_frame_cnt_ % key_int == 0 ? aom::kKeyFrame : aom::kInterFrame;
    encoder_exit_ = video->frame() == kNumFrames;
    frame_flags_ = 0;

    if (dynamic_temporal_layers_) {
      if (superframe_cnt_ == 100 && layer_id_.spatial_layer_id == 0) {
        // Go down to 2 temporal layers.
        SetConfigSvc(3, 2);
        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
        frame_flags_ = AOM_EFLAG_FORCE_KF;
        frame_params_.frame_type = aom::kKeyFrame;
        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
      } else if (superframe_cnt_ == 200 && layer_id_.spatial_layer_id == 0) {
        // Go down to 1 temporal layer.
        SetConfigSvc(3, 1);
        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
        frame_flags_ = AOM_EFLAG_FORCE_KF;
        frame_params_.frame_type = aom::kKeyFrame;
        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
      } else if (superframe_cnt_ == 300 && layer_id_.spatial_layer_id == 0) {
        // Go back up to 3 temporal layers.
        SetConfigSvc(3, 3);
        frame_flags_ = AOM_EFLAG_FORCE_KF;
        frame_params_.frame_type = aom::kKeyFrame;
        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
      }
    } else if (dynamic_spatial_layers_) {
      // In this example the #spatial layers is modified on the fly,
      // so we go from (120p,240p,480p) to (240p,480p), etc.
      if (superframe_cnt_ == 100 && layer_id_.spatial_layer_id == 0) {
        // Change to 2 spatial layers (240p, 480p).
        SetConfigSvc(2, 3);
        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
        frame_flags_ = AOM_EFLAG_FORCE_KF;
        frame_params_.frame_type = aom::kKeyFrame;
        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
      } else if (superframe_cnt_ == 200 && layer_id_.spatial_layer_id == 0) {
        // Change to 1 spatial layer (480p).
        SetConfigSvc(1, 3);
        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
        frame_flags_ = AOM_EFLAG_FORCE_KF;
        frame_params_.frame_type = aom::kKeyFrame;
        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
      } else if (superframe_cnt_ == 300 && layer_id_.spatial_layer_id == 0) {
        // Go back to 3 spatial layers (120p, 240p, 480p).
        SetConfigSvc(3, 3);
        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
        // In the fixed SVC mode (which is what is used in this test):
        // Key frame is required here on SL0 since 120p will try to predict
        // from LAST which was the 480p, so decoder will throw an error
        // (reference must be smaller than 4x4). In the flexible mode
        // (not used here) we can set the frame flags to predict off the 2x2
        // reference instead,
        frame_flags_ = AOM_EFLAG_FORCE_KF;
        frame_params_.frame_type = aom::kKeyFrame;
        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
      }
    }
    // TODO(marpan): Add dynamic spatial layers based on 0 layer bitrate.
    // That is actual usage in SW where configuration (#spatial, #temporal)
    // layers is fixed, but top layer is dropped or re-enabled based on
    // bitrate. This requires external RC to handle dropped (zero-size) frames.
  }

  void PostEncodeFrameHook(::libaom_test::Encoder *encoder) override {
    if (encoder_exit_) {
      return;
    }
    int num_operating_points;
    encoder->Control(AV1E_GET_NUM_OPERATING_POINTS, &num_operating_points);
    ASSERT_EQ(num_operating_points,
              rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers);
    layer_frame_cnt_++;
    frame_cnt_++;
    if (layer_id_.spatial_layer_id == rc_cfg_.ss_number_layers - 1)
      superframe_cnt_++;
    int qp;
    encoder->Control(AOME_GET_LAST_QUANTIZER, &qp);
    if (rc_api_->ComputeQP(frame_params_) == aom::kFrameDropDecisionOk) {
      ASSERT_EQ(rc_api_->GetQP(), qp) << "at frame " << frame_cnt_ - 1;
      int encoder_lpf_level;
      encoder->Control(AOME_GET_LOOPFILTER_LEVEL, &encoder_lpf_level);
      aom::AV1LoopfilterLevel loopfilter_level = rc_api_->GetLoopfilterLevel();
      ASSERT_EQ(loopfilter_level.filter_level[0], encoder_lpf_level);
      aom::AV1CdefInfo cdef_level = rc_api_->GetCdefInfo();
      int cdef_y_strengths[16];
      encoder->Control(AV1E_GET_LUMA_CDEF_STRENGTH, cdef_y_strengths);
      ASSERT_EQ(cdef_level.cdef_strength_y, cdef_y_strengths[0]);
    } else {
      num_drops_++;
    }
  }

  void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
    if (layer_id_.spatial_layer_id == 0)
      rc_api_->PostEncodeUpdate(pkt->data.frame.sz - 2);
    else
      rc_api_->PostEncodeUpdate(pkt->data.frame.sz);
  }

  void MismatchHook(const aom_image_t *img1, const aom_image_t *img2) override {
    (void)img1;
    (void)img2;
  }

  void RunOneLayer() {
    key_interval_ = 10000;
    SetConfig();
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
                                         1, 0, kNumFrames);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }

  void RunOneLayerScreen() {
    key_interval_ = 10000;
    SetConfig();
    rc_cfg_.is_screen = true;
    rc_cfg_.width = 352;
    rc_cfg_.height = 288;
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
                                         288, 30, 1, 0, 140);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }

  void RunOneLayerDropFramesCBR() {
    key_interval_ = 10000;
    max_consec_drop_ms_ = 250;
    frame_drop_thresh_ = 30;
    SetConfig();
    rc_cfg_.target_bandwidth = 100;
    cfg_.rc_target_bitrate = 100;
    rc_cfg_.max_quantizer = 50;
    cfg_.rc_max_quantizer = 50;
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
                                         1, 0, kNumFrames);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    // Check that some frames were dropped, otherwise test has no value.
    ASSERT_GE(num_drops_, 1);
  }

  void RunOneLayerPeriodicKey() {
    key_interval_ = 100;
    SetConfig();
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
                                         1, 0, kNumFrames);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }

  void RunSvcInvalidInputs() {
    key_interval_ = 10000;
    // Initial resolution is set to 640x480.
    SetConfigSvc(3, 3);
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    // Verfiy return false on UpdateRateControl if resolution goes above
    // configured setting.
    rc_cfg_.width = 1280;
    rc_cfg_.height = 720;
    ASSERT_FALSE(rc_api_->UpdateRateControl(rc_cfg_));
    // Go back to original resolution.
    rc_cfg_.width = 640;
    rc_cfg_.height = 480;
    ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
    // Set layer_id beyond the range set in init (#spatial=3, #temporal=3).
    // Expect ComputeQP() to return kFrameDropDecisionDrop.
    frame_params_.spatial_layer_id = 4;
    frame_params_.temporal_layer_id = 0;
    ASSERT_EQ(rc_api_->ComputeQP(frame_params_), aom::kFrameDropDecisionDrop);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 4;
    ASSERT_EQ(rc_api_->ComputeQP(frame_params_), aom::kFrameDropDecisionDrop);
    // Start with valid (0, 0) layer_id, expect return kFrameDropDecisionOk.
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;
    ASSERT_EQ(rc_api_->ComputeQP(frame_params_), aom::kFrameDropDecisionOk);
  }

  void RunSvc() {
    key_interval_ = 10000;
    SetConfigSvc(3, 3);
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
                                         1, 0, kNumFrames);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }

  void RunSvcPeriodicKey() {
    key_interval_ = 100;
    SetConfigSvc(3, 3);
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
                                         1, 0, kNumFrames);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }

  void RunSvcDynamicTemporal() {
    dynamic_temporal_layers_ = true;
    key_interval_ = 10000;
    SetConfigSvc(3, 3);
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
                                         1, 0, kNumFrames);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }

  void RunSvcDynamicSpatial() {
    dynamic_spatial_layers_ = true;
    key_interval_ = 10000;
    SetConfigSvc(3, 3);
    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    frame_params_.spatial_layer_id = 0;
    frame_params_.temporal_layer_id = 0;

    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
                                         1, 0, kNumFrames);

    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
  }

 private:
  void SetConfig() {
    rc_cfg_.width = 640;
    rc_cfg_.height = 480;
    rc_cfg_.max_quantizer = 52;
    rc_cfg_.min_quantizer = 2;
    rc_cfg_.target_bandwidth = 1000;
    rc_cfg_.buf_initial_sz = 600;
    rc_cfg_.buf_optimal_sz = 600;
    rc_cfg_.buf_sz = 1000;
    rc_cfg_.undershoot_pct = 50;
    rc_cfg_.overshoot_pct = 50;
    rc_cfg_.max_intra_bitrate_pct = 1000;
    rc_cfg_.framerate = 30.0;
    rc_cfg_.ss_number_layers = 1;
    rc_cfg_.ts_number_layers = 1;
    rc_cfg_.scaling_factor_num[0] = 1;
    rc_cfg_.scaling_factor_den[0] = 1;
    rc_cfg_.layer_target_bitrate[0] = 1000;
    rc_cfg_.max_quantizers[0] = 52;
    rc_cfg_.min_quantizers[0] = 2;
    rc_cfg_.aq_mode = aq_mode_;
    rc_cfg_.frame_drop_thresh = frame_drop_thresh_;
    rc_cfg_.max_consec_drop_ms = max_consec_drop_ms_;

    // Encoder settings for ground truth.
    cfg_.g_w = 640;
    cfg_.g_h = 480;
    cfg_.rc_undershoot_pct = 50;
    cfg_.rc_overshoot_pct = 50;
    cfg_.rc_buf_initial_sz = 600;
    cfg_.rc_buf_optimal_sz = 600;
    cfg_.rc_buf_sz = 1000;
    cfg_.rc_dropframe_thresh = 0;
    cfg_.rc_min_quantizer = 2;
    cfg_.rc_max_quantizer = 52;
    cfg_.rc_end_usage = AOM_CBR;
    cfg_.g_lag_in_frames = 0;
    cfg_.g_error_resilient = 0;
    cfg_.rc_target_bitrate = 1000;
    cfg_.kf_min_dist = key_interval_;
    cfg_.kf_max_dist = key_interval_;
    cfg_.rc_dropframe_thresh = frame_drop_thresh_;
  }

  void SetConfigSvc(int number_spatial_layers, int number_temporal_layers) {
    rc_cfg_.width = 640;
    rc_cfg_.height = 480;
    rc_cfg_.max_quantizer = 56;
    rc_cfg_.min_quantizer = 2;
    rc_cfg_.buf_initial_sz = 600;
    rc_cfg_.buf_optimal_sz = 600;
    rc_cfg_.buf_sz = 1000;
    rc_cfg_.undershoot_pct = 50;
    rc_cfg_.overshoot_pct = 50;
    rc_cfg_.max_intra_bitrate_pct = 1000;
    rc_cfg_.framerate = 30.0;
    rc_cfg_.aq_mode = aq_mode_;
    rc_cfg_.ss_number_layers = number_spatial_layers;
    rc_cfg_.ts_number_layers = number_temporal_layers;

    // Encoder settings for ground truth.
    cfg_.g_w = 640;
    cfg_.g_h = 480;
    cfg_.rc_max_quantizer = 56;
    cfg_.rc_min_quantizer = 2;
    cfg_.rc_buf_initial_sz = 600;
    cfg_.rc_buf_optimal_sz = 600;
    cfg_.rc_buf_sz = 1000;
    cfg_.rc_overshoot_pct = 50;
    cfg_.rc_undershoot_pct = 50;
    cfg_.g_threads = 1;
    cfg_.kf_min_dist = key_interval_;
    cfg_.kf_max_dist = key_interval_;
    cfg_.g_timebase.num = 1;
    cfg_.g_timebase.den = 30;
    cfg_.rc_end_usage = AOM_CBR;
    cfg_.g_lag_in_frames = 0;
    cfg_.g_error_resilient = 0;
    svc_params_.number_spatial_layers = number_spatial_layers;
    svc_params_.number_temporal_layers = number_temporal_layers;

    // Scale factors.
    if (number_spatial_layers == 3) {
      rc_cfg_.scaling_factor_num[0] = 1;
      rc_cfg_.scaling_factor_den[0] = 4;
      rc_cfg_.scaling_factor_num[1] = 2;
      rc_cfg_.scaling_factor_den[1] = 4;
      rc_cfg_.scaling_factor_num[2] = 4;
      rc_cfg_.scaling_factor_den[2] = 4;
      svc_params_.scaling_factor_num[0] = 1;
      svc_params_.scaling_factor_den[0] = 4;
      svc_params_.scaling_factor_num[1] = 2;
      svc_params_.scaling_factor_den[1] = 4;
      svc_params_.scaling_factor_num[2] = 4;
      svc_params_.scaling_factor_den[2] = 4;
    } else if (number_spatial_layers == 2) {
      rc_cfg_.scaling_factor_num[0] = 1;
      rc_cfg_.scaling_factor_den[0] = 2;
      rc_cfg_.scaling_factor_num[1] = 2;
      rc_cfg_.scaling_factor_den[1] = 2;
      svc_params_.scaling_factor_num[0] = 1;
      svc_params_.scaling_factor_den[0] = 2;
      svc_params_.scaling_factor_num[1] = 2;
      svc_params_.scaling_factor_den[1] = 2;
    } else if (number_spatial_layers == 1) {
      rc_cfg_.scaling_factor_num[0] = 1;
      rc_cfg_.scaling_factor_den[0] = 1;
      svc_params_.scaling_factor_num[0] = 1;
      svc_params_.scaling_factor_den[0] = 1;
    }

    // TS rate decimator.
    if (number_temporal_layers == 3) {
      rc_cfg_.ts_rate_decimator[0] = 4;
      rc_cfg_.ts_rate_decimator[1] = 2;
      rc_cfg_.ts_rate_decimator[2] = 1;
      svc_params_.framerate_factor[0] = 4;
      svc_params_.framerate_factor[1] = 2;
      svc_params_.framerate_factor[2] = 1;
    } else if (number_temporal_layers == 2) {
      rc_cfg_.ts_rate_decimator[0] = 2;
      rc_cfg_.ts_rate_decimator[1] = 1;
      svc_params_.framerate_factor[0] = 2;
      svc_params_.framerate_factor[1] = 1;
    } else if (number_temporal_layers == 1) {
      rc_cfg_.ts_rate_decimator[0] = 1;
      svc_params_.framerate_factor[0] = 1;
    }

    // Bitate.
    rc_cfg_.target_bandwidth = 0;
    cfg_.rc_target_bitrate = 0;
    for (int sl = 0; sl < number_spatial_layers; sl++) {
      int spatial_bitrate = 0;
      if (number_spatial_layers <= 3)
        spatial_bitrate = kSpatialLayerBitrate[sl];
      for (int tl = 0; tl < number_temporal_layers; tl++) {
        int layer = sl * number_temporal_layers + tl;
        if (number_temporal_layers == 3) {
          rc_cfg_.layer_target_bitrate[layer] =
              kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100;
          svc_params_.layer_target_bitrate[layer] =
              kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100;
        } else if (number_temporal_layers == 2) {
          rc_cfg_.layer_target_bitrate[layer] =
              kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100;
          svc_params_.layer_target_bitrate[layer] =
              kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100;
        } else if (number_temporal_layers == 1) {
          rc_cfg_.layer_target_bitrate[layer] = spatial_bitrate;
          svc_params_.layer_target_bitrate[layer] = spatial_bitrate;
        }
      }
      rc_cfg_.target_bandwidth += spatial_bitrate;
      cfg_.rc_target_bitrate += spatial_bitrate;
    }

    // Layer min/max quantizer.
    for (int sl = 0; sl < number_spatial_layers; ++sl) {
      for (int tl = 0; tl < number_temporal_layers; ++tl) {
        const int i = sl * number_temporal_layers + tl;
        rc_cfg_.max_quantizers[i] = rc_cfg_.max_quantizer;
        rc_cfg_.min_quantizers[i] = rc_cfg_.min_quantizer;
        svc_params_.max_quantizers[i] = cfg_.rc_max_quantizer;
        svc_params_.min_quantizers[i] = cfg_.rc_min_quantizer;
      }
    }
  }

  std::unique_ptr<aom::AV1RateControlRTC> rc_api_;
  aom::AV1RateControlRtcConfig rc_cfg_;
  int aq_mode_;
  int key_interval_;
  aom::AV1FrameParamsRTC frame_params_;
  bool encoder_exit_;
  aom_svc_params_t svc_params_;
  aom_svc_layer_id_t layer_id_;
  int layer_frame_cnt_;
  int superframe_cnt_;
  int frame_cnt_;
  bool dynamic_temporal_layers_;
  bool dynamic_spatial_layers_;
  int num_drops_;
  int max_consec_drop_ms_;
  int frame_drop_thresh_;
};

class RcExternMethodsInterfaceTest
    : public ::libaom_test::EncoderTest,
      public ::libaom_test::CodecTestWithParam<int> {
 public:
  RcExternMethodsInterfaceTest()
      : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)) {
    SetConfig();
  }
  ~RcExternMethodsInterfaceTest() = default;

  // Test APIS
  void TestCreateRateControl();
  void TestUpdateRateControl();
  void TestGetLoopFilterLevelRateControl();
  void TestPostEncodeUpdateRateControl();
  void TestGetQPRateControl();
  void TestComputeQPRateControl();
  void TestGetSegmentationDataRateControl();
  void TestGetCdefInfoRateControl();
  void TestCreateRateControlConfig();
  void TestDestroyRateControlRTC();
  void SetConfig();

 private:
  aom::AV1RateControlRtcConfig rc_cfg_;
  int aq_mode_;
  aom::AV1FrameParamsRTC frame_params_;
};

void RcExternMethodsInterfaceTest::SetConfig() {
  rc_cfg_.width = 640;
  rc_cfg_.height = 480;
  rc_cfg_.max_quantizer = 52;
  rc_cfg_.min_quantizer = 2;
  rc_cfg_.target_bandwidth = 1000;
  rc_cfg_.buf_initial_sz = 600;
  rc_cfg_.buf_optimal_sz = 600;
  rc_cfg_.buf_sz = 1000;
  rc_cfg_.undershoot_pct = 50;
  rc_cfg_.overshoot_pct = 50;
  rc_cfg_.max_intra_bitrate_pct = 1000;
  rc_cfg_.framerate = 30.0;
  rc_cfg_.ss_number_layers = 1;
  rc_cfg_.ts_number_layers = 1;
  rc_cfg_.scaling_factor_num[0] = 1;
  rc_cfg_.scaling_factor_den[0] = 1;
  rc_cfg_.layer_target_bitrate[0] = 1000;
  rc_cfg_.max_quantizers[0] = 52;
  rc_cfg_.min_quantizers[0] = 2;
  rc_cfg_.aq_mode = aq_mode_;
}

void RcExternMethodsInterfaceTest::TestCreateRateControl() {
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);

  ASSERT_NE(controller, nullptr);

  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestUpdateRateControl() {
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);

  ASSERT_NE(controller, nullptr);

  ASSERT_TRUE(av1_ratecontrol_rtc_update(controller, &rc_cfg_));

  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestGetQPRateControl() {
  frame_params_.spatial_layer_id = 0;
  frame_params_.temporal_layer_id = 0;
  frame_params_.frame_type = kAomKeyFrame;

  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);

  const AomFrameDropDecision decision =
      av1_ratecontrol_rtc_compute_qp(controller, &frame_params_);
  if (decision == kAomFrameDropDecisionOk) {
    int qp = av1_ratecontrol_rtc_get_qp(controller);
    ASSERT_NE(qp, 0);  // 0 is invalid for qp
  }
  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestComputeQPRateControl() {
  frame_params_.spatial_layer_id = 0;
  frame_params_.temporal_layer_id = 0;
  frame_params_.frame_type = kAomKeyFrame;

  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);

  const AomFrameDropDecision decision =
      av1_ratecontrol_rtc_compute_qp(controller, &frame_params_);
  ASSERT_EQ(decision, kAomFrameDropDecisionOk);
  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestGetLoopFilterLevelRateControl() {
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);

  AomAV1LoopfilterLevel lpf_level;
  lpf_level.filter_level[0] = 0xfdbd;
  lpf_level.filter_level[1] = 0xfdbd;
  lpf_level.filter_level_u = 0xfdbd;
  lpf_level.filter_level_v = 0xfdbd;

  lpf_level = av1_ratecontrol_rtc_get_loop_filter_level(controller);

  ASSERT_NE(lpf_level.filter_level[0], 0xfdbd);
  ASSERT_NE(lpf_level.filter_level[1], 0xfdbd);
  ASSERT_NE(lpf_level.filter_level_u, 0xfdbd);
  ASSERT_NE(lpf_level.filter_level_v, 0xfdbd);

  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestPostEncodeUpdateRateControl() {
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);
  av1_ratecontrol_rtc_post_encode_update(controller, 380);
  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestGetSegmentationDataRateControl() {
  rc_cfg_.aq_mode = 1;  // VARIANCE_AQ = 1
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);
  AomAV1SegmentationData segmentation_data;
  // This should return false as this test case doesn't run any part of the
  // underlying rate control, and cyclic refresh will not be turned on.
  ASSERT_FALSE(
      av1_ratecontrol_rtc_get_segmentation(controller, &segmentation_data));
  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestGetCdefInfoRateControl() {
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);
  AomAV1CdefInfo cdef_level;
  cdef_level.cdef_strength_y = 0xabcd;
  cdef_level.cdef_strength_uv = 0xabcd;
  cdef_level.damping = 0xabcd;
  cdef_level = av1_ratecontrol_rtc_get_cdef_info(controller);

  ASSERT_NE(cdef_level.cdef_strength_y, 0xabcd);
  ASSERT_NE(cdef_level.cdef_strength_uv, 0xabcd);
  ASSERT_NE(cdef_level.damping, 0xabcd);

  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestCreateRateControlConfig() {
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);

  AomAV1RateControlRtcConfig config;
  av1_ratecontrol_rtc_init_ratecontrol_config(&config);
  ASSERT_EQ(config.width, 1280);
  ASSERT_EQ(config.height, 720);
  // only width and height is checked. can be extended

  av1_ratecontrol_rtc_destroy(controller);
}

void RcExternMethodsInterfaceTest::TestDestroyRateControlRTC() {
  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
  ASSERT_NE(controller, nullptr);

  av1_ratecontrol_rtc_destroy(controller);
}

TEST_P(RcInterfaceTest, OneLayer) { RunOneLayer(); }

TEST_P(RcInterfaceTest, OneLayerDropFramesCBR) { RunOneLayerDropFramesCBR(); }

TEST_P(RcInterfaceTest, OneLayerPeriodicKey) { RunOneLayerPeriodicKey(); }

TEST_P(RcInterfaceTest, OneLayerScreen) { RunOneLayerScreen(); }

TEST_P(RcInterfaceTest, SvcInvalidInputs) { RunSvcInvalidInputs(); }

TEST_P(RcInterfaceTest, Svc) { RunSvc(); }

TEST_P(RcInterfaceTest, SvcPeriodicKey) { RunSvcPeriodicKey(); }

TEST_P(RcInterfaceTest, SvcDynamicTemporal) { RunSvcDynamicTemporal(); }

TEST_P(RcInterfaceTest, SvcDynamicSpatial) { RunSvcDynamicSpatial(); }

TEST_P(RcExternMethodsInterfaceTest, CreateRateControlTest) {
  TestCreateRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, UpdateRateControllerTest) {
  TestUpdateRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, GetQpRateControllerTest) {
  TestGetQPRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, ComputeQPRateControllerTest) {
  TestComputeQPRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, GetLoopFilterLevelRateControllerTest) {
  TestGetLoopFilterLevelRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, PostEncodeUpdateRateControllerTest) {
  TestPostEncodeUpdateRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, GetSegmenationDataRateControllerTest) {
  TestGetSegmentationDataRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, GetCdedInfoRateControllerTest) {
  TestGetCdefInfoRateControl();
}

TEST_P(RcExternMethodsInterfaceTest, CreateRateControlConfigTest) {
  TestCreateRateControlConfig();
}

TEST_P(RcExternMethodsInterfaceTest, DestroyRateControlRTCTest) {
  TestDestroyRateControlRTC();
}

AV1_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0, 3));
AV1_INSTANTIATE_TEST_SUITE(RcExternMethodsInterfaceTest,
                           ::testing::Values(0, 3));

}  // namespace
