summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_ratectrl.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_ratectrl.c')
-rw-r--r--vp9/encoder/vp9_ratectrl.c103
1 files changed, 46 insertions, 57 deletions
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 3ebf98c0f..74eb98fb0 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -218,7 +218,7 @@ static void calc_iframe_target_size(VP9_COMP *cpi) {
vp9_clear_system_state(); // __asm emms;
// For 1-pass.
- if (cpi->pass == 0) {
+ if (cpi->pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
if (cpi->common.current_video_frame == 0) {
target = oxcf->starting_buffer_level / 2;
} else {
@@ -246,7 +246,7 @@ static void calc_iframe_target_size(VP9_COMP *cpi) {
if (oxcf->rc_max_intra_bitrate_pct) {
const int max_rate = rc->per_frame_bandwidth *
- oxcf->rc_max_intra_bitrate_pct / 100;
+ oxcf->rc_max_intra_bitrate_pct / 100;
target = MIN(target, max_rate);
}
rc->this_frame_target = target;
@@ -375,27 +375,22 @@ static int target_size_from_buffer_level(const VP9_CONFIG *oxcf,
static void calc_pframe_target_size(VP9_COMP *const cpi) {
RATE_CONTROL *const rc = &cpi->rc;
const VP9_CONFIG *const oxcf = &cpi->oxcf;
- int min_frame_target = MAX(rc->min_frame_bandwidth,
- rc->av_per_frame_bandwidth >> 5);
- if (cpi->refresh_alt_ref_frame) {
- // Special alt reference frame case
- // Per frame bit target for the alt ref frame
- rc->per_frame_bandwidth = cpi->twopass.gf_bits;
- rc->this_frame_target = rc->per_frame_bandwidth;
- } else {
- // Normal frames (gf and inter).
- rc->this_frame_target = rc->per_frame_bandwidth;
- // Set target frame size based on buffer level, for 1 pass CBR.
- if (cpi->pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
- // Need to decide how low min_frame_target should be for 1-pass CBR.
- // For now, use: cpi->rc.av_per_frame_bandwidth / 16:
- min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
- FRAME_OVERHEAD_BITS);
- rc->this_frame_target = target_size_from_buffer_level(oxcf, rc);
- // Adjust qp-max based on buffer level.
- rc->active_worst_quality =
- adjust_active_worst_quality_from_buffer_level(oxcf, rc);
- }
+ int min_frame_target;
+ rc->this_frame_target = rc->per_frame_bandwidth;
+
+ if (cpi->pass == 0 && oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
+ // Need to decide how low min_frame_target should be for 1-pass CBR.
+ // For now, use: cpi->rc.av_per_frame_bandwidth / 16:
+ min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
+ FRAME_OVERHEAD_BITS);
+ rc->this_frame_target = target_size_from_buffer_level(oxcf, rc);
+ // Adjust qp-max based on buffer level.
+ rc->active_worst_quality =
+ adjust_active_worst_quality_from_buffer_level(oxcf, rc);
+
+ if (rc->this_frame_target < min_frame_target)
+ rc->this_frame_target = min_frame_target;
+ return;
}
// Check that the total sum of adjustments is not above the maximum allowed.
@@ -404,6 +399,9 @@ static void calc_pframe_target_size(VP9_COMP *const cpi) {
// not capable of recovering all the extra bits we have spent in the KF or GF,
// then the remainder will have to be recovered over a longer time span via
// other buffer / rate control mechanisms.
+ min_frame_target = MAX(rc->min_frame_bandwidth,
+ rc->av_per_frame_bandwidth >> 5);
+
if (rc->this_frame_target < min_frame_target)
rc->this_frame_target = min_frame_target;
@@ -468,8 +466,8 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) {
// Work out a size correction factor.
if (projected_size_based_on_q > 0)
- correction_factor =
- (100 * cpi->rc.projected_frame_size) / projected_size_based_on_q;
+ correction_factor = (100 * cpi->rc.projected_frame_size) /
+ projected_size_based_on_q;
// More heavily damped adjustment used if we have been oscillating either side
// of target.
@@ -514,26 +512,25 @@ void vp9_rc_update_rate_correction_factors(VP9_COMP *cpi, int damp_var) {
int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
int active_best_quality, int active_worst_quality) {
+ const VP9_COMMON *const cm = &cpi->common;
int q = active_worst_quality;
int last_error = INT_MAX;
- int i, target_bits_per_mb, bits_per_mb_at_this_q;
+ int i, target_bits_per_mb;
const double correction_factor = get_rate_correction_factor(cpi);
// Calculate required scaling factor based on target frame size and size of
// frame produced using previous Q.
if (target_bits_per_frame >= (INT_MAX >> BPER_MB_NORMBITS))
- target_bits_per_mb =
- (target_bits_per_frame / cpi->common.MBs)
- << BPER_MB_NORMBITS; // Case where we would overflow int
+ // Case where we would overflow int
+ target_bits_per_mb = (target_bits_per_frame / cm->MBs) << BPER_MB_NORMBITS;
else
- target_bits_per_mb =
- (target_bits_per_frame << BPER_MB_NORMBITS) / cpi->common.MBs;
+ target_bits_per_mb = (target_bits_per_frame << BPER_MB_NORMBITS) / cm->MBs;
i = active_best_quality;
do {
- bits_per_mb_at_this_q = (int)vp9_rc_bits_per_mb(cpi->common.frame_type, i,
- correction_factor);
+ const int bits_per_mb_at_this_q = (int)vp9_rc_bits_per_mb(cm->frame_type, i,
+ correction_factor);
if (bits_per_mb_at_this_q <= target_bits_per_mb) {
if ((target_bits_per_mb - bits_per_mb_at_this_q) <= last_error)
@@ -550,25 +547,19 @@ int vp9_rc_regulate_q(const VP9_COMP *cpi, int target_bits_per_frame,
return q;
}
-static int get_active_quality(int q,
- int gfu_boost,
- int low,
- int high,
- int *low_motion_minq,
- int *high_motion_minq) {
- int active_best_quality;
+static int get_active_quality(int q, int gfu_boost, int low, int high,
+ int *low_motion_minq, int *high_motion_minq) {
if (gfu_boost > high) {
- active_best_quality = low_motion_minq[q];
+ return low_motion_minq[q];
} else if (gfu_boost < low) {
- active_best_quality = high_motion_minq[q];
+ return high_motion_minq[q];
} else {
const int gap = high - low;
const int offset = high - gfu_boost;
const int qdiff = high_motion_minq[q] - low_motion_minq[q];
const int adjustment = ((offset * qdiff) + (gap >> 1)) / gap;
- active_best_quality = low_motion_minq[q] + adjustment;
+ return low_motion_minq[q] + adjustment;
}
- return active_best_quality;
}
int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
@@ -615,8 +606,8 @@ int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
// Convert the adjustment factor to a qindex delta
// on active_best_quality.
q_val = vp9_convert_qindex_to_q(active_best_quality);
- active_best_quality +=
- vp9_compute_qdelta(cpi, q_val, (q_val * q_adj_factor));
+ active_best_quality += vp9_compute_qdelta(cpi, q_val, q_val *
+ q_adj_factor);
}
#else
double current_q;
@@ -720,15 +711,12 @@ int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
#if LIMIT_QRANGE_FOR_ALTREF_AND_KEY
// Limit Q range for the adaptive loop.
if (cm->frame_type == KEY_FRAME && !rc->this_key_frame_forced) {
- if (!(cpi->pass == 0 && cm->current_video_frame == 0)) {
- *top_index =
- (active_worst_quality + active_best_quality * 3) / 4;
- }
+ if (!(cpi->pass == 0 && cm->current_video_frame == 0))
+ *top_index = (active_worst_quality + active_best_quality * 3) / 4;
} else if (!rc->is_src_frame_alt_ref &&
(oxcf->end_usage != USAGE_STREAM_FROM_SERVER) &&
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
- *top_index =
- (active_worst_quality + active_best_quality) / 2;
+ *top_index = (active_worst_quality + active_best_quality) / 2;
}
#endif
@@ -818,7 +806,8 @@ void vp9_rc_compute_frame_size_bounds(const VP9_COMP *cpi,
// return of 0 means drop frame
int vp9_rc_pick_frame_size_target(VP9_COMP *cpi) {
- VP9_COMMON *cm = &cpi->common;
+ const VP9_COMMON *const cm = &cpi->common;
+ RATE_CONTROL *const rc = &cpi->rc;
if (cm->frame_type == KEY_FRAME)
calc_iframe_target_size(cpi);
@@ -826,12 +815,12 @@ int vp9_rc_pick_frame_size_target(VP9_COMP *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;
+ if (rc->this_frame_target > rc->max_frame_bandwidth)
+ rc->this_frame_target = 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);
+ rc->sb64_target_rate = ((int64_t)rc->this_frame_target * 64 * 64) /
+ (cm->width * cm->height);
return 1;
}