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