pcc_network_controller.cc (15795B)
1 /* 2 * Copyright (c) 2018 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 #include "modules/congestion_controller/pcc/pcc_network_controller.h" 12 13 #include <algorithm> 14 #include <cstddef> 15 #include <cstdint> 16 #include <optional> 17 18 #include "api/transport/network_control.h" 19 #include "api/transport/network_types.h" 20 #include "api/units/data_rate.h" 21 #include "api/units/data_size.h" 22 #include "api/units/time_delta.h" 23 #include "api/units/timestamp.h" 24 #include "rtc_base/checks.h" 25 26 namespace webrtc { 27 namespace pcc { 28 namespace { 29 constexpr int64_t kInitialRttMs = 200; 30 constexpr int64_t kInitialBandwidthKbps = 300; 31 constexpr double kMonitorIntervalDurationRatio = 1; 32 constexpr double kDefaultSamplingStep = 0.05; 33 constexpr double kTimeoutRatio = 2; 34 constexpr double kAlphaForRtt = 0.9; 35 constexpr double kSlowStartModeIncrease = 1.5; 36 37 constexpr double kAlphaForPacketInterval = 0.9; 38 constexpr int64_t kMinPacketsNumberPerInterval = 20; 39 const TimeDelta kMinDurationOfMonitorInterval = TimeDelta::Millis(50); 40 const TimeDelta kStartupDuration = TimeDelta::Millis(500); 41 constexpr double kMinRateChangeBps = 4000; 42 constexpr DataRate kMinRateHaveMultiplicativeRateChange = DataRate::BitsPerSec( 43 static_cast<int64_t>(kMinRateChangeBps / kDefaultSamplingStep)); 44 45 // Bitrate controller constants. 46 constexpr double kInitialConversionFactor = 5; 47 constexpr double kInitialDynamicBoundary = 0.1; 48 constexpr double kDynamicBoundaryIncrement = 0.1; 49 // Utility function parameters. 50 constexpr double kRttGradientCoefficientBps = 0.005; 51 constexpr double kLossCoefficientBps = 10; 52 constexpr double kThroughputCoefficient = 0.001; 53 constexpr double kThroughputPower = 0.9; 54 constexpr double kRttGradientThreshold = 0.01; 55 constexpr double kDelayGradientNegativeBound = 0.1; 56 57 constexpr int64_t kNumberOfPacketsToKeep = 20; 58 const uint64_t kRandomSeed = 100; 59 } // namespace 60 61 PccNetworkController::PccNetworkController(NetworkControllerConfig config) 62 : start_time_(Timestamp::PlusInfinity()), 63 last_sent_packet_time_(Timestamp::PlusInfinity()), 64 smoothed_packets_sending_interval_(TimeDelta::Zero()), 65 mode_(Mode::kStartup), 66 default_bandwidth_(DataRate::KilobitsPerSec(kInitialBandwidthKbps)), 67 bandwidth_estimate_(default_bandwidth_), 68 rtt_tracker_(TimeDelta::Millis(kInitialRttMs), kAlphaForRtt), 69 monitor_interval_timeout_(TimeDelta::Millis(kInitialRttMs) * 70 kTimeoutRatio), 71 monitor_interval_length_strategy_(MonitorIntervalLengthStrategy::kFixed), 72 monitor_interval_duration_ratio_(kMonitorIntervalDurationRatio), 73 sampling_step_(kDefaultSamplingStep), 74 monitor_interval_timeout_ratio_(kTimeoutRatio), 75 min_packets_number_per_interval_(kMinPacketsNumberPerInterval), 76 bitrate_controller_(kInitialConversionFactor, 77 kInitialDynamicBoundary, 78 kDynamicBoundaryIncrement, 79 kRttGradientCoefficientBps, 80 kLossCoefficientBps, 81 kThroughputCoefficient, 82 kThroughputPower, 83 kRttGradientThreshold, 84 kDelayGradientNegativeBound), 85 monitor_intervals_duration_(TimeDelta::Zero()), 86 complete_feedback_monitor_interval_number_(0), 87 random_generator_(kRandomSeed) { 88 if (config.constraints.starting_rate) { 89 default_bandwidth_ = *config.constraints.starting_rate; 90 bandwidth_estimate_ = default_bandwidth_; 91 } 92 } 93 94 PccNetworkController::~PccNetworkController() {} 95 96 NetworkControlUpdate PccNetworkController::CreateRateUpdate( 97 Timestamp at_time) const { 98 DataRate sending_rate = DataRate::Zero(); 99 if (monitor_intervals_.empty() || 100 (monitor_intervals_.size() >= monitor_intervals_bitrates_.size() && 101 at_time >= monitor_intervals_.back().GetEndTime())) { 102 sending_rate = bandwidth_estimate_; 103 } else { 104 sending_rate = monitor_intervals_.back().GetTargetSendingRate(); 105 } 106 // Set up config when sending rate is computed. 107 NetworkControlUpdate update; 108 109 // Set up target rate to encoder. 110 TargetTransferRate target_rate_msg; 111 target_rate_msg.at_time = at_time; 112 target_rate_msg.network_estimate.at_time = at_time; 113 target_rate_msg.network_estimate.round_trip_time = rtt_tracker_.GetRtt(); 114 // TODO(koloskova): Add correct estimate. 115 target_rate_msg.network_estimate.loss_rate_ratio = 0; 116 target_rate_msg.network_estimate.bwe_period = 117 monitor_interval_duration_ratio_ * rtt_tracker_.GetRtt(); 118 119 target_rate_msg.target_rate = sending_rate; 120 update.target_rate = target_rate_msg; 121 122 // Set up pacing/padding target rate. 123 PacerConfig pacer_config; 124 pacer_config.at_time = at_time; 125 pacer_config.time_window = TimeDelta::Millis(1); 126 pacer_config.data_window = sending_rate * pacer_config.time_window; 127 pacer_config.pad_window = sending_rate * pacer_config.time_window; 128 129 update.pacer_config = pacer_config; 130 return update; 131 } 132 133 NetworkControlUpdate PccNetworkController::OnSentPacket(SentPacket msg) { 134 // Start new monitor interval if previous has finished. 135 // Monitor interval is initialized in OnProcessInterval function. 136 if (start_time_.IsInfinite()) { 137 start_time_ = msg.send_time; 138 monitor_intervals_duration_ = kStartupDuration; 139 monitor_intervals_bitrates_ = {bandwidth_estimate_}; 140 monitor_intervals_.emplace_back(bandwidth_estimate_, msg.send_time, 141 monitor_intervals_duration_); 142 complete_feedback_monitor_interval_number_ = 0; 143 } 144 if (last_sent_packet_time_.IsFinite()) { 145 smoothed_packets_sending_interval_ = 146 (msg.send_time - last_sent_packet_time_) * kAlphaForPacketInterval + 147 (1 - kAlphaForPacketInterval) * smoothed_packets_sending_interval_; 148 } 149 last_sent_packet_time_ = msg.send_time; 150 if (!monitor_intervals_.empty() && 151 msg.send_time >= monitor_intervals_.back().GetEndTime() && 152 monitor_intervals_bitrates_.size() > monitor_intervals_.size()) { 153 // Start new monitor interval. 154 monitor_intervals_.emplace_back( 155 monitor_intervals_bitrates_[monitor_intervals_.size()], msg.send_time, 156 monitor_intervals_duration_); 157 } 158 if (IsTimeoutExpired(msg.send_time)) { 159 DataSize received_size = DataSize::Zero(); 160 for (size_t i = 1; i < last_received_packets_.size(); ++i) { 161 received_size += last_received_packets_[i].sent_packet.size; 162 } 163 TimeDelta sending_time = TimeDelta::Zero(); 164 if (!last_received_packets_.empty()) 165 sending_time = last_received_packets_.back().receive_time - 166 last_received_packets_.front().receive_time; 167 DataRate receiving_rate = bandwidth_estimate_; 168 if (sending_time > TimeDelta::Zero()) 169 receiving_rate = received_size / sending_time; 170 bandwidth_estimate_ = 171 std::min<DataRate>(bandwidth_estimate_ * 0.5, receiving_rate); 172 if (mode_ == Mode::kSlowStart) 173 mode_ = Mode::kOnlineLearning; 174 } 175 if (mode_ == Mode::kStartup && 176 msg.send_time - start_time_ >= kStartupDuration) { 177 DataSize received_size = DataSize::Zero(); 178 for (size_t i = 1; i < last_received_packets_.size(); ++i) { 179 received_size += last_received_packets_[i].sent_packet.size; 180 } 181 TimeDelta sending_time = TimeDelta::Zero(); 182 if (!last_received_packets_.empty()) 183 sending_time = last_received_packets_.back().receive_time - 184 last_received_packets_.front().receive_time; 185 DataRate receiving_rate = bandwidth_estimate_; 186 if (sending_time > TimeDelta::Zero()) 187 receiving_rate = received_size / sending_time; 188 bandwidth_estimate_ = receiving_rate; 189 monitor_intervals_.clear(); 190 mode_ = Mode::kSlowStart; 191 monitor_intervals_duration_ = ComputeMonitorIntervalsDuration(); 192 monitor_intervals_bitrates_ = {bandwidth_estimate_}; 193 monitor_intervals_.emplace_back(bandwidth_estimate_, msg.send_time, 194 monitor_intervals_duration_); 195 bandwidth_estimate_ = bandwidth_estimate_ * (1 / kSlowStartModeIncrease); 196 complete_feedback_monitor_interval_number_ = 0; 197 return CreateRateUpdate(msg.send_time); 198 } 199 if (IsFeedbackCollectionDone() || IsTimeoutExpired(msg.send_time)) { 200 // Creating new monitor intervals. 201 monitor_intervals_.clear(); 202 monitor_interval_timeout_ = 203 rtt_tracker_.GetRtt() * monitor_interval_timeout_ratio_; 204 monitor_intervals_duration_ = ComputeMonitorIntervalsDuration(); 205 complete_feedback_monitor_interval_number_ = 0; 206 // Compute bitrates and start first monitor interval. 207 if (mode_ == Mode::kSlowStart) { 208 monitor_intervals_bitrates_ = {kSlowStartModeIncrease * 209 bandwidth_estimate_}; 210 monitor_intervals_.emplace_back( 211 kSlowStartModeIncrease * bandwidth_estimate_, msg.send_time, 212 monitor_intervals_duration_); 213 } else { 214 RTC_DCHECK(mode_ == Mode::kOnlineLearning || mode_ == Mode::kDoubleCheck); 215 monitor_intervals_.clear(); 216 int64_t sign = 2 * (random_generator_.Rand(0, 1) % 2) - 1; 217 RTC_DCHECK_GE(sign, -1); 218 RTC_DCHECK_LE(sign, 1); 219 if (bandwidth_estimate_ >= kMinRateHaveMultiplicativeRateChange) { 220 monitor_intervals_bitrates_ = { 221 bandwidth_estimate_ * (1 + sign * sampling_step_), 222 bandwidth_estimate_ * (1 - sign * sampling_step_)}; 223 } else { 224 monitor_intervals_bitrates_ = { 225 DataRate::BitsPerSec(std::max<double>( 226 bandwidth_estimate_.bps() + sign * kMinRateChangeBps, 0)), 227 DataRate::BitsPerSec(std::max<double>( 228 bandwidth_estimate_.bps() - sign * kMinRateChangeBps, 0))}; 229 } 230 monitor_intervals_.emplace_back(monitor_intervals_bitrates_[0], 231 msg.send_time, 232 monitor_intervals_duration_); 233 } 234 } 235 return CreateRateUpdate(msg.send_time); 236 } 237 238 TimeDelta PccNetworkController::ComputeMonitorIntervalsDuration() const { 239 TimeDelta monitor_intervals_duration = TimeDelta::Zero(); 240 if (monitor_interval_length_strategy_ == 241 MonitorIntervalLengthStrategy::kAdaptive) { 242 monitor_intervals_duration = std::max( 243 rtt_tracker_.GetRtt() * monitor_interval_duration_ratio_, 244 smoothed_packets_sending_interval_ * min_packets_number_per_interval_); 245 } else { 246 RTC_DCHECK(monitor_interval_length_strategy_ == 247 MonitorIntervalLengthStrategy::kFixed); 248 monitor_intervals_duration = 249 smoothed_packets_sending_interval_ * min_packets_number_per_interval_; 250 } 251 monitor_intervals_duration = 252 std::max(kMinDurationOfMonitorInterval, monitor_intervals_duration); 253 return monitor_intervals_duration; 254 } 255 256 bool PccNetworkController::IsTimeoutExpired(Timestamp current_time) const { 257 if (complete_feedback_monitor_interval_number_ >= monitor_intervals_.size()) { 258 return false; 259 } 260 return current_time - 261 monitor_intervals_[complete_feedback_monitor_interval_number_] 262 .GetEndTime() >= 263 monitor_interval_timeout_; 264 } 265 266 bool PccNetworkController::IsFeedbackCollectionDone() const { 267 return complete_feedback_monitor_interval_number_ >= 268 monitor_intervals_bitrates_.size(); 269 } 270 271 NetworkControlUpdate PccNetworkController::OnTransportPacketsFeedback( 272 TransportPacketsFeedback msg) { 273 if (msg.packet_feedbacks.empty()) 274 return NetworkControlUpdate(); 275 // Save packets to last_received_packets_ array. 276 for (const PacketResult& packet_result : msg.ReceivedWithSendInfo()) { 277 last_received_packets_.push_back(packet_result); 278 } 279 while (last_received_packets_.size() > kNumberOfPacketsToKeep) { 280 last_received_packets_.pop_front(); 281 } 282 rtt_tracker_.OnPacketsFeedback(msg.PacketsWithFeedback(), msg.feedback_time); 283 // Skip rate update in case when online learning mode just started, but 284 // corresponding monitor intervals were not started yet. 285 if (mode_ == Mode::kOnlineLearning && 286 monitor_intervals_bitrates_.size() < 2) { 287 return NetworkControlUpdate(); 288 } 289 if (!IsFeedbackCollectionDone() && !monitor_intervals_.empty()) { 290 while (complete_feedback_monitor_interval_number_ < 291 monitor_intervals_.size()) { 292 monitor_intervals_[complete_feedback_monitor_interval_number_] 293 .OnPacketsFeedback(msg.PacketsWithFeedback()); 294 if (!monitor_intervals_[complete_feedback_monitor_interval_number_] 295 .IsFeedbackCollectionDone()) 296 break; 297 ++complete_feedback_monitor_interval_number_; 298 } 299 } 300 if (IsFeedbackCollectionDone()) { 301 if (mode_ == Mode::kDoubleCheck) { 302 mode_ = Mode::kOnlineLearning; 303 } else if (NeedDoubleCheckMeasurments()) { 304 mode_ = Mode::kDoubleCheck; 305 } 306 if (mode_ != Mode::kDoubleCheck) 307 UpdateSendingRateAndMode(); 308 } 309 return NetworkControlUpdate(); 310 } 311 312 bool PccNetworkController::NeedDoubleCheckMeasurments() const { 313 if (mode_ == Mode::kSlowStart) { 314 return false; 315 } 316 double first_loss_rate = monitor_intervals_[0].GetLossRate(); 317 double second_loss_rate = monitor_intervals_[1].GetLossRate(); 318 DataRate first_bitrate = monitor_intervals_[0].GetTargetSendingRate(); 319 DataRate second_bitrate = monitor_intervals_[1].GetTargetSendingRate(); 320 if ((first_bitrate.bps() - second_bitrate.bps()) * 321 (first_loss_rate - second_loss_rate) < 322 0) { 323 return true; 324 } 325 return false; 326 } 327 328 void PccNetworkController::UpdateSendingRateAndMode() { 329 if (monitor_intervals_.empty() || !IsFeedbackCollectionDone()) { 330 return; 331 } 332 if (mode_ == Mode::kSlowStart) { 333 DataRate old_bandwidth_estimate = bandwidth_estimate_; 334 bandwidth_estimate_ = 335 bitrate_controller_ 336 .ComputeRateUpdateForSlowStartMode(monitor_intervals_[0]) 337 .value_or(bandwidth_estimate_); 338 if (bandwidth_estimate_ <= old_bandwidth_estimate) 339 mode_ = Mode::kOnlineLearning; 340 } else { 341 RTC_DCHECK(mode_ == Mode::kOnlineLearning); 342 bandwidth_estimate_ = 343 bitrate_controller_.ComputeRateUpdateForOnlineLearningMode( 344 monitor_intervals_, bandwidth_estimate_); 345 } 346 } 347 348 NetworkControlUpdate PccNetworkController::OnNetworkAvailability( 349 NetworkAvailability /* msg */) { 350 return NetworkControlUpdate(); 351 } 352 353 NetworkControlUpdate PccNetworkController::OnNetworkRouteChange( 354 NetworkRouteChange /* msg */) { 355 return NetworkControlUpdate(); 356 } 357 358 NetworkControlUpdate PccNetworkController::OnProcessInterval( 359 ProcessInterval msg) { 360 return CreateRateUpdate(msg.at_time); 361 } 362 363 NetworkControlUpdate PccNetworkController::OnTargetRateConstraints( 364 TargetRateConstraints /* msg */) { 365 return NetworkControlUpdate(); 366 } 367 368 NetworkControlUpdate PccNetworkController::OnRemoteBitrateReport( 369 RemoteBitrateReport) { 370 return NetworkControlUpdate(); 371 } 372 373 NetworkControlUpdate PccNetworkController::OnRoundTripTimeUpdate( 374 RoundTripTimeUpdate) { 375 return NetworkControlUpdate(); 376 } 377 378 NetworkControlUpdate PccNetworkController::OnTransportLossReport( 379 TransportLossReport) { 380 return NetworkControlUpdate(); 381 } 382 383 NetworkControlUpdate PccNetworkController::OnStreamsConfig( 384 StreamsConfig /* msg */) { 385 return NetworkControlUpdate(); 386 } 387 388 NetworkControlUpdate PccNetworkController::OnReceivedPacket( 389 ReceivedPacket /* msg */) { 390 return NetworkControlUpdate(); 391 } 392 393 NetworkControlUpdate PccNetworkController::OnNetworkStateEstimate( 394 NetworkStateEstimate /* msg */) { 395 return NetworkControlUpdate(); 396 } 397 398 } // namespace pcc 399 } // namespace webrtc