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 |