Add max burst bitrate control.
Applies an upper limit on burst bitrate for any frame. This is to insure that typical encodes for YT do not produce frames that are so large that they risk stalling HW implementations. Such frames could also cause playback problems in SW. For now the limit is set at 250 bits per MB for 1080P and larger (with the 1080P limit used for smaller frames). Setting maxQ, constant quality mode or targeting a very high bandwidth will have precedence over this limit. Change-Id: Ie6f776c38b06ac7cec043d034085f4b79ee46a38
This commit is contained in:
Родитель
4f2a80f05f
Коммит
5c808ba13a
|
@ -353,13 +353,14 @@ static double simple_weight(YV12_BUFFER_CONFIG *source) {
|
||||||
// This function returns the maximum target rate per frame.
|
// This function returns the maximum target rate per frame.
|
||||||
static int frame_max_bits(VP9_COMP *cpi) {
|
static int frame_max_bits(VP9_COMP *cpi) {
|
||||||
int64_t max_bits =
|
int64_t max_bits =
|
||||||
((int64_t)cpi->rc.av_per_frame_bandwidth *
|
((int64_t)cpi->rc.av_per_frame_bandwidth *
|
||||||
(int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
|
(int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
|
||||||
|
|
||||||
if (max_bits < 0)
|
if (max_bits < 0)
|
||||||
return 0;
|
max_bits = 0;
|
||||||
if (max_bits >= INT_MAX)
|
else if (max_bits > cpi->rc.max_frame_bandwidth)
|
||||||
return INT_MAX;
|
max_bits = cpi->rc.max_frame_bandwidth;
|
||||||
|
|
||||||
return (int)max_bits;
|
return (int)max_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,11 @@ void vp9_coef_tree_initialize();
|
||||||
#define DISABLE_COMPOUND_SPLIT 0x18
|
#define DISABLE_COMPOUND_SPLIT 0x18
|
||||||
#define LAST_AND_INTRA_SPLIT_ONLY 0x1E
|
#define LAST_AND_INTRA_SPLIT_ONLY 0x1E
|
||||||
|
|
||||||
|
// Max rate target for 1080P and below encodes under normal circumstances
|
||||||
|
// (1920 * 1080 / (16 * 16)) * MAX_MB_RATE bits per MB
|
||||||
|
#define MAX_MB_RATE 250
|
||||||
|
#define MAXRATE_1080P 2025000
|
||||||
|
|
||||||
#if CONFIG_INTERNAL_STATS
|
#if CONFIG_INTERNAL_STATS
|
||||||
extern double vp9_calc_ssim(YV12_BUFFER_CONFIG *source,
|
extern double vp9_calc_ssim(YV12_BUFFER_CONFIG *source,
|
||||||
YV12_BUFFER_CONFIG *dest, int lumamask,
|
YV12_BUFFER_CONFIG *dest, int lumamask,
|
||||||
|
@ -1093,6 +1098,9 @@ int vp9_reverse_trans(int x) {
|
||||||
};
|
};
|
||||||
|
|
||||||
void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
|
void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
|
||||||
|
VP9_COMMON *const cm = &cpi->common;
|
||||||
|
int64_t vbr_max_bits;
|
||||||
|
|
||||||
if (framerate < 0.1)
|
if (framerate < 0.1)
|
||||||
framerate = 30;
|
framerate = 30;
|
||||||
|
|
||||||
|
@ -1109,6 +1117,19 @@ void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
|
||||||
cpi->rc.min_frame_bandwidth = MAX(cpi->rc.min_frame_bandwidth,
|
cpi->rc.min_frame_bandwidth = MAX(cpi->rc.min_frame_bandwidth,
|
||||||
FRAME_OVERHEAD_BITS);
|
FRAME_OVERHEAD_BITS);
|
||||||
|
|
||||||
|
// A maximum bitrate for a frame is defined.
|
||||||
|
// The baseline for this aligns with HW implementations that
|
||||||
|
// can support decode of 1080P content up to a bitrate of MAX_MB_RATE bits
|
||||||
|
// per 16x16 MB (averaged over a frame). However this limit is extended if
|
||||||
|
// a very high rate is given on the command line or the the rate cannnot
|
||||||
|
// be acheived because of a user specificed max q (e.g. when the user
|
||||||
|
// specifies lossless encode.
|
||||||
|
//
|
||||||
|
vbr_max_bits = ((int64_t)cpi->rc.av_per_frame_bandwidth *
|
||||||
|
(int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
|
||||||
|
cpi->rc.max_frame_bandwidth =
|
||||||
|
MAX(MAX((cm->MBs * MAX_MB_RATE), MAXRATE_1080P), vbr_max_bits);
|
||||||
|
|
||||||
// Set Maximum gf/arf interval
|
// Set Maximum gf/arf interval
|
||||||
cpi->rc.max_gf_interval = 16;
|
cpi->rc.max_gf_interval = 16;
|
||||||
|
|
||||||
|
@ -2449,10 +2470,14 @@ static int recode_loop_test(VP9_COMP *cpi,
|
||||||
int force_recode = 0;
|
int force_recode = 0;
|
||||||
VP9_COMMON *cm = &cpi->common;
|
VP9_COMMON *cm = &cpi->common;
|
||||||
|
|
||||||
// Is frame recode allowed at all
|
// Special case trap if maximum allowed frame size exceeded.
|
||||||
// Yes if either recode mode 1 is selected or mode two is selected
|
if (cpi->rc.projected_frame_size > cpi->rc.max_frame_bandwidth) {
|
||||||
// and the frame is a key frame. golden frame or alt_ref_frame
|
force_recode = 1;
|
||||||
if ((cpi->sf.recode_loop == 1) ||
|
|
||||||
|
// Is frame recode allowed.
|
||||||
|
// Yes if either recode mode 1 is selected or mode 2 is selected
|
||||||
|
// and the frame is a key frame, golden frame or alt_ref_frame
|
||||||
|
} else if ((cpi->sf.recode_loop == 1) ||
|
||||||
((cpi->sf.recode_loop == 2) &&
|
((cpi->sf.recode_loop == 2) &&
|
||||||
((cm->frame_type == KEY_FRAME) ||
|
((cm->frame_type == KEY_FRAME) ||
|
||||||
cpi->refresh_golden_frame ||
|
cpi->refresh_golden_frame ||
|
||||||
|
@ -2630,7 +2655,8 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
|
||||||
"%6d %6d %5d %5d %5d %10d %10.3f"
|
"%6d %6d %5d %5d %5d %10d %10.3f"
|
||||||
"%10.3f %8d %10d %10d %10d\n",
|
"%10.3f %8d %10d %10d %10d\n",
|
||||||
cpi->common.current_video_frame, cpi->rc.this_frame_target,
|
cpi->common.current_video_frame, cpi->rc.this_frame_target,
|
||||||
cpi->rc.projected_frame_size, 0,
|
cpi->rc.projected_frame_size,
|
||||||
|
cpi->rc.projected_frame_size / cpi->common.MBs,
|
||||||
(cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
|
(cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
|
||||||
(int)cpi->rc.total_target_vs_actual,
|
(int)cpi->rc.total_target_vs_actual,
|
||||||
(int)(cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target),
|
(int)(cpi->oxcf.starting_buffer_level - cpi->rc.bits_off_target),
|
||||||
|
@ -2740,8 +2766,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
|
||||||
if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
|
if (cpi->oxcf.end_usage == USAGE_CONSTANT_QUALITY) {
|
||||||
loop = 0;
|
loop = 0;
|
||||||
} else {
|
} else {
|
||||||
// Special case handling for forced key frames
|
if ((cm->frame_type == KEY_FRAME) &&
|
||||||
if ((cm->frame_type == KEY_FRAME) && cpi->rc.this_key_frame_forced) {
|
cpi->rc.this_key_frame_forced &&
|
||||||
|
(cpi->rc.projected_frame_size < cpi->rc.max_frame_bandwidth)) {
|
||||||
int last_q = *q;
|
int last_q = *q;
|
||||||
int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
|
int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
|
||||||
|
|
||||||
|
@ -2780,7 +2807,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
|
||||||
loop = *q != last_q;
|
loop = *q != last_q;
|
||||||
} else if (recode_loop_test(
|
} else if (recode_loop_test(
|
||||||
cpi, frame_over_shoot_limit, frame_under_shoot_limit,
|
cpi, frame_over_shoot_limit, frame_under_shoot_limit,
|
||||||
*q, top_index, bottom_index)) {
|
*q, MAX(q_high, top_index), bottom_index)) {
|
||||||
// Is the projected frame size out of range and are we allowed
|
// Is the projected frame size out of range and are we allowed
|
||||||
// to attempt to recode.
|
// to attempt to recode.
|
||||||
int last_q = *q;
|
int last_q = *q;
|
||||||
|
@ -2791,6 +2818,10 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
|
||||||
|
|
||||||
// Frame is too large
|
// Frame is too large
|
||||||
if (cpi->rc.projected_frame_size > cpi->rc.this_frame_target) {
|
if (cpi->rc.projected_frame_size > cpi->rc.this_frame_target) {
|
||||||
|
// Special case if the projected size is > the max allowed.
|
||||||
|
if (cpi->rc.projected_frame_size >= cpi->rc.max_frame_bandwidth)
|
||||||
|
q_high = cpi->rc.worst_quality;
|
||||||
|
|
||||||
// Raise Qlow as to at least the current value
|
// Raise Qlow as to at least the current value
|
||||||
q_low = *q < q_high ? *q + 1 : q_high;
|
q_low = *q < q_high ? *q + 1 : q_high;
|
||||||
|
|
||||||
|
@ -2804,12 +2835,12 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
|
||||||
vp9_rc_update_rate_correction_factors(cpi, 0);
|
vp9_rc_update_rate_correction_factors(cpi, 0);
|
||||||
|
|
||||||
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
|
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
|
||||||
bottom_index, top_index);
|
bottom_index, MAX(q_high, top_index));
|
||||||
|
|
||||||
while (*q < q_low && retries < 10) {
|
while (*q < q_low && retries < 10) {
|
||||||
vp9_rc_update_rate_correction_factors(cpi, 0);
|
vp9_rc_update_rate_correction_factors(cpi, 0);
|
||||||
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
|
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
|
||||||
bottom_index, top_index);
|
bottom_index, MAX(q_high, top_index));
|
||||||
retries++;
|
retries++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2855,7 +2886,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cpi->rc.is_src_frame_alt_ref)
|
// Special case for overlay frame.
|
||||||
|
if (cpi->rc.is_src_frame_alt_ref &&
|
||||||
|
(cpi->rc.projected_frame_size < cpi->rc.max_frame_bandwidth))
|
||||||
loop = 0;
|
loop = 0;
|
||||||
|
|
||||||
if (loop) {
|
if (loop) {
|
||||||
|
|
|
@ -442,9 +442,10 @@ typedef struct {
|
||||||
unsigned int source_alt_ref_active;
|
unsigned int source_alt_ref_active;
|
||||||
unsigned int is_src_frame_alt_ref;
|
unsigned int is_src_frame_alt_ref;
|
||||||
|
|
||||||
int per_frame_bandwidth; // Current section per frame bandwidth target
|
int per_frame_bandwidth; // Current section per frame bandwidth target
|
||||||
int av_per_frame_bandwidth; // Average frame size target for clip
|
int av_per_frame_bandwidth; // Average frame size target for clip
|
||||||
int min_frame_bandwidth; // Minimum allocation used for any frame
|
int min_frame_bandwidth; // Minimum allocation used for any frame
|
||||||
|
int max_frame_bandwidth; // Maximum burst rate allowed for a frame.
|
||||||
|
|
||||||
int ni_av_qi;
|
int ni_av_qi;
|
||||||
int ni_tot_qi;
|
int ni_tot_qi;
|
||||||
|
|
|
@ -746,8 +746,13 @@ int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
|
||||||
} else {
|
} else {
|
||||||
q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
|
q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
|
||||||
active_best_quality, active_worst_quality);
|
active_best_quality, active_worst_quality);
|
||||||
if (q > *top_index)
|
if (q > *top_index) {
|
||||||
q = *top_index;
|
// Special case when we are targeting the max allowed rate
|
||||||
|
if (cpi->rc.this_frame_target >= cpi->rc.max_frame_bandwidth)
|
||||||
|
*top_index = q;
|
||||||
|
else
|
||||||
|
q = *top_index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if CONFIG_MULTIPLE_ARF
|
#if CONFIG_MULTIPLE_ARF
|
||||||
// Force the quantizer determined by the coding order pattern.
|
// Force the quantizer determined by the coding order pattern.
|
||||||
|
@ -810,6 +815,11 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi,
|
||||||
*frame_under_shoot_limit -= 200;
|
*frame_under_shoot_limit -= 200;
|
||||||
if (*frame_under_shoot_limit < 0)
|
if (*frame_under_shoot_limit < 0)
|
||||||
*frame_under_shoot_limit = 0;
|
*frame_under_shoot_limit = 0;
|
||||||
|
|
||||||
|
// Clip to maximum allowed rate for a frame.
|
||||||
|
if (*frame_over_shoot_limit > cpi->rc.max_frame_bandwidth) {
|
||||||
|
*frame_over_shoot_limit = cpi->rc.max_frame_bandwidth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,6 +832,10 @@ int vp9_rc_pick_frame_size_target(VP9_COMP *cpi) {
|
||||||
else
|
else
|
||||||
calc_pframe_target_size(cpi);
|
calc_pframe_target_size(cpi);
|
||||||
|
|
||||||
|
// Clip the frame target to the maximum allowed value.
|
||||||
|
if (cpi->rc.this_frame_target > cpi->rc.max_frame_bandwidth)
|
||||||
|
cpi->rc.this_frame_target = cpi->rc.max_frame_bandwidth;
|
||||||
|
|
||||||
// Target rate per SB64 (including partial SB64s.
|
// Target rate per SB64 (including partial SB64s.
|
||||||
cpi->rc.sb64_target_rate = ((int64_t)cpi->rc.this_frame_target * 64 * 64) /
|
cpi->rc.sb64_target_rate = ((int64_t)cpi->rc.this_frame_target * 64 * 64) /
|
||||||
(cpi->common.width * cpi->common.height);
|
(cpi->common.width * cpi->common.height);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче