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));
}
}
}