Further one-pass vbr rate control changes

Some parameter changes and fixes on one-pass rate control.
derfraw300 is now only 10% below 2-pass speed 0 rate control.

Change-Id: I1940eef8a5a035dc18e71b880d5e00cabd1f01b9
This commit is contained in:
Deb Mukherjee 2014-02-07 15:52:41 -08:00
Родитель ae8bc7a8e1
Коммит 15fb5510a8
5 изменённых файлов: 100 добавлений и 66 удалений

Просмотреть файл

@ -902,8 +902,8 @@ static double calc_correction_factor(double err_per_mb,
return fclamp(pow(error_term, power_term), 0.05, 5.0);
}
static int estimate_max_q(VP9_COMP *cpi, FIRSTPASS_STATS *fpstats,
int section_target_bandwitdh) {
int vp9_twopass_worst_quality(VP9_COMP *cpi, FIRSTPASS_STATS *fpstats,
int section_target_bandwitdh) {
int q;
const int num_mbs = cpi->common.MBs;
int target_norm_bits_per_mb;
@ -2280,8 +2280,8 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
// Special case code for first frame.
const int section_target_bandwidth = (int)(twopass->bits_left /
frames_left);
const int tmp_q = estimate_max_q(cpi, &twopass->total_left_stats,
section_target_bandwidth);
const int tmp_q = vp9_twopass_worst_quality(cpi, &twopass->total_left_stats,
section_target_bandwidth);
rc->active_worst_quality = tmp_q;
rc->ni_av_qi = tmp_q;

Просмотреть файл

@ -88,6 +88,8 @@ void vp9_end_first_pass(struct VP9_COMP *cpi);
void vp9_init_second_pass(struct VP9_COMP *cpi);
void vp9_rc_get_second_pass_params(struct VP9_COMP *cpi);
void vp9_end_second_pass(struct VP9_COMP *cpi);
int vp9_twopass_worst_quality(struct VP9_COMP *cpi, FIRSTPASS_STATS *fpstats,
int section_target_bandwitdh);
// Post encode update of the rate control parameters for 2-pass
void vp9_twopass_postencode_update(struct VP9_COMP *cpi,

Просмотреть файл

@ -2776,10 +2776,10 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
static void encode_without_recode_loop(VP9_COMP *cpi,
size_t *size,
uint8_t *dest,
int *q) {
int q) {
VP9_COMMON *const cm = &cpi->common;
vp9_clear_system_state(); // __asm emms;
vp9_set_quantizer(cpi, *q);
vp9_set_quantizer(cpi, q);
// Set up entropy context depending on frame type. The decoder mandates
// the use of the default context, index 0, for keyframes and inter
@ -2813,7 +2813,7 @@ static void encode_without_recode_loop(VP9_COMP *cpi,
static void encode_with_recode_loop(VP9_COMP *cpi,
size_t *size,
uint8_t *dest,
int *q,
int q,
int bottom_index,
int top_index) {
VP9_COMMON *const cm = &cpi->common;
@ -2833,7 +2833,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
do {
vp9_clear_system_state(); // __asm emms;
vp9_set_quantizer(cpi, *q);
vp9_set_quantizer(cpi, q);
if (loop_count == 0) {
// Set up entropy context depending on frame type. The decoder mandates
@ -2890,7 +2890,7 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
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 last_q = q;
int kf_err = vp9_calc_ss_err(cpi->Source, get_frame_new_buffer(cm));
int high_err_target = cpi->ambient_err;
@ -2906,32 +2906,32 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
(kf_err > low_err_target &&
cpi->rc.projected_frame_size <= frame_under_shoot_limit)) {
// Lower q_high
q_high = *q > q_low ? *q - 1 : q_low;
q_high = q > q_low ? q - 1 : q_low;
// Adjust Q
*q = ((*q) * high_err_target) / kf_err;
*q = MIN((*q), (q_high + q_low) >> 1);
q = (q * high_err_target) / kf_err;
q = MIN(q, (q_high + q_low) >> 1);
} else if (kf_err < low_err_target &&
cpi->rc.projected_frame_size >= frame_under_shoot_limit) {
// The key frame is much better than the previous frame
// Raise q_low
q_low = *q < q_high ? *q + 1 : q_high;
q_low = q < q_high ? q + 1 : q_high;
// Adjust Q
*q = ((*q) * low_err_target) / kf_err;
*q = MIN((*q), (q_high + q_low + 1) >> 1);
q = (q * low_err_target) / kf_err;
q = MIN(q, (q_high + q_low + 1) >> 1);
}
// Clamp Q to upper and lower limits:
*q = clamp(*q, q_low, q_high);
q = clamp(q, q_low, q_high);
loop = *q != last_q;
loop = q != last_q;
} else if (recode_loop_test(
cpi, frame_over_shoot_limit, frame_under_shoot_limit,
*q, MAX(q_high, 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;
int last_q = q;
int retries = 0;
// Frame size out of permitted range:
@ -2944,23 +2944,23 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
q_high = cpi->rc.worst_quality;
// Raise Qlow as to at least the current value
q_low = *q < q_high ? *q + 1 : q_high;
q_low = q < q_high ? q + 1 : q_high;
if (undershoot_seen || loop_count > 1) {
// Update rate_correction_factor unless
vp9_rc_update_rate_correction_factors(cpi, 1);
*q = (q_high + q_low + 1) / 2;
q = (q_high + q_low + 1) / 2;
} else {
// Update rate_correction_factor unless
vp9_rc_update_rate_correction_factors(cpi, 0);
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
bottom_index, MAX(q_high, top_index));
while (*q < q_low && retries < 10) {
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,
q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
bottom_index, MAX(q_high, top_index));
retries++;
}
@ -2969,27 +2969,27 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
overshoot_seen = 1;
} else {
// Frame is too small
q_high = *q > q_low ? *q - 1 : q_low;
q_high = q > q_low ? q - 1 : q_low;
if (overshoot_seen || loop_count > 1) {
vp9_rc_update_rate_correction_factors(cpi, 1);
*q = (q_high + q_low) / 2;
q = (q_high + q_low) / 2;
} else {
vp9_rc_update_rate_correction_factors(cpi, 0);
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
bottom_index, top_index);
// Special case reset for qlow for constrained quality.
// This should only trigger where there is very substantial
// undershoot on a frame and the auto cq level is above
// the user passsed in value.
if (cpi->oxcf.end_usage == USAGE_CONSTRAINED_QUALITY &&
*q < q_low) {
q_low = *q;
q < q_low) {
q_low = q;
}
while (*q > q_high && retries < 10) {
while (q > q_high && retries < 10) {
vp9_rc_update_rate_correction_factors(cpi, 0);
*q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
q = vp9_rc_regulate_q(cpi, cpi->rc.this_frame_target,
bottom_index, top_index);
retries++;
}
@ -2999,9 +2999,9 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
}
// Clamp Q to upper and lower limits:
*q = clamp(*q, q_low, q_high);
q = clamp(q, q_low, q_high);
loop = *q != last_q;
loop = q != last_q;
} else {
loop = 0;
}
@ -3219,9 +3219,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
encode_without_recode_loop(cpi, size, dest, &q);
encode_without_recode_loop(cpi, size, dest, q);
} else {
encode_with_recode_loop(cpi, size, dest, &q, bottom_index, top_index);
encode_with_recode_loop(cpi, size, dest, q, bottom_index, top_index);
}
// Special case code to reduce pulsing when key frames are forced at a

Просмотреть файл

@ -45,7 +45,7 @@ extern "C" {
#else
#define MIN_GF_INTERVAL 4
#endif
#define DEFAULT_GF_INTERVAL 11
#define DEFAULT_GF_INTERVAL 10
#define DEFAULT_KF_BOOST 2000
#define DEFAULT_GF_BOOST 2000

Просмотреть файл

@ -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) &&
@ -1057,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
@ -1074,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;
@ -1095,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;
@ -1122,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
@ -1140,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);
@ -1229,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;
@ -1259,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;