vp9 rc: add vbr to rtc rate control library
Change-Id: I3d2565572c2b905966d60bcaa6e5e6f057b1bd51
This commit is contained in:
+93
-11
@@ -32,6 +32,7 @@ struct FrameInfo {
|
||||
info.bytes_used;
|
||||
return is;
|
||||
}
|
||||
|
||||
int frame_id;
|
||||
int spatial_id;
|
||||
int temporal_id;
|
||||
@@ -48,24 +49,32 @@ struct FrameInfo {
|
||||
// This test runs the rate control interface and compare against ground truth
|
||||
// generated by encoders.
|
||||
// Settings for the encoder:
|
||||
// For 1 layer:
|
||||
// For 1 layer CBR:
|
||||
// - AQ_Mode 0
|
||||
// - Disable golden refresh
|
||||
// - Bitrate x 2 at frame/superframe 200
|
||||
// - Bitrate / 4 at frame/superframe 400
|
||||
// examples/vpx_temporal_svc_encoder gipsrec_motion1.1280_720.yuv out vp9
|
||||
// 1280 720 1 30 7 0 0 1 0 1000
|
||||
//
|
||||
// For 1 layer VBR:
|
||||
// - Set rc_end_usage to VPX_VBR
|
||||
// - AQ Mode 0
|
||||
// - Disable vp9_compute_frame_low_motion in vp9_encoder.c
|
||||
// examples/vpx_temporal_svc_encoder gipsrec_motion1.1280_720.yuv out vp9
|
||||
// 1280 720 1 30 7 0 0 1 0 1000
|
||||
//
|
||||
// For SVC (3 temporal layers, 3 spatial layers):
|
||||
//
|
||||
// - AQ_Mode 0
|
||||
// - Disable golden refresh
|
||||
// - Bitrate x 2 at frame/superframe 200
|
||||
// - Bitrate / 4 at frame/superframe 400
|
||||
// examples/vp9_spatial_svc_encoder -f 10000 -w 1280 -h 720 -t 1/30 -sl 3
|
||||
// -k 10000 -bl 100,140,200,250,350,500,450,630,900 -b 1600 --rc-end-usage=1
|
||||
// --lag-in-frames=0 --passes=1 --speed=7 --threads=1
|
||||
// --temporal-layering-mode=3 -aq 1 -rcstat 1
|
||||
// gipsrec_motion1.1280_720.yuv -o out.webm
|
||||
//
|
||||
// - AQ_Mode 0
|
||||
// - Disable golden refresh
|
||||
// - Bitrate x 2 at frame/superframe 200
|
||||
// - Bitrate / 4 at frame/superframe 400
|
||||
//
|
||||
// The generated file includes:
|
||||
// frame number, spatial layer ID, temporal layer ID, base QP, target
|
||||
// bandwidth, buffer level, loopfilter level, encoded frame size
|
||||
@@ -77,8 +86,8 @@ class RcInterfaceTest : public ::testing::Test {
|
||||
virtual ~RcInterfaceTest() {}
|
||||
|
||||
protected:
|
||||
void RunOneLayer() {
|
||||
SetConfigOneLayer();
|
||||
void RunOneLayerCBR() {
|
||||
SetConfigOneLayerCBR();
|
||||
rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
|
||||
FrameInfo frame_info;
|
||||
libvpx::VP9FrameParamsQpRTC frame_params;
|
||||
@@ -144,8 +153,58 @@ class RcInterfaceTest : public ::testing::Test {
|
||||
}
|
||||
}
|
||||
|
||||
void RunOneLayerVBR() {
|
||||
SetConfigOneLayerVBR();
|
||||
rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
|
||||
FrameInfo frame_info;
|
||||
libvpx::VP9FrameParamsQpRTC frame_params;
|
||||
frame_params.frame_type = KEY_FRAME;
|
||||
frame_params.spatial_layer_id = 0;
|
||||
frame_params.temporal_layer_id = 0;
|
||||
std::ifstream one_layer_file;
|
||||
one_layer_file.open(libvpx_test::GetDataPath() +
|
||||
"/rc_interface_test_one_layer_vbr");
|
||||
ASSERT_TRUE(one_layer_file.good());
|
||||
for (size_t i = 0; i < kNumFrame; i++) {
|
||||
one_layer_file >> frame_info;
|
||||
if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
|
||||
ASSERT_EQ(frame_info.spatial_id, 0);
|
||||
ASSERT_EQ(frame_info.temporal_id, 0);
|
||||
rc_api_->ComputeQP(frame_params);
|
||||
ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
|
||||
ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
|
||||
rc_api_->PostEncodeUpdate(frame_info.bytes_used);
|
||||
}
|
||||
}
|
||||
|
||||
void RunOneLayerVBRPeriodicKey() {
|
||||
SetConfigOneLayerVBRPeriodicKey();
|
||||
rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
|
||||
FrameInfo frame_info;
|
||||
libvpx::VP9FrameParamsQpRTC frame_params;
|
||||
frame_params.frame_type = KEY_FRAME;
|
||||
frame_params.spatial_layer_id = 0;
|
||||
frame_params.temporal_layer_id = 0;
|
||||
std::ifstream one_layer_file;
|
||||
one_layer_file.open(libvpx_test::GetDataPath() +
|
||||
"/rc_interface_test_one_layer_vbr_periodic_key");
|
||||
ASSERT_TRUE(one_layer_file.good());
|
||||
for (size_t i = 0; i < kNumFrame; i++) {
|
||||
one_layer_file >> frame_info;
|
||||
if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
|
||||
if (frame_info.frame_id % rc_cfg_.key_freq == 0)
|
||||
frame_params.frame_type = KEY_FRAME;
|
||||
ASSERT_EQ(frame_info.spatial_id, 0);
|
||||
ASSERT_EQ(frame_info.temporal_id, 0);
|
||||
rc_api_->ComputeQP(frame_params);
|
||||
ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
|
||||
ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
|
||||
rc_api_->PostEncodeUpdate(frame_info.bytes_used);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void SetConfigOneLayer() {
|
||||
void SetConfig() {
|
||||
rc_cfg_.width = 1280;
|
||||
rc_cfg_.height = 720;
|
||||
rc_cfg_.max_quantizer = 52;
|
||||
@@ -167,6 +226,24 @@ class RcInterfaceTest : public ::testing::Test {
|
||||
rc_cfg_.min_quantizers[0] = 2;
|
||||
}
|
||||
|
||||
void SetConfigOneLayerCBR() {
|
||||
SetConfig();
|
||||
rc_cfg_.rc_mode = VPX_CBR;
|
||||
rc_cfg_.key_freq = 3000;
|
||||
}
|
||||
|
||||
void SetConfigOneLayerVBR() {
|
||||
SetConfig();
|
||||
rc_cfg_.rc_mode = VPX_VBR;
|
||||
rc_cfg_.key_freq = 3000;
|
||||
}
|
||||
|
||||
void SetConfigOneLayerVBRPeriodicKey() {
|
||||
SetConfig();
|
||||
rc_cfg_.rc_mode = VPX_VBR;
|
||||
rc_cfg_.key_freq = 300;
|
||||
}
|
||||
|
||||
void SetConfigSVC() {
|
||||
rc_cfg_.width = 1280;
|
||||
rc_cfg_.height = 720;
|
||||
@@ -182,6 +259,7 @@ class RcInterfaceTest : public ::testing::Test {
|
||||
rc_cfg_.framerate = 30.0;
|
||||
rc_cfg_.ss_number_layers = 3;
|
||||
rc_cfg_.ts_number_layers = 3;
|
||||
rc_cfg_.rc_mode = VPX_CBR;
|
||||
|
||||
rc_cfg_.scaling_factor_num[0] = 1;
|
||||
rc_cfg_.scaling_factor_den[0] = 4;
|
||||
@@ -217,7 +295,11 @@ class RcInterfaceTest : public ::testing::Test {
|
||||
libvpx::VP9RateControlRtcConfig rc_cfg_;
|
||||
};
|
||||
|
||||
TEST_F(RcInterfaceTest, OneLayer) { RunOneLayer(); }
|
||||
TEST_F(RcInterfaceTest, OneLayerCBR) { RunOneLayerCBR(); }
|
||||
|
||||
TEST_F(RcInterfaceTest, OneLayerVBR) { RunOneLayerVBR(); }
|
||||
|
||||
TEST_F(RcInterfaceTest, OneLayerVBRPeriodicKey) { RunOneLayerVBRPeriodicKey(); }
|
||||
|
||||
TEST_F(RcInterfaceTest, SVC) { RunSVC(); }
|
||||
} // namespace
|
||||
|
||||
@@ -28,6 +28,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rush_hour_444.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += screendata.y4m
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += niklas_640_480_30.yuv
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rc_interface_test_one_layer
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rc_interface_test_one_layer_vbr
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rc_interface_test_one_layer_vbr_periodic_key
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += rc_interface_test_svc
|
||||
LIBVPX_TEST_DATA-$(CONFIG_VP9_ENCODER) += bus_352x288_420_f20_b8.yuv
|
||||
|
||||
|
||||
@@ -39,9 +39,6 @@
|
||||
#define MAX_MB_RATE 250
|
||||
#define MAXRATE_1080P 4000000
|
||||
|
||||
#define DEFAULT_KF_BOOST 2000
|
||||
#define DEFAULT_GF_BOOST 2000
|
||||
|
||||
#define LIMIT_QRANGE_FOR_ALTREF_AND_KEY 1
|
||||
|
||||
#define MIN_BPB_FACTOR 0.005
|
||||
|
||||
@@ -27,6 +27,9 @@ extern "C" {
|
||||
// Bits Per MB at different Q (Multiplied by 512)
|
||||
#define BPER_MB_NORMBITS 9
|
||||
|
||||
#define DEFAULT_KF_BOOST 2000
|
||||
#define DEFAULT_GF_BOOST 2000
|
||||
|
||||
#define MIN_GF_INTERVAL 4
|
||||
#define MAX_GF_INTERVAL 16
|
||||
#define FIXED_GF_INTERVAL 8 // Used in some testing modes only
|
||||
|
||||
+24
-7
@@ -38,13 +38,16 @@ void VP9RateControlRTC::InitRateControl(const VP9RateControlRtcConfig &rc_cfg) {
|
||||
cm->profile = PROFILE_0;
|
||||
cm->bit_depth = VPX_BITS_8;
|
||||
cm->show_frame = 1;
|
||||
oxcf->rc_mode = VPX_CBR;
|
||||
oxcf->profile = cm->profile;
|
||||
oxcf->bit_depth = cm->bit_depth;
|
||||
oxcf->rc_mode = rc_cfg.rc_mode;
|
||||
oxcf->pass = 0;
|
||||
oxcf->aq_mode = NO_AQ;
|
||||
oxcf->content = VP9E_CONTENT_DEFAULT;
|
||||
oxcf->drop_frames_water_mark = 0;
|
||||
cm->current_video_frame = 0;
|
||||
oxcf->key_freq = rc_cfg.key_freq;
|
||||
rc->kf_boost = DEFAULT_KF_BOOST;
|
||||
|
||||
UpdateRateControl(rc_cfg);
|
||||
|
||||
@@ -57,8 +60,8 @@ void VP9RateControlRTC::InitRateControl(const VP9RateControlRtcConfig &rc_cfg) {
|
||||
rc->rc_2_frame = 0;
|
||||
vp9_rc_init_minq_luts();
|
||||
vp9_rc_init(oxcf, 0, rc);
|
||||
rc->frames_to_key = oxcf->key_freq;
|
||||
cpi_->sf.use_nonrd_pick_mode = 1;
|
||||
cm->current_video_frame = 0;
|
||||
}
|
||||
|
||||
void VP9RateControlRTC::UpdateRateControl(
|
||||
@@ -75,6 +78,7 @@ void VP9RateControlRTC::UpdateRateControl(
|
||||
oxcf->best_allowed_q = vp9_quantizer_to_qindex(rc_cfg.min_quantizer);
|
||||
rc->worst_quality = oxcf->worst_allowed_q;
|
||||
rc->best_quality = oxcf->best_allowed_q;
|
||||
oxcf->init_framerate = rc_cfg.framerate;
|
||||
oxcf->target_bandwidth = 1000 * rc_cfg.target_bandwidth;
|
||||
oxcf->starting_buffer_level_ms = rc_cfg.buf_initial_sz;
|
||||
oxcf->optimal_buffer_level_ms = rc_cfg.buf_optimal_sz;
|
||||
@@ -140,11 +144,24 @@ void VP9RateControlRTC::ComputeQP(const VP9FrameParamsQpRTC &frame_params) {
|
||||
cpi_->sf.use_nonrd_pick_mode = 1;
|
||||
if (cpi_->svc.number_spatial_layers == 1 &&
|
||||
cpi_->svc.number_temporal_layers == 1) {
|
||||
int target;
|
||||
if (frame_is_intra_only(cm))
|
||||
target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_);
|
||||
else
|
||||
target = vp9_calc_pframe_target_size_one_pass_cbr(cpi_);
|
||||
int target = 0;
|
||||
if (cpi_->oxcf.rc_mode == VPX_CBR) {
|
||||
if (frame_is_intra_only(cm))
|
||||
target = vp9_calc_iframe_target_size_one_pass_cbr(cpi_);
|
||||
else
|
||||
target = vp9_calc_pframe_target_size_one_pass_cbr(cpi_);
|
||||
} else if (cpi_->oxcf.rc_mode == VPX_VBR) {
|
||||
if (cm->frame_type == KEY_FRAME) {
|
||||
cpi_->rc.this_key_frame_forced =
|
||||
cm->current_video_frame != 0 && cpi_->rc.frames_to_key == 0;
|
||||
cpi_->rc.frames_to_key = cpi_->oxcf.key_freq;
|
||||
}
|
||||
vp9_set_gf_update_one_pass_vbr(cpi_);
|
||||
if (frame_is_intra_only(cm))
|
||||
target = vp9_calc_iframe_target_size_one_pass_vbr(cpi_);
|
||||
else
|
||||
target = vp9_calc_pframe_target_size_one_pass_vbr(cpi_);
|
||||
}
|
||||
vp9_rc_set_frame_target(cpi_, target);
|
||||
vp9_update_buffer_level_preencode(cpi_);
|
||||
} else {
|
||||
|
||||
@@ -49,6 +49,10 @@ struct VP9RateControlRtcConfig {
|
||||
int scaling_factor_den[VPX_SS_MAX_LAYERS];
|
||||
int layer_target_bitrate[VPX_MAX_LAYERS];
|
||||
int ts_rate_decimator[VPX_TS_MAX_LAYERS];
|
||||
// vbr, cbr
|
||||
enum vpx_rc_mode rc_mode;
|
||||
// key frame frequency
|
||||
int key_freq;
|
||||
};
|
||||
|
||||
struct VP9FrameParamsQpRTC {
|
||||
|
||||
Reference in New Issue
Block a user