Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: webrtc/modules/congestion_controller/send_side_congestion_controller.cc

Issue 2918323002: Add functionality which limits the number of bytes on the network. (Closed)
Patch Set: Switch to max-rtt within a feedback message and fix race. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698