ref: 3be14200fcad97e6fda143d11bd300bb3e3a63d8
parent: c22b17dcefe05981918e4b7d0b6527c27e9ceda8
parent: 5b44ef0c501a8756fe53de2deb07647239aefe69
author: Paul Wilkins <paulwilkins@google.com>
date: Tue Aug 1 04:58:36 EDT 2017
Merge "Respond more rapidly to excessive local overshoot."
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2676,13 +2676,35 @@
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
static int two_pass_first_group_inter(VP9_COMP *cpi) {
TWO_PASS *const twopass = &cpi->twopass;
@@ -2705,8 +2727,7 @@
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,9 +2737,13 @@
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) ||
(rc->projected_frame_size < low_limit && q > minq)) {
@@ -3780,11 +3805,16 @@
// 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 @@
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,7 +3850,6 @@
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);
@@ -3828,8 +3856,8 @@
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 @@
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;
}
@@ -3880,6 +3907,14 @@
if (two_pass_first_group_inter(cpi)) {
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