summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorPaul Wilkins <paulwilkins@google.com>2014-01-10 17:26:44 +0000
committerPaul Wilkins <paulwilkins@google.com>2014-01-14 09:52:49 +0000
commit5c808ba13acf26a9a5037583f3ca8156163ff06a (patch)
tree8314e8d055737d769fff0c8e5fe8f837a6c045c0 /vp9/encoder
parent4f2a80f05fdd4bfb75c61483498d09fc8f1eb075 (diff)
downloadlibvpx-5c808ba13acf26a9a5037583f3ca8156163ff06a.tar
libvpx-5c808ba13acf26a9a5037583f3ca8156163ff06a.tar.gz
libvpx-5c808ba13acf26a9a5037583f3ca8156163ff06a.tar.bz2
libvpx-5c808ba13acf26a9a5037583f3ca8156163ff06a.zip
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
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_firstpass.c11
-rw-r--r--vp9/encoder/vp9_onyx_if.c55
-rw-r--r--vp9/encoder/vp9_onyx_int.h7
-rw-r--r--vp9/encoder/vp9_ratectrl.c18
4 files changed, 70 insertions, 21 deletions
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 7c4ca6378..adc1b7935 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -353,13 +353,14 @@ static double simple_weight(YV12_BUFFER_CONFIG *source) {
// This function returns the maximum target rate per frame.
static int frame_max_bits(VP9_COMP *cpi) {
int64_t max_bits =
- ((int64_t)cpi->rc.av_per_frame_bandwidth *
- (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
+ ((int64_t)cpi->rc.av_per_frame_bandwidth *
+ (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
if (max_bits < 0)
- return 0;
- if (max_bits >= INT_MAX)
- return INT_MAX;
+ max_bits = 0;
+ else if (max_bits > cpi->rc.max_frame_bandwidth)
+ max_bits = cpi->rc.max_frame_bandwidth;
+
return (int)max_bits;
}
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 8e60bc96d..2bcfcd4f0 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -59,6 +59,11 @@ void vp9_coef_tree_initialize();
#define DISABLE_COMPOUND_SPLIT 0x18
#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
extern double vp9_calc_ssim(YV12_BUFFER_CONFIG *source,
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) {
+ VP9_COMMON *const cm = &cpi->common;
+ int64_t vbr_max_bits;
+
if (framerate < 0.1)
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,
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
cpi->rc.max_gf_interval = 16;
@@ -2449,10 +2470,14 @@ static int recode_loop_test(VP9_COMP *cpi,
int force_recode = 0;
VP9_COMMON *cm = &cpi->common;
- // Is frame recode allowed at all
- // Yes if either recode mode 1 is selected or mode two is selected
- // and the frame is a key frame. golden frame or alt_ref_frame
- if ((cpi->sf.recode_loop == 1) ||
+ // Special case trap if maximum allowed frame size exceeded.
+ if (cpi->rc.projected_frame_size > cpi->rc.max_frame_bandwidth) {
+ force_recode = 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) &&
((cm->frame_type == KEY_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"
"%10.3f %8d %10d %10d %10d\n",
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),
(int)cpi->rc.total_target_vs_actual,
(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) {
loop = 0;
} else {
- // Special case handling for forced key frames
- if ((cm->frame_type == KEY_FRAME) && cpi->rc.this_key_frame_forced) {
+ if ((cm->frame_type == KEY_FRAME) &&
+ cpi->rc.this_key_frame_forced &&
+ (cpi->rc.projected_frame_size < cpi->rc.max_frame_bandwidth)) {
int last_q = *q;
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;
} else if (recode_loop_test(
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
// to attempt to recode.
int last_q = *q;
@@ -2791,6 +2818,10 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
// Frame is too large
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
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);
*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) {
vp9_rc_update_rate_correction_factors(cpi, 0);
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
- bottom_index, top_index);
+ bottom_index, MAX(q_high, top_index));
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;
if (loop) {
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index a5be0f424..be079d859 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -442,9 +442,10 @@ typedef struct {
unsigned int source_alt_ref_active;
unsigned int is_src_frame_alt_ref;
- int per_frame_bandwidth; // Current section per frame bandwidth target
- int av_per_frame_bandwidth; // Average frame size target for clip
- int min_frame_bandwidth; // Minimum allocation used for any frame
+ int per_frame_bandwidth; // Current section per frame bandwidth target
+ int av_per_frame_bandwidth; // Average frame size target for clip
+ 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_tot_qi;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 939a7f998..ae1aaa32e 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -746,8 +746,13 @@ int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
} else {
q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
active_best_quality, active_worst_quality);
- if (q > *top_index)
- q = *top_index;
+ if (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
// 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;
if (*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
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.
cpi->rc.sb64_target_rate = ((int64_t)cpi->rc.this_frame_target * 64 * 64) /
(cpi->common.width * cpi->common.height);