Refactor the initialization of accumulate_stats_stage Remove the accumulate_stats_stage from p_rc structure, and pass it as an input of function calc_frame_boost(). Change-Id: I0fb385f4379c7b02bca9cecf5aa34ccbab77525e
diff --git a/av1/encoder/gop_structure.c b/av1/encoder/gop_structure.c index f10bf93..01c3e76 100644 --- a/av1/encoder/gop_structure.c +++ b/av1/encoder/gop_structure.c
@@ -67,7 +67,7 @@ GF_GROUP *const gf_group, int *cur_frame_idx, int *frame_ind, int *parallel_frame_count, int max_parallel_frames, int do_frame_parallel_encode, int *first_frame_index, int *cur_disp_index, - int layer_depth, int start, int end) { + int layer_depth, int start, int end, const bool scale_max_boost) { gf_group->update_type[*frame_ind] = LF_UPDATE; gf_group->arf_src_offset[*frame_ind] = 0; gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx; @@ -78,7 +78,7 @@ gf_group->display_idx[*frame_ind] = (*cur_disp_index); gf_group->arf_boost[*frame_ind] = av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, start, - end - start, 0, NULL, NULL, 0); + end - start, 0, NULL, NULL, 0, scale_max_boost); ++(*cur_disp_index); // Set the level of parallelism for the LF_UPDATE frame. @@ -120,7 +120,7 @@ int *parallel_frame_count, int max_parallel_frames, int do_frame_parallel_encode, int *first_frame_index, int depth_thr, int *cur_disp_idx, int layer_depth, int arf_src_offset, int offset, - int f_frames, int b_frames) { + int f_frames, int b_frames, const bool scale_max_boost) { gf_group->update_type[*frame_ind] = INTNL_ARF_UPDATE; gf_group->arf_src_offset[*frame_ind] = arf_src_offset; gf_group->cur_frame_idx[*frame_ind] = *cur_frame_idx; @@ -131,7 +131,7 @@ (*cur_disp_idx) + gf_group->arf_src_offset[*frame_ind]; gf_group->arf_boost[*frame_ind] = av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, offset, - f_frames, b_frames, NULL, NULL, 0); + f_frames, b_frames, NULL, NULL, 0, scale_max_boost); if (do_frame_parallel_encode) { if (depth_thr != INT_MAX) { @@ -179,7 +179,8 @@ RATE_CONTROL *rc, FRAME_INFO *frame_info, int start, int end, int *cur_frame_idx, int *frame_ind, int *parallel_frame_count, int max_parallel_frames, int do_frame_parallel_encode, - int *first_frame_index, int depth_thr, int *cur_disp_idx, int layer_depth) { + int *first_frame_index, int depth_thr, int *cur_disp_idx, int layer_depth, + const bool scale_max_boost) { const int num_frames_to_process = end - start; // Either we are at the last level of the pyramid, or we don't have enough @@ -188,11 +189,11 @@ num_frames_to_process < 3) { // Leaf nodes. while (start < end) { - set_params_for_leaf_frames(twopass, twopass_frame, p_rc, frame_info, - gf_group, cur_frame_idx, frame_ind, - parallel_frame_count, max_parallel_frames, - do_frame_parallel_encode, first_frame_index, - cur_disp_idx, layer_depth, start, end); + set_params_for_leaf_frames( + twopass, twopass_frame, p_rc, frame_info, gf_group, cur_frame_idx, + frame_ind, parallel_frame_count, max_parallel_frames, + do_frame_parallel_encode, first_frame_index, cur_disp_idx, + layer_depth, start, end, scale_max_boost); ++start; } } else { @@ -204,7 +205,7 @@ twopass, twopass_frame, p_rc, frame_info, gf_group, cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames, do_frame_parallel_encode, first_frame_index, INT_MAX, cur_disp_idx, - layer_depth, arf_src_offset, m, end - m, m - start); + layer_depth, arf_src_offset, m, end - m, m - start, scale_max_boost); // If encode reordering is enabled, configure the multi-layers accordingly // and return. For e.g., the encode order for gf-interval 16 after @@ -226,7 +227,7 @@ frame_ind, parallel_frame_count, max_parallel_frames, do_frame_parallel_encode, first_frame_index, depth_thr, cur_disp_idx, layer_depth + 1, arf_src_offsets[i], offset[i], - f_frames[i], b_frames[i]); + f_frames[i], b_frames[i], scale_max_boost); } // Initialize the start and end indices to configure LF_UPDATE frames. @@ -242,7 +243,8 @@ twopass, twopass_frame, gf_group, p_rc, rc, frame_info, start_idx[i], end_idx[i], cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames, do_frame_parallel_encode, - first_frame_index, depth_thr, cur_disp_idx, layer_depth + 2); + first_frame_index, depth_thr, cur_disp_idx, layer_depth + 2, + scale_max_boost); if (layer_depth_for_intnl_overlay[i] != INVALID_IDX) set_params_for_intnl_overlay_frames( gf_group, cur_frame_idx, frame_ind, first_frame_index, @@ -256,7 +258,7 @@ twopass, twopass_frame, gf_group, p_rc, rc, frame_info, start, m, cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames, do_frame_parallel_encode, first_frame_index, depth_thr, cur_disp_idx, - layer_depth + 1); + layer_depth + 1, scale_max_boost); // Overlay for internal ARF. set_params_for_intnl_overlay_frames(gf_group, cur_frame_idx, frame_ind, @@ -268,7 +270,7 @@ twopass, twopass_frame, gf_group, p_rc, rc, frame_info, m + 1, end, cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames, do_frame_parallel_encode, first_frame_index, depth_thr, cur_disp_idx, - layer_depth + 1); + layer_depth + 1, scale_max_boost); } } @@ -381,7 +383,7 @@ int *cur_frame_idx, int *frame_ind, int *count_arf_frames, int *doh_gf_index_map, int *parallel_frame_count, int *first_frame_index, int *cur_disp_index, int gf_interval, int layer_depth, - int max_parallel_frames) { + int max_parallel_frames, const bool scale_max_boost) { assert(layer_depth == 2); assert(gf_group->max_layer_depth_allowed >= 4); int layer, node_start, node_end = 0; @@ -418,7 +420,7 @@ set_params_for_leaf_frames( twopass, twopass_frame, p_rc, frame_info, gf_group, cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames, 1, - first_frame_index, cur_disp_index, layer, 0, 0); + first_frame_index, cur_disp_index, layer, 0, 0, scale_max_boost); } else { // In order to obtain the layer depths of INTNL_OVERLAY_UPDATE frames, get // the gf index of corresponding INTNL_ARF_UPDATE frames. @@ -438,7 +440,8 @@ RATE_CONTROL *rc, FRAME_INFO *frame_info, int start, int end, int *cur_frame_idx, int *frame_ind, int *parallel_frame_count, int max_parallel_frames, int do_frame_parallel_encode, - int *first_frame_index, int *cur_disp_idx, int layer_depth) { + int *first_frame_index, int *cur_disp_idx, int layer_depth, + const bool scale_max_boost) { const int num_frames_to_process = end - start; // Either we are at the last level of the pyramid, or we don't have enough @@ -454,7 +457,7 @@ gf_group->layer_depth[*frame_ind] = MAX_ARF_LAYERS; gf_group->arf_boost[*frame_ind] = av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, start, - end - start, 0, NULL, NULL, 0); + end - start, 0, NULL, NULL, 0, scale_max_boost); gf_group->frame_type[*frame_ind] = INTER_FRAME; gf_group->refbuf_state[*frame_ind] = REFBUF_UPDATE; gf_group->max_layer_depth = @@ -500,7 +503,7 @@ // Get the boost factor for intermediate ARF frames. gf_group->arf_boost[*frame_ind] = av1_calc_arf_boost(twopass, twopass_frame, p_rc, frame_info, m, end - m, - m - start, NULL, NULL, 0); + m - start, NULL, NULL, 0, scale_max_boost); ++(*frame_ind); // Frames displayed before this internal ARF. @@ -508,7 +511,7 @@ frame_info, start, m, cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames, do_frame_parallel_encode, first_frame_index, - cur_disp_idx, layer_depth + 1); + cur_disp_idx, layer_depth + 1, scale_max_boost); // Overlay for internal ARF. gf_group->update_type[*frame_ind] = INTNL_OVERLAY_UPDATE; @@ -530,7 +533,7 @@ frame_info, m + 1, end, cur_frame_idx, frame_ind, parallel_frame_count, max_parallel_frames, do_frame_parallel_encode, first_frame_index, - cur_disp_idx, layer_depth + 1); + cur_disp_idx, layer_depth + 1, scale_max_boost); } } @@ -667,6 +670,8 @@ gf_group->max_layer_depth_allowed >= 4); int first_frame_index = cur_frame_index; + const bool scale_max_boost = (cpi->oxcf.mode != REALTIME); + if (do_frame_parallel_encode) { // construct_multi_layer_gf_structure() takes the input parameter // 'gf_interval' as p_rc->baseline_gf_interval - 1 . Below code computes the @@ -710,7 +715,7 @@ arf_frame_stats, &cur_frame_index, &frame_index, &count_arf_frames, doh_gf_index_map, ¶llel_frame_count, &first_frame_index, &cur_disp_index, actual_gf_length, use_altref + 1, - cpi->ppi->num_fp_contexts); + cpi->ppi->num_fp_contexts, scale_max_boost); // Set gf_group->skip_frame_refresh. for (int i = 0; i < actual_gf_length; i++) { @@ -738,7 +743,7 @@ cur_frame_index, gf_interval, &cur_frame_index, &frame_index, ¶llel_frame_count, cpi->ppi->num_fp_contexts, do_frame_parallel_encode, &first_frame_index, depth_thr, - &cur_disp_index, use_altref + 1); + &cur_disp_index, use_altref + 1, scale_max_boost); } is_multi_layer_configured = 1; } @@ -750,7 +755,7 @@ &cur_frame_index, &frame_index, ¶llel_frame_count, cpi->ppi->num_fp_contexts, do_frame_parallel_encode, &first_frame_index, - &cur_disp_index, use_altref + 1); + &cur_disp_index, use_altref + 1, scale_max_boost); if (use_altref) { gf_group->update_type[frame_index] = OVERLAY_UPDATE;
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c index ae0b28b..0c448cf 100644 --- a/av1/encoder/pass2_strategy.c +++ b/av1/encoder/pass2_strategy.c
@@ -583,10 +583,15 @@ } } +// scale_max_boost = (cpi->oxcf.mode != REALTIME) in most cases as it was only +// tuned in non-rtc cases. The only exception is when we derive +// gfu_boost_average, we pass scale_max_boost = false for better coding +// efficiency. static double calc_frame_boost(const PRIMARY_RATE_CONTROL *p_rc, const FRAME_INFO *frame_info, const FIRSTPASS_STATS *this_frame, - double this_frame_mv_in_out, double max_boost) { + double this_frame_mv_in_out, double max_boost, + const bool scale_max_boost) { double frame_boost; const double lq = av1_convert_qindex_to_q(p_rc->avg_frame_qindex[INTER_FRAME], frame_info->bit_depth); @@ -604,8 +609,7 @@ // (zoom in). The range for this_frame_mv_in_out is -1.0 to +1.0. if (this_frame_mv_in_out > 0.0) { frame_boost += frame_boost * (this_frame_mv_in_out * 2.0); - if (!p_rc->accumulate_stats_stage) - max_boost += max_boost * (this_frame_mv_in_out * 2.0); + if (scale_max_boost) max_boost += max_boost * (this_frame_mv_in_out * 2.0); } // In the extreme case the boost is halved. else { @@ -677,7 +681,7 @@ const PRIMARY_RATE_CONTROL *p_rc, FRAME_INFO *frame_info, int offset, int f_frames, int b_frames, int *num_fpstats_used, int *num_fpstats_required, - int project_gfu_boost) { + int project_gfu_boost, const bool scale_max_boost) { int i; GF_GROUP_STATS gf_stats; init_gf_stats(&gf_stats); @@ -710,10 +714,10 @@ : gf_stats.decay_accumulator; } - boost_score += - gf_stats.decay_accumulator * - calc_frame_boost(p_rc, frame_info, this_frame, - gf_stats.this_frame_mv_in_out, GF_MAX_BOOST); + boost_score += gf_stats.decay_accumulator * + calc_frame_boost(p_rc, frame_info, this_frame, + gf_stats.this_frame_mv_in_out, GF_MAX_BOOST, + scale_max_boost); if (num_fpstats_used) (*num_fpstats_used)++; } @@ -746,10 +750,10 @@ : gf_stats.decay_accumulator; } - boost_score += - gf_stats.decay_accumulator * - calc_frame_boost(p_rc, frame_info, this_frame, - gf_stats.this_frame_mv_in_out, GF_MAX_BOOST); + boost_score += gf_stats.decay_accumulator * + calc_frame_boost(p_rc, frame_info, this_frame, + gf_stats.this_frame_mv_in_out, GF_MAX_BOOST, + scale_max_boost); if (num_fpstats_used) (*num_fpstats_used)++; } arf_boost += (int)boost_score; @@ -2420,7 +2424,6 @@ int gfu_boost_sum = 0; int gfu_count = 0; int accumulate_i = 0; - p_rc->accumulate_stats_stage = true; if (rc->frames_since_key == 0) { for (int k = 0; k < MAX_NUM_GF_INTERVALS; k++) { if (p_rc->gf_intervals[k] == 0) { @@ -2446,11 +2449,14 @@ } } reset_fpf_position(&cpi->twopass_frame, cpi->twopass_frame.stats_in); - // Calculate the boost for alt ref. + // Calculate the boost for alt ref. Note that we pass the + // scale_max_boost=false to derive gfu_boost_average, which can help + // the coding efficiency for some clips with global motion. int gfu_boost_tmp = av1_calc_arf_boost( twopass, &cpi->twopass_frame, p_rc, frame_info, alt_offset, forward_frames, ext_len_new, &p_rc->num_stats_used_for_gfu_boost, - &p_rc->num_stats_required_for_gfu_boost, cpi->ppi->lap_enabled); + &p_rc->num_stats_required_for_gfu_boost, cpi->ppi->lap_enabled, + /*scale_max_boost=*/false); gfu_boost_sum += gfu_boost_tmp; } gfu_count++; @@ -2462,9 +2468,9 @@ cpi->twopass_frame = stats_in_backup; } - p_rc->accumulate_stats_stage = (cpi->oxcf.mode == REALTIME); - int ext_len = i - is_intra_only; + const bool scale_max_boost = (cpi->oxcf.mode != REALTIME); + if (use_alt_ref) { const int forward_frames = (rc->frames_to_key - i >= ext_len) ? ext_len @@ -2474,15 +2480,17 @@ p_rc->gfu_boost = av1_calc_arf_boost( twopass, &cpi->twopass_frame, p_rc, frame_info, alt_offset, forward_frames, ext_len, &p_rc->num_stats_used_for_gfu_boost, - &p_rc->num_stats_required_for_gfu_boost, cpi->ppi->lap_enabled); + &p_rc->num_stats_required_for_gfu_boost, cpi->ppi->lap_enabled, + scale_max_boost); } else { reset_fpf_position(&cpi->twopass_frame, start_pos); - p_rc->gfu_boost = AOMMIN( - MAX_GF_BOOST, - av1_calc_arf_boost( - twopass, &cpi->twopass_frame, p_rc, frame_info, alt_offset, ext_len, - 0, &p_rc->num_stats_used_for_gfu_boost, - &p_rc->num_stats_required_for_gfu_boost, cpi->ppi->lap_enabled)); + p_rc->gfu_boost = + AOMMIN(MAX_GF_BOOST, + av1_calc_arf_boost(twopass, &cpi->twopass_frame, p_rc, + frame_info, alt_offset, ext_len, 0, + &p_rc->num_stats_used_for_gfu_boost, + &p_rc->num_stats_required_for_gfu_boost, + cpi->ppi->lap_enabled, scale_max_boost)); } #define LAST_ALR_BOOST_FACTOR 0.2f
diff --git a/av1/encoder/pass2_strategy.h b/av1/encoder/pass2_strategy.h index 1ca39ec..be14d8e 100644 --- a/av1/encoder/pass2_strategy.h +++ b/av1/encoder/pass2_strategy.h
@@ -109,7 +109,7 @@ const PRIMARY_RATE_CONTROL *p_rc, FRAME_INFO *frame_info, int offset, int f_frames, int b_frames, int *num_fpstats_used, int *num_fpstats_required, - int project_gfu_boost); + int project_gfu_boost, const bool scale_max_boost); void av1_gop_bit_allocation(const AV1_COMP *cpi, RATE_CONTROL *const rc, GF_GROUP *gf_group, int is_key_frame, int use_arf,
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h index e83b7c0..deea12d 100644 --- a/av1/encoder/ratectrl.h +++ b/av1/encoder/ratectrl.h
@@ -334,11 +334,6 @@ int gfu_boost_average; /*! - * Indicate if it is gfu_boost accumulation stage - */ - bool accumulate_stats_stage; - - /*! * Stores the determined gf group lengths for a set of gf groups */ int gf_intervals[MAX_NUM_GF_INTERVALS];
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c index da81e04..daab015 100644 --- a/av1/encoder/temporal_filter.c +++ b/av1/encoder/temporal_filter.c
@@ -1365,10 +1365,10 @@ num_before = AOMMIN(is_forward_keyframe ? num_frames / 2 : 0, max_before); num_after = AOMMIN(num_frames - 1, max_after); } else { - int gfu_boost = av1_calc_arf_boost(&cpi->ppi->twopass, &cpi->twopass_frame, - &cpi->ppi->p_rc, &cpi->frame_info, - filter_frame_lookahead_idx, max_before, - max_after, NULL, NULL, 0); + int gfu_boost = av1_calc_arf_boost( + &cpi->ppi->twopass, &cpi->twopass_frame, &cpi->ppi->p_rc, + &cpi->frame_info, filter_frame_lookahead_idx, max_before, max_after, + NULL, NULL, 0, cpi->oxcf.mode != REALTIME); num_frames = AOMMIN(num_frames, gfu_boost / 150); num_frames += !(num_frames & 1); // Make the number odd.