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,