Rate control bug with long key frame interval.

In two pass encodes, the calculation of the number of bits
allocated to a KF group had the potential to overflow for high data
rates if the interval is very long.

We observed the problem in one test clip where there was one
section where there was an 8000 frame gap between key frames.

Change-Id: Ic48eb86271775d7573b4afd166b567b64f25b787
This commit is contained in:
Paul Wilkins 2010-07-23 17:01:12 +01:00
parent d576690ba1
commit 9404c7db6d
2 changed files with 65 additions and 25 deletions

View File

@ -1572,26 +1572,36 @@ static void define_gf_group(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
// Calculate the number of bits to be spent on the gf or arf based on the boost number
cpi->gf_bits = (int)((double)Boost * (cpi->gf_group_bits / (double)allocation_chunks));
// If the frame that is to be boosted is simpler than the average for the gf/arf group then use an alternative calculation
// If the frame that is to be boosted is simpler than the average for
// the gf/arf group then use an alternative calculation
// based on the error score of the frame itself
if (mod_frame_err < gf_group_err / (double)cpi->baseline_gf_interval)
{
double alt_gf_grp_bits;
int alt_gf_bits;
alt_gf_grp_bits = ((double)cpi->kf_group_bits * (mod_frame_err * (double)cpi->baseline_gf_interval) / (double)cpi->kf_group_error_left) ;
alt_gf_bits = (int)((double)Boost * (alt_gf_grp_bits / (double)allocation_chunks));
alt_gf_grp_bits =
(double)cpi->kf_group_bits *
(mod_frame_err * (double)cpi->baseline_gf_interval) /
DOUBLE_DIVIDE_CHECK((double)cpi->kf_group_error_left);
alt_gf_bits = (int)((double)Boost * (alt_gf_grp_bits /
(double)allocation_chunks));
if (cpi->gf_bits > alt_gf_bits)
{
cpi->gf_bits = alt_gf_bits;
}
}
// Else if it is harder than other frames in the group make sure it at least receives an allocation in keeping with
// its relative error score, otherwise it may be worse off than an "un-boosted" frame
// Else if it is harder than other frames in the group make sure it at
// least receives an allocation in keeping with its relative error
// score, otherwise it may be worse off than an "un-boosted" frame
else
{
int alt_gf_bits = (int)((double)cpi->kf_group_bits * (mod_frame_err / (double)cpi->kf_group_error_left));
int alt_gf_bits =
(int)((double)cpi->kf_group_bits *
mod_frame_err /
DOUBLE_DIVIDE_CHECK((double)cpi->kf_group_error_left));
if (alt_gf_bits > cpi->gf_bits)
{
@ -2062,7 +2072,7 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
// Take a copy of the initial frame details
vpx_memcpy(&first_frame, this_frame, sizeof(*this_frame));
cpi->kf_group_bits = 0; // Estimate of total bits avaialable to kf group
cpi->kf_group_bits = 0; // Total bits avaialable to kf group
cpi->kf_group_error_left = 0; // Group modified error score.
kf_mod_err = calculate_modified_err(cpi, this_frame);
@ -2129,39 +2139,64 @@ void vp8_find_next_key_frame(VP8_COMP *cpi, FIRSTPASS_STATS *this_frame)
// Calculate the number of bits that should be assigned to the kf group.
if ((cpi->bits_left > 0) && ((int)cpi->modified_total_error_left > 0))
{
int max_bits = frame_max_bits(cpi); // Max for a single normal frame (not key frame)
// Max for a single normal frame (not key frame)
int max_bits = frame_max_bits(cpi);
// Default allocation based on bits left and relative complexity of the section
cpi->kf_group_bits = (int)(cpi->bits_left * (kf_group_err / cpi->modified_total_error_left));
// Maximum bits for the kf group
long long max_grp_bits;
// Default allocation based on bits left and relative
// complexity of the section
cpi->kf_group_bits = (long long)( cpi->bits_left *
( kf_group_err /
cpi->modified_total_error_left ));
// Clip based on maximum per frame rate defined by the user.
if (cpi->kf_group_bits > max_bits * cpi->frames_to_key)
cpi->kf_group_bits = max_bits * cpi->frames_to_key;
max_grp_bits = (long long)max_bits * (long long)cpi->frames_to_key;
if (cpi->kf_group_bits > max_grp_bits)
cpi->kf_group_bits = max_grp_bits;
// Additional special case for CBR if buffer is getting full.
if (cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)
{
// If the buffer is near or above the optimal and this kf group is not being allocated much
// then increase the allocation a bit.
if (cpi->buffer_level >= cpi->oxcf.optimal_buffer_level)
int opt_buffer_lvl = cpi->oxcf.optimal_buffer_level;
int buffer_lvl = cpi->buffer_level;
// If the buffer is near or above the optimal and this kf group is
// not being allocated much then increase the allocation a bit.
if (buffer_lvl >= opt_buffer_lvl)
{
int high_water_mark = (cpi->oxcf.optimal_buffer_level + cpi->oxcf.maximum_buffer_size) >> 1;
int min_group_bits;
int high_water_mark = (opt_buffer_lvl +
cpi->oxcf.maximum_buffer_size) >> 1;
long long av_group_bits;
// Av bits per frame * number of frames
av_group_bits = (long long)cpi->av_per_frame_bandwidth *
(long long)cpi->frames_to_key;
// We are at or above the maximum.
if (cpi->buffer_level >= high_water_mark)
{
min_group_bits = (cpi->av_per_frame_bandwidth * cpi->frames_to_key) + (cpi->buffer_level - high_water_mark);
long long min_group_bits;
min_group_bits = av_group_bits +
(long long)(buffer_lvl -
high_water_mark);
if (cpi->kf_group_bits < min_group_bits)
cpi->kf_group_bits = min_group_bits;
}
// We are above optimal but below the maximum
else if (cpi->kf_group_bits < (cpi->av_per_frame_bandwidth * cpi->frames_to_key))
else if (cpi->kf_group_bits < av_group_bits)
{
int bits_below_av = (cpi->av_per_frame_bandwidth * cpi->frames_to_key) - cpi->kf_group_bits;
cpi->kf_group_bits += (int)((double)bits_below_av * (double)(cpi->buffer_level - cpi->oxcf.optimal_buffer_level) /
(double)(high_water_mark - cpi->oxcf.optimal_buffer_level));
long long bits_below_av = av_group_bits -
cpi->kf_group_bits;
cpi->kf_group_bits +=
(long long)((double)bits_below_av *
(double)(buffer_lvl - opt_buffer_lvl) /
(double)(high_water_mark - opt_buffer_lvl));
}
}
}

View File

@ -356,9 +356,14 @@ typedef struct
int gf_bits; // Bits for the golden frame or ARF - 2 pass only
int mid_gf_extra_bits; // A few extra bits for the frame half way between two gfs.
int kf_group_bits; // Projected total bits available for a key frame group of frames
int kf_group_error_left; // Error score of frames still to be coded in kf group
int kf_bits; // Bits for the key frame in a key frame group - 2 pass only
// Projected total bits available for a key frame group of frames
long long kf_group_bits;
// Error score of frames still to be coded in kf group
long long kf_group_error_left;
// Bits for the key frame in a key frame group - 2 pass only
int kf_bits;
int non_gf_bitrate_adjustment; // Used in the few frames following a GF to recover the extra bits spent in that GF
int initial_gf_use; // percentage use of gf 2 frames after gf