rtc: Fixes to rate control for CBR mode

For 1 pass CBR mode: constrain the active_best for
gf/arf refresh frames on the gf_cbr_boost_pct flag,
as this logic was intended only for boosted gf/arf
frames. Also move the QP adjustmemnt to separate
function and fix the conditions for the
adjustment/clamping.

Neutral/negligible change in bdrate for speed >= 6 rtc.

Change helps to reduce excessive overshoot in some cases.

Change-Id: I981c452752c7bde61a25c24dfa52d4cfaae48ed1
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index de96e97..7f96b24 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -369,6 +369,36 @@
   }
 }
 
+static int adjust_q_cbr(const AV1_COMP *cpi, int q) {
+  const RATE_CONTROL *const rc = &cpi->rc;
+  const AV1_COMMON *const cm = &cpi->common;
+  const int max_delta = 16;
+  const int change_avg_frame_bandwidth =
+      abs(rc->avg_frame_bandwidth - rc->prev_avg_frame_bandwidth) >
+      0.1 * (rc->avg_frame_bandwidth);
+  // If resolution changes or avg_frame_bandwidth significantly changed,
+  // then set this flag to indicate change in target bits per macroblock.
+  const int change_target_bits_mb =
+      cm->prev_frame &&
+      (cm->width != cm->prev_frame->width ||
+       cm->height != cm->prev_frame->height || change_avg_frame_bandwidth);
+  // Apply some control/clamp to QP under certain conditions.
+  if (cm->current_frame.frame_type != KEY_FRAME && !cpi->use_svc &&
+      rc->frames_since_key > 1 && !change_target_bits_mb &&
+      (!cpi->oxcf.gf_cbr_boost_pct ||
+       !(cpi->refresh_alt_ref_frame || cpi->refresh_golden_frame))) {
+    // Make sure q is between oscillating Qs to prevent resonance.
+    if (rc->rc_1_frame * rc->rc_2_frame == -1 &&
+        rc->q_1_frame != rc->q_2_frame) {
+      q = clamp(q, AOMMIN(rc->q_1_frame, rc->q_2_frame),
+                AOMMAX(rc->q_1_frame, rc->q_2_frame));
+    }
+    // Limit the decrease in Q from previous frame.
+    if (rc->q_1_frame - q > max_delta) q = rc->q_1_frame - max_delta;
+  }
+  return AOMMAX(AOMMIN(q, cpi->rc.worst_quality), cpi->rc.best_quality);
+}
+
 static const RATE_FACTOR_LEVEL rate_factor_levels[FRAME_UPDATE_TYPES] = {
   KF_STD,        // KF_UPDATE
   INTER_NORMAL,  // LF_UPDATE
@@ -582,14 +612,9 @@
       find_closest_qindex_by_rate(target_bits_per_mb, cpi, correction_factor,
                                   active_best_quality, active_worst_quality);
 
-  // In CBR mode, this makes sure q is between oscillating Qs to prevent
-  // resonance.
-  if (cpi->oxcf.rc_mode == AOM_CBR && !cpi->use_svc &&
-      (cpi->rc.rc_1_frame * cpi->rc.rc_2_frame == -1) &&
-      cpi->rc.q_1_frame != cpi->rc.q_2_frame) {
-    q = clamp(q, AOMMIN(cpi->rc.q_1_frame, cpi->rc.q_2_frame),
-              AOMMAX(cpi->rc.q_1_frame, cpi->rc.q_2_frame));
-  }
+  if (cpi->oxcf.rc_mode == AOM_CBR && cpi->oxcf.pass == 0)
+    return adjust_q_cbr(cpi, q);
+
   return q;
 }
 
@@ -756,6 +781,7 @@
           av1_compute_qdelta(rc, q_val, q_val * q_adj_factor, bit_depth);
     }
   } else if (!rc->is_src_frame_alt_ref && !cpi->use_svc &&
+             cpi->oxcf.gf_cbr_boost_pct &&
              (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)) {
     // Use the lower of active_worst_quality and recent
     // average Q as basis for GF/ARF best Q limit unless last frame was
@@ -1515,6 +1541,7 @@
   if (current_frame->frame_type == KEY_FRAME) rc->last_kf_qindex = qindex;
 
   update_buffer_level(cpi, rc->projected_frame_size);
+  rc->prev_avg_frame_bandwidth = rc->avg_frame_bandwidth;
 
   // Rolling monitors of whether we are over or underspending used to help
   // regulate min and Max Q in two pass.
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 0c92af6..530c02a 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -108,6 +108,7 @@
   int avg_frame_bandwidth;  // Average frame size target for clip
   int min_frame_bandwidth;  // Minimum allocation used for any frame
   int max_frame_bandwidth;  // Maximum burst rate allowed for a frame.
+  int prev_avg_frame_bandwidth;
 
   int ni_av_qi;
   int ni_tot_qi;