xref: /aosp_15_r20/external/webrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2021 The WebRTC project authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_
12 #define MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_
13 
14 #include <cstddef>
15 #include <deque>
16 #include <vector>
17 
18 #include "absl/types/optional.h"
19 #include "api/array_view.h"
20 #include "api/field_trials_view.h"
21 #include "api/network_state_predictor.h"
22 #include "api/transport/network_types.h"
23 #include "api/units/data_rate.h"
24 #include "api/units/data_size.h"
25 #include "api/units/time_delta.h"
26 #include "api/units/timestamp.h"
27 
28 namespace webrtc {
29 
30 // State of the loss based estimate, which can be either increasing/decreasing
31 // when network is loss limited, or equal to the delay based estimate.
32 enum class LossBasedState {
33   kIncreasing = 0,
34   kDecreasing = 1,
35   kDelayBasedEstimate = 2
36 };
37 
38 class LossBasedBweV2 {
39  public:
40   struct Result {
41     ~Result() = default;
42     DataRate bandwidth_estimate = DataRate::Zero();
43     LossBasedState state = LossBasedState::kDelayBasedEstimate;
44   };
45   // Creates a disabled `LossBasedBweV2` if the
46   // `key_value_config` is not valid.
47   explicit LossBasedBweV2(const FieldTrialsView* key_value_config);
48 
49   LossBasedBweV2(const LossBasedBweV2&) = delete;
50   LossBasedBweV2& operator=(const LossBasedBweV2&) = delete;
51 
52   ~LossBasedBweV2() = default;
53 
54   bool IsEnabled() const;
55   // Returns true iff a BWE can be calculated, i.e., the estimator has been
56   // initialized with a BWE and then has received enough `PacketResult`s.
57   bool IsReady() const;
58 
59   // Returns `DataRate::PlusInfinity` if no BWE can be calculated.
60   Result GetLossBasedResult() const;
61 
62   void SetAcknowledgedBitrate(DataRate acknowledged_bitrate);
63   void SetBandwidthEstimate(DataRate bandwidth_estimate);
64   void SetMinMaxBitrate(DataRate min_bitrate, DataRate max_bitrate);
65   void UpdateBandwidthEstimate(
66       rtc::ArrayView<const PacketResult> packet_results,
67       DataRate delay_based_estimate,
68       BandwidthUsage delay_detector_state,
69       absl::optional<DataRate> probe_bitrate,
70       DataRate upper_link_capacity);
71 
72  private:
73   struct ChannelParameters {
74     double inherent_loss = 0.0;
75     DataRate loss_limited_bandwidth = DataRate::MinusInfinity();
76   };
77 
78   struct Config {
79     double bandwidth_rampup_upper_bound_factor = 0.0;
80     double rampup_acceleration_max_factor = 0.0;
81     TimeDelta rampup_acceleration_maxout_time = TimeDelta::Zero();
82     std::vector<double> candidate_factors;
83     double higher_bandwidth_bias_factor = 0.0;
84     double higher_log_bandwidth_bias_factor = 0.0;
85     double inherent_loss_lower_bound = 0.0;
86     double loss_threshold_of_high_bandwidth_preference = 0.0;
87     double bandwidth_preference_smoothing_factor = 0.0;
88     DataRate inherent_loss_upper_bound_bandwidth_balance =
89         DataRate::MinusInfinity();
90     double inherent_loss_upper_bound_offset = 0.0;
91     double initial_inherent_loss_estimate = 0.0;
92     int newton_iterations = 0;
93     double newton_step_size = 0.0;
94     bool append_acknowledged_rate_candidate = true;
95     bool append_delay_based_estimate_candidate = false;
96     TimeDelta observation_duration_lower_bound = TimeDelta::Zero();
97     int observation_window_size = 0;
98     double sending_rate_smoothing_factor = 0.0;
99     double instant_upper_bound_temporal_weight_factor = 0.0;
100     DataRate instant_upper_bound_bandwidth_balance = DataRate::MinusInfinity();
101     double instant_upper_bound_loss_offset = 0.0;
102     double temporal_weight_factor = 0.0;
103     double bandwidth_backoff_lower_bound_factor = 0.0;
104     bool trendline_integration_enabled = false;
105     int trendline_observations_window_size = 0;
106     double max_increase_factor = 0.0;
107     TimeDelta delayed_increase_window = TimeDelta::Zero();
108     bool use_acked_bitrate_only_when_overusing = false;
109     bool not_increase_if_inherent_loss_less_than_average_loss = false;
110     double high_loss_rate_threshold = 1.0;
111     DataRate bandwidth_cap_at_high_loss_rate = DataRate::MinusInfinity();
112     double slope_of_bwe_high_loss_func = 1000.0;
113     bool probe_integration_enabled = false;
114     bool bound_by_upper_link_capacity_when_loss_limited = false;
115   };
116 
117   struct Derivatives {
118     double first = 0.0;
119     double second = 0.0;
120   };
121 
122   struct Observation {
IsInitializedObservation123     bool IsInitialized() const { return id != -1; }
124 
125     int num_packets = 0;
126     int num_lost_packets = 0;
127     int num_received_packets = 0;
128     DataRate sending_rate = DataRate::MinusInfinity();
129     int id = -1;
130   };
131 
132   struct PartialObservation {
133     int num_packets = 0;
134     int num_lost_packets = 0;
135     DataSize size = DataSize::Zero();
136   };
137 
138   static absl::optional<Config> CreateConfig(
139       const FieldTrialsView* key_value_config);
140   bool IsConfigValid() const;
141 
142   // Returns `0.0` if not enough loss statistics have been received.
143   double GetAverageReportedLossRatio() const;
144   std::vector<ChannelParameters> GetCandidates() const;
145   DataRate GetCandidateBandwidthUpperBound() const;
146   Derivatives GetDerivatives(const ChannelParameters& channel_parameters) const;
147   double GetFeasibleInherentLoss(
148       const ChannelParameters& channel_parameters) const;
149   double GetInherentLossUpperBound(DataRate bandwidth) const;
150   double AdjustBiasFactor(double loss_rate, double bias_factor) const;
151   double GetHighBandwidthBias(DataRate bandwidth) const;
152   double GetObjective(const ChannelParameters& channel_parameters) const;
153   DataRate GetSendingRate(DataRate instantaneous_sending_rate) const;
154   DataRate GetInstantUpperBound() const;
155   void CalculateInstantUpperBound();
156 
157   void CalculateTemporalWeights();
158   void NewtonsMethodUpdate(ChannelParameters& channel_parameters) const;
159 
160   // Returns false if there exists a kBwOverusing or kBwUnderusing in the
161   // window.
162   bool TrendlineEsimateAllowBitrateIncrease() const;
163 
164   // Returns true if there exists an overusing state in the window.
165   bool TrendlineEsimateAllowEmergencyBackoff() const;
166 
167   // Returns false if no observation was created.
168   bool PushBackObservation(rtc::ArrayView<const PacketResult> packet_results,
169                            BandwidthUsage delay_detector_state);
170   void UpdateTrendlineEstimator(
171       const std::vector<PacketResult>& packet_feedbacks,
172       Timestamp at_time);
173   void UpdateDelayDetector(BandwidthUsage delay_detector_state);
174   bool IsEstimateIncreasingWhenLossLimited(
175       const ChannelParameters& best_candidate);
176   bool IsBandwidthLimitedDueToLoss() const;
177   void SetProbeBitrate(absl::optional<DataRate> probe_bitrate);
178 
179   absl::optional<DataRate> acknowledged_bitrate_;
180   absl::optional<Config> config_;
181   ChannelParameters current_estimate_;
182   int num_observations_ = 0;
183   std::vector<Observation> observations_;
184   PartialObservation partial_observation_;
185   Timestamp last_send_time_most_recent_observation_ = Timestamp::PlusInfinity();
186   Timestamp last_time_estimate_reduced_ = Timestamp::MinusInfinity();
187   absl::optional<DataRate> cached_instant_upper_bound_;
188   std::vector<double> instant_upper_bound_temporal_weights_;
189   std::vector<double> temporal_weights_;
190   std::deque<BandwidthUsage> delay_detector_states_;
191   Timestamp recovering_after_loss_timestamp_ = Timestamp::MinusInfinity();
192   DataRate bandwidth_limit_in_current_window_ = DataRate::PlusInfinity();
193   DataRate min_bitrate_ = DataRate::KilobitsPerSec(1);
194   DataRate max_bitrate_ = DataRate::PlusInfinity();
195   LossBasedState current_state_ = LossBasedState::kDelayBasedEstimate;
196   DataRate probe_bitrate_ = DataRate::PlusInfinity();
197   DataRate delay_based_estimate_ = DataRate::PlusInfinity();
198   DataRate upper_link_capacity_ = DataRate::PlusInfinity();
199 };
200 
201 }  // namespace webrtc
202 
203 #endif  // MODULES_CONGESTION_CONTROLLER_GOOG_CC_LOSS_BASED_BWE_V2_H_
204