Commit 1455a9744d for aom

commit 1455a9744dab382804b0a32282dd166460508682
Author: Marco Paniconi <marpan@google.com>
Date:   Thu Sep 17 04:54:50 2026 +0000

    rtc: Fix integer overflow in update_layer_buffer_level

    Use saturate_cast_double_to_int when computing the
    target bandwidth per frame in update_layer_buffer_level,
    av1_update_layer_context_change_config, and
    av1_update_temporal_layer_framerate. Also promote the
    subtraction in update_layer_buffer_level to 64-bit signed
    integer arithmetic.

    This prevents signed integer overflow when target_bandwidth
    is very large and framerate is very low.

    Bug: 560374698
    Change-Id: I4fc450bf81006154beb3ae4d0e007884e2d70cb2

diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index f68c78f4ec..677432fb9d 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -365,8 +365,9 @@ static void update_layer_buffer_level(SVC *svc, int encoded_frame_size,
         LAYER_IDS_TO_IDX(svc->spatial_layer_id, i, svc->number_temporal_layers);
     LAYER_CONTEXT *lc = &svc->layer_context[layer];
     PRIMARY_RATE_CONTROL *lp_rc = &lc->p_rc;
-    lp_rc->bits_off_target +=
-        (int)round(lc->target_bandwidth / lc->framerate) - encoded_frame_size;
+    lp_rc->bits_off_target += (int64_t)saturate_cast_double_to_int(
+                                  round(lc->target_bandwidth / lc->framerate)) -
+                              encoded_frame_size;
     // Clip buffer level to maximum buffer size for the layer.
     lp_rc->bits_off_target =
         AOMMIN(lp_rc->bits_off_target, lp_rc->maximum_buffer_size);
diff --git a/av1/encoder/svc_layercontext.c b/av1/encoder/svc_layercontext.c
index 8b8d4c51e9..af22f8ff70 100644
--- a/av1/encoder/svc_layercontext.c
+++ b/av1/encoder/svc_layercontext.c
@@ -141,8 +141,8 @@ void av1_update_layer_context_change_config(AV1_COMP *const cpi,
       lp_rc->buffer_level =
           AOMMIN(lp_rc->buffer_level, lp_rc->maximum_buffer_size);
       lc->framerate = cpi->framerate / lc->framerate_factor;
-      lrc->avg_frame_bandwidth =
-          (int)round(lc->target_bandwidth / lc->framerate);
+      lrc->avg_frame_bandwidth = saturate_cast_double_to_int(
+          round(lc->target_bandwidth / lc->framerate));
       lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
       lrc->rtc_external_ratectrl = rc->rtc_external_ratectrl;
       lrc->worst_quality = av1_quantizer_to_qindex(lc->max_q);
@@ -203,11 +203,12 @@ void av1_update_temporal_layer_framerate(AV1_COMP *const cpi) {
         cpi->framerate / lcprev->framerate_factor;
     const int64_t prev_layer_target_bandwidth = lcprev->layer_target_bitrate;
     if (lc->framerate > prev_layer_framerate) {
-      lc->avg_frame_size =
-          (int)round((lc->target_bandwidth - prev_layer_target_bandwidth) /
-                     (lc->framerate - prev_layer_framerate));
+      lc->avg_frame_size = saturate_cast_double_to_int(
+          round((lc->target_bandwidth - prev_layer_target_bandwidth) /
+                (lc->framerate - prev_layer_framerate)));
     } else {
-      lc->avg_frame_size = (int)round(lc->target_bandwidth / lc->framerate);
+      lc->avg_frame_size = saturate_cast_double_to_int(
+          round(lc->target_bandwidth / lc->framerate));
     }
   }
 }