| Index: source/libvpx/vp9/encoder/vp9_firstpass.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_firstpass.c (revision 292608)
|
| +++ source/libvpx/vp9/encoder/vp9_firstpass.c (working copy)
|
| @@ -38,14 +38,16 @@
|
| #define OUTPUT_FPF 0
|
| #define ARF_STATS_OUTPUT 0
|
|
|
| +#define BOOST_BREAKOUT 12.5
|
| #define BOOST_FACTOR 12.5
|
| -#define ERR_DIVISOR 100.0
|
| -#define FACTOR_PT_LOW 0.5
|
| -#define FACTOR_PT_HIGH 0.9
|
| +#define ERR_DIVISOR 128.0
|
| +#define FACTOR_PT_LOW 0.70
|
| +#define FACTOR_PT_HIGH 0.90
|
| #define FIRST_PASS_Q 10.0
|
| #define GF_MAX_BOOST 96.0
|
| #define INTRA_MODE_PENALTY 1024
|
| #define KF_MAX_BOOST 128.0
|
| +#define MIN_ARF_GF_BOOST 240
|
| #define MIN_DECAY_FACTOR 0.01
|
| #define MIN_GF_INTERVAL 4
|
| #define MIN_KF_BOOST 300
|
| @@ -64,13 +66,6 @@
|
| *b = temp;
|
| }
|
|
|
| -static int gfboost_qadjust(int qindex, vpx_bit_depth_t bit_depth) {
|
| - const double q = vp9_convert_qindex_to_q(qindex, bit_depth);
|
| - return (int)((0.00000828 * q * q * q) +
|
| - (-0.0055 * q * q) +
|
| - (1.32 * q) + 79.3);
|
| -}
|
| -
|
| // Resets the first pass file to the given position using a relative seek from
|
| // the current position.
|
| static void reset_fpf_position(TWO_PASS *p,
|
| @@ -281,6 +276,60 @@
|
| return sse;
|
| }
|
|
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| +static vp9_variance_fn_t highbd_get_block_variance_fn(BLOCK_SIZE bsize,
|
| + int bd) {
|
| + switch (bd) {
|
| + default:
|
| + switch (bsize) {
|
| + case BLOCK_8X8:
|
| + return vp9_highbd_mse8x8;
|
| + case BLOCK_16X8:
|
| + return vp9_highbd_mse16x8;
|
| + case BLOCK_8X16:
|
| + return vp9_highbd_mse8x16;
|
| + default:
|
| + return vp9_highbd_mse16x16;
|
| + }
|
| + break;
|
| + case 10:
|
| + switch (bsize) {
|
| + case BLOCK_8X8:
|
| + return vp9_highbd_10_mse8x8;
|
| + case BLOCK_16X8:
|
| + return vp9_highbd_10_mse16x8;
|
| + case BLOCK_8X16:
|
| + return vp9_highbd_10_mse8x16;
|
| + default:
|
| + return vp9_highbd_10_mse16x16;
|
| + }
|
| + break;
|
| + case 12:
|
| + switch (bsize) {
|
| + case BLOCK_8X8:
|
| + return vp9_highbd_12_mse8x8;
|
| + case BLOCK_16X8:
|
| + return vp9_highbd_12_mse16x8;
|
| + case BLOCK_8X16:
|
| + return vp9_highbd_12_mse8x16;
|
| + default:
|
| + return vp9_highbd_12_mse16x16;
|
| + }
|
| + break;
|
| + }
|
| +}
|
| +
|
| +static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize,
|
| + const struct buf_2d *src,
|
| + const struct buf_2d *ref,
|
| + int bd) {
|
| + unsigned int sse;
|
| + const vp9_variance_fn_t fn = highbd_get_block_variance_fn(bsize, bd);
|
| + fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
|
| + return sse;
|
| +}
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
| +
|
| // Refine the motion search range according to the frame dimension
|
| // for first pass test.
|
| static int get_search_range(const VP9_COMMON *cm) {
|
| @@ -311,6 +360,11 @@
|
|
|
| // Override the default variance function to use MSE.
|
| v_fn_ptr.vf = get_block_variance_fn(bsize);
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
| + v_fn_ptr.vf = highbd_get_block_variance_fn(bsize, xd->bd);
|
| + }
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
|
| // Center the initial step/diamond search on best mv.
|
| tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
|
| @@ -562,6 +616,24 @@
|
| (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
|
| vp9_encode_intra_block_plane(x, bsize, 0);
|
| this_error = vp9_get_mb_ss(x->plane[0].src_diff);
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + if (cm->use_highbitdepth) {
|
| + switch (cm->bit_depth) {
|
| + case VPX_BITS_8:
|
| + break;
|
| + case VPX_BITS_10:
|
| + this_error >>= 4;
|
| + break;
|
| + case VPX_BITS_12:
|
| + this_error >>= 8;
|
| + break;
|
| + default:
|
| + assert(0 && "cm->bit_depth should be VPX_BITS_8, "
|
| + "VPX_BITS_10 or VPX_BITS_12");
|
| + return;
|
| + }
|
| + }
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
|
| if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
|
| vp9_clear_system_state();
|
| @@ -601,8 +673,18 @@
|
| struct buf_2d unscaled_last_source_buf_2d;
|
|
|
| xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
|
| - motion_error = get_prediction_error(bsize, &x->plane[0].src,
|
| - &xd->plane[0].pre[0]);
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
| + motion_error = highbd_get_prediction_error(
|
| + bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd);
|
| + } else {
|
| + motion_error = get_prediction_error(
|
| + bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
|
| + }
|
| +#else
|
| + motion_error = get_prediction_error(
|
| + bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
|
| // Compute the motion error of the 0,0 motion using the last source
|
| // frame as the reference. Skip the further motion search on
|
| @@ -611,8 +693,18 @@
|
| cpi->unscaled_last_source->y_buffer + recon_yoffset;
|
| unscaled_last_source_buf_2d.stride =
|
| cpi->unscaled_last_source->y_stride;
|
| - raw_motion_error = get_prediction_error(bsize, &x->plane[0].src,
|
| - &unscaled_last_source_buf_2d);
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
| + raw_motion_error = highbd_get_prediction_error(
|
| + bsize, &x->plane[0].src, &unscaled_last_source_buf_2d, xd->bd);
|
| + } else {
|
| + raw_motion_error = get_prediction_error(
|
| + bsize, &x->plane[0].src, &unscaled_last_source_buf_2d);
|
| + }
|
| +#else
|
| + raw_motion_error = get_prediction_error(
|
| + bsize, &x->plane[0].src, &unscaled_last_source_buf_2d);
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
|
| // TODO(pengchong): Replace the hard-coded threshold
|
| if (raw_motion_error > 25 || lc != NULL) {
|
| @@ -648,8 +740,18 @@
|
| int gf_motion_error;
|
|
|
| xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
|
| - gf_motion_error = get_prediction_error(bsize, &x->plane[0].src,
|
| - &xd->plane[0].pre[0]);
|
| +#if CONFIG_VP9_HIGHBITDEPTH
|
| + if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
| + gf_motion_error = highbd_get_prediction_error(
|
| + bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd);
|
| + } else {
|
| + gf_motion_error = get_prediction_error(
|
| + bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
|
| + }
|
| +#else
|
| + gf_motion_error = get_prediction_error(
|
| + bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
|
| +#endif // CONFIG_VP9_HIGHBITDEPTH
|
|
|
| first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv,
|
| &gf_motion_error);
|
| @@ -949,7 +1051,7 @@
|
|
|
| // Adjustment based on actual quantizer to power term.
|
| const double power_term =
|
| - MIN(vp9_convert_qindex_to_q(q, bit_depth) * 0.0125 + pt_low, pt_high);
|
| + MIN(vp9_convert_qindex_to_q(q, bit_depth) * 0.01 + pt_low, pt_high);
|
|
|
| // Calculate correction factor.
|
| if (power_term < 1.0)
|
| @@ -958,6 +1060,11 @@
|
| return fclamp(pow(error_term, power_term), 0.05, 5.0);
|
| }
|
|
|
| +// Larger image formats are expected to be a little harder to code relatively
|
| +// given the same prediction error score. This in part at least relates to the
|
| +// increased size and hence coding cost of motion vectors.
|
| +#define EDIV_SIZE_FACTOR 800
|
| +
|
| static int get_twopass_worst_quality(const VP9_COMP *cpi,
|
| const FIRSTPASS_STATS *stats,
|
| int section_target_bandwidth) {
|
| @@ -971,8 +1078,10 @@
|
| const double section_err = stats->coded_error / stats->count;
|
| const double err_per_mb = section_err / num_mbs;
|
| const double speed_term = 1.0 + 0.04 * oxcf->speed;
|
| + const double ediv_size_correction = num_mbs / EDIV_SIZE_FACTOR;
|
| const int target_norm_bits_per_mb = ((uint64_t)section_target_bandwidth <<
|
| BPER_MB_NORMBITS) / num_mbs;
|
| +
|
| int q;
|
| int is_svc_upper_layer = 0;
|
| if (is_two_pass_svc(cpi) && cpi->svc.spatial_layer_id > 0)
|
| @@ -982,7 +1091,7 @@
|
| // content at the given rate.
|
| for (q = rc->best_quality; q < rc->worst_quality; ++q) {
|
| const double factor =
|
| - calc_correction_factor(err_per_mb, ERR_DIVISOR,
|
| + calc_correction_factor(err_per_mb, ERR_DIVISOR - ediv_size_correction,
|
| is_svc_upper_layer ? SVC_FACTOR_PT_LOW :
|
| FACTOR_PT_LOW, FACTOR_PT_HIGH, q,
|
| cpi->common.bit_depth);
|
| @@ -1065,6 +1174,8 @@
|
| // Reset the vbr bits off target counter
|
| cpi->rc.vbr_bits_off_target = 0;
|
|
|
| + cpi->rc.rate_error_estimate = 0;
|
| +
|
| // Static sequence monitor variables.
|
| twopass->kf_zeromotion_pct = 100;
|
| twopass->last_kfgroup_zeromotion_pct = 100;
|
| @@ -1199,11 +1310,15 @@
|
| double this_frame_mv_in_out,
|
| double max_boost) {
|
| double frame_boost;
|
| + const double lq =
|
| + vp9_convert_qindex_to_q(cpi->rc.avg_frame_qindex[INTER_FRAME],
|
| + cpi->common.bit_depth);
|
| + const double boost_correction = MIN((0.5 + (lq * 0.015)), 1.5);
|
|
|
| // Underlying boost factor is based on inter error ratio.
|
| frame_boost = (BASELINE_ERR_PER_MB * cpi->common.MBs) /
|
| DOUBLE_DIVIDE_CHECK(this_frame->coded_error);
|
| - frame_boost = frame_boost * BOOST_FACTOR;
|
| + frame_boost = frame_boost * BOOST_FACTOR * boost_correction;
|
|
|
| // Increase boost for frames where new data coming into frame (e.g. zoom out).
|
| // Slightly reduce boost if there is a net balance of motion out of the frame
|
| @@ -1214,7 +1329,7 @@
|
| else
|
| frame_boost += frame_boost * (this_frame_mv_in_out / 2.0);
|
|
|
| - return MIN(frame_boost, max_boost);
|
| + return MIN(frame_boost, max_boost * boost_correction);
|
| }
|
|
|
| static int calc_arf_boost(VP9_COMP *cpi, int offset,
|
| @@ -1303,6 +1418,7 @@
|
| arf_boost = (*f_boost + *b_boost);
|
| if (arf_boost < ((b_frames + f_frames) * 20))
|
| arf_boost = ((b_frames + f_frames) * 20);
|
| + arf_boost = MAX(arf_boost, MIN_ARF_GF_BOOST);
|
|
|
| return arf_boost;
|
| }
|
| @@ -1580,6 +1696,7 @@
|
| int b_boost = 0;
|
| int flash_detected;
|
| int active_max_gf_interval;
|
| + int active_min_gf_interval;
|
| int64_t gf_group_bits;
|
| double gf_group_error_left;
|
| int gf_arf_bits;
|
| @@ -1608,21 +1725,30 @@
|
| // Motion breakout threshold for loop below depends on image size.
|
| mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 4.0;
|
|
|
| - // Work out a maximum interval for the GF group.
|
| + // Set a maximum and minimum interval for the GF group.
|
| // If the image appears almost completely static we can extend beyond this.
|
| - if (cpi->multi_arf_allowed) {
|
| - active_max_gf_interval = rc->max_gf_interval;
|
| - } else {
|
| - // The value chosen depends on the active Q range. At low Q we have
|
| - // bits to spare and are better with a smaller interval and smaller boost.
|
| - // At high Q when there are few bits to spare we are better with a longer
|
| - // interval to spread the cost of the GF.
|
| - active_max_gf_interval =
|
| - 12 + ((int)vp9_convert_qindex_to_q(rc->last_q[INTER_FRAME],
|
| - cpi->common.bit_depth) >> 5);
|
| + {
|
| + int int_max_q =
|
| + (int)(vp9_convert_qindex_to_q(twopass->active_worst_quality,
|
| + cpi->common.bit_depth));
|
| + int int_lbq =
|
| + (int)(vp9_convert_qindex_to_q(rc->last_boosted_qindex,
|
| + cpi->common.bit_depth));
|
| + active_min_gf_interval = MIN_GF_INTERVAL + MIN(2, int_max_q / 200);
|
| + if (active_min_gf_interval > rc->max_gf_interval)
|
| + active_min_gf_interval = rc->max_gf_interval;
|
|
|
| - if (active_max_gf_interval > rc->max_gf_interval)
|
| - active_max_gf_interval = rc->max_gf_interval;
|
| + if (cpi->multi_arf_allowed) {
|
| + active_max_gf_interval = rc->max_gf_interval;
|
| + } else {
|
| + // The value chosen depends on the active Q range. At low Q we have
|
| + // bits to spare and are better with a smaller interval and smaller boost.
|
| + // At high Q when there are few bits to spare we are better with a longer
|
| + // interval to spread the cost of the GF.
|
| + active_max_gf_interval = 12 + MIN(4, (int_lbq / 6));
|
| + if (active_max_gf_interval > rc->max_gf_interval)
|
| + active_max_gf_interval = rc->max_gf_interval;
|
| + }
|
| }
|
|
|
| i = 0;
|
| @@ -1678,12 +1804,12 @@
|
| (i >= active_max_gf_interval && (zero_motion_accumulator < 0.995)) ||
|
| (
|
| // Don't break out with a very short interval.
|
| - (i > MIN_GF_INTERVAL) &&
|
| + (i > active_min_gf_interval) &&
|
| (!flash_detected) &&
|
| ((mv_ratio_accumulator > mv_ratio_accumulator_thresh) ||
|
| (abs_mv_in_out_accumulator > 3.0) ||
|
| (mv_in_out_accumulator < -2.0) ||
|
| - ((boost_score - old_boost_score) < BOOST_FACTOR)))) {
|
| + ((boost_score - old_boost_score) < BOOST_BREAKOUT)))) {
|
| boost_score = old_boost_score;
|
| break;
|
| }
|
| @@ -1731,7 +1857,7 @@
|
| (cpi->multi_arf_allowed && (rc->baseline_gf_interval >= 6) &&
|
| (zero_motion_accumulator < 0.995)) ? 1 : 0;
|
| } else {
|
| - rc->gfu_boost = MAX((int)boost_score, 125);
|
| + rc->gfu_boost = MAX((int)boost_score, MIN_ARF_GF_BOOST);
|
| rc->source_alt_ref_pending = 0;
|
| }
|
|
|
| @@ -1742,19 +1868,9 @@
|
| gf_group_bits = calculate_total_gf_group_bits(cpi, gf_group_err);
|
|
|
| // Calculate the extra bits to be used for boosted frame(s)
|
| - {
|
| - int q = rc->last_q[INTER_FRAME];
|
| - int boost =
|
| - (rc->gfu_boost * gfboost_qadjust(q, cpi->common.bit_depth)) / 100;
|
| + gf_arf_bits = calculate_boost_bits(rc->baseline_gf_interval,
|
| + rc->gfu_boost, gf_group_bits);
|
|
|
| - // Set max and minimum boost and hence minimum allocation.
|
| - boost = clamp(boost, 125, (rc->baseline_gf_interval + 1) * 200);
|
| -
|
| - // Calculate the extra bits to be used for boosted frame(s)
|
| - gf_arf_bits = calculate_boost_bits(rc->baseline_gf_interval,
|
| - boost, gf_group_bits);
|
| - }
|
| -
|
| // Adjust KF group bits and error remaining.
|
| twopass->kf_group_error_left -= (int64_t)gf_group_err;
|
|
|
| @@ -2101,11 +2217,24 @@
|
| twopass->modified_error_left -= kf_group_err;
|
| }
|
|
|
| +#define VBR_PCT_ADJUSTMENT_LIMIT 50
|
| // For VBR...adjustment to the frame target based on error from previous frames
|
| -void vbr_rate_correction(int * this_frame_target,
|
| +void vbr_rate_correction(VP9_COMP *cpi,
|
| + int * this_frame_target,
|
| const int64_t vbr_bits_off_target) {
|
| - int max_delta = (*this_frame_target * 15) / 100;
|
| + 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 +=
|
| @@ -2202,7 +2331,7 @@
|
|
|
| // Correction to rate target based on prior over or under shoot.
|
| if (cpi->oxcf.rc_mode == VPX_VBR)
|
| - vbr_rate_correction(&target_rate, rc->vbr_bits_off_target);
|
| + vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target);
|
|
|
| vp9_rc_set_frame_target(cpi, target_rate);
|
| cm->frame_type = INTER_FRAME;
|
| @@ -2234,7 +2363,11 @@
|
| section_target_bandwidth);
|
| twopass->active_worst_quality = tmp_q;
|
| rc->ni_av_qi = tmp_q;
|
| + rc->last_q[INTER_FRAME] = tmp_q;
|
| rc->avg_q = vp9_convert_qindex_to_q(tmp_q, cm->bit_depth);
|
| + rc->avg_frame_qindex[INTER_FRAME] = tmp_q;
|
| + rc->last_q[KEY_FRAME] = (tmp_q + cpi->oxcf.best_allowed_q) / 2;
|
| + rc->avg_frame_qindex[KEY_FRAME] = rc->last_q[KEY_FRAME];
|
| }
|
| vp9_zero(this_frame);
|
| if (EOF == input_stats(twopass, &this_frame))
|
| @@ -2259,6 +2392,9 @@
|
| cpi->ref_frame_flags &=
|
| (~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG);
|
| lc->frames_from_key_frame = 0;
|
| + // Reset the empty frame resolution since we have a key frame.
|
| + cpi->svc.empty_frame_width = cm->width;
|
| + cpi->svc.empty_frame_height = cm->height;
|
| }
|
| } else {
|
| cm->frame_type = INTER_FRAME;
|
| @@ -2275,16 +2411,6 @@
|
| if (rc->frames_till_gf_update_due == 0) {
|
| define_gf_group(cpi, &this_frame_copy);
|
|
|
| - if (twopass->gf_zeromotion_pct > 995) {
|
| - // As long as max_thresh for encode breakout is small enough, it is ok
|
| - // to enable it for show frame, i.e. set allow_encode_breakout to
|
| - // ENCODE_BREAKOUT_LIMITED.
|
| - if (!cm->show_frame)
|
| - cpi->allow_encode_breakout = ENCODE_BREAKOUT_DISABLED;
|
| - else
|
| - cpi->allow_encode_breakout = ENCODE_BREAKOUT_LIMITED;
|
| - }
|
| -
|
| rc->frames_till_gf_update_due = rc->baseline_gf_interval;
|
| if (lc != NULL)
|
| cpi->refresh_golden_frame = 1;
|
| @@ -2294,8 +2420,9 @@
|
| FILE *fpfile;
|
| fpfile = fopen("arf.stt", "a");
|
| ++arf_count;
|
| - fprintf(fpfile, "%10d %10d %10d %10ld\n",
|
| - cm->current_video_frame, rc->kf_boost, arf_count, rc->gfu_boost);
|
| + fprintf(fpfile, "%10d %10ld %10d %10d %10ld\n",
|
| + cm->current_video_frame, rc->frames_till_gf_update_due,
|
| + rc->kf_boost, arf_count, rc->gfu_boost);
|
|
|
| fclose(fpfile);
|
| }
|
| @@ -2314,7 +2441,7 @@
|
|
|
| // Correction to rate target based on prior over or under shoot.
|
| if (cpi->oxcf.rc_mode == VPX_VBR)
|
| - vbr_rate_correction(&target_rate, rc->vbr_bits_off_target);
|
| + vbr_rate_correction(cpi, &target_rate, rc->vbr_bits_off_target);
|
|
|
| vp9_rc_set_frame_target(cpi, target_rate);
|
|
|
| @@ -2322,9 +2449,12 @@
|
| subtract_stats(&twopass->total_left_stats, &this_frame);
|
| }
|
|
|
| +#define MINQ_ADJ_LIMIT 32
|
| +#define Q_LIMIT_STEP 1
|
| void vp9_twopass_postencode_update(VP9_COMP *cpi) {
|
| TWO_PASS *const twopass = &cpi->twopass;
|
| RATE_CONTROL *const rc = &cpi->rc;
|
| + const int bits_used = rc->base_frame_target;
|
|
|
| // VBR correction is done through rc->vbr_bits_off_target. Based on the
|
| // sign of this value, a limited % adjustment is made to the target rate
|
| @@ -2331,11 +2461,18 @@
|
| // of subsequent frames, to try and push it back towards 0. This method
|
| // is designed to prevent extreme behaviour at the end of a clip
|
| // or group of frames.
|
| - const int bits_used = rc->base_frame_target;
|
| rc->vbr_bits_off_target += rc->base_frame_target - rc->projected_frame_size;
|
| -
|
| twopass->bits_left = MAX(twopass->bits_left - bits_used, 0);
|
|
|
| + // Calculate the pct rc error.
|
| + if (rc->total_actual_bits) {
|
| + rc->rate_error_estimate =
|
| + (int)((rc->vbr_bits_off_target * 100) / rc->total_actual_bits);
|
| + rc->rate_error_estimate = clamp(rc->rate_error_estimate, -100, 100);
|
| + } else {
|
| + rc->rate_error_estimate = 0;
|
| + }
|
| +
|
| if (cpi->common.frame_type != KEY_FRAME &&
|
| !vp9_is_upper_layer_key_frame(cpi)) {
|
| twopass->kf_group_bits -= bits_used;
|
| @@ -2345,4 +2482,32 @@
|
|
|
| // Increment the gf group index ready for the next frame.
|
| ++twopass->gf_group.index;
|
| +
|
| + // If the rate control is drifting consider adjustment ot min or maxq.
|
| + // Only make adjustments on gf/arf
|
| + if ((cpi->oxcf.rc_mode == VPX_VBR) &&
|
| + (cpi->twopass.gf_zeromotion_pct < VLOW_MOTION_THRESHOLD) &&
|
| + !cpi->rc.is_src_frame_alt_ref) {
|
| + const int maxq_adj_limit =
|
| + rc->worst_quality - twopass->active_worst_quality;
|
| +
|
| + // Undershoot.
|
| + if (rc->rate_error_estimate > cpi->oxcf.under_shoot_pct) {
|
| + --twopass->extend_maxq;
|
| + if (rc->rolling_target_bits >= rc->rolling_actual_bits)
|
| + twopass->extend_minq += Q_LIMIT_STEP;
|
| + // Overshoot.
|
| + } else if (rc->rate_error_estimate < -cpi->oxcf.over_shoot_pct) {
|
| + --twopass->extend_minq;
|
| + if (rc->rolling_target_bits < rc->rolling_actual_bits)
|
| + twopass->extend_maxq += Q_LIMIT_STEP;
|
| + } else {
|
| + if (rc->rolling_target_bits < rc->rolling_actual_bits)
|
| + --twopass->extend_minq;
|
| + if (rc->rolling_target_bits > rc->rolling_actual_bits)
|
| + --twopass->extend_maxq;
|
| + }
|
| + twopass->extend_minq = clamp(twopass->extend_minq, 0, MINQ_ADJ_LIMIT);
|
| + twopass->extend_maxq = clamp(twopass->extend_maxq, 0, maxq_adj_limit);
|
| + }
|
| }
|
|
|