Alter clamping of max_delta_up in adjust_q_cbr()
Link the maximum upwards adjustment of Q to the max
downwards value.
Rate overshoot a bit higher at lower rates but undershoot less
at slightly higher rates.
Good improvements for screen content set in metrics.
(Bdrate %:- Overall PSNR, SSIM against head on 9th March).
Speed 8: -2.982, -2.922
Speed 10: -2.288, -2.551
STATS_CHANGED
Change-Id: I1338cfed4c7bca72ee50516fa8fd0ea9708fcf57
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 0c1e81c..2534199 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -482,7 +482,7 @@
const AV1_COMMON *const cm = &cpi->common;
const RefreshFrameInfo *const refresh_frame = &cpi->refresh_frame;
int max_delta_down;
- const int max_delta_up = 20;
+ int max_delta_up = 20;
const int change_avg_frame_bandwidth =
abs(rc->avg_frame_bandwidth - rc->prev_avg_frame_bandwidth) >
0.1 * (rc->avg_frame_bandwidth);
@@ -490,12 +490,20 @@
// Set the maximum adjustment down for Q for this frame.
if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ &&
cpi->cyclic_refresh->apply_cyclic_refresh) {
- max_delta_down = AOMMIN(16, AOMMAX(1, rc->q_1_frame / 8));
// For static screen type content limit the Q drop till the start of the
// next refresh cycle.
- if (cpi->is_screen_content_type) {
- if (cpi->cyclic_refresh->sb_index > cpi->cyclic_refresh->last_sb_index) {
- max_delta_down = AOMMIN(8, AOMMAX(1, rc->q_1_frame / 32));
+ if (cpi->is_screen_content_type &&
+ (cpi->cyclic_refresh->sb_index > cpi->cyclic_refresh->last_sb_index)) {
+ max_delta_down = AOMMIN(8, AOMMAX(1, rc->q_1_frame / 32));
+ } else {
+ max_delta_down = AOMMIN(16, AOMMAX(1, rc->q_1_frame / 8));
+ }
+ if (!cpi->ppi->use_svc && cpi->is_screen_content_type) {
+ // Link max_delta_up linked to max_delta_down and buffer status.
+ if (p_rc->buffer_level > p_rc->optimal_buffer_level) {
+ max_delta_up = AOMMAX(4, max_delta_down);
+ } else {
+ max_delta_up = AOMMAX(8, max_delta_down);
}
}
} else {
@@ -515,7 +523,8 @@
!change_target_bits_mb && !cpi->rc.rtc_external_ratectrl &&
(!cpi->oxcf.rc_cfg.gf_cbr_boost_pct ||
!(refresh_frame->alt_ref_frame || refresh_frame->golden_frame))) {
- // Make sure q is between oscillating Qs to prevent resonance.
+ // If in the previous two frames we have seen both overshoot and undershoot
+ // clamp Q between the two.
if (rc->rc_1_frame * rc->rc_2_frame == -1 &&
rc->q_1_frame != rc->q_2_frame) {
int qclamp = clamp(q, AOMMIN(rc->q_1_frame, rc->q_2_frame),
@@ -555,8 +564,7 @@
// Limit the decrease in Q from previous frame.
if (rc->q_1_frame - q > max_delta_down) q = rc->q_1_frame - max_delta_down;
// Limit the increase in Q from previous frame.
- else if (q - rc->q_1_frame > max_delta_up &&
- cpi->oxcf.tune_cfg.content != AOM_CONTENT_SCREEN)
+ else if (q - rc->q_1_frame > max_delta_up)
q = rc->q_1_frame + max_delta_up;
}
// For non-svc (single layer): if resolution has increased push q closer