Allow realtime lookahead mode for CBR

Remove the constraint of CBR for the
realtime with nonzero lookahead mode.
This encoding mode is still only for
!CONFIG_REALTIME_ONLY

Change-Id: I76da097cfead655f480852b69e2dac1b7e015eb4
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 08e48cb..0ad53cd 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -3020,9 +3020,8 @@
       reduce_ratio(&priv->timestamp_ratio);
 
       set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg);
-      if (priv->oxcf.rc_cfg.mode != AOM_CBR &&
-          priv->oxcf.pass == AOM_RC_ONE_PASS) {
-        // Enable look ahead - enabled for AOM_Q, AOM_CQ, AOM_VBR
+      if (priv->oxcf.pass == AOM_RC_ONE_PASS) {
+        // Enable look ahead.
         *num_lap_buffers =
             AOMMIN((int)priv->cfg.g_lag_in_frames,
                    AOMMIN(MAX_LAP_BUFFERS, priv->oxcf.kf_cfg.key_freq_max +
diff --git a/av1/encoder/aq_cyclicrefresh.c b/av1/encoder/aq_cyclicrefresh.c
index d0135fd..d3aabdb 100644
--- a/av1/encoder/aq_cyclicrefresh.c
+++ b/av1/encoder/aq_cyclicrefresh.c
@@ -439,6 +439,8 @@
   // should we enable cyclic refresh on this frame.
   cr->apply_cyclic_refresh = 1;
   if (frame_is_intra_only(cm) || is_lossless_requested(&cpi->oxcf.rc_cfg) ||
+      (is_one_pass_rt_lag_params(cpi) &&
+       (cpi->refresh_frame.alt_ref_frame || cpi->rc.is_src_frame_alt_ref)) ||
       cpi->roi.enabled || cpi->rc.high_motion_content_screen_rtc ||
       scene_change_detected || svc->temporal_layer_id > 0 ||
       svc->prev_number_spatial_layers != svc->number_spatial_layers ||
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c
index e821162..3b7973a 100644
--- a/av1/encoder/encode_strategy.c
+++ b/av1/encoder/encode_strategy.c
@@ -1508,6 +1508,21 @@
                                *frame_flags);
     if (use_rtc_reference_structure_one_layer(cpi))
       av1_set_rtc_reference_structure_one_layer(cpi, cpi->gf_frame_index == 0);
+  } else if (is_one_pass_rt_lag_params(cpi) && oxcf->rc_cfg.mode == AOM_CBR) {
+    // For realtime mode with lookahead in CBR: the current frame buffer_level
+    // is used to update the frame target_bandwidth, so we need to call
+    // av1_calc_i/pframe_target_size_one_pass_cbr() here for every frame.
+    int target;
+    const FRAME_UPDATE_TYPE cur_update_type =
+        gf_group->update_type[cpi->gf_frame_index];
+    if (cur_update_type == KF_UPDATE) {
+      target = av1_calc_iframe_target_size_one_pass_cbr(cpi);
+    } else {
+      target = av1_calc_pframe_target_size_one_pass_cbr(cpi, cur_update_type);
+    }
+    gf_group->bit_allocation[cpi->gf_frame_index] = target;
+    av1_rc_set_frame_target(cpi, target, cm->width, cm->height);
+    cpi->rc.base_frame_target = target;
   }
 #endif
 #if CONFIG_COLLECT_COMPONENT_TIMING
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 95202d1..90f36b7 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -4157,8 +4157,7 @@
 
 static inline int is_one_pass_rt_lag_params(const AV1_COMP *cpi) {
   return cpi->oxcf.pass == AOM_RC_ONE_PASS &&
-         cpi->oxcf.gf_cfg.lag_in_frames > 0 && cpi->oxcf.mode == REALTIME &&
-         cpi->oxcf.rc_cfg.mode != AOM_CBR;
+         cpi->oxcf.gf_cfg.lag_in_frames > 0 && cpi->oxcf.mode == REALTIME;
 }
 
 static inline int is_one_pass_rt_params(const AV1_COMP *cpi) {
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 8e09f0f..fe339d4 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -2772,7 +2772,14 @@
   const RATE_CONTROL *rc = &cpi->rc;
   const PRIMARY_RATE_CONTROL *p_rc = &cpi->ppi->p_rc;
   const RateControlCfg *rc_cfg = &oxcf->rc_cfg;
-  const int64_t diff = p_rc->optimal_buffer_level - p_rc->buffer_level;
+  const RefreshFrameInfo *const refresh_frame = &cpi->refresh_frame;
+  int64_t diff = p_rc->optimal_buffer_level - p_rc->buffer_level;
+  // For refresh alt or golden: keep diff negative to force setting
+  // higher target bandwidth on these frames.
+  // Only realtime mode with lookahead.
+  if (is_one_pass_rt_lag_params(cpi) &&
+      (refresh_frame->alt_ref_frame || refresh_frame->golden_frame))
+    diff = AOMMIN(diff, -p_rc->optimal_buffer_level);
   const int64_t one_pct_bits = 1 + p_rc->optimal_buffer_level / 100;
   int min_frame_target =
       AOMMAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS);
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 058204c..2f96b2c 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1857,6 +1857,9 @@
       sf->rt_sf.increase_source_sad_thresh = 0;
       sf->rt_sf.part_early_exit_zeromv = 0;
     }
+    // This feature is for CBR mode, turning if off means the gop interval
+    // will not be changed after encoding.
+    sf->rt_sf.gf_refresh_based_on_qp = 0;
   }
 }
 
diff --git a/test/monochrome_test.cc b/test/monochrome_test.cc
index 78afd4f..da2b3d9 100644
--- a/test/monochrome_test.cc
+++ b/test/monochrome_test.cc
@@ -34,7 +34,7 @@
 // kPsnrFluctuation represents the maximum allowed psnr fluctuation w.r.t first
 // frame. The indices correspond to one/two-pass, allintra and realtime
 // encoding modes.
-const double kPsnrFluctuation[3] = { 2.5, 0.3, 17.0 };
+const double kPsnrFluctuation[3] = { 8.0, 0.3, 17.0 };
 
 class MonochromeTest
     : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, int,