| /* |
| * Copyright 2025 The WebRTC Project Authors. All rights reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| #ifndef MODULES_CONGESTION_CONTROLLER_SCREAM_DELAY_BASED_CONGESTION_CONTROL_H_ |
| #define MODULES_CONGESTION_CONTROLLER_SCREAM_DELAY_BASED_CONGESTION_CONTROL_H_ |
| |
| #include <algorithm> |
| |
| #include "api/transport/network_types.h" |
| #include "api/units/data_rate.h" |
| #include "api/units/data_size.h" |
| #include "api/units/time_delta.h" |
| #include "api/units/timestamp.h" |
| #include "modules/congestion_controller/scream/scream_v2_parameters.h" |
| #include "rtc_base/numerics/windowed_min_filter.h" |
| |
| namespace webrtc { |
| |
| // Implements logic necessary for backing off if queue delay increase as |
| // proposed in |
| // https://datatracker.ietf.org/doc/draft-johansson-ccwg-rfc8298bis-screamv2/. |
| // The functionality is split out into a separate class since it may be possible |
| // to replace this logic with the trend line filter from Goog CC or a ML model. |
| class DelayBasedCongestionControl { |
| public: |
| explicit DelayBasedCongestionControl(ScreamV2Parameters params); |
| |
| void OnTransportPacketsFeedback(const TransportPacketsFeedback& msg, |
| bool alr); |
| |
| // Set a limit on how much the reference window can be reduced due to |
| // increased delay. |
| void SetMinDelayBasedBwe(DataRate min_delay_based_bwe) { |
| min_delay_based_bwe_ = min_delay_based_bwe; |
| } |
| |
| // Returns true if queue delay is detected and above a threshold. |
| bool IsQueueDelayDetected() const { |
| return queue_delay_avg_.IsFinite() && |
| queue_delay_avg_ > params_.queue_delay_target.Get() / 2; |
| } |
| |
| DataSize UpdateReferenceWindow(DataSize rew_window, |
| double ref_window_mss_ratio) const; |
| |
| // Returns false if the minimum queue delay has been above the drain threshold |
| // for a prolonged time. This can happen if minimum possible latency has |
| // increased, or queues has been filled for a longer period of time without |
| // being drained. |
| bool IsQueueDrainedInTime(Timestamp now) const { |
| return min_queue_delay_above_threshold_start_.IsInfinite() || |
| (now - min_queue_delay_above_threshold_start_ < |
| params_.queue_delay_drain_period.Get()); |
| } |
| |
| // Resets queue delay estimates to start values. |
| void ResetQueueDelay(); |
| |
| TimeDelta queue_delay() const { return queue_delay_avg_; } |
| |
| TimeDelta queue_delay_min_avg() const { return queue_delay_min_avg_; } |
| TimeDelta latency_difference_avg() const { return latency_difference_avg_; } |
| |
| // Scale factor used for scaling reference window increase/decrease due to |
| // minimum average queue delay per feedback. The scale factor is 0.1 |
| // if the delay is higher than the threshold, and increases linearly to 1.0 if |
| // the delay is lower than the threshold / 4. |
| double ref_window_scale_factor_due_to_avg_min_delay( |
| bool allow_zero = false) const; |
| |
| // Scale factor used for scaling reference window increase if |
| // latency differences per feedback is larger than the threshold. If the send |
| // rate is close to link capacity, the difference between min and max latency |
| // per feedback increases and the scale factor decreases. |
| double ref_window_scale_factor_due_to_latency_difference() const; |
| |
| TimeDelta rtt() const { return last_smoothed_rtt_; } |
| |
| double l4s_alpha_v() const; |
| |
| private: |
| TimeDelta min_base_delay() const { |
| return std::min(next_base_delay_, base_delay_history_.GetMin()); |
| } |
| void UpdateSmoothedRtt(TimeDelta rtt_sample, bool alr); |
| void UpdateQueueDelayAverage(TimeDelta one_way_delay); |
| void UpdateQueueDelayMinAverage(TimeDelta packet_qdelay); |
| void UpdateLatencyDifferenceAverage(TimeDelta packet_latency_diff); |
| |
| const ScreamV2Parameters params_; |
| |
| DataRate min_delay_based_bwe_; |
| |
| // For computing min one way delay and compensate for clock drift. |
| // Based on https://datatracker.ietf.org/doc/html/rfc6817 |
| Timestamp last_base_delay_update_ = Timestamp::MinusInfinity(); |
| TimeDelta next_base_delay_ = TimeDelta::PlusInfinity(); |
| WindowedMinFilter<TimeDelta> base_delay_history_; |
| |
| Timestamp min_queue_delay_above_threshold_start_ = Timestamp::MinusInfinity(); |
| TimeDelta last_smoothed_rtt_ = TimeDelta::Zero(); |
| |
| Timestamp last_update_qdelay_avg_time_ = Timestamp::MinusInfinity(); |
| TimeDelta last_queue_delay_sample_ = TimeDelta::PlusInfinity(); |
| TimeDelta queue_delay_avg_ = TimeDelta::PlusInfinity(); |
| TimeDelta queue_delay_min_avg_ = TimeDelta::Zero(); |
| TimeDelta latency_difference_avg_ = TimeDelta::Zero(); |
| }; |
| |
| } // namespace webrtc |
| #endif // MODULES_CONGESTION_CONTROLLER_SCREAM_DELAY_BASED_CONGESTION_CONTROL_H_ |