From abc5cf73031288e6a3727f658fbe3fbdb62d2105 Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Mon, 11 Aug 2025 11:12:14 -0400 Subject: [PATCH] rtpgccbwe: avoid clamp() panic when min_bitrate > max_bitrate Prevent calling clamp() with invalid bounds where min > max, which would cause a panic with "assertion failed: min <= max". This panic would poison the mutex lock, causing all subsequent lock().unwrap() calls to fail with PoisonError. This can happen when min-bitrate and max-bitrate properties are set individually, creating a temporary inconsistent state between the values. Fix by validating the bitrate range before calling clamp() and using max_bitrate for both bounds when min > max to ensure safe operation. Use LogContext to log the error only once per unique invalid pair. Fixes #711 Part-of: --- net/rtp/src/gcc/imp.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/net/rtp/src/gcc/imp.rs b/net/rtp/src/gcc/imp.rs index 93abc2a1a..69ffb92db 100644 --- a/net/rtp/src/gcc/imp.rs +++ b/net/rtp/src/gcc/imp.rs @@ -946,19 +946,33 @@ impl State { ) -> bool { let prev_bitrate = Bitrate::min(self.target_bitrate_on_delay, self.target_bitrate_on_loss); + // Ensure min_bitrate <= max_bitrate to avoid panic in clamp() + let (min_bitrate, max_bitrate) = if self.min_bitrate <= self.max_bitrate { + (self.min_bitrate, self.max_bitrate) + } else { + gst::error!( + CAT, + obj = bwe, + "min_bitrate ({}) > max_bitrate ({}), using max_bitrate for both to avoid panic", + self.min_bitrate, + self.max_bitrate + ); + (self.max_bitrate, self.max_bitrate) + }; + match controller_type { ControllerType::Loss => { - self.target_bitrate_on_loss = bitrate.clamp(self.min_bitrate, self.max_bitrate) + self.target_bitrate_on_loss = bitrate.clamp(min_bitrate, max_bitrate) } ControllerType::Delay => { - self.target_bitrate_on_delay = bitrate.clamp(self.min_bitrate, self.max_bitrate) + self.target_bitrate_on_delay = bitrate.clamp(min_bitrate, max_bitrate) } } let target_bitrate = Bitrate::min(self.target_bitrate_on_delay, self.target_bitrate_on_loss) - .clamp(self.min_bitrate, self.max_bitrate); + .clamp(min_bitrate, max_bitrate); if target_bitrate == prev_bitrate { return false;