blob: 08cdb11d2fbaf66a385429a66fe6e197cbef4200 [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
mflodman0c478b32015-10-21 15:52:16 +020011#include "webrtc/call/congestion_controller.h"
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +000012
Stefan Holmer58c664c2016-02-08 14:31:30 +010013#include <vector>
14
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +000015#include "webrtc/base/checks.h"
Peter Boström7c704b82015-12-04 16:13:05 +010016#include "webrtc/base/logging.h"
Stefan Holmer58c664c2016-02-08 14:31:30 +010017#include "webrtc/base/socket.h"
pbos@webrtc.org38344ed2014-09-24 06:05:00 +000018#include "webrtc/base/thread_annotations.h"
mflodman0e7e2592015-11-12 21:02:42 -080019#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
Henrik Kjellander0b9e29c2015-11-16 11:12:24 +010020#include "webrtc/modules/pacing/paced_sender.h"
21#include "webrtc/modules/pacing/packet_router.h"
sprang867fb522015-08-03 04:38:41 -070022#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
Erik Språng468e62a2015-07-06 10:50:47 +020023#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"
Erik Språng6b8d3552015-09-24 15:06:57 +020025#include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h"
sprang5e023eb2015-09-14 06:42:43 -070026#include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.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/call_stats.h"
30#include "webrtc/video/payload_router.h"
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +000031
32namespace webrtc {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000033namespace {
34
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000035static const uint32_t kTimeOffsetSwitchThreshold = 30;
36
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000037class WrappingBitrateEstimator : public RemoteBitrateEstimator {
38 public:
pbosef35f062015-07-27 08:37:06 -070039 WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock)
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000040 : observer_(observer),
41 clock_(clock),
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000042 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
stefan4fbd1452015-09-28 03:57:14 -070043 rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)),
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000044 using_absolute_send_time_(false),
stefan4fbd1452015-09-28 03:57:14 -070045 packets_since_absolute_send_time_(0),
46 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {}
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000047
48 virtual ~WrappingBitrateEstimator() {}
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000049
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000050 void IncomingPacket(int64_t arrival_time_ms,
51 size_t payload_size,
Stefan Holmerff4ea932015-06-18 16:01:33 +020052 const RTPHeader& header,
53 bool was_paced) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000054 CriticalSectionScoped cs(crit_sect_.get());
stefan@webrtc.orga16147c2014-03-25 10:37:31 +000055 PickEstimatorFromHeader(header);
Stefan Holmerff4ea932015-06-18 16:01:33 +020056 rbe_->IncomingPacket(arrival_time_ms, payload_size, header, was_paced);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000057 }
58
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000059 int32_t Process() override {
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000060 CriticalSectionScoped cs(crit_sect_.get());
61 return rbe_->Process();
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000062 }
63
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000064 int64_t TimeUntilNextProcess() override {
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000065 CriticalSectionScoped cs(crit_sect_.get());
66 return rbe_->TimeUntilNextProcess();
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000067 }
68
stefan2328a942015-08-07 04:27:51 -070069 void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000070 CriticalSectionScoped cs(crit_sect_.get());
stefan2328a942015-08-07 04:27:51 -070071 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000072 }
73
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000074 void RemoveStream(unsigned int ssrc) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000075 CriticalSectionScoped cs(crit_sect_.get());
76 rbe_->RemoveStream(ssrc);
77 }
78
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000079 bool LatestEstimate(std::vector<unsigned int>* ssrcs,
80 unsigned int* bitrate_bps) const override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000081 CriticalSectionScoped cs(crit_sect_.get());
82 return rbe_->LatestEstimate(ssrcs, bitrate_bps);
83 }
84
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000085 bool GetStats(ReceiveBandwidthEstimatorStats* output) const override {
jiayl@webrtc.org1f64f062014-02-10 19:12:14 +000086 CriticalSectionScoped cs(crit_sect_.get());
87 return rbe_->GetStats(output);
88 }
89
stefan4fbd1452015-09-28 03:57:14 -070090 void SetMinBitrate(int min_bitrate_bps) {
91 CriticalSectionScoped cs(crit_sect_.get());
92 rbe_->SetMinBitrate(min_bitrate_bps);
93 min_bitrate_bps_ = min_bitrate_bps;
94 }
95
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000096 private:
stefan@webrtc.orga16147c2014-03-25 10:37:31 +000097 void PickEstimatorFromHeader(const RTPHeader& header)
98 EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000099 if (header.extension.hasAbsoluteSendTime) {
100 // If we see AST in header, switch RBE strategy immediately.
101 if (!using_absolute_send_time_) {
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000102 LOG(LS_INFO) <<
103 "WrappingBitrateEstimator: Switching to absolute send time RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000104 using_absolute_send_time_ = true;
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000105 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000106 }
107 packets_since_absolute_send_time_ = 0;
108 } else {
109 // When we don't see AST, wait for a few packets before going back to TOF.
110 if (using_absolute_send_time_) {
111 ++packets_since_absolute_send_time_;
112 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000113 LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission "
114 << "time offset RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000115 using_absolute_send_time_ = false;
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000116 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000117 }
118 }
119 }
120 }
121
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000122 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
123 void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000124 if (using_absolute_send_time_) {
stefan4fbd1452015-09-28 03:57:14 -0700125 rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_));
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000126 } else {
stefan4fbd1452015-09-28 03:57:14 -0700127 rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_));
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000128 }
stefan4fbd1452015-09-28 03:57:14 -0700129 rbe_->SetMinBitrate(min_bitrate_bps_);
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000130 }
131
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000132 RemoteBitrateObserver* observer_;
Stefan Holmer58c664c2016-02-08 14:31:30 +0100133 Clock* const clock_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000134 rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000135 rtc::scoped_ptr<RemoteBitrateEstimator> rbe_;
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000136 bool using_absolute_send_time_;
137 uint32_t packets_since_absolute_send_time_;
stefan4fbd1452015-09-28 03:57:14 -0700138 int min_bitrate_bps_;
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000139
henrikg3c089d72015-09-16 05:37:44 -0700140 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000141};
sprang867fb522015-08-03 04:38:41 -0700142
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000143} // namespace
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000144
Stefan Holmer58c664c2016-02-08 14:31:30 +0100145CongestionController::CongestionController(
146 Clock* clock,
147 ProcessThread* process_thread,
148 CallStats* call_stats,
149 BitrateObserver* bitrate_observer,
150 RemoteBitrateObserver* remote_bitrate_observer)
151 : clock_(clock),
Stefan Holmere5904162015-03-26 11:11:06 +0100152 packet_router_(new PacketRouter()),
Stefan Holmer58c664c2016-02-08 14:31:30 +0100153 pacer_(new PacedSender(clock_,
Stefan Holmere5904162015-03-26 11:11:06 +0100154 packet_router_.get(),
155 BitrateController::kDefaultStartBitrateKbps,
156 PacedSender::kDefaultPaceMultiplier *
157 BitrateController::kDefaultStartBitrateKbps,
158 0)),
Erik Språng6b8d3552015-09-24 15:06:57 +0200159 remote_bitrate_estimator_(
Stefan Holmer58c664c2016-02-08 14:31:30 +0100160 new WrappingBitrateEstimator(remote_bitrate_observer, clock_)),
Erik Språng6b8d3552015-09-24 15:06:57 +0200161 remote_estimator_proxy_(
Stefan Holmer58c664c2016-02-08 14:31:30 +0100162 new RemoteEstimatorProxy(clock_, packet_router_.get())),
Stefan Holmere5904162015-03-26 11:11:06 +0100163 process_thread_(process_thread),
mflodmane3787022015-10-21 13:24:28 +0200164 call_stats_(call_stats),
stefan847855b2015-09-11 09:52:15 -0700165 pacer_thread_(ProcessThread::Create("PacerThread")),
Stefan Holmere5904162015-03-26 11:11:06 +0100166 // Constructed last as this object calls the provided callback on
167 // construction.
168 bitrate_controller_(
Stefan Holmer58c664c2016-02-08 14:31:30 +0100169 BitrateController::CreateBitrateController(clock_, bitrate_observer)),
stefan4fbd1452015-09-28 03:57:14 -0700170 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {
andresp@webrtc.org1295dc62014-07-02 13:23:19 +0000171 call_stats_->RegisterStatsObserver(remote_bitrate_estimator_.get());
172
Stefan Holmere5904162015-03-26 11:11:06 +0100173 pacer_thread_->RegisterModule(pacer_.get());
stefanbba9dec2016-02-01 04:39:55 -0800174 pacer_thread_->RegisterModule(remote_estimator_proxy_.get());
Stefan Holmere5904162015-03-26 11:11:06 +0100175 pacer_thread_->Start();
176
Stefan Holmer58c664c2016-02-08 14:31:30 +0100177 process_thread_->RegisterModule(remote_bitrate_estimator_.get());
178 process_thread_->RegisterModule(bitrate_controller_.get());
pwestin@webrtc.org49888ce2012-04-27 05:25:53 +0000179}
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000180
mflodman0c478b32015-10-21 15:52:16 +0200181CongestionController::~CongestionController() {
Stefan Holmere5904162015-03-26 11:11:06 +0100182 pacer_thread_->Stop();
183 pacer_thread_->DeRegisterModule(pacer_.get());
stefanbba9dec2016-02-01 04:39:55 -0800184 pacer_thread_->DeRegisterModule(remote_estimator_proxy_.get());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000185 process_thread_->DeRegisterModule(bitrate_controller_.get());
andresp@webrtc.org1295dc62014-07-02 13:23:19 +0000186 process_thread_->DeRegisterModule(remote_bitrate_estimator_.get());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000187 call_stats_->DeregisterStatsObserver(remote_bitrate_estimator_.get());
Erik Språng6b8d3552015-09-24 15:06:57 +0200188 if (transport_feedback_adapter_.get())
189 call_stats_->DeregisterStatsObserver(transport_feedback_adapter_.get());
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +0000190}
191
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +0000192
mflodman0c478b32015-10-21 15:52:16 +0200193void CongestionController::SetBweBitrates(int min_bitrate_bps,
194 int start_bitrate_bps,
195 int max_bitrate_bps) {
stefan4fbd1452015-09-28 03:57:14 -0700196 if (start_bitrate_bps > 0)
197 bitrate_controller_->SetStartBitrate(start_bitrate_bps);
198 bitrate_controller_->SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
199 if (remote_bitrate_estimator_.get())
200 remote_bitrate_estimator_->SetMinBitrate(min_bitrate_bps);
201 if (transport_feedback_adapter_.get())
202 transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate(
203 min_bitrate_bps);
204 min_bitrate_bps_ = min_bitrate_bps;
205}
206
mflodman0c478b32015-10-21 15:52:16 +0200207BitrateController* CongestionController::GetBitrateController() const {
bjornv@webrtc.orgcb89c6f2012-06-05 12:25:35 +0000208 return bitrate_controller_.get();
stefan@webrtc.orgf7288142012-06-05 10:44:00 +0000209}
210
mflodman0c478b32015-10-21 15:52:16 +0200211RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator(
mflodmana20de202015-10-18 22:08:19 -0700212 bool send_side_bwe) const {
213
214 if (send_side_bwe)
215 return remote_estimator_proxy_.get();
216 else
217 return remote_bitrate_estimator_.get();
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000218}
219
mflodman0c478b32015-10-21 15:52:16 +0200220TransportFeedbackObserver*
221CongestionController::GetTransportFeedbackObserver() {
mflodman949c2f02015-10-16 02:31:11 -0700222 if (transport_feedback_adapter_.get() == nullptr) {
223 transport_feedback_adapter_.reset(new TransportFeedbackAdapter(
Stefan Holmer58c664c2016-02-08 14:31:30 +0100224 bitrate_controller_.get(), clock_, process_thread_));
mflodman949c2f02015-10-16 02:31:11 -0700225 transport_feedback_adapter_->SetBitrateEstimator(
Stefan Holmer58c664c2016-02-08 14:31:30 +0100226 new RemoteBitrateEstimatorAbsSendTime(transport_feedback_adapter_.get(),
227 clock_));
mflodman949c2f02015-10-16 02:31:11 -0700228 transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate(
229 min_bitrate_bps_);
230 call_stats_->RegisterStatsObserver(transport_feedback_adapter_.get());
231 }
232 return transport_feedback_adapter_.get();
233}
234
mflodman0e7e2592015-11-12 21:02:42 -0800235void CongestionController::UpdatePacerBitrate(int bitrate_kbps,
236 int max_bitrate_kbps,
237 int min_bitrate_kbps) {
238 pacer_->UpdateBitrate(bitrate_kbps, max_bitrate_kbps, min_bitrate_kbps);
239}
240
mflodman0c478b32015-10-21 15:52:16 +0200241int64_t CongestionController::GetPacerQueuingDelayMs() const {
Stefan Holmere5904162015-03-26 11:11:06 +0100242 return pacer_->QueueInMs();
243}
244
mflodman0c478b32015-10-21 15:52:16 +0200245void CongestionController::SignalNetworkState(NetworkState state) {
stefan457a61d2015-10-14 03:12:59 -0700246 if (state == kNetworkUp) {
247 pacer_->Resume();
248 } else {
249 pacer_->Pause();
250 }
251}
252
mflodman0c478b32015-10-21 15:52:16 +0200253void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) {
stefanc1aeaf02015-10-15 07:26:07 -0700254 if (transport_feedback_adapter_) {
stefanbbe876f2015-10-23 02:05:40 -0700255 transport_feedback_adapter_->OnSentPacket(sent_packet.packet_id,
256 sent_packet.send_time_ms);
stefanc1aeaf02015-10-15 07:26:07 -0700257 }
258}
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000259} // namespace webrtc