Revert "rtc: Refactor 1 pass rate control" This reverts commit 328953aa9e90b15e457a92f07c8d5befc51a73b3. Reason for revert: Breaks tests Change-Id: Ie425712c6ec01ba393219bec728708ff5e8ed3ea
diff --git a/av1/encoder/encode_strategy.c b/av1/encoder/encode_strategy.c index 52c153b..caf8b8b 100644 --- a/av1/encoder/encode_strategy.c +++ b/av1/encoder/encode_strategy.c
@@ -1164,15 +1164,8 @@ cpi->common.frame_presentation_time = (uint32_t)pts64; } -#if CONFIG_REALTIME_ONLY - av1_get_one_pass_params(cpi, &frame_params, *frame_flags); - frame_update_type = get_frame_update_type(cpi); -#else - if (oxcf->pass == 0) { - av1_get_one_pass_params(cpi, &frame_params, *frame_flags); - frame_update_type = get_frame_update_type(cpi); - } else if (oxcf->pass != 1 && - (!frame_params.show_existing_frame || is_overlay)) { +#if !CONFIG_REALTIME_ONLY + if (oxcf->pass != 1 && (!frame_params.show_existing_frame || is_overlay)) { // GF_GROUP needs updating for arf overlays as well as non-show-existing av1_get_second_pass_params(cpi, &frame_params, *frame_flags); frame_update_type = get_frame_update_type(cpi);
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c index e1863de..3e5f17f 100644 --- a/av1/encoder/pass2_strategy.c +++ b/av1/encoder/pass2_strategy.c
@@ -776,8 +776,148 @@ rc->avg_frame_qindex[INTER_FRAME] = avg_frame_qindex; } +static int calc_pframe_target_size_one_pass_vbr( + const AV1_COMP *const cpi, FRAME_UPDATE_TYPE frame_update_type) { + static const int af_ratio = 10; + const RATE_CONTROL *const rc = &cpi->rc; + int target; +#if USE_ALTREF_FOR_ONE_PASS + if (frame_update_type == KF_UPDATE || frame_update_type == GF_UPDATE || + frame_update_type == ARF_UPDATE) { + target = (rc->avg_frame_bandwidth * rc->baseline_gf_interval * af_ratio) / + (rc->baseline_gf_interval + af_ratio - 1); + } else { + target = (rc->avg_frame_bandwidth * rc->baseline_gf_interval) / + (rc->baseline_gf_interval + af_ratio - 1); + } +#else + target = rc->avg_frame_bandwidth; +#endif + return av1_rc_clamp_pframe_target_size(cpi, target, frame_update_type); +} + +static int calc_iframe_target_size_one_pass_vbr(const AV1_COMP *const cpi) { + static const int kf_ratio = 25; + const RATE_CONTROL *rc = &cpi->rc; + const int target = rc->avg_frame_bandwidth * kf_ratio; + return av1_rc_clamp_iframe_target_size(cpi, target); +} + #define FRAME_OVERHEAD_BITS 200 +static int calc_pframe_target_size_one_pass_cbr( + const AV1_COMP *cpi, FRAME_UPDATE_TYPE frame_update_type) { + const AV1EncoderConfig *oxcf = &cpi->oxcf; + const RATE_CONTROL *rc = &cpi->rc; + const int64_t diff = rc->optimal_buffer_level - rc->buffer_level; + const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100; + int min_frame_target = + AOMMAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS); + int target; + + if (oxcf->gf_cbr_boost_pct) { + const int af_ratio_pct = oxcf->gf_cbr_boost_pct + 100; + if (frame_update_type == GF_UPDATE || frame_update_type == OVERLAY_UPDATE) { + target = + (rc->avg_frame_bandwidth * rc->baseline_gf_interval * af_ratio_pct) / + (rc->baseline_gf_interval * 100 + af_ratio_pct - 100); + } else { + target = (rc->avg_frame_bandwidth * rc->baseline_gf_interval * 100) / + (rc->baseline_gf_interval * 100 + af_ratio_pct - 100); + } + } else { + target = rc->avg_frame_bandwidth; + } + + if (diff > 0) { + // Lower the target bandwidth for this frame. + const int pct_low = (int)AOMMIN(diff / one_pct_bits, oxcf->under_shoot_pct); + target -= (target * pct_low) / 200; + } else if (diff < 0) { + // Increase the target bandwidth for this frame. + const int pct_high = + (int)AOMMIN(-diff / one_pct_bits, oxcf->over_shoot_pct); + target += (target * pct_high) / 200; + } + if (oxcf->rc_max_inter_bitrate_pct) { + const int max_rate = + rc->avg_frame_bandwidth * oxcf->rc_max_inter_bitrate_pct / 100; + target = AOMMIN(target, max_rate); + } + return AOMMAX(min_frame_target, target); +} + +static int calc_iframe_target_size_one_pass_cbr(const AV1_COMP *cpi) { + const RATE_CONTROL *rc = &cpi->rc; + int target; + if (cpi->common.current_frame.frame_number == 0) { + target = ((rc->starting_buffer_level / 2) > INT_MAX) + ? INT_MAX + : (int)(rc->starting_buffer_level / 2); + } else { + int kf_boost = 32; + double framerate = cpi->framerate; + + kf_boost = AOMMAX(kf_boost, (int)(2 * framerate - 16)); + if (rc->frames_since_key < framerate / 2) { + kf_boost = (int)(kf_boost * rc->frames_since_key / (framerate / 2)); + } + target = ((16 + kf_boost) * rc->avg_frame_bandwidth) >> 4; + } + return av1_rc_clamp_iframe_target_size(cpi, target); +} + +static void define_gf_group_pass0(AV1_COMP *cpi, + const EncodeFrameParams *const frame_params) { + RATE_CONTROL *const rc = &cpi->rc; + GF_GROUP *const gf_group = &cpi->gf_group; + int target; + + if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) + av1_cyclic_refresh_set_golden_update(cpi); + else + rc->baseline_gf_interval = MAX_GF_INTERVAL; + + if (rc->baseline_gf_interval > rc->frames_to_key) + rc->baseline_gf_interval = rc->frames_to_key; + + rc->gfu_boost = DEFAULT_GF_BOOST; + rc->constrained_gf_group = + (rc->baseline_gf_interval >= rc->frames_to_key) ? 1 : 0; + const int use_alt_ref = + is_altref_enabled(cpi) && + (rc->baseline_gf_interval < cpi->oxcf.lag_in_frames) && + !(cpi->lookahead->sz < rc->baseline_gf_interval - 1) && + (cpi->oxcf.gf_max_pyr_height > MIN_PYRAMID_LVL); + rc->source_alt_ref_pending = use_alt_ref; + cpi->preserve_arf_as_gld = use_alt_ref; + + // Set up the structure of this Group-Of-Pictures (same as GF_GROUP) + av1_gop_setup_structure(cpi, frame_params); + + if (cpi->oxcf.rc_mode == AOM_Q) av1_assign_q_and_bounds_q_mode(cpi); + + // Allocate bits to each of the frames in the GF group. + // TODO(sarahparker) Extend this to work with pyramid structure. + for (int cur_index = 0; cur_index < gf_group->size; ++cur_index) { + const FRAME_UPDATE_TYPE cur_update_type = gf_group->update_type[cur_index]; + if (cpi->oxcf.rc_mode == AOM_CBR) { + if (cur_update_type == KEY_FRAME) { + target = calc_iframe_target_size_one_pass_cbr(cpi); + } else { + target = calc_pframe_target_size_one_pass_cbr(cpi, cur_update_type); + } + } else { + if (cur_update_type == KEY_FRAME) { + target = calc_iframe_target_size_one_pass_vbr(cpi); + } else { + target = calc_pframe_target_size_one_pass_vbr(cpi, cur_update_type); + } + } + gf_group->bit_allocation[cur_index] = target; + } +} + // Analyse and define a gf/arf group. static void define_gf_group(AV1_COMP *cpi, FIRSTPASS_STATS *this_frame, const EncodeFrameParams *const frame_params) { @@ -833,6 +973,11 @@ aom_clear_system_state(); av1_zero(next_frame); + if (oxcf->pass == 0) { + define_gf_group_pass0(cpi, frame_params); + return; + } + // Load stats for the current frame. mod_frame_err = calculate_modified_err(cpi, twopass, oxcf, this_frame); @@ -1341,6 +1486,8 @@ RATE_CONTROL *const rc = &cpi->rc; TWO_PASS *const twopass = &cpi->twopass; GF_GROUP *const gf_group = &cpi->gf_group; + AV1_COMMON *const cm = &cpi->common; + CurrentFrame *const current_frame = &cm->current_frame; const AV1EncoderConfig *const oxcf = &cpi->oxcf; const FIRSTPASS_STATS first_frame = *this_frame; FIRSTPASS_STATS next_frame; @@ -1361,6 +1508,15 @@ rc->frames_to_key = 1; + if (cpi->oxcf.pass == 0) { + rc->this_key_frame_forced = + current_frame->frame_number != 0 && rc->frames_to_key == 0; + rc->frames_to_key = cpi->oxcf.key_freq; + rc->kf_boost = DEFAULT_KF_BOOST; + rc->source_alt_ref_active = 0; + gf_group->update_type[0] = KF_UPDATE; + return; + } int i, j; const FIRSTPASS_STATS *const start_position = twopass->stats_in; int kf_bits = 0; @@ -1676,6 +1832,11 @@ int target_rate = gf_group->bit_allocation[gf_group->index]; + if (cpi->oxcf.pass == 0) { + av1_rc_set_frame_target(cpi, target_rate, cpi->common.width, + cpi->common.height); + } + rc->base_frame_target = target_rate; }
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c index 6c3d417..863681e 100644 --- a/av1/encoder/ratectrl.c +++ b/av1/encoder/ratectrl.c
@@ -1849,171 +1849,3 @@ vbr_rate_correction(cpi, &target_rate); av1_rc_set_frame_target(cpi, target_rate, width, height); } - -static int calc_pframe_target_size_one_pass_vbr( - const AV1_COMP *const cpi, FRAME_UPDATE_TYPE frame_update_type) { - static const int af_ratio = 10; - const RATE_CONTROL *const rc = &cpi->rc; - int target; -#if USE_ALTREF_FOR_ONE_PASS - if (frame_update_type == KF_UPDATE || frame_update_type == GF_UPDATE || - frame_update_type == ARF_UPDATE) { - target = (rc->avg_frame_bandwidth * rc->baseline_gf_interval * af_ratio) / - (rc->baseline_gf_interval + af_ratio - 1); - } else { - target = (rc->avg_frame_bandwidth * rc->baseline_gf_interval) / - (rc->baseline_gf_interval + af_ratio - 1); - } -#else - target = rc->avg_frame_bandwidth; -#endif - return av1_rc_clamp_pframe_target_size(cpi, target, frame_update_type); -} - -static int calc_iframe_target_size_one_pass_vbr(const AV1_COMP *const cpi) { - static const int kf_ratio = 25; - const RATE_CONTROL *rc = &cpi->rc; - const int target = rc->avg_frame_bandwidth * kf_ratio; - return av1_rc_clamp_iframe_target_size(cpi, target); -} - -static int calc_pframe_target_size_one_pass_cbr( - const AV1_COMP *cpi, FRAME_UPDATE_TYPE frame_update_type) { - const AV1EncoderConfig *oxcf = &cpi->oxcf; - const RATE_CONTROL *rc = &cpi->rc; - const int64_t diff = rc->optimal_buffer_level - rc->buffer_level; - const int64_t one_pct_bits = 1 + rc->optimal_buffer_level / 100; - int min_frame_target = - AOMMAX(rc->avg_frame_bandwidth >> 4, FRAME_OVERHEAD_BITS); - int target; - - if (oxcf->gf_cbr_boost_pct) { - const int af_ratio_pct = oxcf->gf_cbr_boost_pct + 100; - if (frame_update_type == GF_UPDATE || frame_update_type == OVERLAY_UPDATE) { - target = - (rc->avg_frame_bandwidth * rc->baseline_gf_interval * af_ratio_pct) / - (rc->baseline_gf_interval * 100 + af_ratio_pct - 100); - } else { - target = (rc->avg_frame_bandwidth * rc->baseline_gf_interval * 100) / - (rc->baseline_gf_interval * 100 + af_ratio_pct - 100); - } - } else { - target = rc->avg_frame_bandwidth; - } - - if (diff > 0) { - // Lower the target bandwidth for this frame. - const int pct_low = (int)AOMMIN(diff / one_pct_bits, oxcf->under_shoot_pct); - target -= (target * pct_low) / 200; - } else if (diff < 0) { - // Increase the target bandwidth for this frame. - const int pct_high = - (int)AOMMIN(-diff / one_pct_bits, oxcf->over_shoot_pct); - target += (target * pct_high) / 200; - } - if (oxcf->rc_max_inter_bitrate_pct) { - const int max_rate = - rc->avg_frame_bandwidth * oxcf->rc_max_inter_bitrate_pct / 100; - target = AOMMIN(target, max_rate); - } - return AOMMAX(min_frame_target, target); -} - -static int calc_iframe_target_size_one_pass_cbr(const AV1_COMP *cpi) { - const RATE_CONTROL *rc = &cpi->rc; - int target; - if (cpi->common.current_frame.frame_number == 0) { - target = ((rc->starting_buffer_level / 2) > INT_MAX) - ? INT_MAX - : (int)(rc->starting_buffer_level / 2); - } else { - int kf_boost = 32; - double framerate = cpi->framerate; - - kf_boost = AOMMAX(kf_boost, (int)(2 * framerate - 16)); - if (rc->frames_since_key < framerate / 2) { - kf_boost = (int)(kf_boost * rc->frames_since_key / (framerate / 2)); - } - target = ((16 + kf_boost) * rc->avg_frame_bandwidth) >> 4; - } - return av1_rc_clamp_iframe_target_size(cpi, target); -} - -#define DEFAULT_KF_BOOST 2300 -#define DEFAULT_GF_BOOST 2000 - -static void define_gf_group_pass0(AV1_COMP *cpi, - const EncodeFrameParams *const frame_params) { - RATE_CONTROL *const rc = &cpi->rc; - GF_GROUP *const gf_group = &cpi->gf_group; - int target; - - if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) - av1_cyclic_refresh_set_golden_update(cpi); - else - rc->baseline_gf_interval = MAX_GF_INTERVAL; - - if (rc->baseline_gf_interval > rc->frames_to_key) - rc->baseline_gf_interval = rc->frames_to_key; - - rc->gfu_boost = DEFAULT_GF_BOOST; - rc->constrained_gf_group = - (rc->baseline_gf_interval >= rc->frames_to_key) ? 1 : 0; - - // Set up the structure of this Group-Of-Pictures (same as GF_GROUP) - av1_gop_setup_structure(cpi, frame_params); - - // Allocate bits to each of the frames in the GF group. - // TODO(marpan): Fix this: frame size should be based on current - // buffer level, updated after each encoded frame. - for (int cur_index = 0; cur_index < gf_group->size; ++cur_index) { - const FRAME_UPDATE_TYPE cur_update_type = gf_group->update_type[cur_index]; - if (cpi->oxcf.rc_mode == AOM_CBR) { - if (cur_update_type == KEY_FRAME) { - target = calc_iframe_target_size_one_pass_cbr(cpi); - } else { - target = calc_pframe_target_size_one_pass_cbr(cpi, cur_update_type); - } - } else { - if (cur_update_type == KEY_FRAME) { - target = calc_iframe_target_size_one_pass_vbr(cpi); - } else { - target = calc_pframe_target_size_one_pass_vbr(cpi, cur_update_type); - } - } - gf_group->bit_allocation[cur_index] = target; - } -} - -void av1_get_one_pass_params(AV1_COMP *cpi, - EncodeFrameParams *const frame_params, - unsigned int frame_flags) { - RATE_CONTROL *const rc = &cpi->rc; - AV1_COMMON *const cm = &cpi->common; - GF_GROUP *const gf_group = &cpi->gf_group; - int target_size; - if (rc->frames_to_key == 0 || (frame_flags & FRAMEFLAGS_KEY)) { - frame_params->frame_type = KEY_FRAME; - rc->this_key_frame_forced = - cm->current_frame.frame_number != 0 && rc->frames_to_key == 0; - rc->frames_to_key = cpi->oxcf.key_freq; - rc->kf_boost = DEFAULT_KF_BOOST; - rc->source_alt_ref_active = 0; - gf_group->update_type[0] = KF_UPDATE; - } else { - frame_params->frame_type = INTER_FRAME; - } - if (rc->frames_till_gf_update_due == 0) { - assert(cpi->common.current_frame.frame_number == 0 || - gf_group->index == gf_group->size); - define_gf_group_pass0(cpi, frame_params); - rc->frames_till_gf_update_due = rc->baseline_gf_interval; - cpi->num_gf_group_show_frames = 0; - gf_group->index = 0; - } - assert(gf_group->index < gf_group->size); - target_size = gf_group->bit_allocation[gf_group->index]; - av1_rc_set_frame_target(cpi, target_size, cpi->common.width, - cpi->common.height); - rc->base_frame_target = target_size; -}
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h index b281ce4..cbe925d 100644 --- a/av1/encoder/ratectrl.h +++ b/av1/encoder/ratectrl.h
@@ -266,10 +266,6 @@ int width, int height, int *arf_q, int gf_index); -void av1_get_one_pass_params(struct AV1_COMP *cpi, - struct EncodeFrameParams *const frame_params, - unsigned int frame_flags); - #ifdef __cplusplus } // extern "C" #endif