diff options
author | Paul Wilkins <paulwilkins@google.com> | 2017-08-01 08:58:36 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2017-08-01 08:58:36 +0000 |
commit | 3be14200fcad97e6fda143d11bd300bb3e3a63d8 (patch) | |
tree | 131c8273d0d873f36f37796ff48d11a993695701 /vp9/encoder/vp9_encoder.c | |
parent | c22b17dcefe05981918e4b7d0b6527c27e9ceda8 (diff) | |
parent | 5b44ef0c501a8756fe53de2deb07647239aefe69 (diff) | |
download | libvpx-3be14200fcad97e6fda143d11bd300bb3e3a63d8.tar libvpx-3be14200fcad97e6fda143d11bd300bb3e3a63d8.tar.gz libvpx-3be14200fcad97e6fda143d11bd300bb3e3a63d8.tar.bz2 libvpx-3be14200fcad97e6fda143d11bd300bb3e3a63d8.zip |
Merge "Respond more rapidly to excessive local overshoot."
Diffstat (limited to 'vp9/encoder/vp9_encoder.c')
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index db651290d..c6e34117e 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -2676,11 +2676,33 @@ static int scale_down(VP9_COMP *cpi, int q) { return scale; } -static int big_rate_miss(VP9_COMP *cpi, int high_limit, int low_limit) { +static int big_rate_miss_high_threshold(VP9_COMP *cpi) { const RATE_CONTROL *const rc = &cpi->rc; + int big_miss_high; - return (rc->projected_frame_size > ((high_limit * 3) / 2)) || - (rc->projected_frame_size < (low_limit / 2)); + if (frame_is_kf_gf_arf(cpi)) + big_miss_high = rc->this_frame_target * 3 / 2; + else + big_miss_high = rc->this_frame_target * 2; + + return big_miss_high; +} + +static int big_rate_miss(VP9_COMP *cpi) { + const RATE_CONTROL *const rc = &cpi->rc; + int big_miss_high; + int big_miss_low; + + // Ignore for overlay frames + if (rc->is_src_frame_alt_ref) { + return 0; + } else { + big_miss_low = (rc->this_frame_target / 2); + big_miss_high = big_rate_miss_high_threshold(cpi); + + return (rc->projected_frame_size > big_miss_high) || + (rc->projected_frame_size < big_miss_low); + } } // test in two pass for the first @@ -2705,8 +2727,7 @@ static int recode_loop_test(VP9_COMP *cpi, int high_limit, int low_limit, int q, int force_recode = 0; if ((rc->projected_frame_size >= rc->max_frame_bandwidth) || - big_rate_miss(cpi, high_limit, low_limit) || - (cpi->sf.recode_loop == ALLOW_RECODE) || + big_rate_miss(cpi) || (cpi->sf.recode_loop == ALLOW_RECODE) || (two_pass_first_group_inter(cpi) && (cpi->sf.recode_loop == ALLOW_RECODE_FIRST)) || (frame_is_kfgfarf && (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF))) { @@ -2716,8 +2737,12 @@ static int recode_loop_test(VP9_COMP *cpi, int high_limit, int low_limit, int q, cpi->resize_pending = 1; return 1; } - // Force recode if projected_frame_size > max_frame_bandwidth - if (rc->projected_frame_size >= rc->max_frame_bandwidth) return 1; + + // Force recode for extreme overshoot. + if ((rc->projected_frame_size >= rc->max_frame_bandwidth) || + (rc->projected_frame_size >= big_rate_miss_high_threshold(cpi))) { + return 1; + } // TODO(agrange) high_limit could be greater than the scale-down threshold. if ((rc->projected_frame_size > high_limit && q < maxq) || @@ -3780,11 +3805,16 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, // Frame is too large if (rc->projected_frame_size > rc->this_frame_target) { // Special case if the projected size is > the max allowed. - if (rc->projected_frame_size >= rc->max_frame_bandwidth) { + if ((q == q_high) && + ((rc->projected_frame_size >= rc->max_frame_bandwidth) || + (rc->projected_frame_size >= + big_rate_miss_high_threshold(cpi)))) { + int max_rate = VPXMAX(1, VPXMIN(rc->max_frame_bandwidth, + big_rate_miss_high_threshold(cpi))); double q_val_high; q_val_high = vp9_convert_qindex_to_q(q_high, cm->bit_depth); - q_val_high = q_val_high * ((double)rc->projected_frame_size / - rc->max_frame_bandwidth); + q_val_high = + q_val_high * ((double)rc->projected_frame_size / max_rate); q_high = vp9_convert_q_to_qindex(q_val_high, cm->bit_depth); q_high = clamp(q_high, rc->best_quality, rc->worst_quality); } @@ -3793,7 +3823,6 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, qstep = get_qstep_adj(rc->projected_frame_size, rc->this_frame_target); q_low = VPXMIN(q + qstep, q_high); - // q_low = q < q_high ? q + 1 : q_high; if (undershoot_seen || loop_at_this_size > 1) { // Update rate_correction_factor unless @@ -3821,15 +3850,14 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, qstep = get_qstep_adj(rc->this_frame_target, rc->projected_frame_size); q_high = VPXMAX(q - qstep, q_low); - // q_high = q > q_low ? q - 1 : q_low; if (overshoot_seen || loop_at_this_size > 1) { vp9_rc_update_rate_correction_factors(cpi); q = (q_high + q_low) / 2; } else { vp9_rc_update_rate_correction_factors(cpi); - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, bottom_index, - top_index); + q = vp9_rc_regulate_q(cpi, rc->this_frame_target, + VPXMIN(q_low, 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 @@ -3840,12 +3868,11 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, while (q > q_high && retries < 10) { vp9_rc_update_rate_correction_factors(cpi); - q = vp9_rc_regulate_q(cpi, rc->this_frame_target, bottom_index, - top_index); + q = vp9_rc_regulate_q(cpi, rc->this_frame_target, + VPXMIN(q_low, bottom_index), top_index); retries++; } } - undershoot_seen = 1; } @@ -3881,6 +3908,14 @@ static void encode_with_recode_loop(VP9_COMP *cpi, size_t *size, cpi->twopass.active_worst_quality = VPXMIN(q + qrange_adj, cpi->oxcf.worst_allowed_q); } +#else + if (!frame_is_kf_gf_arf(cpi)) { + // Have we been forced to adapt Q outside the expected range by an extreme + // rate miss. If so adjust the active maxQ for the subsequent frames. + if (q > cpi->twopass.active_worst_quality) { + cpi->twopass.active_worst_quality = q; + } + } #endif if (enable_acl) { |