| /* | |
| * 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); | |
| // 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); | |
| 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_ |