tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ratectrl_rtc_test.cc (26443B)


      1 /*
      2 * Copyright (c) 2021, Alliance for Open Media. All rights reserved.
      3 *
      4 * This source code is subject to the terms of the BSD 2 Clause License and
      5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
      6 * was not distributed with this source code in the LICENSE file, you can
      7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
      8 * Media Patent License 1.0 was not distributed with this source code in the
      9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
     10 */
     11 
     12 #include "av1/ratectrl_rtc.h"
     13 
     14 #include <memory>
     15 
     16 #include "gtest/gtest.h"
     17 #include "test/codec_factory.h"
     18 #include "test/encode_test_driver.h"
     19 #include "test/i420_video_source.h"
     20 #include "test/util.h"
     21 
     22 namespace {
     23 
     24 constexpr size_t kNumFrames = 450;
     25 
     26 const int kTemporalId3Layer[4] = { 0, 2, 1, 2 };
     27 const int kTemporalId2Layer[2] = { 0, 1 };
     28 const int kTemporalRateAllocation3Layer[3] = { 50, 70, 100 };
     29 const int kTemporalRateAllocation2Layer[2] = { 60, 100 };
     30 const int kSpatialLayerBitrate[3] = { 200, 500, 900 };
     31 
     32 // Parameter: aq mode: 0 and 3
     33 class RcInterfaceTest : public ::libaom_test::EncoderTest,
     34                        public ::libaom_test::CodecTestWithParam<int> {
     35 public:
     36  RcInterfaceTest()
     37      : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)), key_interval_(3000),
     38        encoder_exit_(false), layer_frame_cnt_(0), superframe_cnt_(0),
     39        frame_cnt_(0), dynamic_temporal_layers_(false),
     40        dynamic_spatial_layers_(false), num_drops_(0), max_consec_drop_ms_(0),
     41        frame_drop_thresh_(0) {
     42    memset(&svc_params_, 0, sizeof(svc_params_));
     43    memset(&layer_id_, 0, sizeof(layer_id_));
     44  }
     45 
     46  ~RcInterfaceTest() override = default;
     47 
     48 protected:
     49  void SetUp() override { InitializeConfig(::libaom_test::kRealTime); }
     50 
     51  int GetNumSpatialLayers() override { return rc_cfg_.ss_number_layers; }
     52 
     53  void PreEncodeFrameHook(libaom_test::VideoSource *video,
     54                          libaom_test::Encoder *encoder) override {
     55    int key_int = key_interval_;
     56    const int use_svc =
     57        rc_cfg_.ss_number_layers > 1 || rc_cfg_.ts_number_layers > 1;
     58    encoder->Control(AV1E_SET_RTC_EXTERNAL_RC, 1);
     59    if (video->frame() == 0 && layer_frame_cnt_ == 0) {
     60      encoder->Control(AOME_SET_CPUUSED, 7);
     61      encoder->Control(AV1E_SET_AQ_MODE, aq_mode_);
     62      encoder->Control(AV1E_SET_ENABLE_ORDER_HINT, 0);
     63      if (rc_cfg_.is_screen) {
     64        encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN);
     65      } else {
     66        encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT);
     67      }
     68      encoder->Control(AOME_SET_MAX_INTRA_BITRATE_PCT,
     69                       rc_cfg_.max_intra_bitrate_pct);
     70      if (use_svc) encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
     71      encoder->Control(AV1E_SET_MAX_CONSEC_FRAME_DROP_MS_CBR,
     72                       max_consec_drop_ms_);
     73    }
     74    // SVC specific settings
     75    if (use_svc) {
     76      frame_params_.spatial_layer_id =
     77          layer_frame_cnt_ % rc_cfg_.ss_number_layers;
     78      if (rc_cfg_.ts_number_layers == 3)
     79        frame_params_.temporal_layer_id =
     80            kTemporalId3Layer[superframe_cnt_ % 4];
     81      else if (rc_cfg_.ts_number_layers == 2)
     82        frame_params_.temporal_layer_id =
     83            kTemporalId2Layer[superframe_cnt_ % 2];
     84      else
     85        frame_params_.temporal_layer_id = 0;
     86      layer_id_.spatial_layer_id = frame_params_.spatial_layer_id;
     87      layer_id_.temporal_layer_id = frame_params_.temporal_layer_id;
     88      encoder->Control(AV1E_SET_SVC_LAYER_ID, &layer_id_);
     89      key_int = key_interval_ * rc_cfg_.ss_number_layers;
     90    }
     91    frame_params_.frame_type =
     92        layer_frame_cnt_ % key_int == 0 ? aom::kKeyFrame : aom::kInterFrame;
     93    encoder_exit_ = video->frame() == kNumFrames;
     94    frame_flags_ = 0;
     95 
     96    if (dynamic_temporal_layers_) {
     97      if (superframe_cnt_ == 100 && layer_id_.spatial_layer_id == 0) {
     98        // Go down to 2 temporal layers.
     99        SetConfigSvc(3, 2);
    100        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
    101        frame_flags_ = AOM_EFLAG_FORCE_KF;
    102        frame_params_.frame_type = aom::kKeyFrame;
    103        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
    104      } else if (superframe_cnt_ == 200 && layer_id_.spatial_layer_id == 0) {
    105        // Go down to 1 temporal layer.
    106        SetConfigSvc(3, 1);
    107        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
    108        frame_flags_ = AOM_EFLAG_FORCE_KF;
    109        frame_params_.frame_type = aom::kKeyFrame;
    110        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
    111      } else if (superframe_cnt_ == 300 && layer_id_.spatial_layer_id == 0) {
    112        // Go back up to 3 temporal layers.
    113        SetConfigSvc(3, 3);
    114        frame_flags_ = AOM_EFLAG_FORCE_KF;
    115        frame_params_.frame_type = aom::kKeyFrame;
    116        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
    117        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
    118      }
    119    } else if (dynamic_spatial_layers_) {
    120      // In this example the #spatial layers is modified on the fly,
    121      // so we go from (120p,240p,480p) to (240p,480p), etc.
    122      if (superframe_cnt_ == 100 && layer_id_.spatial_layer_id == 0) {
    123        // Change to 2 spatial layers (240p, 480p).
    124        SetConfigSvc(2, 3);
    125        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
    126        frame_flags_ = AOM_EFLAG_FORCE_KF;
    127        frame_params_.frame_type = aom::kKeyFrame;
    128        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
    129      } else if (superframe_cnt_ == 200 && layer_id_.spatial_layer_id == 0) {
    130        // Change to 1 spatial layer (480p).
    131        SetConfigSvc(1, 3);
    132        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
    133        frame_flags_ = AOM_EFLAG_FORCE_KF;
    134        frame_params_.frame_type = aom::kKeyFrame;
    135        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
    136      } else if (superframe_cnt_ == 300 && layer_id_.spatial_layer_id == 0) {
    137        // Go back to 3 spatial layers (120p, 240p, 480p).
    138        SetConfigSvc(3, 3);
    139        encoder->Control(AV1E_SET_SVC_PARAMS, &svc_params_);
    140        // In the fixed SVC mode (which is what is used in this test):
    141        // Key frame is required here on SL0 since 120p will try to predict
    142        // from LAST which was the 480p, so decoder will throw an error
    143        // (reference must be smaller than 4x4). In the flexible mode
    144        // (not used here) we can set the frame flags to predict off the 2x2
    145        // reference instead,
    146        frame_flags_ = AOM_EFLAG_FORCE_KF;
    147        frame_params_.frame_type = aom::kKeyFrame;
    148        ASSERT_TRUE(rc_api_->UpdateRateControl(rc_cfg_));
    149      }
    150    }
    151    // TODO(marpan): Add dynamic spatial layers based on 0 layer bitrate.
    152    // That is actual usage in SW where configuration (#spatial, #temporal)
    153    // layers is fixed, but top layer is dropped or re-enabled based on
    154    // bitrate. This requires external RC to handle dropped (zero-size) frames.
    155  }
    156 
    157  void PostEncodeFrameHook(::libaom_test::Encoder *encoder) override {
    158    if (encoder_exit_) {
    159      return;
    160    }
    161    int num_operating_points;
    162    encoder->Control(AV1E_GET_NUM_OPERATING_POINTS, &num_operating_points);
    163    ASSERT_EQ(num_operating_points,
    164              rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers);
    165    layer_frame_cnt_++;
    166    frame_cnt_++;
    167    if (layer_id_.spatial_layer_id == rc_cfg_.ss_number_layers - 1)
    168      superframe_cnt_++;
    169    int qp;
    170    encoder->Control(AOME_GET_LAST_QUANTIZER, &qp);
    171    if (rc_api_->ComputeQP(frame_params_) == aom::kFrameDropDecisionOk) {
    172      ASSERT_EQ(rc_api_->GetQP(), qp) << "at frame " << frame_cnt_ - 1;
    173      int encoder_lpf_level;
    174      encoder->Control(AOME_GET_LOOPFILTER_LEVEL, &encoder_lpf_level);
    175      aom::AV1LoopfilterLevel loopfilter_level = rc_api_->GetLoopfilterLevel();
    176      ASSERT_EQ(loopfilter_level.filter_level[0], encoder_lpf_level);
    177      aom::AV1CdefInfo cdef_level = rc_api_->GetCdefInfo();
    178      int cdef_y_strengths[16];
    179      encoder->Control(AV1E_GET_LUMA_CDEF_STRENGTH, cdef_y_strengths);
    180      ASSERT_EQ(cdef_level.cdef_strength_y, cdef_y_strengths[0]);
    181    } else {
    182      num_drops_++;
    183    }
    184  }
    185 
    186  void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
    187    if (layer_id_.spatial_layer_id == 0)
    188      rc_api_->PostEncodeUpdate(pkt->data.frame.sz - 2);
    189    else
    190      rc_api_->PostEncodeUpdate(pkt->data.frame.sz);
    191  }
    192 
    193  void MismatchHook(const aom_image_t *img1, const aom_image_t *img2) override {
    194    (void)img1;
    195    (void)img2;
    196  }
    197 
    198  void RunOneLayer() {
    199    key_interval_ = 10000;
    200    SetConfig();
    201    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    202    frame_params_.spatial_layer_id = 0;
    203    frame_params_.temporal_layer_id = 0;
    204 
    205    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
    206                                         1, 0, kNumFrames);
    207 
    208    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    209  }
    210 
    211  void RunOneLayerScreen() {
    212    key_interval_ = 10000;
    213    SetConfig();
    214    rc_cfg_.is_screen = true;
    215    rc_cfg_.width = 352;
    216    rc_cfg_.height = 288;
    217    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    218    frame_params_.spatial_layer_id = 0;
    219    frame_params_.temporal_layer_id = 0;
    220 
    221    ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
    222                                         288, 30, 1, 0, 140);
    223 
    224    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    225  }
    226 
    227  void RunOneLayerDropFramesCBR() {
    228    key_interval_ = 10000;
    229    max_consec_drop_ms_ = 250;
    230    frame_drop_thresh_ = 30;
    231    SetConfig();
    232    rc_cfg_.target_bandwidth = 100;
    233    cfg_.rc_target_bitrate = 100;
    234    rc_cfg_.max_quantizer = 50;
    235    cfg_.rc_max_quantizer = 50;
    236    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    237    frame_params_.spatial_layer_id = 0;
    238    frame_params_.temporal_layer_id = 0;
    239 
    240    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
    241                                         1, 0, kNumFrames);
    242 
    243    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    244    // Check that some frames were dropped, otherwise test has no value.
    245    ASSERT_GE(num_drops_, 1);
    246  }
    247 
    248  void RunOneLayerPeriodicKey() {
    249    key_interval_ = 100;
    250    SetConfig();
    251    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    252    frame_params_.spatial_layer_id = 0;
    253    frame_params_.temporal_layer_id = 0;
    254 
    255    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
    256                                         1, 0, kNumFrames);
    257 
    258    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    259  }
    260 
    261  void RunSvc() {
    262    key_interval_ = 10000;
    263    SetConfigSvc(3, 3);
    264    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    265    frame_params_.spatial_layer_id = 0;
    266    frame_params_.temporal_layer_id = 0;
    267 
    268    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
    269                                         1, 0, kNumFrames);
    270 
    271    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    272  }
    273 
    274  void RunSvcPeriodicKey() {
    275    key_interval_ = 100;
    276    SetConfigSvc(3, 3);
    277    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    278    frame_params_.spatial_layer_id = 0;
    279    frame_params_.temporal_layer_id = 0;
    280 
    281    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
    282                                         1, 0, kNumFrames);
    283 
    284    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    285  }
    286 
    287  void RunSvcDynamicTemporal() {
    288    dynamic_temporal_layers_ = true;
    289    key_interval_ = 10000;
    290    SetConfigSvc(3, 3);
    291    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    292    frame_params_.spatial_layer_id = 0;
    293    frame_params_.temporal_layer_id = 0;
    294 
    295    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
    296                                         1, 0, kNumFrames);
    297 
    298    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    299  }
    300 
    301  void RunSvcDynamicSpatial() {
    302    dynamic_spatial_layers_ = true;
    303    key_interval_ = 10000;
    304    SetConfigSvc(3, 3);
    305    rc_api_ = aom::AV1RateControlRTC::Create(rc_cfg_);
    306    frame_params_.spatial_layer_id = 0;
    307    frame_params_.temporal_layer_id = 0;
    308 
    309    ::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
    310                                         1, 0, kNumFrames);
    311 
    312    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    313  }
    314 
    315 private:
    316  void SetConfig() {
    317    rc_cfg_.width = 640;
    318    rc_cfg_.height = 480;
    319    rc_cfg_.max_quantizer = 52;
    320    rc_cfg_.min_quantizer = 2;
    321    rc_cfg_.target_bandwidth = 1000;
    322    rc_cfg_.buf_initial_sz = 600;
    323    rc_cfg_.buf_optimal_sz = 600;
    324    rc_cfg_.buf_sz = 1000;
    325    rc_cfg_.undershoot_pct = 50;
    326    rc_cfg_.overshoot_pct = 50;
    327    rc_cfg_.max_intra_bitrate_pct = 1000;
    328    rc_cfg_.framerate = 30.0;
    329    rc_cfg_.ss_number_layers = 1;
    330    rc_cfg_.ts_number_layers = 1;
    331    rc_cfg_.scaling_factor_num[0] = 1;
    332    rc_cfg_.scaling_factor_den[0] = 1;
    333    rc_cfg_.layer_target_bitrate[0] = 1000;
    334    rc_cfg_.max_quantizers[0] = 52;
    335    rc_cfg_.min_quantizers[0] = 2;
    336    rc_cfg_.aq_mode = aq_mode_;
    337    rc_cfg_.frame_drop_thresh = frame_drop_thresh_;
    338    rc_cfg_.max_consec_drop_ms = max_consec_drop_ms_;
    339 
    340    // Encoder settings for ground truth.
    341    cfg_.g_w = 640;
    342    cfg_.g_h = 480;
    343    cfg_.rc_undershoot_pct = 50;
    344    cfg_.rc_overshoot_pct = 50;
    345    cfg_.rc_buf_initial_sz = 600;
    346    cfg_.rc_buf_optimal_sz = 600;
    347    cfg_.rc_buf_sz = 1000;
    348    cfg_.rc_dropframe_thresh = 0;
    349    cfg_.rc_min_quantizer = 2;
    350    cfg_.rc_max_quantizer = 52;
    351    cfg_.rc_end_usage = AOM_CBR;
    352    cfg_.g_lag_in_frames = 0;
    353    cfg_.g_error_resilient = 0;
    354    cfg_.rc_target_bitrate = 1000;
    355    cfg_.kf_min_dist = key_interval_;
    356    cfg_.kf_max_dist = key_interval_;
    357    cfg_.rc_dropframe_thresh = frame_drop_thresh_;
    358  }
    359 
    360  void SetConfigSvc(int number_spatial_layers, int number_temporal_layers) {
    361    rc_cfg_.width = 640;
    362    rc_cfg_.height = 480;
    363    rc_cfg_.max_quantizer = 56;
    364    rc_cfg_.min_quantizer = 2;
    365    rc_cfg_.buf_initial_sz = 600;
    366    rc_cfg_.buf_optimal_sz = 600;
    367    rc_cfg_.buf_sz = 1000;
    368    rc_cfg_.undershoot_pct = 50;
    369    rc_cfg_.overshoot_pct = 50;
    370    rc_cfg_.max_intra_bitrate_pct = 1000;
    371    rc_cfg_.framerate = 30.0;
    372    rc_cfg_.aq_mode = aq_mode_;
    373    rc_cfg_.ss_number_layers = number_spatial_layers;
    374    rc_cfg_.ts_number_layers = number_temporal_layers;
    375 
    376    // Encoder settings for ground truth.
    377    cfg_.g_w = 640;
    378    cfg_.g_h = 480;
    379    cfg_.rc_max_quantizer = 56;
    380    cfg_.rc_min_quantizer = 2;
    381    cfg_.rc_buf_initial_sz = 600;
    382    cfg_.rc_buf_optimal_sz = 600;
    383    cfg_.rc_buf_sz = 1000;
    384    cfg_.rc_overshoot_pct = 50;
    385    cfg_.rc_undershoot_pct = 50;
    386    cfg_.g_threads = 1;
    387    cfg_.kf_min_dist = key_interval_;
    388    cfg_.kf_max_dist = key_interval_;
    389    cfg_.g_timebase.num = 1;
    390    cfg_.g_timebase.den = 30;
    391    cfg_.rc_end_usage = AOM_CBR;
    392    cfg_.g_lag_in_frames = 0;
    393    cfg_.g_error_resilient = 0;
    394    svc_params_.number_spatial_layers = number_spatial_layers;
    395    svc_params_.number_temporal_layers = number_temporal_layers;
    396 
    397    // Scale factors.
    398    if (number_spatial_layers == 3) {
    399      rc_cfg_.scaling_factor_num[0] = 1;
    400      rc_cfg_.scaling_factor_den[0] = 4;
    401      rc_cfg_.scaling_factor_num[1] = 2;
    402      rc_cfg_.scaling_factor_den[1] = 4;
    403      rc_cfg_.scaling_factor_num[2] = 4;
    404      rc_cfg_.scaling_factor_den[2] = 4;
    405      svc_params_.scaling_factor_num[0] = 1;
    406      svc_params_.scaling_factor_den[0] = 4;
    407      svc_params_.scaling_factor_num[1] = 2;
    408      svc_params_.scaling_factor_den[1] = 4;
    409      svc_params_.scaling_factor_num[2] = 4;
    410      svc_params_.scaling_factor_den[2] = 4;
    411    } else if (number_spatial_layers == 2) {
    412      rc_cfg_.scaling_factor_num[0] = 1;
    413      rc_cfg_.scaling_factor_den[0] = 2;
    414      rc_cfg_.scaling_factor_num[1] = 2;
    415      rc_cfg_.scaling_factor_den[1] = 2;
    416      svc_params_.scaling_factor_num[0] = 1;
    417      svc_params_.scaling_factor_den[0] = 2;
    418      svc_params_.scaling_factor_num[1] = 2;
    419      svc_params_.scaling_factor_den[1] = 2;
    420    } else if (number_spatial_layers == 1) {
    421      rc_cfg_.scaling_factor_num[0] = 1;
    422      rc_cfg_.scaling_factor_den[0] = 1;
    423      svc_params_.scaling_factor_num[0] = 1;
    424      svc_params_.scaling_factor_den[0] = 1;
    425    }
    426 
    427    // TS rate decimator.
    428    if (number_temporal_layers == 3) {
    429      rc_cfg_.ts_rate_decimator[0] = 4;
    430      rc_cfg_.ts_rate_decimator[1] = 2;
    431      rc_cfg_.ts_rate_decimator[2] = 1;
    432      svc_params_.framerate_factor[0] = 4;
    433      svc_params_.framerate_factor[1] = 2;
    434      svc_params_.framerate_factor[2] = 1;
    435    } else if (number_temporal_layers == 2) {
    436      rc_cfg_.ts_rate_decimator[0] = 2;
    437      rc_cfg_.ts_rate_decimator[1] = 1;
    438      svc_params_.framerate_factor[0] = 2;
    439      svc_params_.framerate_factor[1] = 1;
    440    } else if (number_temporal_layers == 1) {
    441      rc_cfg_.ts_rate_decimator[0] = 1;
    442      svc_params_.framerate_factor[0] = 1;
    443    }
    444 
    445    // Bitate.
    446    rc_cfg_.target_bandwidth = 0;
    447    cfg_.rc_target_bitrate = 0;
    448    for (int sl = 0; sl < number_spatial_layers; sl++) {
    449      int spatial_bitrate = 0;
    450      if (number_spatial_layers <= 3)
    451        spatial_bitrate = kSpatialLayerBitrate[sl];
    452      for (int tl = 0; tl < number_temporal_layers; tl++) {
    453        int layer = sl * number_temporal_layers + tl;
    454        if (number_temporal_layers == 3) {
    455          rc_cfg_.layer_target_bitrate[layer] =
    456              kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100;
    457          svc_params_.layer_target_bitrate[layer] =
    458              kTemporalRateAllocation3Layer[tl] * spatial_bitrate / 100;
    459        } else if (number_temporal_layers == 2) {
    460          rc_cfg_.layer_target_bitrate[layer] =
    461              kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100;
    462          svc_params_.layer_target_bitrate[layer] =
    463              kTemporalRateAllocation2Layer[tl] * spatial_bitrate / 100;
    464        } else if (number_temporal_layers == 1) {
    465          rc_cfg_.layer_target_bitrate[layer] = spatial_bitrate;
    466          svc_params_.layer_target_bitrate[layer] = spatial_bitrate;
    467        }
    468      }
    469      rc_cfg_.target_bandwidth += spatial_bitrate;
    470      cfg_.rc_target_bitrate += spatial_bitrate;
    471    }
    472 
    473    // Layer min/max quantizer.
    474    for (int sl = 0; sl < number_spatial_layers; ++sl) {
    475      for (int tl = 0; tl < number_temporal_layers; ++tl) {
    476        const int i = sl * number_temporal_layers + tl;
    477        rc_cfg_.max_quantizers[i] = rc_cfg_.max_quantizer;
    478        rc_cfg_.min_quantizers[i] = rc_cfg_.min_quantizer;
    479        svc_params_.max_quantizers[i] = cfg_.rc_max_quantizer;
    480        svc_params_.min_quantizers[i] = cfg_.rc_min_quantizer;
    481      }
    482    }
    483  }
    484 
    485  std::unique_ptr<aom::AV1RateControlRTC> rc_api_;
    486  aom::AV1RateControlRtcConfig rc_cfg_;
    487  int aq_mode_;
    488  int key_interval_;
    489  aom::AV1FrameParamsRTC frame_params_;
    490  bool encoder_exit_;
    491  aom_svc_params_t svc_params_;
    492  aom_svc_layer_id_t layer_id_;
    493  int layer_frame_cnt_;
    494  int superframe_cnt_;
    495  int frame_cnt_;
    496  bool dynamic_temporal_layers_;
    497  bool dynamic_spatial_layers_;
    498  int num_drops_;
    499  int max_consec_drop_ms_;
    500  int frame_drop_thresh_;
    501 };
    502 
    503 class RcExternMethodsInterfaceTest
    504    : public ::libaom_test::EncoderTest,
    505      public ::libaom_test::CodecTestWithParam<int> {
    506 public:
    507  RcExternMethodsInterfaceTest()
    508      : EncoderTest(GET_PARAM(0)), aq_mode_(GET_PARAM(1)) {
    509    SetConfig();
    510  }
    511  ~RcExternMethodsInterfaceTest() = default;
    512 
    513  // Test APIS
    514  void TestCreateRateControl();
    515  void TestUpdateRateControl();
    516  void TestGetLoopFilterLevelRateControl();
    517  void TestPostEncodeUpdateRateControl();
    518  void TestGetQPRateControl();
    519  void TestComputeQPRateControl();
    520  void TestGetSegmentationDataRateControl();
    521  void TestGetCdefInfoRateControl();
    522  void TestCreateRateControlConfig();
    523  void TestDestroyRateControlRTC();
    524  void SetConfig();
    525 
    526 private:
    527  aom::AV1RateControlRtcConfig rc_cfg_;
    528  int aq_mode_;
    529  aom::AV1FrameParamsRTC frame_params_;
    530 };
    531 
    532 void RcExternMethodsInterfaceTest::SetConfig() {
    533  rc_cfg_.width = 640;
    534  rc_cfg_.height = 480;
    535  rc_cfg_.max_quantizer = 52;
    536  rc_cfg_.min_quantizer = 2;
    537  rc_cfg_.target_bandwidth = 1000;
    538  rc_cfg_.buf_initial_sz = 600;
    539  rc_cfg_.buf_optimal_sz = 600;
    540  rc_cfg_.buf_sz = 1000;
    541  rc_cfg_.undershoot_pct = 50;
    542  rc_cfg_.overshoot_pct = 50;
    543  rc_cfg_.max_intra_bitrate_pct = 1000;
    544  rc_cfg_.framerate = 30.0;
    545  rc_cfg_.ss_number_layers = 1;
    546  rc_cfg_.ts_number_layers = 1;
    547  rc_cfg_.scaling_factor_num[0] = 1;
    548  rc_cfg_.scaling_factor_den[0] = 1;
    549  rc_cfg_.layer_target_bitrate[0] = 1000;
    550  rc_cfg_.max_quantizers[0] = 52;
    551  rc_cfg_.min_quantizers[0] = 2;
    552  rc_cfg_.aq_mode = aq_mode_;
    553 }
    554 
    555 void RcExternMethodsInterfaceTest::TestCreateRateControl() {
    556  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    557 
    558  ASSERT_NE(controller, nullptr);
    559 
    560  av1_ratecontrol_rtc_destroy(controller);
    561 }
    562 
    563 void RcExternMethodsInterfaceTest::TestUpdateRateControl() {
    564  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    565 
    566  ASSERT_NE(controller, nullptr);
    567 
    568  ASSERT_TRUE(av1_ratecontrol_rtc_update(controller, &rc_cfg_));
    569 
    570  av1_ratecontrol_rtc_destroy(controller);
    571 }
    572 
    573 void RcExternMethodsInterfaceTest::TestGetQPRateControl() {
    574  frame_params_.spatial_layer_id = 0;
    575  frame_params_.temporal_layer_id = 0;
    576  frame_params_.frame_type = kAomKeyFrame;
    577 
    578  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    579  ASSERT_NE(controller, nullptr);
    580 
    581  const AomFrameDropDecision decision =
    582      av1_ratecontrol_rtc_compute_qp(controller, &frame_params_);
    583  if (decision == kAomFrameDropDecisionOk) {
    584    int qp = av1_ratecontrol_rtc_get_qp(controller);
    585    ASSERT_NE(qp, 0);  // 0 is invalid for qp
    586  }
    587  av1_ratecontrol_rtc_destroy(controller);
    588 }
    589 
    590 void RcExternMethodsInterfaceTest::TestComputeQPRateControl() {
    591  frame_params_.spatial_layer_id = 0;
    592  frame_params_.temporal_layer_id = 0;
    593  frame_params_.frame_type = kAomKeyFrame;
    594 
    595  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    596  ASSERT_NE(controller, nullptr);
    597 
    598  const AomFrameDropDecision decision =
    599      av1_ratecontrol_rtc_compute_qp(controller, &frame_params_);
    600  ASSERT_EQ(decision, kAomFrameDropDecisionOk);
    601  av1_ratecontrol_rtc_destroy(controller);
    602 }
    603 
    604 void RcExternMethodsInterfaceTest::TestGetLoopFilterLevelRateControl() {
    605  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    606  ASSERT_NE(controller, nullptr);
    607 
    608  AomAV1LoopfilterLevel lpf_level;
    609  lpf_level.filter_level[0] = 0xfdbd;
    610  lpf_level.filter_level[1] = 0xfdbd;
    611  lpf_level.filter_level_u = 0xfdbd;
    612  lpf_level.filter_level_v = 0xfdbd;
    613 
    614  lpf_level = av1_ratecontrol_rtc_get_loop_filter_level(controller);
    615 
    616  ASSERT_NE(lpf_level.filter_level[0], 0xfdbd);
    617  ASSERT_NE(lpf_level.filter_level[1], 0xfdbd);
    618  ASSERT_NE(lpf_level.filter_level_u, 0xfdbd);
    619  ASSERT_NE(lpf_level.filter_level_v, 0xfdbd);
    620 
    621  av1_ratecontrol_rtc_destroy(controller);
    622 }
    623 
    624 void RcExternMethodsInterfaceTest::TestPostEncodeUpdateRateControl() {
    625  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    626  ASSERT_NE(controller, nullptr);
    627  av1_ratecontrol_rtc_post_encode_update(controller, 380);
    628  av1_ratecontrol_rtc_destroy(controller);
    629 }
    630 
    631 void RcExternMethodsInterfaceTest::TestGetSegmentationDataRateControl() {
    632  rc_cfg_.aq_mode = 1;  // VARIANCE_AQ = 1
    633  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    634  ASSERT_NE(controller, nullptr);
    635  AomAV1SegmentationData segmentation_data;
    636  // This should return false as this test case doesn't run any part of the
    637  // underlying rate control, and cyclic refresh will not be turned on.
    638  ASSERT_FALSE(
    639      av1_ratecontrol_rtc_get_segmentation(controller, &segmentation_data));
    640  av1_ratecontrol_rtc_destroy(controller);
    641 }
    642 
    643 void RcExternMethodsInterfaceTest::TestGetCdefInfoRateControl() {
    644  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    645  ASSERT_NE(controller, nullptr);
    646  AomAV1CdefInfo cdef_level;
    647  cdef_level.cdef_strength_y = 0xabcd;
    648  cdef_level.cdef_strength_uv = 0xabcd;
    649  cdef_level.damping = 0xabcd;
    650  cdef_level = av1_ratecontrol_rtc_get_cdef_info(controller);
    651 
    652  ASSERT_NE(cdef_level.cdef_strength_y, 0xabcd);
    653  ASSERT_NE(cdef_level.cdef_strength_uv, 0xabcd);
    654  ASSERT_NE(cdef_level.damping, 0xabcd);
    655 
    656  av1_ratecontrol_rtc_destroy(controller);
    657 }
    658 
    659 void RcExternMethodsInterfaceTest::TestCreateRateControlConfig() {
    660  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    661  ASSERT_NE(controller, nullptr);
    662 
    663  AomAV1RateControlRtcConfig config;
    664  av1_ratecontrol_rtc_init_ratecontrol_config(&config);
    665  ASSERT_EQ(config.width, 1280);
    666  ASSERT_EQ(config.height, 720);
    667  // only width and height is checked. can be extended
    668 
    669  av1_ratecontrol_rtc_destroy(controller);
    670 }
    671 
    672 void RcExternMethodsInterfaceTest::TestDestroyRateControlRTC() {
    673  AomAV1RateControlRTC *controller = av1_ratecontrol_rtc_create(&rc_cfg_);
    674  ASSERT_NE(controller, nullptr);
    675 
    676  av1_ratecontrol_rtc_destroy(controller);
    677 }
    678 
    679 TEST_P(RcInterfaceTest, OneLayer) { RunOneLayer(); }
    680 
    681 TEST_P(RcInterfaceTest, OneLayerDropFramesCBR) { RunOneLayerDropFramesCBR(); }
    682 
    683 TEST_P(RcInterfaceTest, OneLayerPeriodicKey) { RunOneLayerPeriodicKey(); }
    684 
    685 TEST_P(RcInterfaceTest, OneLayerScreen) { RunOneLayerScreen(); }
    686 
    687 TEST_P(RcInterfaceTest, Svc) { RunSvc(); }
    688 
    689 TEST_P(RcInterfaceTest, SvcPeriodicKey) { RunSvcPeriodicKey(); }
    690 
    691 TEST_P(RcInterfaceTest, SvcDynamicTemporal) { RunSvcDynamicTemporal(); }
    692 
    693 TEST_P(RcInterfaceTest, SvcDynamicSpatial) { RunSvcDynamicSpatial(); }
    694 
    695 TEST_P(RcExternMethodsInterfaceTest, CreateRateControlTest) {
    696  TestCreateRateControl();
    697 }
    698 
    699 TEST_P(RcExternMethodsInterfaceTest, UpdateRateControllerTest) {
    700  TestUpdateRateControl();
    701 }
    702 
    703 TEST_P(RcExternMethodsInterfaceTest, GetQpRateControllerTest) {
    704  TestGetQPRateControl();
    705 }
    706 
    707 TEST_P(RcExternMethodsInterfaceTest, ComputeQPRateControllerTest) {
    708  TestComputeQPRateControl();
    709 }
    710 
    711 TEST_P(RcExternMethodsInterfaceTest, GetLoopFilterLevelRateControllerTest) {
    712  TestGetLoopFilterLevelRateControl();
    713 }
    714 
    715 TEST_P(RcExternMethodsInterfaceTest, PostEncodeUpdateRateControllerTest) {
    716  TestPostEncodeUpdateRateControl();
    717 }
    718 
    719 TEST_P(RcExternMethodsInterfaceTest, GetSegmenationDataRateControllerTest) {
    720  TestGetSegmentationDataRateControl();
    721 }
    722 
    723 TEST_P(RcExternMethodsInterfaceTest, GetCdedInfoRateControllerTest) {
    724  TestGetCdefInfoRateControl();
    725 }
    726 
    727 TEST_P(RcExternMethodsInterfaceTest, CreateRateControlConfigTest) {
    728  TestCreateRateControlConfig();
    729 }
    730 
    731 TEST_P(RcExternMethodsInterfaceTest, DestroyRateControlRTCTest) {
    732  TestDestroyRateControlRTC();
    733 }
    734 
    735 AV1_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0, 3));
    736 AV1_INSTANTIATE_TEST_SUITE(RcExternMethodsInterfaceTest,
    737                           ::testing::Values(0, 3));
    738 
    739 }  // namespace