rtc: Layer constraint on Q for temporal layers

For temporal layers CBR: constrain how much lower
the Q for an enhancement layer can go relative
to avg Q of base TL0.

This reduces visual quality flicker for
temporal layers.

Gains for 2 TL speed 10, 70/30 split, rtc_derf:
avg/ovr/ssim, IC speeedup
-0.48/-0.46/-0.48, 0.13

Several clips ~1% bdrate gain.

Change-Id: I0c91dfdbd07abd0c3e0a2e36652615109fbccff0
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 8bdbe17..f485aba 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -480,6 +480,7 @@
   const RATE_CONTROL *const rc = &cpi->rc;
   const PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
   const AV1_COMMON *const cm = &cpi->common;
+  const SVC *const svc = &cpi->svc;
   const RefreshFrameInfo *const refresh_frame = &cpi->refresh_frame;
   int max_delta_down;
   int max_delta_up = 20;
@@ -511,7 +512,7 @@
                          ? AOMMIN(8, AOMMAX(1, rc->q_1_frame / 16))
                          : AOMMIN(16, AOMMAX(1, rc->q_1_frame / 8));
   }
-  if (cpi->svc.number_temporal_layers > 1 && cpi->svc.temporal_layer_id == 0)
+  if (svc->number_temporal_layers > 1 && svc->temporal_layer_id == 0)
     max_delta_up = AOMMIN(max_delta_up, 14);
   // If resolution changes or avg_frame_bandwidth significantly changed,
   // then set this flag to indicate change in target bits per macroblock.
@@ -568,6 +569,18 @@
     else if (q - rc->q_1_frame > max_delta_up)
       q = rc->q_1_frame + max_delta_up;
   }
+  // Constrain the Q for enhancement temporal layer, relative to base TLO.
+  if (svc->number_temporal_layers > 1 && svc->temporal_layer_id > 0 &&
+      svc->spatial_layer_id == 0) {
+    // Get base temporal layer TL0.
+    const int layer = LAYER_IDS_TO_IDX(0, 0, svc->number_temporal_layers);
+    LAYER_CONTEXT *lc = &svc->layer_context[layer];
+    // lc->rc.avg_frame_bandwidth and lc->p_rc.last_q correspond to the
+    // last TL0 frame.
+    if (rc->avg_frame_bandwidth < lc->rc.avg_frame_bandwidth &&
+        q < lc->p_rc.last_q[INTER_FRAME] - 4)
+      q = lc->p_rc.last_q[INTER_FRAME] - 4;
+  }
   // For non-svc (single layer): if resolution has increased push q closer
   // to the active_worst to avoid excess overshoot.
   if (!cpi->ppi->use_svc && cm->prev_frame &&