From cd260eba10b9155f6e6086c999bd4c9d3ca6c706 Mon Sep 17 00:00:00 2001 From: Jerome Jiang Date: Tue, 29 Jun 2021 14:48:35 -0700 Subject: Add cyclic refresh to vp9 rtc external ratecontrol Change-Id: Ia2a881399aa31ca0f34481b975362ddd4ad87f1c --- test/ratectrl_rtc_test.cc | 3 ++- vp9/encoder/vp9_aq_cyclicrefresh.c | 3 ++- vp9/ratectrl_rtc.cc | 27 ++++++++++++++++++++++++++- vp9/ratectrl_rtc.h | 10 ++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/test/ratectrl_rtc_test.cc b/test/ratectrl_rtc_test.cc index 141437708..8136bd8b9 100644 --- a/test/ratectrl_rtc_test.cc +++ b/test/ratectrl_rtc_test.cc @@ -127,6 +127,7 @@ class RcInterfaceTest rc_cfg_.max_quantizers[0] = 52; rc_cfg_.min_quantizers[0] = 2; rc_cfg_.rc_mode = rc_mode; + rc_cfg_.aq_mode = aq_mode_; // Encoder settings for ground truth. cfg_.g_w = 1280; @@ -364,7 +365,7 @@ TEST_P(RcInterfaceTest, OneLayerVBRPeriodicKey) { RunOneLayerVBRPeriodicKey(); } TEST_P(RcInterfaceSvcTest, Svc) { RunSvc(); } -VP9_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0), +VP9_INSTANTIATE_TEST_SUITE(RcInterfaceTest, ::testing::Values(0, 3), ::testing::Values(VPX_CBR, VPX_VBR)); VP9_INSTANTIATE_TEST_SUITE(RcInterfaceSvcTest, ::testing::Values(0)); } // namespace diff --git a/vp9/encoder/vp9_aq_cyclicrefresh.c b/vp9/encoder/vp9_aq_cyclicrefresh.c index e6edf5a92..f06fe4726 100644 --- a/vp9/encoder/vp9_aq_cyclicrefresh.c +++ b/vp9/encoder/vp9_aq_cyclicrefresh.c @@ -516,7 +516,8 @@ void vp9_cyclic_refresh_update_parameters(VP9_COMP *const cpi) { cr->rate_ratio_qdelta = 3.0; } else { cr->rate_ratio_qdelta = 2.0; - if (cpi->noise_estimate.enabled && cpi->noise_estimate.level >= kMedium) { + if (cr->content_mode && cpi->noise_estimate.enabled && + cpi->noise_estimate.level >= kMedium) { // Reduce the delta-qp if the estimated source noise is above threshold. cr->rate_ratio_qdelta = 1.7; cr->rate_boost_fac = 13; diff --git a/vp9/ratectrl_rtc.cc b/vp9/ratectrl_rtc.cc index b38a0db9c..0f56e67e8 100644 --- a/vp9/ratectrl_rtc.cc +++ b/vp9/ratectrl_rtc.cc @@ -11,6 +11,7 @@ #include +#include "vp9/common/vp9_common.h" #include "vp9/encoder/vp9_encoder.h" #include "vp9/encoder/vp9_picklpf.h" #include "vpx/vp8cx.h" @@ -28,6 +29,15 @@ std::unique_ptr VP9RateControlRTC::Create( return nullptr; } rc_api->InitRateControl(cfg); + if (cfg.aq_mode) { + VP9_COMP *const cpi = rc_api->cpi_; + cpi->segmentation_map = static_cast( + vpx_calloc(cpi->common.mi_rows * cpi->common.mi_cols, + sizeof(*cpi->segmentation_map))); + cpi->cyclic_refresh = + vp9_cyclic_refresh_alloc(cpi->common.mi_rows, cpi->common.mi_cols); + cpi->cyclic_refresh->content_mode = 0; + } return rc_api; } @@ -42,13 +52,14 @@ void VP9RateControlRTC::InitRateControl(const VP9RateControlRtcConfig &rc_cfg) { oxcf->bit_depth = cm->bit_depth; oxcf->rc_mode = rc_cfg.rc_mode; oxcf->pass = 0; - oxcf->aq_mode = NO_AQ; + oxcf->aq_mode = rc_cfg.aq_mode ? CYCLIC_REFRESH_AQ : NO_AQ; oxcf->content = VP9E_CONTENT_DEFAULT; oxcf->drop_frames_water_mark = 0; cm->current_video_frame = 0; rc->kf_boost = DEFAULT_KF_BOOST; UpdateRateControl(rc_cfg); + vp9_set_mb_mi(cm, cm->width, cm->height); cpi_->use_svc = (cpi_->svc.number_spatial_layers > 1 || cpi_->svc.number_temporal_layers > 1) @@ -146,6 +157,8 @@ void VP9RateControlRTC::ComputeQP(const VP9FrameParamsQpRTC &frame_params) { cpi_->svc.number_temporal_layers == 1) { int target = 0; if (cpi_->oxcf.rc_mode == VPX_CBR) { + if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) + vp9_cyclic_refresh_update_parameters(cpi_); if (frame_is_intra_only(cm)) target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_); else @@ -156,6 +169,8 @@ void VP9RateControlRTC::ComputeQP(const VP9FrameParamsQpRTC &frame_params) { cpi_->rc.frames_to_key = cpi_->oxcf.key_freq; } vp9_set_gf_update_one_pass_vbr(cpi_); + if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) + vp9_cyclic_refresh_update_parameters(cpi_); if (frame_is_intra_only(cm)) target = vp9_calc_iframe_target_size_one_pass_vbr(cpi_); else @@ -171,6 +186,8 @@ void VP9RateControlRTC::ComputeQP(const VP9FrameParamsQpRTC &frame_params) { int bottom_index, top_index; cpi_->common.base_qindex = vp9_rc_pick_q_and_bounds(cpi_, &bottom_index, &top_index); + + if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) vp9_cyclic_refresh_setup(cpi_); } int VP9RateControlRTC::GetQP() const { return cpi_->common.base_qindex; } @@ -181,6 +198,14 @@ int VP9RateControlRTC::GetLoopfilterLevel() const { return lf->filter_level; } +signed char *VP9RateControlRTC::GetCyclicRefreshMap() const { + return cpi_->cyclic_refresh->map; +} + +int *VP9RateControlRTC::GetDeltaQ() const { + return cpi_->cyclic_refresh->qindex_delta; +} + void VP9RateControlRTC::PostEncodeUpdate(uint64_t encoded_frame_size) { vp9_rc_postencode_update(cpi_, encoded_frame_size); if (cpi_->svc.number_spatial_layers > 1 || diff --git a/vp9/ratectrl_rtc.h b/vp9/ratectrl_rtc.h index 4e0cb8b4c..5cc7ec945 100644 --- a/vp9/ratectrl_rtc.h +++ b/vp9/ratectrl_rtc.h @@ -18,6 +18,7 @@ #include "vp9/common/vp9_enums.h" #include "vp9/common/vp9_onyxc_int.h" #include "vp9/vp9_iface_common.h" +#include "vp9/encoder/vp9_aq_cyclicrefresh.h" #include "vp9/encoder/vp9_encoder.h" #include "vp9/encoder/vp9_firstpass.h" #include "vp9/vp9_cx_iface.h" @@ -42,6 +43,7 @@ struct VP9RateControlRtcConfig { framerate = 30.0; ss_number_layers = ts_number_layers = 1; rc_mode = VPX_CBR; + aq_mode = 0; vp9_zero(max_quantizers); vp9_zero(min_quantizers); vp9_zero(scaling_factor_den); @@ -82,6 +84,7 @@ struct VP9RateControlRtcConfig { int ts_rate_decimator[VPX_TS_MAX_LAYERS]; // vbr, cbr enum vpx_rc_mode rc_mode; + int aq_mode; }; struct VP9FrameParamsQpRTC { @@ -129,6 +132,11 @@ class VP9RateControlRTC { } } } + if (cpi_->oxcf.aq_mode == CYCLIC_REFRESH_AQ) { + vpx_free(cpi_->segmentation_map); + cpi_->segmentation_map = NULL; + vp9_cyclic_refresh_free(cpi_->cyclic_refresh); + } vpx_free(cpi_); } } @@ -137,6 +145,8 @@ class VP9RateControlRTC { // GetQP() needs to be called after ComputeQP() to get the latest QP int GetQP() const; int GetLoopfilterLevel() const; + signed char *GetCyclicRefreshMap() const; + int *GetDeltaQ() const; void ComputeQP(const VP9FrameParamsQpRTC &frame_params); // Feedback to rate control with the size of current encoded frame void PostEncodeUpdate(uint64_t encoded_frame_size); -- cgit v1.2.1