From c99f9d7abf90538bc569a5683299766276b287c9 Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Mon, 11 Apr 2011 11:29:23 -0400 Subject: [PATCH] Change rc undershoot/overshoot semantics This patch changes the rc_undershoot_pct and rc_overshoot_pct controls to set the "aggressiveness" of rate adaptation, by limiting the amount of difference between the target buffer level and the actual buffer level which is applied to the target frame rate for this frame. This patch was initially provided by arosenberg at logitech.com as an attachment to issue #270. It was modified to separate these controls from the other unrelated modifications in that patch, as well as to use the pre-existing variables rather than introducing new ones. Change-Id: Id542e3f5667dd92d857d5eabf29878f2fd730a62 --- vp8/common/onyx.h | 3 ++- vp8/encoder/ratectrl.c | 51 +++++++++++++++++++++++++------------------------- vp8/vp8_cx_iface.c | 10 ++++++---- vpx/vpx_encoder.h | 24 ++++++++++++++++-------- 4 files changed, 49 insertions(+), 39 deletions(-) diff --git a/vp8/common/onyx.h b/vp8/common/onyx.h index 426b8fc..2e8f804 100644 --- a/vp8/common/onyx.h +++ b/vp8/common/onyx.h @@ -139,8 +139,9 @@ extern "C" int end_usage; // vbr or cbr - // shoot to keep buffer full at all times by undershooting a bit 95 recommended + // buffer targeting aggressiveness int under_shoot_pct; + int over_shoot_pct; // buffering parameters int starting_buffer_level; // in seconds diff --git a/vp8/encoder/ratectrl.c b/vp8/encoder/ratectrl.c index 9821d29..767b271 100644 --- a/vp8/encoder/ratectrl.c +++ b/vp8/encoder/ratectrl.c @@ -817,11 +817,6 @@ void vp8_calc_pframe_target_size(VP8_COMP *cpi) } } - // Set a reduced data rate target for our initial Q calculation. - // This should help to save bits during earier sections. - if ((cpi->oxcf.under_shoot_pct > 0) && (cpi->oxcf.under_shoot_pct <= 100)) - cpi->this_frame_target = (cpi->this_frame_target * cpi->oxcf.under_shoot_pct) / 100; - // Sanity check that the total sum of adjustments is not above the maximum allowed // That is that having allowed for KF and GF penalties we have not pushed the // current interframe target to low. If the adjustment we apply here is not capable of recovering @@ -858,11 +853,6 @@ void vp8_calc_pframe_target_size(VP8_COMP *cpi) percent_low = (cpi->oxcf.optimal_buffer_level - cpi->buffer_level) / one_percent_bits; - - if (percent_low > 100) - percent_low = 100; - else if (percent_low < 0) - percent_low = 0; } // Are we overshooting the long term clip data rate... else if (cpi->bits_off_target < 0) @@ -870,16 +860,16 @@ void vp8_calc_pframe_target_size(VP8_COMP *cpi) // Adjust per frame data target downwards to compensate. percent_low = (int)(100 * -cpi->bits_off_target / (cpi->total_byte_count * 8)); - - if (percent_low > 100) - percent_low = 100; - else if (percent_low < 0) - percent_low = 0; } + if (percent_low > cpi->oxcf.under_shoot_pct) + percent_low = cpi->oxcf.under_shoot_pct; + else if (percent_low < 0) + percent_low = 0; + // lower the target bandwidth for this frame. - cpi->this_frame_target = - (cpi->this_frame_target * (100 - (percent_low / 2))) / 100; + cpi->this_frame_target -= (cpi->this_frame_target * percent_low) + / 200; // Are we using allowing control of active_worst_allowed_q // according to buffer level. @@ -950,20 +940,29 @@ void vp8_calc_pframe_target_size(VP8_COMP *cpi) } else { - int percent_high; + int percent_high = 0; - if (cpi->bits_off_target > cpi->oxcf.optimal_buffer_level) + if ((cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) + && (cpi->buffer_level > cpi->oxcf.optimal_buffer_level)) { - percent_high = (int)(100 * (cpi->bits_off_target - cpi->oxcf.optimal_buffer_level) / (cpi->total_byte_count * 8)); + percent_high = (cpi->buffer_level + - cpi->oxcf.optimal_buffer_level) + / one_percent_bits; + } + else if (cpi->bits_off_target > cpi->oxcf.optimal_buffer_level) + { + percent_high = (int)((100 * cpi->bits_off_target) + / (cpi->total_byte_count * 8)); + } - if (percent_high > 100) - percent_high = 100; - else if (percent_high < 0) - percent_high = 0; + if (percent_high > cpi->oxcf.over_shoot_pct) + percent_high = cpi->oxcf.over_shoot_pct; + else if (percent_high < 0) + percent_high = 0; - cpi->this_frame_target = (cpi->this_frame_target * (100 + (percent_high / 2))) / 100; + cpi->this_frame_target += (cpi->this_frame_target * + percent_high) / 200; - } // Are we allowing control of active_worst_allowed_q according to bufferl level. if (cpi->auto_worst_q) diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 2622738..6b13033 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -151,7 +151,8 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(cfg, g_lag_in_frames, 0); #endif RANGE_CHECK(cfg, rc_end_usage, VPX_VBR, VPX_CQ); - RANGE_CHECK_HI(cfg, rc_undershoot_pct, 100); + RANGE_CHECK_HI(cfg, rc_undershoot_pct, 1000); + RANGE_CHECK_HI(cfg, rc_overshoot_pct, 1000); RANGE_CHECK_HI(cfg, rc_2pass_vbr_bias_pct, 100); RANGE_CHECK(cfg, kf_mode, VPX_KF_DISABLED, VPX_KF_AUTO); //RANGE_CHECK_BOOL(cfg, g_delete_firstpassfile); @@ -316,7 +317,7 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, oxcf->fixed_q = -1; oxcf->under_shoot_pct = cfg.rc_undershoot_pct; - //oxcf->over_shoot_pct = cfg.rc_overshoot_pct; + oxcf->over_shoot_pct = cfg.rc_overshoot_pct; oxcf->maximum_buffer_size = cfg.rc_buf_sz; oxcf->starting_buffer_level = cfg.rc_buf_initial_sz; @@ -362,6 +363,7 @@ static vpx_codec_err_t set_vp8e_config(VP8_CONFIG *oxcf, printf("key_freq: %d\n", oxcf->key_freq); printf("end_usage: %d\n", oxcf->end_usage); printf("under_shoot_pct: %d\n", oxcf->under_shoot_pct); + printf("over_shoot_pct: %d\n", oxcf->over_shoot_pct); printf("starting_buffer_level: %d\n", oxcf->starting_buffer_level); printf("optimal_buffer_level: %d\n", oxcf->optimal_buffer_level); printf("maximum_buffer_size: %d\n", oxcf->maximum_buffer_size); @@ -1091,8 +1093,8 @@ static vpx_codec_enc_cfg_map_t vp8e_usage_cfg_map[] = 4, /* rc_min_quantizer */ 63, /* rc_max_quantizer */ - 95, /* rc_undershoot_pct */ - 200, /* rc_overshoot_pct */ + 100, /* rc_undershoot_pct */ + 100, /* rc_overshoot_pct */ 6000, /* rc_max_buffer_size */ 4000, /* rc_buffer_initial_size; */ diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h index 9c44414..3760241 100644 --- a/vpx/vpx_encoder.h +++ b/vpx/vpx_encoder.h @@ -430,20 +430,28 @@ extern "C" { */ - /*!\brief Rate control undershoot tolerance + /*!\brief Rate control adaptation undershoot control * - * This value, expressed as a percentage of the target bitrate, describes - * the target bitrate for easier frames, allowing bits to be saved for - * harder frames. Set to zero to use the codec default. + * This value, expressed as a percentage of the target bitrate, + * controls the maximum allowed adaptation speed of the codec. + * This factor controls the maximum amount of bits that can + * be subtracted from the target bitrate in order to compensate + * for prior overshoot. + * + * Valid values in the range 0-1000. */ unsigned int rc_undershoot_pct; - /*!\brief Rate control overshoot tolerance + /*!\brief Rate control adaptation overshoot control + * + * This value, expressed as a percentage of the target bitrate, + * controls the maximum allowed adaptation speed of the codec. + * This factor controls the maximum amount of bits that can + * be added to the target bitrate in order to compensate for + * prior undershoot. * - * This value, expressed as a percentage of the target bitrate, describes - * the maximum allowed bitrate for a given frame. Set to zero to use the - * codec default. + * Valid values in the range 0-1000. */ unsigned int rc_overshoot_pct; -- 2.7.4