Improved 1-pass CBR rate control

This patch attempts to improve the handling of CBR streams with
respect to the short term buffering requirements. The "buffer level"
is changed to be an average over the rc buffer, rather than a long
running average. Overshoot is also tracked over the same interval
and the golden frame targets suppressed accordingly to correct for
overly aggressive boosting.

Testing shows that this is fairly consistently positive in one
metric or another -- some clips that show significant decreases
in quality have better buffering characteristics, others show
improvenents in both.

Change-Id: I924c89aa9bdb210271f2e03311e63de3f1f8f920
This commit is contained in:
John Koleszar
2011-06-29 11:41:50 -04:00
parent 74ad25a4c6
commit b5ea2fbc2c
5 changed files with 216 additions and 46 deletions

View File

@@ -608,7 +608,7 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
int min_frame_target;
int Adjustment;
min_frame_target = 0;
min_frame_target = 1;
if (cpi->pass == 2)
{
@@ -617,9 +617,11 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
if (min_frame_target < (cpi->av_per_frame_bandwidth >> 5))
min_frame_target = cpi->av_per_frame_bandwidth >> 5;
}
else if (min_frame_target < cpi->per_frame_bandwidth / 4)
min_frame_target = cpi->per_frame_bandwidth / 4;
else
{
if (min_frame_target < cpi->per_frame_bandwidth / 4)
min_frame_target = cpi->per_frame_bandwidth / 4;
}
// Special alt reference frame case
if (cpi->common.refresh_alt_ref_frame)
@@ -1112,6 +1114,33 @@ static void calc_pframe_target_size(VP8_COMP *cpi)
}
}
if (cpi->pass==0
&& cpi->common.refresh_golden_frame
&& cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
long long adjust;
/*
frames_in_buffer = cpi->oxcf.maximum_buffer_size
/ cpi->av_per_frame_bandwidth;
gf_in_buffer = frames_in_buffer /
cpi->frames_till_gf_update_due;
overshoot_per_gf = cpi->accumulated_overshoot / gf_in_buffer;
*/
adjust = cpi->accumulated_overshoot;
adjust *= cpi->frames_till_gf_update_due + 1;
adjust *= cpi->av_per_frame_bandwidth;
adjust /= cpi->oxcf.maximum_buffer_size;
if (adjust > (cpi->this_frame_target - min_frame_target))
adjust = (cpi->this_frame_target - min_frame_target);
else if (adjust < 0)
adjust = 0;
cpi->this_frame_target -= adjust;
}
}