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.c112
1 files changed, 77 insertions, 35 deletions
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 04539c845..39fea09dd 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -215,7 +215,7 @@ int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) {
rc->av_per_frame_bandwidth >> 5);
if (target < min_frame_target)
target = min_frame_target;
- if (cpi->refresh_golden_frame && rc->source_alt_ref_active) {
+ if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
// If there is an active ARF at this location use the minimum
// bits on this frame even if it is a constructed arf.
// The active maximum quantizer insures that an appropriate
@@ -487,8 +487,7 @@ static int rc_pick_q_and_adjust_q_bounds_one_pass(const VP9_COMP *cpi,
double q_adj_factor = 1.0;
double q_val;
- // Baseline value derived from cpi->active_worst_quality and kf boost
- active_best_quality = get_active_quality(active_worst_quality,
+ active_best_quality = get_active_quality(rc->avg_frame_qindex[KEY_FRAME],
rc->kf_boost,
kf_low, kf_high,
kf_low_motion_minq,
@@ -521,7 +520,8 @@ static int rc_pick_q_and_adjust_q_bounds_one_pass(const VP9_COMP *cpi,
rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
q = rc->avg_frame_qindex[INTER_FRAME];
} else {
- q = active_worst_quality;
+ q = (oxcf->end_usage == USAGE_STREAM_FROM_SERVER) ?
+ active_worst_quality : rc->avg_frame_qindex[KEY_FRAME];
}
// For constrained quality dont allow Q less than the cq level
if (oxcf->end_usage == USAGE_CONSTRAINED_QUALITY) {
@@ -565,10 +565,24 @@ static int rc_pick_q_and_adjust_q_bounds_one_pass(const VP9_COMP *cpi,
active_best_quality = cpi->cq_target_quality;
} else {
// Use the lower of active_worst_quality and recent/average Q.
- if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality)
- active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]];
- else
- active_best_quality = inter_minq[active_worst_quality];
+ if (oxcf->end_usage == USAGE_STREAM_FROM_SERVER) {
+ if (cm->current_video_frame > 1) {
+ if (rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality)
+ active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]];
+ else
+ active_best_quality = inter_minq[active_worst_quality];
+ } else {
+ if (rc->avg_frame_qindex[KEY_FRAME] < active_worst_quality)
+ active_best_quality = inter_minq[rc->avg_frame_qindex[KEY_FRAME]];
+ else
+ active_best_quality = inter_minq[active_worst_quality];
+ }
+ } else {
+ if (cm->current_video_frame > 1)
+ active_best_quality = inter_minq[rc->avg_frame_qindex[INTER_FRAME]];
+ else
+ active_best_quality = inter_minq[rc->avg_frame_qindex[KEY_FRAME]];
+ }
// For the constrained quality mode we don't want
// q to fall below the cq level.
if ((oxcf->end_usage == USAGE_CONSTRAINED_QUALITY) &&
@@ -850,7 +864,7 @@ int vp9_rc_pick_q_and_adjust_q_bounds(const VP9_COMP *cpi,
// JBB : This is realtime mode. In real time mode the first frame
// should be larger. Q of 0 is disabled because we force tx size to be
// 16x16...
- if (cpi->sf.super_fast_rtc) {
+ if (cpi->sf.use_pick_mode) {
if (cpi->common.current_video_frame == 0)
q /= 3;
if (q == 0)
@@ -973,7 +987,8 @@ void vp9_rc_postencode_update(VP9_COMP *cpi, uint64_t bytes_used) {
rc->avg_frame_qindex[KEY_FRAME] = ROUND_POWER_OF_TWO(
3 * rc->avg_frame_qindex[KEY_FRAME] + cm->base_qindex, 2);
} else if (!rc->is_src_frame_alt_ref &&
- (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame) &&
+ !(cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER)) {
rc->last_q[2] = cm->base_qindex;
rc->avg_frame_qindex[2] = ROUND_POWER_OF_TWO(
3 * rc->avg_frame_qindex[2] + cm->base_qindex, 2);
@@ -1056,7 +1071,7 @@ static int test_for_kf_one_pass(VP9_COMP *cpi) {
#define USE_ALTREF_FOR_ONE_PASS 1
static int calc_pframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
- static const int af_ratio = 5;
+ static const int af_ratio = 10;
const RATE_CONTROL *rc = &cpi->rc;
int target;
#if USE_ALTREF_FOR_ONE_PASS
@@ -1073,12 +1088,42 @@ static int calc_pframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
}
static int calc_iframe_target_size_one_pass_vbr(const VP9_COMP *const cpi) {
- static const int kf_ratio = 12;
+ static const int kf_ratio = 25;
const RATE_CONTROL *rc = &cpi->rc;
int target = rc->av_per_frame_bandwidth * kf_ratio;
return vp9_rc_clamp_iframe_target_size(cpi, target);
}
+static int calc_active_worst_quality_one_pass_vbr(const VP9_COMP *cpi) {
+ int active_worst_quality;
+ if (cpi->common.frame_type == KEY_FRAME) {
+ if (cpi->common.current_video_frame == 0) {
+ active_worst_quality = cpi->rc.worst_quality;
+ } else {
+ // Choose active worst quality twice as large as the last q.
+ active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 2;
+ }
+ } else if (!cpi->rc.is_src_frame_alt_ref &&
+ (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
+ if (cpi->common.current_video_frame == 1) {
+ active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 5 / 4;
+ } else {
+ // Choose active worst quality twice as large as the last q.
+ active_worst_quality = cpi->rc.last_q[INTER_FRAME];
+ }
+ } else {
+ if (cpi->common.current_video_frame == 1) {
+ active_worst_quality = cpi->rc.last_q[KEY_FRAME] * 2;
+ } else {
+ // Choose active worst quality twice as large as the last q.
+ active_worst_quality = cpi->rc.last_q[INTER_FRAME] * 2;
+ }
+ }
+ if (active_worst_quality > cpi->rc.worst_quality)
+ active_worst_quality = cpi->rc.worst_quality;
+ return active_worst_quality;
+}
+
void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
@@ -1094,22 +1139,8 @@ void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) {
rc->frames_to_key = cpi->key_frame_frequency;
rc->kf_boost = DEFAULT_KF_BOOST;
rc->source_alt_ref_active = 0;
- if (cm->current_video_frame == 0) {
- rc->active_worst_quality = rc->worst_quality;
- } else {
- // Choose active worst quality twice as large as the last q.
- rc->active_worst_quality = MIN(rc->worst_quality,
- rc->last_q[KEY_FRAME] * 2);
- }
} else {
cm->frame_type = INTER_FRAME;
- if (cm->current_video_frame == 1) {
- rc->active_worst_quality = rc->worst_quality;
- } else {
- // Choose active worst quality twice as large as the last q.
- rc->active_worst_quality = MIN(rc->worst_quality,
- rc->last_q[INTER_FRAME] * 2);
- }
}
if (rc->frames_till_gf_update_due == 0) {
rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
@@ -1121,6 +1152,7 @@ void vp9_rc_get_one_pass_vbr_params(VP9_COMP *cpi) {
rc->source_alt_ref_pending = USE_ALTREF_FOR_ONE_PASS;
rc->gfu_boost = DEFAULT_GF_BOOST;
}
+ cpi->rc.active_worst_quality = calc_active_worst_quality_one_pass_vbr(cpi);
if (cm->frame_type == KEY_FRAME)
target = calc_iframe_target_size_one_pass_vbr(cpi);
else
@@ -1139,13 +1171,15 @@ static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) {
const RATE_CONTROL *rc = &cpi->rc;
int active_worst_quality = rc->active_worst_quality;
// Maximum limit for down adjustment, ~20%.
- int max_adjustment_down = active_worst_quality / 5;
// Buffer level below which we push active_worst to worst_quality.
int critical_level = oxcf->optimal_buffer_level >> 2;
int adjustment = 0;
int buff_lvl_step = 0;
+ if (cpi->common.frame_type == KEY_FRAME)
+ return rc->worst_quality;
if (rc->buffer_level > oxcf->optimal_buffer_level) {
// Adjust down.
+ int max_adjustment_down = active_worst_quality / 5;
if (max_adjustment_down) {
buff_lvl_step = (int)((oxcf->maximum_buffer_size -
oxcf->optimal_buffer_level) / max_adjustment_down);
@@ -1175,11 +1209,20 @@ static int calc_active_worst_quality_one_pass_cbr(const VP9_COMP *cpi) {
static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) {
const VP9_CONFIG *oxcf = &cpi->oxcf;
const RATE_CONTROL *rc = &cpi->rc;
- int target = rc->av_per_frame_bandwidth;
- const int min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
- FRAME_OVERHEAD_BITS);
const int64_t diff = oxcf->optimal_buffer_level - rc->buffer_level;
const int one_pct_bits = 1 + oxcf->optimal_buffer_level / 100;
+ int min_frame_target = MAX(rc->av_per_frame_bandwidth >> 4,
+ FRAME_OVERHEAD_BITS);
+ int target = rc->av_per_frame_bandwidth;
+ if (cpi->use_svc && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
+ // Note that for layers, av_per_frame_bandwidth is the cumulative
+ // per-frame-bandwidth. For the target size of this frame, use the
+ // layer average frame size (i.e., non-cumulative per-frame-bw).
+ int current_temporal_layer = cpi->svc.temporal_layer_id;
+ const LAYER_CONTEXT *lc = &cpi->svc.layer_context[current_temporal_layer];
+ target = lc->avg_frame_size;
+ min_frame_target = MAX(lc->avg_frame_size >> 4, FRAME_OVERHEAD_BITS);
+ }
if (diff > 0) {
// Lower the target bandwidth for this frame.
const int pct_low = MIN(diff / one_pct_bits, oxcf->under_shoot_pct);
@@ -1219,16 +1262,15 @@ void vp9_rc_get_svc_params(VP9_COMP *cpi) {
cpi->rc.source_alt_ref_active = 0;
if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
target = calc_iframe_target_size_one_pass_cbr(cpi);
- cpi->rc.active_worst_quality = cpi->rc.worst_quality;
}
} else {
cm->frame_type = INTER_FRAME;
if (cpi->pass == 0 && cpi->oxcf.end_usage == USAGE_STREAM_FROM_SERVER) {
target = calc_pframe_target_size_one_pass_cbr(cpi);
- cpi->rc.active_worst_quality =
- calc_active_worst_quality_one_pass_cbr(cpi);
}
}
+ cpi->rc.active_worst_quality =
+ calc_active_worst_quality_one_pass_cbr(cpi);
vp9_rc_set_frame_target(cpi, target);
cpi->rc.frames_till_gf_update_due = INT_MAX;
cpi->rc.baseline_gf_interval = INT_MAX;
@@ -1249,12 +1291,12 @@ void vp9_rc_get_one_pass_cbr_params(VP9_COMP *cpi) {
rc->kf_boost = DEFAULT_KF_BOOST;
rc->source_alt_ref_active = 0;
target = calc_iframe_target_size_one_pass_cbr(cpi);
- rc->active_worst_quality = rc->worst_quality;
} else {
cm->frame_type = INTER_FRAME;
target = calc_pframe_target_size_one_pass_cbr(cpi);
- rc->active_worst_quality = calc_active_worst_quality_one_pass_cbr(cpi);
}
+ cpi->rc.active_worst_quality =
+ calc_active_worst_quality_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;