| 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);
|
| +}
|
|
|