Commit 26f9a4186d for aom

commit 26f9a4186d20b699bfc84fccc2892147c8f7b4c9
Author: Lin Zheng <linzhen@google.com>
Date:   Mon Mar 16 17:36:44 2026 +0000

    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 f10bf93730..01c3e764cd 100644
--- a/av1/encoder/gop_structure.c
+++ b/av1/encoder/gop_structure.c
@@ -67,7 +67,7 @@ static inline void set_params_for_leaf_frames(
     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 @@ static inline void set_params_for_leaf_frames(
   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 @@ static inline void set_params_for_internal_arfs(
     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 @@ static inline void set_params_for_internal_arfs(
       (*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 @@ static void set_multi_layer_params_for_fp(
     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 @@ static void set_multi_layer_params_for_fp(
       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 @@ static void set_multi_layer_params_for_fp(
         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 @@ static void set_multi_layer_params_for_fp(
             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 @@ static void set_multi_layer_params_for_fp(
             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 @@ static void set_multi_layer_params_for_fp(
         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 @@ static void set_multi_layer_params_for_fp(
         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 @@ static inline void set_multi_layer_params_for_gf14(
     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 @@ static inline void set_multi_layer_params_for_gf14(
       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 @@ static void set_multi_layer_params(
     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 @@ static void set_multi_layer_params(
       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 @@ static void set_multi_layer_params(
     // 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 @@ static void set_multi_layer_params(
                            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 @@ static void set_multi_layer_params(
                            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 @@ static int construct_multi_layer_gf_structure(
                                   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 @@ static int construct_multi_layer_gf_structure(
           arf_frame_stats, &cur_frame_index, &frame_index, &count_arf_frames,
           doh_gf_index_map, &parallel_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 @@ static int construct_multi_layer_gf_structure(
           cur_frame_index, gf_interval, &cur_frame_index, &frame_index,
           &parallel_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 @@ static int construct_multi_layer_gf_structure(
                            &cur_frame_index, &frame_index,
                            &parallel_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 ae0b28b4b4..0c448cf7e5 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -583,10 +583,15 @@ static double baseline_err_per_mb(const FRAME_INFO *frame_info) {
   }
 }

+// 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 @@ static double calc_frame_boost(const PRIMARY_RATE_CONTROL *p_rc,
   // (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 @@ int av1_calc_arf_boost(const TWO_PASS *twopass,
                        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 @@ int av1_calc_arf_boost(const TWO_PASS *twopass,
                                        : 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 @@ int av1_calc_arf_boost(const TWO_PASS *twopass,
                                        : 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 @@ static void set_gop_bits_boost(AV1_COMP *cpi, int i, int is_intra_only,
     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 @@ static void set_gop_bits_boost(AV1_COMP *cpi, int i, int is_intra_only,
             }
           }
           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 @@ static void set_gop_bits_boost(AV1_COMP *cpi, int i, int is_intra_only,
     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 @@ static void set_gop_bits_boost(AV1_COMP *cpi, int i, int is_intra_only,
     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 1ca39ec7b8..be14d8eefb 100644
--- a/av1/encoder/pass2_strategy.h
+++ b/av1/encoder/pass2_strategy.h
@@ -109,7 +109,7 @@ int av1_calc_arf_boost(const TWO_PASS *twopass,
                        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 e83b7c0e18..deea12d775 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -333,11 +333,6 @@ typedef struct {
    */
   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
    */
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index da81e041e3..daab015fff 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -1365,10 +1365,10 @@ static void tf_setup_filtering_buffer(AV1_COMP *cpi,
     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.