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,