blob: 593f4a50d679318d58eb7f0d208ae27110e5d5a6 [file] [log] [blame]
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Stefan Holmer80e12072016-02-23 13:30:42 +010011#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +000012
Stefan Holmer62a5ccd2016-02-16 17:07:21 +010013#include <algorithm>
kwiberg22feaa32016-03-17 09:17:43 -070014#include <memory>
Stefan Holmer58c664c2016-02-08 14:31:30 +010015#include <vector>
16
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +000017#include "webrtc/base/checks.h"
kwiberg4485ffb2016-04-26 08:14:39 -070018#include "webrtc/base/constructormagic.h"
Peter Boström7c704b82015-12-04 16:13:05 +010019#include "webrtc/base/logging.h"
Stefan Holmer58c664c2016-02-08 14:31:30 +010020#include "webrtc/base/socket.h"
pbos@webrtc.org38344ed2014-09-24 06:05:00 +000021#include "webrtc/base/thread_annotations.h"
mflodman0e7e2592015-11-12 21:02:42 -080022#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
philipel863a8262016-06-17 09:21:34 -070023#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
sprang867fb522015-08-03 04:38:41 -070024#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
Erik Språng468e62a2015-07-06 10:50:47 +020025#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
26#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010027#include "webrtc/modules/utility/include/process_thread.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010028#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
Peter Boström7623ce42015-12-09 12:13:30 +010029#include "webrtc/video/payload_router.h"
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +000030
31namespace webrtc {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000032namespace {
33
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000034static const uint32_t kTimeOffsetSwitchThreshold = 30;
35
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000036class WrappingBitrateEstimator : public RemoteBitrateEstimator {
37 public:
pbosef35f062015-07-27 08:37:06 -070038 WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock)
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000039 : observer_(observer),
40 clock_(clock),
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000041 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
stefan4fbd1452015-09-28 03:57:14 -070042 rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)),
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000043 using_absolute_send_time_(false),
stefan4fbd1452015-09-28 03:57:14 -070044 packets_since_absolute_send_time_(0),
45 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {}
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000046
47 virtual ~WrappingBitrateEstimator() {}
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000048
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000049 void IncomingPacket(int64_t arrival_time_ms,
50 size_t payload_size,
Stefan Holmerff4ea932015-06-18 16:01:33 +020051 const RTPHeader& header,
52 bool was_paced) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000053 CriticalSectionScoped cs(crit_sect_.get());
stefan@webrtc.orga16147c2014-03-25 10:37:31 +000054 PickEstimatorFromHeader(header);
Stefan Holmerff4ea932015-06-18 16:01:33 +020055 rbe_->IncomingPacket(arrival_time_ms, payload_size, header, was_paced);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000056 }
57
pbosa26ac922016-02-25 04:50:01 -080058 void Process() override {
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000059 CriticalSectionScoped cs(crit_sect_.get());
pbosa26ac922016-02-25 04:50:01 -080060 rbe_->Process();
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000061 }
62
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000063 int64_t TimeUntilNextProcess() override {
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000064 CriticalSectionScoped cs(crit_sect_.get());
65 return rbe_->TimeUntilNextProcess();
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000066 }
67
stefan2328a942015-08-07 04:27:51 -070068 void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000069 CriticalSectionScoped cs(crit_sect_.get());
stefan2328a942015-08-07 04:27:51 -070070 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000071 }
72
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000073 void RemoveStream(unsigned int ssrc) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000074 CriticalSectionScoped cs(crit_sect_.get());
75 rbe_->RemoveStream(ssrc);
76 }
77
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000078 bool LatestEstimate(std::vector<unsigned int>* ssrcs,
79 unsigned int* bitrate_bps) const override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000080 CriticalSectionScoped cs(crit_sect_.get());
81 return rbe_->LatestEstimate(ssrcs, bitrate_bps);
82 }
83
nisseef8b61e2016-04-29 06:09:15 -070084 void SetMinBitrate(int min_bitrate_bps) override {
stefan4fbd1452015-09-28 03:57:14 -070085 CriticalSectionScoped cs(crit_sect_.get());
86 rbe_->SetMinBitrate(min_bitrate_bps);
87 min_bitrate_bps_ = min_bitrate_bps;
88 }
89
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000090 private:
stefan@webrtc.orga16147c2014-03-25 10:37:31 +000091 void PickEstimatorFromHeader(const RTPHeader& header)
92 EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000093 if (header.extension.hasAbsoluteSendTime) {
94 // If we see AST in header, switch RBE strategy immediately.
95 if (!using_absolute_send_time_) {
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +000096 LOG(LS_INFO) <<
97 "WrappingBitrateEstimator: Switching to absolute send time RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000098 using_absolute_send_time_ = true;
stefan@webrtc.orga16147c2014-03-25 10:37:31 +000099 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000100 }
101 packets_since_absolute_send_time_ = 0;
102 } else {
103 // When we don't see AST, wait for a few packets before going back to TOF.
104 if (using_absolute_send_time_) {
105 ++packets_since_absolute_send_time_;
106 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000107 LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission "
108 << "time offset RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000109 using_absolute_send_time_ = false;
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000110 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000111 }
112 }
113 }
114 }
115
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000116 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
117 void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000118 if (using_absolute_send_time_) {
stefan1112b2b2016-04-14 08:08:15 -0700119 rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_));
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000120 } else {
stefan4fbd1452015-09-28 03:57:14 -0700121 rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_));
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000122 }
stefan4fbd1452015-09-28 03:57:14 -0700123 rbe_->SetMinBitrate(min_bitrate_bps_);
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000124 }
125
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000126 RemoteBitrateObserver* observer_;
Stefan Holmer58c664c2016-02-08 14:31:30 +0100127 Clock* const clock_;
kwiberg22feaa32016-03-17 09:17:43 -0700128 std::unique_ptr<CriticalSectionWrapper> crit_sect_;
129 std::unique_ptr<RemoteBitrateEstimator> rbe_;
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000130 bool using_absolute_send_time_;
131 uint32_t packets_since_absolute_send_time_;
stefan4fbd1452015-09-28 03:57:14 -0700132 int min_bitrate_bps_;
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000133
henrikg3c089d72015-09-16 05:37:44 -0700134 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000135};
sprang867fb522015-08-03 04:38:41 -0700136
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000137} // namespace
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000138
Stefan Holmer58c664c2016-02-08 14:31:30 +0100139CongestionController::CongestionController(
140 Clock* clock,
perkj825eb582016-05-04 01:08:05 -0700141 BitrateObserver* bitrate_observer,
Stefan Holmer58c664c2016-02-08 14:31:30 +0100142 RemoteBitrateObserver* remote_bitrate_observer)
143 : clock_(clock),
perkjec81bcd2016-05-11 06:01:13 -0700144 observer_(nullptr),
145 packet_router_(new PacketRouter()),
perkjfea93092016-05-14 00:58:48 -0700146 pacer_(new PacedSender(clock_, packet_router_.get())),
perkjec81bcd2016-05-11 06:01:13 -0700147 remote_bitrate_estimator_(
148 new WrappingBitrateEstimator(remote_bitrate_observer, clock_)),
149 bitrate_controller_(
150 BitrateController::CreateBitrateController(clock_, bitrate_observer)),
151 remote_estimator_proxy_(clock_, packet_router_.get()),
152 transport_feedback_adapter_(bitrate_controller_.get(), clock_),
153 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps),
perkjfea93092016-05-14 00:58:48 -0700154 last_reported_bitrate_bps_(0),
155 last_reported_fraction_loss_(0),
156 last_reported_rtt_(0),
157 network_state_(kNetworkUp) {
perkjec81bcd2016-05-11 06:01:13 -0700158 Init();
159}
160
161CongestionController::CongestionController(
162 Clock* clock,
163 Observer* observer,
164 RemoteBitrateObserver* remote_bitrate_observer)
165 : clock_(clock),
166 observer_(observer),
167 packet_router_(new PacketRouter()),
perkjfea93092016-05-14 00:58:48 -0700168 pacer_(new PacedSender(clock_, packet_router_.get())),
perkjec81bcd2016-05-11 06:01:13 -0700169 remote_bitrate_estimator_(
170 new WrappingBitrateEstimator(remote_bitrate_observer, clock_)),
171 bitrate_controller_(BitrateController::CreateBitrateController(clock_)),
172 remote_estimator_proxy_(clock_, packet_router_.get()),
173 transport_feedback_adapter_(bitrate_controller_.get(), clock_),
174 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps),
perkjfea93092016-05-14 00:58:48 -0700175 last_reported_bitrate_bps_(0),
176 last_reported_fraction_loss_(0),
177 last_reported_rtt_(0),
178 network_state_(kNetworkUp) {
perkjec81bcd2016-05-11 06:01:13 -0700179 Init();
180}
181
182CongestionController::CongestionController(
183 Clock* clock,
184 Observer* observer,
185 RemoteBitrateObserver* remote_bitrate_observer,
186 std::unique_ptr<PacketRouter> packet_router,
187 std::unique_ptr<PacedSender> pacer)
188 : clock_(clock),
189 observer_(observer),
190 packet_router_(std::move(packet_router)),
191 pacer_(std::move(pacer)),
Erik Språng6b8d3552015-09-24 15:06:57 +0200192 remote_bitrate_estimator_(
Stefan Holmer58c664c2016-02-08 14:31:30 +0100193 new WrappingBitrateEstimator(remote_bitrate_observer, clock_)),
Stefan Holmere5904162015-03-26 11:11:06 +0100194 // Constructed last as this object calls the provided callback on
195 // construction.
perkjec81bcd2016-05-11 06:01:13 -0700196 bitrate_controller_(BitrateController::CreateBitrateController(clock_)),
197 remote_estimator_proxy_(clock_, packet_router_.get()),
Stefan Holmer789ba922016-02-17 15:52:17 +0100198 transport_feedback_adapter_(bitrate_controller_.get(), clock_),
perkjec81bcd2016-05-11 06:01:13 -0700199 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps),
perkjfea93092016-05-14 00:58:48 -0700200 last_reported_bitrate_bps_(0),
201 last_reported_fraction_loss_(0),
202 last_reported_rtt_(0),
203 network_state_(kNetworkUp) {
perkjec81bcd2016-05-11 06:01:13 -0700204 Init();
205}
206
207CongestionController::~CongestionController() {}
208
209void CongestionController::Init() {
Stefan Holmer789ba922016-02-17 15:52:17 +0100210 transport_feedback_adapter_.SetBitrateEstimator(
philipel863a8262016-06-17 09:21:34 -0700211 new DelayBasedBwe(&transport_feedback_adapter_));
Stefan Holmer789ba922016-02-17 15:52:17 +0100212 transport_feedback_adapter_.GetBitrateEstimator()->SetMinBitrate(
213 min_bitrate_bps_);
perkje30c2722016-05-09 04:57:11 -0700214}
215
guidou72d41aa2016-06-02 23:24:51 -0700216
mflodman0c478b32015-10-21 15:52:16 +0200217void CongestionController::SetBweBitrates(int min_bitrate_bps,
218 int start_bitrate_bps,
219 int max_bitrate_bps) {
guidou72d41aa2016-06-02 23:24:51 -0700220 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps,
221 // and that we don't try to set the min bitrate to 0 from any applications.
222 // The congestion controller should allow a min bitrate of 0.
223 const int kMinBitrateBps = 10000;
224 if (min_bitrate_bps < kMinBitrateBps)
225 min_bitrate_bps = kMinBitrateBps;
226 if (max_bitrate_bps > 0)
227 max_bitrate_bps = std::max(min_bitrate_bps, max_bitrate_bps);
228 if (start_bitrate_bps > 0)
229 start_bitrate_bps = std::max(min_bitrate_bps, start_bitrate_bps);
230
philipelc6957c72016-04-28 15:52:49 +0200231 bitrate_controller_->SetBitrates(start_bitrate_bps,
232 min_bitrate_bps,
233 max_bitrate_bps);
234
Stefan Holmer789ba922016-02-17 15:52:17 +0100235 if (remote_bitrate_estimator_)
stefan4fbd1452015-09-28 03:57:14 -0700236 remote_bitrate_estimator_->SetMinBitrate(min_bitrate_bps);
stefan4fbd1452015-09-28 03:57:14 -0700237 min_bitrate_bps_ = min_bitrate_bps;
Stefan Holmer789ba922016-02-17 15:52:17 +0100238 transport_feedback_adapter_.GetBitrateEstimator()->SetMinBitrate(
239 min_bitrate_bps_);
perkjec81bcd2016-05-11 06:01:13 -0700240 MaybeTriggerOnNetworkChanged();
stefan4fbd1452015-09-28 03:57:14 -0700241}
242
mflodman0c478b32015-10-21 15:52:16 +0200243BitrateController* CongestionController::GetBitrateController() const {
bjornv@webrtc.orgcb89c6f2012-06-05 12:25:35 +0000244 return bitrate_controller_.get();
stefan@webrtc.orgf7288142012-06-05 10:44:00 +0000245}
246
mflodman0c478b32015-10-21 15:52:16 +0200247RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator(
Stefan Holmer789ba922016-02-17 15:52:17 +0100248 bool send_side_bwe) {
249 if (send_side_bwe) {
250 return &remote_estimator_proxy_;
251 } else {
mflodmana20de202015-10-18 22:08:19 -0700252 return remote_bitrate_estimator_.get();
Stefan Holmer789ba922016-02-17 15:52:17 +0100253 }
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000254}
255
mflodman0c478b32015-10-21 15:52:16 +0200256TransportFeedbackObserver*
257CongestionController::GetTransportFeedbackObserver() {
Stefan Holmer789ba922016-02-17 15:52:17 +0100258 return &transport_feedback_adapter_;
mflodman949c2f02015-10-16 02:31:11 -0700259}
260
perkj71ee44c2016-06-15 00:47:53 -0700261void CongestionController::SetAllocatedSendBitrateLimits(
262 int min_send_bitrate_bps,
263 int max_padding_bitrate_bps) {
264 pacer_->SetSendBitrateLimits(min_send_bitrate_bps, max_padding_bitrate_bps);
mflodman0e7e2592015-11-12 21:02:42 -0800265}
266
mflodman0c478b32015-10-21 15:52:16 +0200267int64_t CongestionController::GetPacerQueuingDelayMs() const {
Stefan Holmere5904162015-03-26 11:11:06 +0100268 return pacer_->QueueInMs();
269}
270
mflodman0c478b32015-10-21 15:52:16 +0200271void CongestionController::SignalNetworkState(NetworkState state) {
stefan457a61d2015-10-14 03:12:59 -0700272 if (state == kNetworkUp) {
273 pacer_->Resume();
274 } else {
275 pacer_->Pause();
276 }
perkjfea93092016-05-14 00:58:48 -0700277 {
278 rtc::CritScope cs(&critsect_);
279 network_state_ = state;
280 }
281 MaybeTriggerOnNetworkChanged();
stefan457a61d2015-10-14 03:12:59 -0700282}
283
mflodman0c478b32015-10-21 15:52:16 +0200284void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) {
Stefan Holmer789ba922016-02-17 15:52:17 +0100285 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
286 sent_packet.send_time_ms);
stefanc1aeaf02015-10-15 07:26:07 -0700287}
Stefan Holmer789ba922016-02-17 15:52:17 +0100288
289void CongestionController::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
290 remote_bitrate_estimator_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
291 transport_feedback_adapter_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
292}
293
294int64_t CongestionController::TimeUntilNextProcess() {
295 return std::min(bitrate_controller_->TimeUntilNextProcess(),
296 remote_bitrate_estimator_->TimeUntilNextProcess());
297}
298
pbosa26ac922016-02-25 04:50:01 -0800299void CongestionController::Process() {
Stefan Holmer789ba922016-02-17 15:52:17 +0100300 bitrate_controller_->Process();
301 remote_bitrate_estimator_->Process();
perkjec81bcd2016-05-11 06:01:13 -0700302 MaybeTriggerOnNetworkChanged();
303}
304
305void CongestionController::MaybeTriggerOnNetworkChanged() {
306 // TODO(perkj): |observer_| can be nullptr if the ctor that accepts a
307 // BitrateObserver is used. Remove this check once the ctor is removed.
308 if (!observer_)
309 return;
310
311 uint32_t bitrate_bps;
312 uint8_t fraction_loss;
313 int64_t rtt;
perkjfea93092016-05-14 00:58:48 -0700314 bool estimate_changed = bitrate_controller_->GetNetworkParameters(
perkjec81bcd2016-05-11 06:01:13 -0700315 &bitrate_bps, &fraction_loss, &rtt);
perkjfea93092016-05-14 00:58:48 -0700316 if (estimate_changed)
perkjec81bcd2016-05-11 06:01:13 -0700317 pacer_->SetEstimatedBitrate(bitrate_bps);
perkjfea93092016-05-14 00:58:48 -0700318
319 bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps;
320
321 if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) {
perkjec81bcd2016-05-11 06:01:13 -0700322 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
323 }
324}
325
perkjfea93092016-05-14 00:58:48 -0700326bool CongestionController::HasNetworkParametersToReportChanged(
327 uint32_t bitrate_bps,
328 uint8_t fraction_loss,
329 int64_t rtt) {
perkjec81bcd2016-05-11 06:01:13 -0700330 rtc::CritScope cs(&critsect_);
perkjfea93092016-05-14 00:58:48 -0700331 bool changed =
332 last_reported_bitrate_bps_ != bitrate_bps ||
333 (bitrate_bps > 0 && (last_reported_fraction_loss_ != fraction_loss ||
334 last_reported_rtt_ != rtt));
335 last_reported_bitrate_bps_ = bitrate_bps;
336 last_reported_fraction_loss_ = fraction_loss;
337 last_reported_rtt_ = rtt;
338 return changed;
339}
340
341bool CongestionController::IsSendQueueFull() const {
342 return pacer_->ExpectedQueueTimeMs() > PacedSender::kMaxQueueLengthMs;
343}
344
345bool CongestionController::IsNetworkDown() const {
346 rtc::CritScope cs(&critsect_);
347 return network_state_ == kNetworkDown;
Stefan Holmer789ba922016-02-17 15:52:17 +0100348}
349
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000350} // namespace webrtc