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

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

Issue 2752233002: Split CongestionController into send- and receive-side classes. (Closed)
Patch Set: Improve comments. Move declaration of destructor. Created 3 years, 9 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/congestion_controller.h" 11 #include "webrtc/modules/congestion_controller/include/congestion_controller.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/base/checks.h" 17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/logging.h" 18 #include "webrtc/base/logging.h"
19 #include "webrtc/base/rate_limiter.h" 19 #include "webrtc/base/rate_limiter.h"
20 #include "webrtc/base/socket.h" 20 #include "webrtc/base/socket.h"
21 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" 21 #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
22 #include "webrtc/modules/congestion_controller/probe_controller.h" 22 #include "webrtc/modules/congestion_controller/probe_controller.h"
23 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" 23 #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h"
24 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_s end_time.h" 24 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_s end_time.h"
25 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_singl e_stream.h" 25 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_singl e_stream.h"
26 26
27 namespace webrtc { 27 namespace webrtc {
28 namespace {
29
30 static const uint32_t kTimeOffsetSwitchThreshold = 30;
31 static const int64_t kRetransmitWindowSizeMs = 500;
32
33 // Makes sure that the bitrate and the min, max values are in valid range.
34 static void ClampBitrates(int* bitrate_bps,
35 int* min_bitrate_bps,
36 int* max_bitrate_bps) {
37 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps,
38 // and that we don't try to set the min bitrate to 0 from any applications.
39 // The congestion controller should allow a min bitrate of 0.
40 if (*min_bitrate_bps < congestion_controller::GetMinBitrateBps())
41 *min_bitrate_bps = congestion_controller::GetMinBitrateBps();
42 if (*max_bitrate_bps > 0)
43 *max_bitrate_bps = std::max(*min_bitrate_bps, *max_bitrate_bps);
44 if (*bitrate_bps > 0)
45 *bitrate_bps = std::max(*min_bitrate_bps, *bitrate_bps);
46 }
47
48 } // namespace
49
50 CongestionController::WrappingBitrateEstimator::WrappingBitrateEstimator(
51 RemoteBitrateObserver* observer, const Clock* clock)
52 : observer_(observer),
53 clock_(clock),
54 rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)),
55 using_absolute_send_time_(false),
56 packets_since_absolute_send_time_(0),
57 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()) {}
58
59 void CongestionController::WrappingBitrateEstimator::IncomingPacket(
60 int64_t arrival_time_ms,
61 size_t payload_size,
62 const RTPHeader& header) {
63 rtc::CritScope cs(&crit_sect_);
64 PickEstimatorFromHeader(header);
65 rbe_->IncomingPacket(arrival_time_ms, payload_size, header);
66 }
67
68 void CongestionController::WrappingBitrateEstimator::Process() {
69 rtc::CritScope cs(&crit_sect_);
70 rbe_->Process();
71 }
72
73 int64_t CongestionController::WrappingBitrateEstimator::TimeUntilNextProcess() {
74 rtc::CritScope cs(&crit_sect_);
75 return rbe_->TimeUntilNextProcess();
76 }
77
78 void CongestionController::WrappingBitrateEstimator::OnRttUpdate(
79 int64_t avg_rtt_ms, int64_t max_rtt_ms) {
80 rtc::CritScope cs(&crit_sect_);
81 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
82 }
83
84 void CongestionController::WrappingBitrateEstimator::RemoveStream(
85 unsigned int ssrc) {
86 rtc::CritScope cs(&crit_sect_);
87 rbe_->RemoveStream(ssrc);
88 }
89
90 bool CongestionController::WrappingBitrateEstimator::LatestEstimate(
91 std::vector<unsigned int>* ssrcs,
92 unsigned int* bitrate_bps) const {
93 rtc::CritScope cs(&crit_sect_);
94 return rbe_->LatestEstimate(ssrcs, bitrate_bps);
95 }
96
97 void CongestionController::WrappingBitrateEstimator::SetMinBitrate(
98 int min_bitrate_bps) {
99 rtc::CritScope cs(&crit_sect_);
100 rbe_->SetMinBitrate(min_bitrate_bps);
101 min_bitrate_bps_ = min_bitrate_bps;
102 }
103
104 void CongestionController::WrappingBitrateEstimator::PickEstimatorFromHeader(
105 const RTPHeader& header) {
106 if (header.extension.hasAbsoluteSendTime) {
107 // If we see AST in header, switch RBE strategy immediately.
108 if (!using_absolute_send_time_) {
109 LOG(LS_INFO) <<
110 "WrappingBitrateEstimator: Switching to absolute send time RBE.";
111 using_absolute_send_time_ = true;
112 PickEstimator();
113 }
114 packets_since_absolute_send_time_ = 0;
115 } else {
116 // When we don't see AST, wait for a few packets before going back to TOF.
117 if (using_absolute_send_time_) {
118 ++packets_since_absolute_send_time_;
119 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
120 LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission "
121 << "time offset RBE.";
122 using_absolute_send_time_ = false;
123 PickEstimator();
124 }
125 }
126 }
127 }
128
129 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
130 void CongestionController::WrappingBitrateEstimator::PickEstimator() {
131 if (using_absolute_send_time_) {
132 rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_));
133 } else {
134 rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_));
135 }
136 rbe_->SetMinBitrate(min_bitrate_bps_);
137 }
138
139 CongestionController::CongestionController(
140 const Clock* clock,
141 Observer* observer,
142 RemoteBitrateObserver* remote_bitrate_observer,
143 RtcEventLog* event_log,
144 PacketRouter* packet_router)
145 : CongestionController(
146 clock,
147 observer,
148 remote_bitrate_observer,
149 event_log,
150 packet_router,
151 std::unique_ptr<PacedSender>(new PacedSender(clock, packet_router))) {
152 }
153
154 CongestionController::CongestionController(
155 const Clock* clock,
156 Observer* observer,
157 RemoteBitrateObserver* remote_bitrate_observer,
158 RtcEventLog* event_log,
159 PacketRouter* packet_router,
160 std::unique_ptr<PacedSender> pacer)
161 : clock_(clock),
162 observer_(observer),
163 event_log_(event_log),
164 packet_router_(packet_router),
165 pacer_(std::move(pacer)),
166 bitrate_controller_(
167 BitrateController::CreateBitrateController(clock_, event_log)),
168 probe_controller_(new ProbeController(pacer_.get(), clock_)),
169 retransmission_rate_limiter_(
170 new RateLimiter(clock, kRetransmitWindowSizeMs)),
171 remote_bitrate_estimator_(remote_bitrate_observer, clock_),
172 remote_estimator_proxy_(clock_, packet_router_),
173 transport_feedback_adapter_(clock_),
174 min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
175 max_bitrate_bps_(0),
176 last_reported_bitrate_bps_(0),
177 last_reported_fraction_loss_(0),
178 last_reported_rtt_(0),
179 network_state_(kNetworkUp),
180 delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)) {
181 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
182 worker_thread_checker_.DetachFromThread();
183 }
184
185 CongestionController::~CongestionController() {}
186 28
187 void CongestionController::OnReceivedPacket(int64_t arrival_time_ms, 29 void CongestionController::OnReceivedPacket(int64_t arrival_time_ms,
188 size_t payload_size, 30 size_t payload_size,
189 const RTPHeader& header) { 31 const RTPHeader& header) {
190 // Send-side BWE. 32 receive_side_congestion_controller_.OnReceivedPacket(arrival_time_ms,
191 if (header.extension.hasTransportSequenceNumber) { 33 payload_size, header);
192 remote_estimator_proxy_.IncomingPacket(arrival_time_ms, payload_size,
193 header);
194 } else {
195 // Receive-side BWE.
196 remote_bitrate_estimator_.IncomingPacket(arrival_time_ms, payload_size,
197 header);
198 }
199 } 34 }
200 35
201 void CongestionController::SetBweBitrates(int min_bitrate_bps, 36 void CongestionController::SetBweBitrates(int min_bitrate_bps,
202 int start_bitrate_bps, 37 int start_bitrate_bps,
203 int max_bitrate_bps) { 38 int max_bitrate_bps) {
204 ClampBitrates(&start_bitrate_bps, &min_bitrate_bps, &max_bitrate_bps); 39 // TODO(nisse): Used to also call
205 bitrate_controller_->SetBitrates(start_bitrate_bps, 40 // remote_bitrate_estimator_.SetMinBitrate. Is that needed?
206 min_bitrate_bps, 41 send_side_congestion_controller_.SetBweBitrates(
207 max_bitrate_bps); 42 min_bitrate_bps, start_bitrate_bps, max_bitrate_bps);
208
209 probe_controller_->SetBitrates(min_bitrate_bps, start_bitrate_bps,
210 max_bitrate_bps);
211 max_bitrate_bps_ = max_bitrate_bps;
212
213 remote_bitrate_estimator_.SetMinBitrate(min_bitrate_bps);
214 min_bitrate_bps_ = min_bitrate_bps;
215 {
216 rtc::CritScope cs(&bwe_lock_);
217 if (start_bitrate_bps > 0)
218 delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
219 delay_based_bwe_->SetMinBitrate(min_bitrate_bps_);
220 }
221 MaybeTriggerOnNetworkChanged();
222 } 43 }
223 44
224 // TODO(holmer): Split this up and use SetBweBitrates in combination with 45 // TODO(holmer): Split this up and use SetBweBitrates in combination with
225 // OnNetworkRouteChanged. 46 // OnNetworkRouteChanged.
226 void CongestionController::OnNetworkRouteChanged( 47 void CongestionController::OnNetworkRouteChanged(
227 const rtc::NetworkRoute& network_route, 48 const rtc::NetworkRoute& network_route,
228 int bitrate_bps, 49 int bitrate_bps,
229 int min_bitrate_bps, 50 int min_bitrate_bps,
230 int max_bitrate_bps) { 51 int max_bitrate_bps) {
231 ClampBitrates(&bitrate_bps, &min_bitrate_bps, &max_bitrate_bps); 52 send_side_congestion_controller_.OnNetworkRouteChanged(
232 // TODO(honghaiz): Recreate this object once the bitrate controller is 53 network_route, bitrate_bps, min_bitrate_bps, max_bitrate_bps);
233 // no longer exposed outside CongestionController. 54 receive_side_congestion_controller_.OnNetworkRouteChanged(min_bitrate_bps);
234 bitrate_controller_->ResetBitrates(bitrate_bps, min_bitrate_bps,
235 max_bitrate_bps);
236 min_bitrate_bps_ = min_bitrate_bps;
237 max_bitrate_bps_ = max_bitrate_bps;
238 // TODO(honghaiz): Recreate this object once the remote bitrate estimator is
239 // no longer exposed outside CongestionController.
240 remote_bitrate_estimator_.SetMinBitrate(min_bitrate_bps);
241
242 transport_feedback_adapter_.SetNetworkIds(network_route.local_network_id,
243 network_route.remote_network_id);
244 {
245 rtc::CritScope cs(&bwe_lock_);
246 delay_based_bwe_.reset(new DelayBasedBwe(event_log_, clock_));
247 delay_based_bwe_->SetStartBitrate(bitrate_bps);
248 delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
249 }
250
251 probe_controller_->Reset();
252 probe_controller_->SetBitrates(min_bitrate_bps, bitrate_bps, max_bitrate_bps);
253
254 MaybeTriggerOnNetworkChanged();
255 } 55 }
256 56
257 BitrateController* CongestionController::GetBitrateController() const { 57 BitrateController* CongestionController::GetBitrateController() const {
258 return bitrate_controller_.get(); 58 return send_side_congestion_controller_.GetBitrateController();
259 } 59 }
260 60
261 RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator( 61 RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator(
262 bool send_side_bwe) { 62 bool send_side_bwe) {
263 if (send_side_bwe) { 63 return receive_side_congestion_controller_.GetRemoteBitrateEstimator(
264 return &remote_estimator_proxy_; 64 send_side_bwe);
265 } else {
266 return &remote_bitrate_estimator_;
267 }
268 } 65 }
269 66
270 RateLimiter* CongestionController::GetRetransmissionRateLimiter() { 67 RateLimiter* CongestionController::GetRetransmissionRateLimiter() {
271 return retransmission_rate_limiter_.get(); 68 return send_side_congestion_controller_.GetRetransmissionRateLimiter();
272 } 69 }
273 70
274 void CongestionController::EnablePeriodicAlrProbing(bool enable) { 71 void CongestionController::EnablePeriodicAlrProbing(bool enable) {
275 probe_controller_->EnablePeriodicAlrProbing(enable); 72 send_side_congestion_controller_.EnablePeriodicAlrProbing(enable);
276 } 73 }
277 74
278 void CongestionController::SetAllocatedSendBitrateLimits( 75 void CongestionController::SetAllocatedSendBitrateLimits(
279 int min_send_bitrate_bps, 76 int min_send_bitrate_bps,
280 int max_padding_bitrate_bps) { 77 int max_padding_bitrate_bps) {
281 pacer_->SetSendBitrateLimits(min_send_bitrate_bps, max_padding_bitrate_bps); 78 send_side_congestion_controller_.SetAllocatedSendBitrateLimits(
79 min_send_bitrate_bps, max_padding_bitrate_bps);
282 } 80 }
283 81
284 int64_t CongestionController::GetPacerQueuingDelayMs() const { 82 int64_t CongestionController::GetPacerQueuingDelayMs() const {
285 return IsNetworkDown() ? 0 : pacer_->QueueInMs(); 83 return send_side_congestion_controller_.GetPacerQueuingDelayMs();
286 } 84 }
287 85
288 void CongestionController::SignalNetworkState(NetworkState state) { 86 void CongestionController::SignalNetworkState(NetworkState state) {
289 LOG(LS_INFO) << "SignalNetworkState " 87 send_side_congestion_controller_.SignalNetworkState(state);
290 << (state == kNetworkUp ? "Up" : "Down");
291 if (state == kNetworkUp) {
292 pacer_->Resume();
293 } else {
294 pacer_->Pause();
295 }
296 {
297 rtc::CritScope cs(&network_state_lock_);
298 network_state_ = state;
299 }
300 probe_controller_->OnNetworkStateChanged(state);
301 MaybeTriggerOnNetworkChanged();
302 } 88 }
303 89
304 void CongestionController::SetTransportOverhead( 90 void CongestionController::SetTransportOverhead(
305 size_t transport_overhead_bytes_per_packet) { 91 size_t transport_overhead_bytes_per_packet) {
306 transport_feedback_adapter_.SetTransportOverhead( 92 send_side_congestion_controller_.SetTransportOverhead(
307 transport_overhead_bytes_per_packet); 93 transport_overhead_bytes_per_packet);
308 } 94 }
309 95
310 void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) { 96 void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) {
311 // We're not interested in packets without an id, which may be stun packets, 97 send_side_congestion_controller_.OnSentPacket(sent_packet);
312 // etc, sent on the same transport.
313 if (sent_packet.packet_id == -1)
314 return;
315 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
316 sent_packet.send_time_ms);
317 } 98 }
318 99
319 void CongestionController::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { 100 void CongestionController::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
320 remote_bitrate_estimator_.OnRttUpdate(avg_rtt_ms, max_rtt_ms); 101 receive_side_congestion_controller_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
321 { 102 send_side_congestion_controller_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
322 rtc::CritScope cs(&bwe_lock_);
323 delay_based_bwe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
324 }
325 } 103 }
326 104
327 int64_t CongestionController::TimeUntilNextProcess() { 105 int64_t CongestionController::TimeUntilNextProcess() {
328 return std::min(bitrate_controller_->TimeUntilNextProcess(), 106 return std::min(send_side_congestion_controller_.TimeUntilNextProcess(),
329 remote_bitrate_estimator_.TimeUntilNextProcess()); 107 receive_side_congestion_controller_.TimeUntilNextProcess());
330 } 108 }
331 109
332 void CongestionController::Process() { 110 void CongestionController::Process() {
333 bitrate_controller_->Process(); 111 send_side_congestion_controller_.Process();
334 remote_bitrate_estimator_.Process(); 112 receive_side_congestion_controller_.Process();
335 probe_controller_->Process();
336 MaybeTriggerOnNetworkChanged();
337 } 113 }
338 114
339 void CongestionController::AddPacket(uint16_t sequence_number, 115 void CongestionController::AddPacket(uint16_t sequence_number,
340 size_t length, 116 size_t length,
341 const PacedPacketInfo& pacing_info) { 117 const PacedPacketInfo& pacing_info) {
342 transport_feedback_adapter_.AddPacket(sequence_number, length, pacing_info); 118 send_side_congestion_controller_.AddPacket(sequence_number, length,
119 pacing_info);
343 } 120 }
344 121
345 void CongestionController::OnTransportFeedback( 122 void CongestionController::OnTransportFeedback(
346 const rtcp::TransportFeedback& feedback) { 123 const rtcp::TransportFeedback& feedback) {
347 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 124 send_side_congestion_controller_.OnTransportFeedback(feedback);
348 transport_feedback_adapter_.OnTransportFeedback(feedback);
349 DelayBasedBwe::Result result;
350 {
351 rtc::CritScope cs(&bwe_lock_);
352 result = delay_based_bwe_->IncomingPacketFeedbackVector(
353 transport_feedback_adapter_.GetTransportFeedbackVector());
354 }
355 if (result.updated)
356 bitrate_controller_->OnDelayBasedBweResult(result);
357 } 125 }
358 126
359 std::vector<PacketFeedback> CongestionController::GetTransportFeedbackVector() 127 std::vector<PacketFeedback> CongestionController::GetTransportFeedbackVector()
360 const { 128 const {
361 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 129 return send_side_congestion_controller_.GetTransportFeedbackVector();
362 return transport_feedback_adapter_.GetTransportFeedbackVector();
363 }
364
365 void CongestionController::MaybeTriggerOnNetworkChanged() {
366 // TODO(perkj): |observer_| can be nullptr if the ctor that accepts a
367 // BitrateObserver is used. Remove this check once the ctor is removed.
368 if (!observer_)
369 return;
370
371 uint32_t bitrate_bps;
372 uint8_t fraction_loss;
373 int64_t rtt;
374 bool estimate_changed = bitrate_controller_->GetNetworkParameters(
375 &bitrate_bps, &fraction_loss, &rtt);
376 if (estimate_changed) {
377 pacer_->SetEstimatedBitrate(bitrate_bps);
378 probe_controller_->SetEstimatedBitrate(bitrate_bps);
379 retransmission_rate_limiter_->SetMaxRate(bitrate_bps);
380 }
381
382 bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps;
383
384 if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {
385 int64_t probing_interval_ms;
386 {
387 rtc::CritScope cs(&bwe_lock_);
388 probing_interval_ms = delay_based_bwe_->GetProbingIntervalMs();
389 }
390 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt,
391 probing_interval_ms);
392 remote_estimator_proxy_.OnBitrateChanged(bitrate_bps);
393 }
394 }
395
396 bool CongestionController::HasNetworkParametersToReportChanged(
397 uint32_t bitrate_bps,
398 uint8_t fraction_loss,
399 int64_t rtt) {
400 rtc::CritScope cs(&network_state_lock_);
401 bool changed =
402 last_reported_bitrate_bps_ != bitrate_bps ||
403 (bitrate_bps > 0 && (last_reported_fraction_loss_ != fraction_loss ||
404 last_reported_rtt_ != rtt));
405 if (changed && (last_reported_bitrate_bps_ == 0 || bitrate_bps == 0)) {
406 LOG(LS_INFO) << "Bitrate estimate state changed, BWE: " << bitrate_bps
407 << " bps.";
408 }
409 last_reported_bitrate_bps_ = bitrate_bps;
410 last_reported_fraction_loss_ = fraction_loss;
411 last_reported_rtt_ = rtt;
412 return changed;
413 }
414
415 bool CongestionController::IsSendQueueFull() const {
416 return pacer_->ExpectedQueueTimeMs() > PacedSender::kMaxQueueLengthMs;
417 }
418
419 bool CongestionController::IsNetworkDown() const {
420 rtc::CritScope cs(&network_state_lock_);
421 return network_state_ == kNetworkDown;
422 } 130 }
423 131
424 } // namespace webrtc 132 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698