blob: 50faeb1953b633fbc135cbf82cec9fc3bac34cb1 [file] [log] [blame] [edit]
/*
* 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_SCREAM_V2_H_
#define MODULES_CONGESTION_CONTROLLER_SCREAM_SCREAM_V2_H_
#include <algorithm>
#include "api/environment/environment.h"
#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/delay_based_congestion_control.h"
#include "modules/congestion_controller/scream/scream_v2_parameters.h"
namespace webrtc {
// Implements ScreamV2 based on the draft RFC in
// https://datatracker.ietf.org/doc/draft-johansson-ccwg-rfc8298bis-screamv2/
// Note, this class is currently in development and not all features are yet
// implemented.
// TODO: bugs.webrtc.org/447037083 - revisit this comment when implementation is
// done.
class ScreamV2 {
public:
explicit ScreamV2(const Environment& env);
~ScreamV2() = default;
void SetTargetBitrateConstraints(DataRate min, DataRate max);
void SetFirstTargetRate(DataRate target_rate) { target_rate_ = target_rate; }
void OnTransportPacketsFeedback(const TransportPacketsFeedback& msg);
DataRate target_rate() const {
return std::min(max_target_bitrate_, target_rate_);
}
DataRate pacing_rate() const {
return target_rate_ * params_.pacing_factor.Get();
}
TimeDelta rtt() const { return delay_based_congestion_control_.rtt(); }
// Max data in flight before the send window is full.
DataSize max_data_in_flight() const;
// Target for the upper limit of the number of bytes that can be in
// flight (transmitted but not yet acknowledged)
DataSize ref_window() const { return ref_window_; }
// Last inflection point where ref_window started to decrease.
DataSize ref_window_i() const { return ref_window_i_; }
// Returns the average fraction of ECN-CE marked data units per RTT.
double l4s_alpha() const { return l4s_alpha_; }
// Exposed for easier logging.
const DelayBasedCongestionControl& delay_based_congestion_control() const {
return delay_based_congestion_control_;
}
private:
void UpdateL4SAlpha(const TransportPacketsFeedback& msg);
void UpdateRefWindow(const TransportPacketsFeedback& msg);
void UpdateTargetRate(const TransportPacketsFeedback& msg);
// Ratio between `max_segment_size` and `ref_window_`.
double ref_window_mss_ratio() const {
return params_.max_segment_size.Get() / ref_window_;
}
// Scaling factor for reference window adjustment
// when close to the last known inflection point.
// (4.2.2.1)
double ref_window_scale_factor_close_to_ref_window_i() const {
const double scale_factor =
params_.backoff_scale_factor_close_to_ref_window_i.Get();
double scl =
ref_window_ > ref_window_i_
? scale_factor * (ref_window_ - ref_window_i_) / ref_window_i_
: scale_factor * (ref_window_i_ - ref_window_) / ref_window_i_;
return std::clamp(scl * scl, 0.1, 1.0);
}
// Scale factor for reference window increase. (4.2.2.2)
// Always > 1.0.
double ref_window_multiplicative_scale_factor() const {
return 1.0 + (params_.multiplicative_increase_factor.Get() * ref_window_) /
params_.max_segment_size.Get();
}
const Environment env_;
const ScreamV2Parameters params_;
DataRate max_target_bitrate_ = DataRate::PlusInfinity();
DataRate min_target_bitrate_ = DataRate::Zero();
DataRate target_rate_ = DataRate::Zero();
// Upper limit on the number of bytes that should be in
// flight (transmitted but not yet acknowledged)
DataSize ref_window_;
// Reference window inflection point. I.e, `ref_window_` when congestion was
// noticed. Increase and decrease of `ref_window_` is scaled down around
// `ref_window_i_`.
DataSize ref_window_i_ = DataSize::Bytes(1);
// `allow_ref_window_i_update_` is set to true if `ref_window_` has increased
// since `ref_window_i_` was last set.
bool allow_ref_window_i_update_ = true;
// `l4s_alpha_` tracks the average fraction of ECN-CE marked data units per
// Round-Trip Time.
double l4s_alpha_ = 0.0;
Timestamp last_ce_mark_detected_time_ = Timestamp::MinusInfinity();
// Per-RTT stats
Timestamp last_data_in_flight_update_ = Timestamp::MinusInfinity();
DataSize max_data_in_flight_this_rtt_ = DataSize::Zero();
DataSize max_data_in_flight_prev_rtt_ = DataSize::Zero();
// `last_reaction_to_congestion_time` is called
// `last_congestion_detected_time` in 4.2.2. Reference Window Update.
// Last received feedback that contained a congestion event that may have
// caused a reaction.
Timestamp last_reaction_to_congestion_time_ = Timestamp::MinusInfinity();
Timestamp drain_queue_start_ = Timestamp::MinusInfinity();
DelayBasedCongestionControl delay_based_congestion_control_;
};
} // namespace webrtc
#endif // MODULES_CONGESTION_CONTROLLER_SCREAM_SCREAM_V2_H_