Index: source/libvpx/vp9/encoder/vp9_ratectrl.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_ratectrl.c (revision 293081) |
+++ source/libvpx/vp9/encoder/vp9_ratectrl.c (working copy) |
@@ -196,6 +196,7 @@ |
int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) { |
const RATE_CONTROL *rc = &cpi->rc; |
+ const VP9EncoderConfig *oxcf = &cpi->oxcf; |
const int min_frame_target = MAX(rc->min_frame_bandwidth, |
rc->avg_frame_bandwidth >> 5); |
if (target < min_frame_target) |
@@ -210,6 +211,11 @@ |
// Clip the frame target to the maximum allowed value. |
if (target > rc->max_frame_bandwidth) |
target = rc->max_frame_bandwidth; |
+ if (oxcf->rc_max_inter_bitrate_pct) { |
+ const int max_rate = rc->avg_frame_bandwidth * |
+ oxcf->rc_max_inter_bitrate_pct / 100; |
+ target = MIN(target, max_rate); |
+ } |
return target; |
} |
@@ -363,8 +369,8 @@ |
return rc->rate_correction_factors[rf_lvl]; |
} else { |
if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) && |
- !rc->is_src_frame_alt_ref && |
- !(cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR)) |
+ !rc->is_src_frame_alt_ref && !cpi->use_svc && |
+ cpi->oxcf.rc_mode != VPX_CBR) |
return rc->rate_correction_factors[GF_ARF_STD]; |
else |
return rc->rate_correction_factors[INTER_NORMAL]; |
@@ -382,8 +388,8 @@ |
rc->rate_correction_factors[rf_lvl] = factor; |
} else { |
if ((cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame) && |
- !rc->is_src_frame_alt_ref && |
- !(cpi->use_svc && cpi->oxcf.rc_mode == VPX_CBR)) |
+ !rc->is_src_frame_alt_ref && !cpi->use_svc && |
+ cpi->oxcf.rc_mode != VPX_CBR) |
rc->rate_correction_factors[GF_ARF_STD] = factor; |
else |
rc->rate_correction_factors[INTER_NORMAL] = factor; |
@@ -424,7 +430,8 @@ |
adjustment_limit = 0.75; |
break; |
case 1: |
- adjustment_limit = 0.375; |
+ adjustment_limit = 0.25 + |
+ 0.5 * MIN(1, fabs(log10(0.01 * correction_factor))); |
break; |
case 2: |
default: |
@@ -432,12 +439,21 @@ |
break; |
} |
+ cpi->rc.q_2_frame = cpi->rc.q_1_frame; |
+ cpi->rc.q_1_frame = cm->base_qindex; |
+ cpi->rc.rc_2_frame = cpi->rc.rc_1_frame; |
+ if (correction_factor > 110) |
+ cpi->rc.rc_1_frame = -1; |
+ else if (correction_factor < 90) |
+ cpi->rc.rc_1_frame = 1; |
+ else |
+ cpi->rc.rc_1_frame = 0; |
+ |
if (correction_factor > 102) { |
// We are not already at the worst allowable quality |
correction_factor = (int)(100 + ((correction_factor - 100) * |
adjustment_limit)); |
rate_correction_factor = (rate_correction_factor * correction_factor) / 100; |
- |
// Keep rate_correction_factor within limits |
if (rate_correction_factor > MAX_BPB_FACTOR) |
rate_correction_factor = MAX_BPB_FACTOR; |
@@ -488,6 +504,14 @@ |
} |
} while (++i <= active_worst_quality); |
+ // In CBR mode, this makes sure q is between oscillating Qs to prevent |
+ // resonance. |
+ if (cpi->oxcf.rc_mode == VPX_CBR && |
+ (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) && |
+ cpi->rc.q_1_frame != cpi->rc.q_2_frame) { |
+ q = clamp(q, MIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame), |
+ MAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame)); |
+ } |
return q; |
} |
@@ -557,18 +581,23 @@ |
const VP9_COMMON *const cm = &cpi->common; |
const RATE_CONTROL *rc = &cpi->rc; |
// Buffer level below which we push active_worst to worst_quality. |
- int64_t critical_level = rc->optimal_buffer_level >> 2; |
+ int64_t critical_level = rc->optimal_buffer_level >> 3; |
int64_t buff_lvl_step = 0; |
int adjustment = 0; |
int active_worst_quality; |
+ int ambient_qp; |
if (cm->frame_type == KEY_FRAME) |
- return rc->worst_quality * 4 / 5; |
- if (cm->current_video_frame > 1) |
- active_worst_quality = MIN(rc->worst_quality, |
- rc->avg_frame_qindex[INTER_FRAME] * 5 / 4); |
- else |
- active_worst_quality = MIN(rc->worst_quality, |
- rc->avg_frame_qindex[KEY_FRAME] * 3 / 2); |
+ return rc->worst_quality; |
+ // For ambient_qp we use minimum of avg_frame_qindex[KEY_FRAME/INTER_FRAME] |
+ // for the first few frames following key frame. These are both initialized |
+ // to worst_quality and updated with (3/4, 1/4) average in postencode_update. |
+ // So for first few frames following key, the qp of that key frame is weighted |
+ // into the active_worst_quality setting. |
+ ambient_qp = (cm->current_video_frame < 5) ? |
+ MIN(rc->avg_frame_qindex[INTER_FRAME], rc->avg_frame_qindex[KEY_FRAME]) : |
+ rc->avg_frame_qindex[INTER_FRAME]; |
+ active_worst_quality = MIN(rc->worst_quality, |
+ ambient_qp * 5 / 4); |
if (rc->buffer_level > rc->optimal_buffer_level) { |
// Adjust down. |
// Maximum limit for down adjustment, ~30%. |
@@ -586,12 +615,11 @@ |
if (critical_level) { |
buff_lvl_step = (rc->optimal_buffer_level - critical_level); |
if (buff_lvl_step) { |
- adjustment = |
- (int)((rc->worst_quality - rc->avg_frame_qindex[INTER_FRAME]) * |
- (rc->optimal_buffer_level - rc->buffer_level) / |
- buff_lvl_step); |
+ adjustment = (int)((rc->worst_quality - ambient_qp) * |
+ (rc->optimal_buffer_level - rc->buffer_level) / |
+ buff_lvl_step); |
} |
- active_worst_quality = rc->avg_frame_qindex[INTER_FRAME] + adjustment; |
+ active_worst_quality = ambient_qp + adjustment; |
} |
} else { |
// Set to worst_quality if buffer is below critical level. |
@@ -971,7 +999,13 @@ |
if (!cpi->refresh_alt_ref_frame) { |
active_best_quality = cq_level; |
} else { |
- active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); |
+ const GF_GROUP *const gf_group = &cpi->twopass.gf_group; |
+ active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); |
+ |
+ // Modify best quality for second level arfs. For mode VPX_Q this |
+ // becomes the baseline frame q. |
+ if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW) |
+ active_best_quality = (active_best_quality + cq_level + 1) / 2; |
} |
} else { |
active_best_quality = get_gf_active_quality(rc, q, cm->bit_depth); |
@@ -1174,8 +1208,8 @@ |
// Post encode loop adjustment of Q prediction. |
vp9_rc_update_rate_correction_factors( |
- cpi, (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF || |
- oxcf->rc_mode == VPX_CBR) ? 2 : 0); |
+ cpi, (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) ? 2 : |
+ ((oxcf->rc_mode == VPX_CBR) ? 1 : 0)); |
// Keep a record of last Q and ambient average Q. |
if (cm->frame_type == KEY_FRAME) { |
@@ -1255,6 +1289,8 @@ |
cpi->common.last_frame_type = cpi->common.frame_type; |
cpi->rc.frames_since_key++; |
cpi->rc.frames_to_key--; |
+ cpi->rc.rc_2_frame = 0; |
+ cpi->rc.rc_1_frame = 0; |
} |
// Use this macro to turn on/off use of alt-refs in one-pass mode. |
@@ -1327,7 +1363,18 @@ |
const int64_t diff = rc->optimal_buffer_level - rc->buffer_level; |
const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100; |
int min_frame_target = MAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS); |
- int target = rc->avg_frame_bandwidth; |
+ int target; |
+ |
+ if (oxcf->gf_cbr_boost_pct) { |
+ const int af_ratio_pct = oxcf->gf_cbr_boost_pct + 100; |
+ target = cpi->refresh_golden_frame ? |
+ (rc->avg_frame_bandwidth * rc->baseline_gf_interval * af_ratio_pct) / |
+ (rc->baseline_gf_interval * 100 + af_ratio_pct - 100) : |
+ (rc->avg_frame_bandwidth * rc->baseline_gf_interval * 100) / |
+ (rc->baseline_gf_interval * 100 + af_ratio_pct - 100); |
+ } else { |
+ target = rc->avg_frame_bandwidth; |
+ } |
if (svc->number_temporal_layers > 1 && |
oxcf->rc_mode == VPX_CBR) { |
// Note that for layers, avg_frame_bandwidth is the cumulative |
@@ -1347,6 +1394,11 @@ |
const int pct_high = (int)MIN(-diff / one_pct_bits, oxcf->over_shoot_pct); |
target += (target * pct_high) / 200; |
} |
+ if (oxcf->rc_max_inter_bitrate_pct) { |
+ const int max_rate = rc->avg_frame_bandwidth * |
+ oxcf->rc_max_inter_bitrate_pct / 100; |
+ target = MIN(target, max_rate); |
+ } |
return MAX(min_frame_target, target); |
} |
@@ -1436,15 +1488,25 @@ |
rc->frames_to_key = cpi->oxcf.key_freq; |
rc->kf_boost = DEFAULT_KF_BOOST; |
rc->source_alt_ref_active = 0; |
- target = calc_iframe_target_size_one_pass_cbr(cpi); |
} else { |
cm->frame_type = INTER_FRAME; |
+ } |
+ if (rc->frames_till_gf_update_due == 0) { |
+ rc->baseline_gf_interval = DEFAULT_GF_INTERVAL; |
+ rc->frames_till_gf_update_due = rc->baseline_gf_interval; |
+ // NOTE: frames_till_gf_update_due must be <= frames_to_key. |
+ if (rc->frames_till_gf_update_due > rc->frames_to_key) |
+ rc->frames_till_gf_update_due = rc->frames_to_key; |
+ cpi->refresh_golden_frame = 1; |
+ rc->gfu_boost = DEFAULT_GF_BOOST; |
+ } |
+ |
+ if (cm->frame_type == KEY_FRAME) |
+ target = calc_iframe_target_size_one_pass_cbr(cpi); |
+ else |
target = calc_pframe_target_size_one_pass_cbr(cpi); |
- } |
+ |
vp9_rc_set_frame_target(cpi, target); |
- // Don't use gf_update by default in CBR mode. |
- rc->frames_till_gf_update_due = INT_MAX; |
- rc->baseline_gf_interval = INT_MAX; |
} |
int vp9_compute_qdelta(const RATE_CONTROL *rc, double qstart, double qtarget, |
@@ -1537,3 +1599,43 @@ |
vp9_rc_set_gf_max_interval(cpi, rc); |
} |
+ |
+#define VBR_PCT_ADJUSTMENT_LIMIT 50 |
+// For VBR...adjustment to the frame target based on error from previous frames |
+static void vbr_rate_correction(VP9_COMP *cpi, |
+ int *this_frame_target, |
+ int64_t vbr_bits_off_target) { |
+ int max_delta; |
+ double position_factor = 1.0; |
+ |
+ // How far through the clip are we. |
+ // This number is used to damp the per frame rate correction. |
+ // Range 0 - 1.0 |
+ if (cpi->twopass.total_stats.count) { |
+ position_factor = sqrt((double)cpi->common.current_video_frame / |
+ cpi->twopass.total_stats.count); |
+ } |
+ max_delta = (int)(position_factor * |
+ ((*this_frame_target * VBR_PCT_ADJUSTMENT_LIMIT) / 100)); |
+ |
+ // vbr_bits_off_target > 0 means we have extra bits to spend |
+ if (vbr_bits_off_target > 0) { |
+ *this_frame_target += |
+ (vbr_bits_off_target > max_delta) ? max_delta |
+ : (int)vbr_bits_off_target; |
+ } else { |
+ *this_frame_target -= |
+ (vbr_bits_off_target < -max_delta) ? max_delta |
+ : (int)-vbr_bits_off_target; |
+ } |
+} |
+ |
+void vp9_set_target_rate(VP9_COMP *cpi) { |
+ RATE_CONTROL *const rc = &cpi->rc; |
+ int target_rate = rc->base_frame_target; |
+ |
+ // Correction to rate target based on prior over or under shoot. |
+ if (cpi->oxcf.rc_mode == VPX_VBR) |
+ vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target); |
+ vp9_rc_set_frame_target(cpi, target_rate); |
+} |