| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/modules/congestion_controller/include/send_side_congestion_cont
roller.h" | 11 #include "webrtc/modules/congestion_controller/include/send_side_congestion_cont
roller.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <memory> | 14 #include <memory> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" | 17 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" |
| 18 #include "webrtc/modules/congestion_controller/acknowledged_bitrate_estimator.h" | 18 #include "webrtc/modules/congestion_controller/acknowledged_bitrate_estimator.h" |
| 19 #include "webrtc/modules/congestion_controller/probe_controller.h" | 19 #include "webrtc/modules/congestion_controller/probe_controller.h" |
| 20 #include "webrtc/modules/pacing/alr_detector.h" | 20 #include "webrtc/modules/pacing/alr_detector.h" |
| 21 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" | 21 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" |
| 22 #include "webrtc/rtc_base/checks.h" | 22 #include "webrtc/rtc_base/checks.h" |
| 23 #include "webrtc/rtc_base/logging.h" | 23 #include "webrtc/rtc_base/logging.h" |
| 24 #include "webrtc/rtc_base/ptr_util.h" | 24 #include "webrtc/rtc_base/ptr_util.h" |
| 25 #include "webrtc/rtc_base/rate_limiter.h" | 25 #include "webrtc/rtc_base/rate_limiter.h" |
| 26 #include "webrtc/rtc_base/socket.h" | 26 #include "webrtc/rtc_base/socket.h" |
| 27 #include "webrtc/rtc_base/timeutils.h" | 27 #include "webrtc/rtc_base/timeutils.h" |
| 28 #include "webrtc/system_wrappers/include/field_trial.h" | |
| 29 | 28 |
| 30 namespace webrtc { | 29 namespace webrtc { |
| 31 namespace { | 30 namespace { |
| 32 | 31 |
| 33 const char kCwndExperiment[] = "WebRTC-CwndExperiment"; | |
| 34 | |
| 35 bool CwndExperimentEnabled() { | |
| 36 std::string experiment_string = | |
| 37 webrtc::field_trial::FindFullName(kCwndExperiment); | |
| 38 // The experiment is enabled iff the field trial string begins with "Enabled". | |
| 39 return experiment_string.find("Enabled") == 0; | |
| 40 } | |
| 41 | |
| 42 static const int64_t kRetransmitWindowSizeMs = 500; | 32 static const int64_t kRetransmitWindowSizeMs = 500; |
| 43 | 33 |
| 44 // Makes sure that the bitrate and the min, max values are in valid range. | 34 // Makes sure that the bitrate and the min, max values are in valid range. |
| 45 static void ClampBitrates(int* bitrate_bps, | 35 static void ClampBitrates(int* bitrate_bps, |
| 46 int* min_bitrate_bps, | 36 int* min_bitrate_bps, |
| 47 int* max_bitrate_bps) { | 37 int* max_bitrate_bps) { |
| 48 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps, | 38 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps, |
| 49 // and that we don't try to set the min bitrate to 0 from any applications. | 39 // and that we don't try to set the min bitrate to 0 from any applications. |
| 50 // The congestion controller should allow a min bitrate of 0. | 40 // The congestion controller should allow a min bitrate of 0. |
| 51 if (*min_bitrate_bps < congestion_controller::GetMinBitrateBps()) | 41 if (*min_bitrate_bps < congestion_controller::GetMinBitrateBps()) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 acknowledged_bitrate_estimator_( | 93 acknowledged_bitrate_estimator_( |
| 104 rtc::MakeUnique<AcknowledgedBitrateEstimator>()), | 94 rtc::MakeUnique<AcknowledgedBitrateEstimator>()), |
| 105 probe_controller_(new ProbeController(pacer_.get(), clock_)), | 95 probe_controller_(new ProbeController(pacer_.get(), clock_)), |
| 106 retransmission_rate_limiter_( | 96 retransmission_rate_limiter_( |
| 107 new RateLimiter(clock, kRetransmitWindowSizeMs)), | 97 new RateLimiter(clock, kRetransmitWindowSizeMs)), |
| 108 transport_feedback_adapter_(clock_), | 98 transport_feedback_adapter_(clock_), |
| 109 last_reported_bitrate_bps_(0), | 99 last_reported_bitrate_bps_(0), |
| 110 last_reported_fraction_loss_(0), | 100 last_reported_fraction_loss_(0), |
| 111 last_reported_rtt_(0), | 101 last_reported_rtt_(0), |
| 112 network_state_(kNetworkUp), | 102 network_state_(kNetworkUp), |
| 113 pause_pacer_(false), | |
| 114 pacer_paused_(false), | |
| 115 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()), | 103 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()), |
| 116 delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)), | 104 delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)), |
| 117 in_cwnd_experiment_(CwndExperimentEnabled()), | |
| 118 was_in_alr_(0) { | 105 was_in_alr_(0) { |
| 119 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); | 106 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); |
| 120 } | 107 } |
| 121 | 108 |
| 122 SendSideCongestionController::~SendSideCongestionController() {} | 109 SendSideCongestionController::~SendSideCongestionController() {} |
| 123 | 110 |
| 124 void SendSideCongestionController::RegisterPacketFeedbackObserver( | 111 void SendSideCongestionController::RegisterPacketFeedbackObserver( |
| 125 PacketFeedbackObserver* observer) { | 112 PacketFeedbackObserver* observer) { |
| 126 transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer); | 113 transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer); |
| 127 } | 114 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 } | 212 } |
| 226 | 213 |
| 227 TransportFeedbackObserver* | 214 TransportFeedbackObserver* |
| 228 SendSideCongestionController::GetTransportFeedbackObserver() { | 215 SendSideCongestionController::GetTransportFeedbackObserver() { |
| 229 return this; | 216 return this; |
| 230 } | 217 } |
| 231 | 218 |
| 232 void SendSideCongestionController::SignalNetworkState(NetworkState state) { | 219 void SendSideCongestionController::SignalNetworkState(NetworkState state) { |
| 233 LOG(LS_INFO) << "SignalNetworkState " | 220 LOG(LS_INFO) << "SignalNetworkState " |
| 234 << (state == kNetworkUp ? "Up" : "Down"); | 221 << (state == kNetworkUp ? "Up" : "Down"); |
| 222 if (state == kNetworkUp) { |
| 223 pacer_->Resume(); |
| 224 } else { |
| 225 pacer_->Pause(); |
| 226 } |
| 235 { | 227 { |
| 236 rtc::CritScope cs(&network_state_lock_); | 228 rtc::CritScope cs(&network_state_lock_); |
| 237 pause_pacer_ = state == kNetworkDown; | |
| 238 network_state_ = state; | 229 network_state_ = state; |
| 239 } | 230 } |
| 240 probe_controller_->OnNetworkStateChanged(state); | 231 probe_controller_->OnNetworkStateChanged(state); |
| 241 MaybeTriggerOnNetworkChanged(); | 232 MaybeTriggerOnNetworkChanged(); |
| 242 } | 233 } |
| 243 | 234 |
| 244 void SendSideCongestionController::SetTransportOverhead( | 235 void SendSideCongestionController::SetTransportOverhead( |
| 245 size_t transport_overhead_bytes_per_packet) { | 236 size_t transport_overhead_bytes_per_packet) { |
| 246 transport_feedback_adapter_.SetTransportOverhead( | 237 transport_feedback_adapter_.SetTransportOverhead( |
| 247 transport_overhead_bytes_per_packet); | 238 transport_overhead_bytes_per_packet); |
| 248 } | 239 } |
| 249 | 240 |
| 250 void SendSideCongestionController::OnSentPacket( | 241 void SendSideCongestionController::OnSentPacket( |
| 251 const rtc::SentPacket& sent_packet) { | 242 const rtc::SentPacket& sent_packet) { |
| 252 // We're not interested in packets without an id, which may be stun packets, | 243 // We're not interested in packets without an id, which may be stun packets, |
| 253 // etc, sent on the same transport. | 244 // etc, sent on the same transport. |
| 254 if (sent_packet.packet_id == -1) | 245 if (sent_packet.packet_id == -1) |
| 255 return; | 246 return; |
| 256 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id, | 247 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id, |
| 257 sent_packet.send_time_ms); | 248 sent_packet.send_time_ms); |
| 258 LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes()); | |
| 259 } | 249 } |
| 260 | 250 |
| 261 void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, | 251 void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, |
| 262 int64_t max_rtt_ms) { | 252 int64_t max_rtt_ms) { |
| 263 rtc::CritScope cs(&bwe_lock_); | 253 rtc::CritScope cs(&bwe_lock_); |
| 264 delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); | 254 delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); |
| 265 } | 255 } |
| 266 | 256 |
| 267 int64_t SendSideCongestionController::TimeUntilNextProcess() { | 257 int64_t SendSideCongestionController::TimeUntilNextProcess() { |
| 268 return bitrate_controller_->TimeUntilNextProcess(); | 258 return bitrate_controller_->TimeUntilNextProcess(); |
| 269 } | 259 } |
| 270 | 260 |
| 271 void SendSideCongestionController::Process() { | 261 void SendSideCongestionController::Process() { |
| 272 bool pause_pacer; | |
| 273 // TODO(holmer): Once this class is running on a task queue we should | |
| 274 // replace this with a task instead. | |
| 275 { | |
| 276 rtc::CritScope lock(&network_state_lock_); | |
| 277 pause_pacer = pause_pacer_; | |
| 278 } | |
| 279 if (pause_pacer && !pacer_paused_) { | |
| 280 pacer_->Pause(); | |
| 281 pacer_paused_ = true; | |
| 282 } else if (!pause_pacer && pacer_paused_) { | |
| 283 pacer_->Resume(); | |
| 284 pacer_paused_ = false; | |
| 285 } | |
| 286 bitrate_controller_->Process(); | 262 bitrate_controller_->Process(); |
| 287 probe_controller_->Process(); | 263 probe_controller_->Process(); |
| 288 MaybeTriggerOnNetworkChanged(); | 264 MaybeTriggerOnNetworkChanged(); |
| 289 } | 265 } |
| 290 | 266 |
| 291 void SendSideCongestionController::AddPacket( | 267 void SendSideCongestionController::AddPacket( |
| 292 uint32_t ssrc, | 268 uint32_t ssrc, |
| 293 uint16_t sequence_number, | 269 uint16_t sequence_number, |
| 294 size_t length, | 270 size_t length, |
| 295 const PacedPacketInfo& pacing_info) { | 271 const PacedPacketInfo& pacing_info) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 322 result = delay_based_bwe_->IncomingPacketFeedbackVector( | 298 result = delay_based_bwe_->IncomingPacketFeedbackVector( |
| 323 feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps()); | 299 feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps()); |
| 324 } | 300 } |
| 325 if (result.updated) { | 301 if (result.updated) { |
| 326 bitrate_controller_->OnDelayBasedBweResult(result); | 302 bitrate_controller_->OnDelayBasedBweResult(result); |
| 327 // Update the estimate in the ProbeController, in case we want to probe. | 303 // Update the estimate in the ProbeController, in case we want to probe. |
| 328 MaybeTriggerOnNetworkChanged(); | 304 MaybeTriggerOnNetworkChanged(); |
| 329 } | 305 } |
| 330 if (result.recovered_from_overuse) | 306 if (result.recovered_from_overuse) |
| 331 probe_controller_->RequestProbe(); | 307 probe_controller_->RequestProbe(); |
| 332 LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes()); | |
| 333 } | |
| 334 | |
| 335 void SendSideCongestionController::LimitOutstandingBytes( | |
| 336 size_t num_outstanding_bytes) { | |
| 337 if (!in_cwnd_experiment_) | |
| 338 return; | |
| 339 { | |
| 340 rtc::CritScope lock(&network_state_lock_); | |
| 341 rtc::Optional<int64_t> min_rtt_ms = | |
| 342 transport_feedback_adapter_.GetMinFeedbackLoopRtt(); | |
| 343 // No valid RTT. Could be because send-side BWE isn't used, in which case | |
| 344 // we don't try to limit the outstanding packets. | |
| 345 if (!min_rtt_ms) | |
| 346 return; | |
| 347 const int64_t kAcceptedQueueMs = 250; | |
| 348 const size_t kMinCwndBytes = 2 * 1500; | |
| 349 size_t max_outstanding_bytes = | |
| 350 std::max<size_t>((*min_rtt_ms + kAcceptedQueueMs) * | |
| 351 last_reported_bitrate_bps_ / 1000 / 8, | |
| 352 kMinCwndBytes); | |
| 353 LOG(LS_INFO) << clock_->TimeInMilliseconds() | |
| 354 << " Outstanding bytes: " << num_outstanding_bytes | |
| 355 << " pacer queue: " << pacer_->QueueInMs() | |
| 356 << " max outstanding: " << max_outstanding_bytes; | |
| 357 LOG(LS_INFO) << "Feedback rtt: " << *min_rtt_ms | |
| 358 << " Bitrate: " << last_reported_bitrate_bps_; | |
| 359 pause_pacer_ = num_outstanding_bytes > max_outstanding_bytes; | |
| 360 } | |
| 361 } | 308 } |
| 362 | 309 |
| 363 std::vector<PacketFeedback> | 310 std::vector<PacketFeedback> |
| 364 SendSideCongestionController::GetTransportFeedbackVector() const { | 311 SendSideCongestionController::GetTransportFeedbackVector() const { |
| 365 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_); | 312 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_); |
| 366 return transport_feedback_adapter_.GetTransportFeedbackVector(); | 313 return transport_feedback_adapter_.GetTransportFeedbackVector(); |
| 367 } | 314 } |
| 368 | 315 |
| 369 void SendSideCongestionController::MaybeTriggerOnNetworkChanged() { | 316 void SendSideCongestionController::MaybeTriggerOnNetworkChanged() { |
| 370 uint32_t bitrate_bps; | 317 uint32_t bitrate_bps; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 418 bool SendSideCongestionController::IsSendQueueFull() const { | 365 bool SendSideCongestionController::IsSendQueueFull() const { |
| 419 return pacer_->ExpectedQueueTimeMs() > PacedSender::kMaxQueueLengthMs; | 366 return pacer_->ExpectedQueueTimeMs() > PacedSender::kMaxQueueLengthMs; |
| 420 } | 367 } |
| 421 | 368 |
| 422 bool SendSideCongestionController::IsNetworkDown() const { | 369 bool SendSideCongestionController::IsNetworkDown() const { |
| 423 rtc::CritScope cs(&network_state_lock_); | 370 rtc::CritScope cs(&network_state_lock_); |
| 424 return network_state_ == kNetworkDown; | 371 return network_state_ == kNetworkDown; |
| 425 } | 372 } |
| 426 | 373 |
| 427 } // namespace webrtc | 374 } // namespace webrtc |
| OLD | NEW |