Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Unified Diff: source/libvpx/vp9/encoder/vp9_ratectrl.c

Issue 756673003: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_ratectrl.h ('k') | source/libvpx/vp9/encoder/vp9_rd.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
+}
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_ratectrl.h ('k') | source/libvpx/vp9/encoder/vp9_rd.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698