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" |
28 | 29 |
29 namespace webrtc { | 30 namespace webrtc { |
30 namespace { | 31 namespace { |
31 | 32 |
| 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 |
32 static const int64_t kRetransmitWindowSizeMs = 500; | 42 static const int64_t kRetransmitWindowSizeMs = 500; |
33 | 43 |
34 // Makes sure that the bitrate and the min, max values are in valid range. | 44 // Makes sure that the bitrate and the min, max values are in valid range. |
35 static void ClampBitrates(int* bitrate_bps, | 45 static void ClampBitrates(int* bitrate_bps, |
36 int* min_bitrate_bps, | 46 int* min_bitrate_bps, |
37 int* max_bitrate_bps) { | 47 int* max_bitrate_bps) { |
38 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps, | 48 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps, |
39 // and that we don't try to set the min bitrate to 0 from any applications. | 49 // and that we don't try to set the min bitrate to 0 from any applications. |
40 // The congestion controller should allow a min bitrate of 0. | 50 // The congestion controller should allow a min bitrate of 0. |
41 if (*min_bitrate_bps < congestion_controller::GetMinBitrateBps()) | 51 if (*min_bitrate_bps < congestion_controller::GetMinBitrateBps()) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 acknowledged_bitrate_estimator_( | 103 acknowledged_bitrate_estimator_( |
94 rtc::MakeUnique<AcknowledgedBitrateEstimator>()), | 104 rtc::MakeUnique<AcknowledgedBitrateEstimator>()), |
95 probe_controller_(new ProbeController(pacer_.get(), clock_)), | 105 probe_controller_(new ProbeController(pacer_.get(), clock_)), |
96 retransmission_rate_limiter_( | 106 retransmission_rate_limiter_( |
97 new RateLimiter(clock, kRetransmitWindowSizeMs)), | 107 new RateLimiter(clock, kRetransmitWindowSizeMs)), |
98 transport_feedback_adapter_(clock_), | 108 transport_feedback_adapter_(clock_), |
99 last_reported_bitrate_bps_(0), | 109 last_reported_bitrate_bps_(0), |
100 last_reported_fraction_loss_(0), | 110 last_reported_fraction_loss_(0), |
101 last_reported_rtt_(0), | 111 last_reported_rtt_(0), |
102 network_state_(kNetworkUp), | 112 network_state_(kNetworkUp), |
| 113 pause_pacer_(false), |
| 114 pacer_paused_(false), |
103 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()), | 115 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()), |
104 delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)), | 116 delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)), |
| 117 in_cwnd_experiment_(CwndExperimentEnabled()), |
105 was_in_alr_(0) { | 118 was_in_alr_(0) { |
106 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); | 119 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); |
107 } | 120 } |
108 | 121 |
109 SendSideCongestionController::~SendSideCongestionController() {} | 122 SendSideCongestionController::~SendSideCongestionController() {} |
110 | 123 |
111 void SendSideCongestionController::RegisterPacketFeedbackObserver( | 124 void SendSideCongestionController::RegisterPacketFeedbackObserver( |
112 PacketFeedbackObserver* observer) { | 125 PacketFeedbackObserver* observer) { |
113 transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer); | 126 transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer); |
114 } | 127 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 } | 225 } |
213 | 226 |
214 TransportFeedbackObserver* | 227 TransportFeedbackObserver* |
215 SendSideCongestionController::GetTransportFeedbackObserver() { | 228 SendSideCongestionController::GetTransportFeedbackObserver() { |
216 return this; | 229 return this; |
217 } | 230 } |
218 | 231 |
219 void SendSideCongestionController::SignalNetworkState(NetworkState state) { | 232 void SendSideCongestionController::SignalNetworkState(NetworkState state) { |
220 LOG(LS_INFO) << "SignalNetworkState " | 233 LOG(LS_INFO) << "SignalNetworkState " |
221 << (state == kNetworkUp ? "Up" : "Down"); | 234 << (state == kNetworkUp ? "Up" : "Down"); |
222 if (state == kNetworkUp) { | |
223 pacer_->Resume(); | |
224 } else { | |
225 pacer_->Pause(); | |
226 } | |
227 { | 235 { |
228 rtc::CritScope cs(&network_state_lock_); | 236 rtc::CritScope cs(&network_state_lock_); |
| 237 pause_pacer_ = state == kNetworkDown; |
229 network_state_ = state; | 238 network_state_ = state; |
230 } | 239 } |
231 probe_controller_->OnNetworkStateChanged(state); | 240 probe_controller_->OnNetworkStateChanged(state); |
232 MaybeTriggerOnNetworkChanged(); | 241 MaybeTriggerOnNetworkChanged(); |
233 } | 242 } |
234 | 243 |
235 void SendSideCongestionController::SetTransportOverhead( | 244 void SendSideCongestionController::SetTransportOverhead( |
236 size_t transport_overhead_bytes_per_packet) { | 245 size_t transport_overhead_bytes_per_packet) { |
237 transport_feedback_adapter_.SetTransportOverhead( | 246 transport_feedback_adapter_.SetTransportOverhead( |
238 transport_overhead_bytes_per_packet); | 247 transport_overhead_bytes_per_packet); |
239 } | 248 } |
240 | 249 |
241 void SendSideCongestionController::OnSentPacket( | 250 void SendSideCongestionController::OnSentPacket( |
242 const rtc::SentPacket& sent_packet) { | 251 const rtc::SentPacket& sent_packet) { |
243 // We're not interested in packets without an id, which may be stun packets, | 252 // We're not interested in packets without an id, which may be stun packets, |
244 // etc, sent on the same transport. | 253 // etc, sent on the same transport. |
245 if (sent_packet.packet_id == -1) | 254 if (sent_packet.packet_id == -1) |
246 return; | 255 return; |
247 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id, | 256 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id, |
248 sent_packet.send_time_ms); | 257 sent_packet.send_time_ms); |
| 258 LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes()); |
249 } | 259 } |
250 | 260 |
251 void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, | 261 void SendSideCongestionController::OnRttUpdate(int64_t avg_rtt_ms, |
252 int64_t max_rtt_ms) { | 262 int64_t max_rtt_ms) { |
253 rtc::CritScope cs(&bwe_lock_); | 263 rtc::CritScope cs(&bwe_lock_); |
254 delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); | 264 delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms); |
255 } | 265 } |
256 | 266 |
257 int64_t SendSideCongestionController::TimeUntilNextProcess() { | 267 int64_t SendSideCongestionController::TimeUntilNextProcess() { |
258 return bitrate_controller_->TimeUntilNextProcess(); | 268 return bitrate_controller_->TimeUntilNextProcess(); |
259 } | 269 } |
260 | 270 |
261 void SendSideCongestionController::Process() { | 271 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 } |
262 bitrate_controller_->Process(); | 286 bitrate_controller_->Process(); |
263 probe_controller_->Process(); | 287 probe_controller_->Process(); |
264 MaybeTriggerOnNetworkChanged(); | 288 MaybeTriggerOnNetworkChanged(); |
265 } | 289 } |
266 | 290 |
267 void SendSideCongestionController::AddPacket( | 291 void SendSideCongestionController::AddPacket( |
268 uint32_t ssrc, | 292 uint32_t ssrc, |
269 uint16_t sequence_number, | 293 uint16_t sequence_number, |
270 size_t length, | 294 size_t length, |
271 const PacedPacketInfo& pacing_info) { | 295 const PacedPacketInfo& pacing_info) { |
(...skipping 26 matching lines...) Expand all Loading... |
298 result = delay_based_bwe_->IncomingPacketFeedbackVector( | 322 result = delay_based_bwe_->IncomingPacketFeedbackVector( |
299 feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps()); | 323 feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps()); |
300 } | 324 } |
301 if (result.updated) { | 325 if (result.updated) { |
302 bitrate_controller_->OnDelayBasedBweResult(result); | 326 bitrate_controller_->OnDelayBasedBweResult(result); |
303 // Update the estimate in the ProbeController, in case we want to probe. | 327 // Update the estimate in the ProbeController, in case we want to probe. |
304 MaybeTriggerOnNetworkChanged(); | 328 MaybeTriggerOnNetworkChanged(); |
305 } | 329 } |
306 if (result.recovered_from_overuse) | 330 if (result.recovered_from_overuse) |
307 probe_controller_->RequestProbe(); | 331 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 } |
308 } | 361 } |
309 | 362 |
310 std::vector<PacketFeedback> | 363 std::vector<PacketFeedback> |
311 SendSideCongestionController::GetTransportFeedbackVector() const { | 364 SendSideCongestionController::GetTransportFeedbackVector() const { |
312 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_); | 365 RTC_DCHECK_RUNS_SERIALIZED(&worker_race_); |
313 return transport_feedback_adapter_.GetTransportFeedbackVector(); | 366 return transport_feedback_adapter_.GetTransportFeedbackVector(); |
314 } | 367 } |
315 | 368 |
316 void SendSideCongestionController::MaybeTriggerOnNetworkChanged() { | 369 void SendSideCongestionController::MaybeTriggerOnNetworkChanged() { |
317 uint32_t bitrate_bps; | 370 uint32_t bitrate_bps; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 bool SendSideCongestionController::IsSendQueueFull() const { | 418 bool SendSideCongestionController::IsSendQueueFull() const { |
366 return pacer_->ExpectedQueueTimeMs() > PacedSender::kMaxQueueLengthMs; | 419 return pacer_->ExpectedQueueTimeMs() > PacedSender::kMaxQueueLengthMs; |
367 } | 420 } |
368 | 421 |
369 bool SendSideCongestionController::IsNetworkDown() const { | 422 bool SendSideCongestionController::IsNetworkDown() const { |
370 rtc::CritScope cs(&network_state_lock_); | 423 rtc::CritScope cs(&network_state_lock_); |
371 return network_state_ == kNetworkDown; | 424 return network_state_ == kNetworkDown; |
372 } | 425 } |
373 | 426 |
374 } // namespace webrtc | 427 } // namespace webrtc |
OLD | NEW |