blob: 50074d50e4477e4bf4be435755b83abda7cd4e81 [file] [log] [blame]
mflodman@webrtc.org9ec883e2012-03-05 17:12:411/*
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 12:30:4211#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
mflodman@webrtc.org9ec883e2012-03-05 17:12:4112
Stefan Holmer62a5ccd2016-02-16 16:07:2113#include <algorithm>
Stefan Holmer58c664c2016-02-08 13:31:3014#include <vector>
15
stefan@webrtc.orga50e6f02015-03-09 10:06:4016#include "webrtc/base/checks.h"
Peter Boström7c704b82015-12-04 15:13:0517#include "webrtc/base/logging.h"
Stefan Holmer58c664c2016-02-08 13:31:3018#include "webrtc/base/socket.h"
pbos@webrtc.org38344ed2014-09-24 06:05:0019#include "webrtc/base/thread_annotations.h"
mflodman0e7e2592015-11-13 05:02:4220#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
Henrik Kjellander0b9e29c2015-11-16 10:12:2421#include "webrtc/modules/pacing/paced_sender.h"
sprang867fb522015-08-03 11:38:4122#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
Erik Språng468e62a2015-07-06 08:50:4723#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
24#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
Henrik Kjellanderff761fb2015-11-04 07:31:5225#include "webrtc/modules/utility/include/process_thread.h"
Henrik Kjellander98f53512015-10-28 17:17:4026#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
Peter Boström7623ce42015-12-09 11:13:3027#include "webrtc/video/payload_router.h"
mflodman@webrtc.org9ec883e2012-03-05 17:12:4128
29namespace webrtc {
solenberg@webrtc.orga6db54d2013-05-27 16:02:5630namespace {
31
pbos@webrtc.org5ab75672013-12-16 12:24:4432static const uint32_t kTimeOffsetSwitchThreshold = 30;
33
solenberg@webrtc.orga6db54d2013-05-27 16:02:5634class WrappingBitrateEstimator : public RemoteBitrateEstimator {
35 public:
pbosef35f062015-07-27 15:37:0636 WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock)
solenberg@webrtc.orga6db54d2013-05-27 16:02:5637 : observer_(observer),
38 clock_(clock),
solenberg@webrtc.orga6db54d2013-05-27 16:02:5639 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
stefan4fbd1452015-09-28 10:57:1440 rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)),
pbos@webrtc.org5ab75672013-12-16 12:24:4441 using_absolute_send_time_(false),
stefan4fbd1452015-09-28 10:57:1442 packets_since_absolute_send_time_(0),
43 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {}
andresp@webrtc.org1295dc62014-07-02 13:23:1944
45 virtual ~WrappingBitrateEstimator() {}
solenberg@webrtc.orga6db54d2013-05-27 16:02:5646
kjellander@webrtc.org14665ff2015-03-04 12:58:3547 void IncomingPacket(int64_t arrival_time_ms,
48 size_t payload_size,
Stefan Holmerff4ea932015-06-18 14:01:3349 const RTPHeader& header,
50 bool was_paced) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:5651 CriticalSectionScoped cs(crit_sect_.get());
stefan@webrtc.orga16147c2014-03-25 10:37:3152 PickEstimatorFromHeader(header);
Stefan Holmerff4ea932015-06-18 14:01:3353 rbe_->IncomingPacket(arrival_time_ms, payload_size, header, was_paced);
solenberg@webrtc.orga6db54d2013-05-27 16:02:5654 }
55
torbjorngda33a8a2016-02-25 12:34:0356 int32_t Process() override {
andresp@webrtc.org1295dc62014-07-02 13:23:1957 CriticalSectionScoped cs(crit_sect_.get());
torbjorngda33a8a2016-02-25 12:34:0358 return rbe_->Process();
solenberg@webrtc.orga6db54d2013-05-27 16:02:5659 }
60
kjellander@webrtc.org14665ff2015-03-04 12:58:3561 int64_t TimeUntilNextProcess() override {
andresp@webrtc.org1295dc62014-07-02 13:23:1962 CriticalSectionScoped cs(crit_sect_.get());
63 return rbe_->TimeUntilNextProcess();
solenberg@webrtc.orga6db54d2013-05-27 16:02:5664 }
65
stefan2328a942015-08-07 11:27:5166 void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:5667 CriticalSectionScoped cs(crit_sect_.get());
stefan2328a942015-08-07 11:27:5168 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
solenberg@webrtc.orga6db54d2013-05-27 16:02:5669 }
70
kjellander@webrtc.org14665ff2015-03-04 12:58:3571 void RemoveStream(unsigned int ssrc) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:5672 CriticalSectionScoped cs(crit_sect_.get());
73 rbe_->RemoveStream(ssrc);
74 }
75
kjellander@webrtc.org14665ff2015-03-04 12:58:3576 bool LatestEstimate(std::vector<unsigned int>* ssrcs,
77 unsigned int* bitrate_bps) const override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:5678 CriticalSectionScoped cs(crit_sect_.get());
79 return rbe_->LatestEstimate(ssrcs, bitrate_bps);
80 }
81
stefan4fbd1452015-09-28 10:57:1482 void SetMinBitrate(int min_bitrate_bps) {
83 CriticalSectionScoped cs(crit_sect_.get());
84 rbe_->SetMinBitrate(min_bitrate_bps);
85 min_bitrate_bps_ = min_bitrate_bps;
86 }
87
solenberg@webrtc.orga6db54d2013-05-27 16:02:5688 private:
stefan@webrtc.orga16147c2014-03-25 10:37:3189 void PickEstimatorFromHeader(const RTPHeader& header)
90 EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
pbos@webrtc.org5ab75672013-12-16 12:24:4491 if (header.extension.hasAbsoluteSendTime) {
92 // If we see AST in header, switch RBE strategy immediately.
93 if (!using_absolute_send_time_) {
mflodman@webrtc.org5574dac2014-04-07 10:56:3194 LOG(LS_INFO) <<
95 "WrappingBitrateEstimator: Switching to absolute send time RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:4496 using_absolute_send_time_ = true;
stefan@webrtc.orga16147c2014-03-25 10:37:3197 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:4498 }
99 packets_since_absolute_send_time_ = 0;
100 } else {
101 // When we don't see AST, wait for a few packets before going back to TOF.
102 if (using_absolute_send_time_) {
103 ++packets_since_absolute_send_time_;
104 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
mflodman@webrtc.org5574dac2014-04-07 10:56:31105 LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission "
106 << "time offset RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:44107 using_absolute_send_time_ = false;
stefan@webrtc.orga16147c2014-03-25 10:37:31108 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:44109 }
110 }
111 }
112 }
113
stefan@webrtc.orga16147c2014-03-25 10:37:31114 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
115 void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
stefan@webrtc.orga16147c2014-03-25 10:37:31116 if (using_absolute_send_time_) {
stefan4fbd1452015-09-28 10:57:14117 rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_));
stefan@webrtc.orga16147c2014-03-25 10:37:31118 } else {
stefan4fbd1452015-09-28 10:57:14119 rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_));
stefan@webrtc.orga16147c2014-03-25 10:37:31120 }
stefan4fbd1452015-09-28 10:57:14121 rbe_->SetMinBitrate(min_bitrate_bps_);
stefan@webrtc.orga16147c2014-03-25 10:37:31122 }
123
solenberg@webrtc.orga6db54d2013-05-27 16:02:56124 RemoteBitrateObserver* observer_;
Stefan Holmer58c664c2016-02-08 13:31:30125 Clock* const clock_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55126 rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55127 rtc::scoped_ptr<RemoteBitrateEstimator> rbe_;
pbos@webrtc.org5ab75672013-12-16 12:24:44128 bool using_absolute_send_time_;
129 uint32_t packets_since_absolute_send_time_;
stefan4fbd1452015-09-28 10:57:14130 int min_bitrate_bps_;
solenberg@webrtc.orga6db54d2013-05-27 16:02:56131
henrikg3c089d72015-09-16 12:37:44132 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56133};
sprang867fb522015-08-03 11:38:41134
solenberg@webrtc.orga6db54d2013-05-27 16:02:56135} // namespace
mflodman@webrtc.org9ec883e2012-03-05 17:12:41136
Stefan Holmer58c664c2016-02-08 13:31:30137CongestionController::CongestionController(
138 Clock* clock,
Stefan Holmer58c664c2016-02-08 13:31:30139 BitrateObserver* bitrate_observer,
140 RemoteBitrateObserver* remote_bitrate_observer)
141 : clock_(clock),
Stefan Holmer58c664c2016-02-08 13:31:30142 pacer_(new PacedSender(clock_,
Stefan Holmer789ba922016-02-17 14:52:17143 &packet_router_,
144 BitrateController::kDefaultStartBitrateKbps,
145 PacedSender::kDefaultPaceMultiplier *
146 BitrateController::kDefaultStartBitrateKbps,
147 0)),
Erik Språng6b8d3552015-09-24 13:06:57148 remote_bitrate_estimator_(
Stefan Holmer58c664c2016-02-08 13:31:30149 new WrappingBitrateEstimator(remote_bitrate_observer, clock_)),
Stefan Holmere5904162015-03-26 10:11:06150 // Constructed last as this object calls the provided callback on
151 // construction.
152 bitrate_controller_(
Stefan Holmer58c664c2016-02-08 13:31:30153 BitrateController::CreateBitrateController(clock_, bitrate_observer)),
Stefan Holmer789ba922016-02-17 14:52:17154 remote_estimator_proxy_(clock_, &packet_router_),
155 transport_feedback_adapter_(bitrate_controller_.get(), clock_),
stefan4fbd1452015-09-28 10:57:14156 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {
Stefan Holmer789ba922016-02-17 14:52:17157 transport_feedback_adapter_.SetBitrateEstimator(
158 new RemoteBitrateEstimatorAbsSendTime(&transport_feedback_adapter_,
159 clock_));
160 transport_feedback_adapter_.GetBitrateEstimator()->SetMinBitrate(
161 min_bitrate_bps_);
pwestin@webrtc.org49888ce2012-04-27 05:25:53162}
mflodman@webrtc.org9ec883e2012-03-05 17:12:41163
mflodman0c478b32015-10-21 13:52:16164CongestionController::~CongestionController() {
stefan@webrtc.orga50e6f02015-03-09 10:06:40165}
166
stefan@webrtc.orga50e6f02015-03-09 10:06:40167
mflodman0c478b32015-10-21 13:52:16168void CongestionController::SetBweBitrates(int min_bitrate_bps,
169 int start_bitrate_bps,
170 int max_bitrate_bps) {
Stefan Holmer789ba922016-02-17 14:52:17171 RTC_DCHECK(config_thread_checker_.CalledOnValidThread());
Stefan Holmer62a5ccd2016-02-16 16:07:21172 // TODO(holmer): We should make sure the default bitrates are set to 10 kbps,
173 // and that we don't try to set the min bitrate to 0 from any applications.
174 // The congestion controller should allow a min bitrate of 0.
175 const int kMinBitrateBps = 10000;
176 if (min_bitrate_bps < kMinBitrateBps)
177 min_bitrate_bps = kMinBitrateBps;
178 if (max_bitrate_bps > 0)
179 max_bitrate_bps = std::max(min_bitrate_bps, max_bitrate_bps);
180 if (start_bitrate_bps > 0) {
181 start_bitrate_bps = std::max(min_bitrate_bps, start_bitrate_bps);
stefan4fbd1452015-09-28 10:57:14182 bitrate_controller_->SetStartBitrate(start_bitrate_bps);
Stefan Holmer62a5ccd2016-02-16 16:07:21183 }
stefan4fbd1452015-09-28 10:57:14184 bitrate_controller_->SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
Stefan Holmer789ba922016-02-17 14:52:17185 if (remote_bitrate_estimator_)
stefan4fbd1452015-09-28 10:57:14186 remote_bitrate_estimator_->SetMinBitrate(min_bitrate_bps);
stefan4fbd1452015-09-28 10:57:14187 min_bitrate_bps_ = min_bitrate_bps;
Stefan Holmer789ba922016-02-17 14:52:17188 transport_feedback_adapter_.GetBitrateEstimator()->SetMinBitrate(
189 min_bitrate_bps_);
stefan4fbd1452015-09-28 10:57:14190}
191
mflodman0c478b32015-10-21 13:52:16192BitrateController* CongestionController::GetBitrateController() const {
bjornv@webrtc.orgcb89c6f2012-06-05 12:25:35193 return bitrate_controller_.get();
stefan@webrtc.orgf7288142012-06-05 10:44:00194}
195
mflodman0c478b32015-10-21 13:52:16196RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator(
Stefan Holmer789ba922016-02-17 14:52:17197 bool send_side_bwe) {
198 if (send_side_bwe) {
199 return &remote_estimator_proxy_;
200 } else {
mflodmana20de202015-10-19 05:08:19201 return remote_bitrate_estimator_.get();
Stefan Holmer789ba922016-02-17 14:52:17202 }
stefan@webrtc.org9354cc92012-06-07 08:10:14203}
204
mflodman0c478b32015-10-21 13:52:16205TransportFeedbackObserver*
206CongestionController::GetTransportFeedbackObserver() {
Stefan Holmer789ba922016-02-17 14:52:17207 RTC_DCHECK(config_thread_checker_.CalledOnValidThread());
208 return &transport_feedback_adapter_;
mflodman949c2f02015-10-16 09:31:11209}
210
mflodman0e7e2592015-11-13 05:02:42211void CongestionController::UpdatePacerBitrate(int bitrate_kbps,
212 int max_bitrate_kbps,
213 int min_bitrate_kbps) {
214 pacer_->UpdateBitrate(bitrate_kbps, max_bitrate_kbps, min_bitrate_kbps);
215}
216
mflodman0c478b32015-10-21 13:52:16217int64_t CongestionController::GetPacerQueuingDelayMs() const {
Stefan Holmere5904162015-03-26 10:11:06218 return pacer_->QueueInMs();
219}
220
mflodman0c478b32015-10-21 13:52:16221void CongestionController::SignalNetworkState(NetworkState state) {
stefan457a61d2015-10-14 10:12:59222 if (state == kNetworkUp) {
223 pacer_->Resume();
224 } else {
225 pacer_->Pause();
226 }
227}
228
mflodman0c478b32015-10-21 13:52:16229void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) {
Stefan Holmer789ba922016-02-17 14:52:17230 transport_feedback_adapter_.OnSentPacket(sent_packet.packet_id,
231 sent_packet.send_time_ms);
stefanc1aeaf02015-10-15 14:26:07232}
Stefan Holmer789ba922016-02-17 14:52:17233
234void CongestionController::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
235 remote_bitrate_estimator_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
236 transport_feedback_adapter_.OnRttUpdate(avg_rtt_ms, max_rtt_ms);
237}
238
239int64_t CongestionController::TimeUntilNextProcess() {
240 return std::min(bitrate_controller_->TimeUntilNextProcess(),
241 remote_bitrate_estimator_->TimeUntilNextProcess());
242}
243
torbjorngda33a8a2016-02-25 12:34:03244int32_t CongestionController::Process() {
Stefan Holmer789ba922016-02-17 14:52:17245 bitrate_controller_->Process();
246 remote_bitrate_estimator_->Process();
torbjorngda33a8a2016-02-25 12:34:03247 return 0;
Stefan Holmer789ba922016-02-17 14:52:17248}
249
mflodman@webrtc.org9ec883e2012-03-05 17:12:41250} // namespace webrtc