blob: 27185c162d91a26837073a7884fd9a41a9666771 [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@webrtc.orga50e6f02015-03-09 10:06:40 +000013#include "webrtc/base/checks.h"
pbos@webrtc.org38344ed2014-09-24 06:05:00 +000014#include "webrtc/base/thread_annotations.h"
andresp@webrtc.org29b22192013-05-14 12:10:58 +000015#include "webrtc/common.h"
Stefan Holmere5904162015-03-26 11:11:06 +010016#include "webrtc/modules/pacing/include/paced_sender.h"
17#include "webrtc/modules/pacing/include/packet_router.h"
sprang867fb522015-08-03 04:38:41 -070018#include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
Erik Språng468e62a2015-07-06 10:50:47 +020019#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h"
20#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020021#include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h"
sprang5e023eb2015-09-14 06:42:43 -070022#include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010023#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
24#include "webrtc/modules/utility/include/process_thread.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010025#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
26#include "webrtc/system_wrappers/include/logging.h"
andresp@webrtc.org29b22192013-05-14 12:10:58 +000027#include "webrtc/video_engine/call_stats.h"
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +000028#include "webrtc/video_engine/payload_router.h"
andresp@webrtc.org29b22192013-05-14 12:10:58 +000029#include "webrtc/video_engine/vie_encoder.h"
30#include "webrtc/video_engine/vie_remb.h"
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +000031#include "webrtc/voice_engine/include/voe_video_sync.h"
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +000032
33namespace webrtc {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000034namespace {
35
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000036static const uint32_t kTimeOffsetSwitchThreshold = 30;
37
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000038class WrappingBitrateEstimator : public RemoteBitrateEstimator {
39 public:
pbosef35f062015-07-27 08:37:06 -070040 WrappingBitrateEstimator(RemoteBitrateObserver* observer, Clock* clock)
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000041 : observer_(observer),
42 clock_(clock),
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000043 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
stefan4fbd1452015-09-28 03:57:14 -070044 rbe_(new RemoteBitrateEstimatorSingleStream(observer_, clock_)),
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000045 using_absolute_send_time_(false),
stefan4fbd1452015-09-28 03:57:14 -070046 packets_since_absolute_send_time_(0),
47 min_bitrate_bps_(RemoteBitrateEstimator::kDefaultMinBitrateBps) {}
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000048
49 virtual ~WrappingBitrateEstimator() {}
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000050
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000051 void IncomingPacket(int64_t arrival_time_ms,
52 size_t payload_size,
Stefan Holmerff4ea932015-06-18 16:01:33 +020053 const RTPHeader& header,
54 bool was_paced) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000055 CriticalSectionScoped cs(crit_sect_.get());
stefan@webrtc.orga16147c2014-03-25 10:37:31 +000056 PickEstimatorFromHeader(header);
Stefan Holmerff4ea932015-06-18 16:01:33 +020057 rbe_->IncomingPacket(arrival_time_ms, payload_size, header, was_paced);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000058 }
59
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000060 int32_t Process() override {
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000061 CriticalSectionScoped cs(crit_sect_.get());
62 return rbe_->Process();
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000063 }
64
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000065 int64_t TimeUntilNextProcess() override {
andresp@webrtc.org1295dc62014-07-02 13:23:19 +000066 CriticalSectionScoped cs(crit_sect_.get());
67 return rbe_->TimeUntilNextProcess();
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000068 }
69
stefan2328a942015-08-07 04:27:51 -070070 void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000071 CriticalSectionScoped cs(crit_sect_.get());
stefan2328a942015-08-07 04:27:51 -070072 rbe_->OnRttUpdate(avg_rtt_ms, max_rtt_ms);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000073 }
74
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000075 void RemoveStream(unsigned int ssrc) override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000076 CriticalSectionScoped cs(crit_sect_.get());
77 rbe_->RemoveStream(ssrc);
78 }
79
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000080 bool LatestEstimate(std::vector<unsigned int>* ssrcs,
81 unsigned int* bitrate_bps) const override {
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000082 CriticalSectionScoped cs(crit_sect_.get());
83 return rbe_->LatestEstimate(ssrcs, bitrate_bps);
84 }
85
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000086 bool GetStats(ReceiveBandwidthEstimatorStats* output) const override {
jiayl@webrtc.org1f64f062014-02-10 19:12:14 +000087 CriticalSectionScoped cs(crit_sect_.get());
88 return rbe_->GetStats(output);
89 }
90
stefan4fbd1452015-09-28 03:57:14 -070091 void SetMinBitrate(int min_bitrate_bps) {
92 CriticalSectionScoped cs(crit_sect_.get());
93 rbe_->SetMinBitrate(min_bitrate_bps);
94 min_bitrate_bps_ = min_bitrate_bps;
95 }
96
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +000097 private:
stefan@webrtc.orga16147c2014-03-25 10:37:31 +000098 void PickEstimatorFromHeader(const RTPHeader& header)
99 EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000100 if (header.extension.hasAbsoluteSendTime) {
101 // If we see AST in header, switch RBE strategy immediately.
102 if (!using_absolute_send_time_) {
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000103 LOG(LS_INFO) <<
104 "WrappingBitrateEstimator: Switching to absolute send time RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000105 using_absolute_send_time_ = true;
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000106 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000107 }
108 packets_since_absolute_send_time_ = 0;
109 } else {
110 // When we don't see AST, wait for a few packets before going back to TOF.
111 if (using_absolute_send_time_) {
112 ++packets_since_absolute_send_time_;
113 if (packets_since_absolute_send_time_ >= kTimeOffsetSwitchThreshold) {
mflodman@webrtc.org5574dac2014-04-07 10:56:31 +0000114 LOG(LS_INFO) << "WrappingBitrateEstimator: Switching to transmission "
115 << "time offset RBE.";
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000116 using_absolute_send_time_ = false;
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000117 PickEstimator();
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000118 }
119 }
120 }
121 }
122
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000123 // Instantiate RBE for Time Offset or Absolute Send Time extensions.
124 void PickEstimator() EXCLUSIVE_LOCKS_REQUIRED(crit_sect_.get()) {
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000125 if (using_absolute_send_time_) {
stefan4fbd1452015-09-28 03:57:14 -0700126 rbe_.reset(new RemoteBitrateEstimatorAbsSendTime(observer_, clock_));
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000127 } else {
stefan4fbd1452015-09-28 03:57:14 -0700128 rbe_.reset(new RemoteBitrateEstimatorSingleStream(observer_, clock_));
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000129 }
stefan4fbd1452015-09-28 03:57:14 -0700130 rbe_->SetMinBitrate(min_bitrate_bps_);
stefan@webrtc.orga16147c2014-03-25 10:37:31 +0000131 }
132
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000133 RemoteBitrateObserver* observer_;
134 Clock* clock_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000135 rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +0000136 rtc::scoped_ptr<RemoteBitrateEstimator> rbe_;
pbos@webrtc.org5ab75672013-12-16 12:24:44 +0000137 bool using_absolute_send_time_;
138 uint32_t packets_since_absolute_send_time_;
stefan4fbd1452015-09-28 03:57:14 -0700139 int min_bitrate_bps_;
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000140
henrikg3c089d72015-09-16 05:37:44 -0700141 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WrappingBitrateEstimator);
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000142};
sprang867fb522015-08-03 04:38:41 -0700143
solenberg@webrtc.orga6db54d2013-05-27 16:02:56 +0000144} // namespace
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000145
mflodman0c478b32015-10-21 15:52:16 +0200146CongestionController::CongestionController(ProcessThread* process_thread,
147 CallStats* call_stats)
stefan@webrtc.orgb5865072013-02-01 14:33:42 +0000148 : remb_(new VieRemb()),
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000149 bitrate_allocator_(new BitrateAllocator()),
Stefan Holmere5904162015-03-26 11:11:06 +0100150 packet_router_(new PacketRouter()),
151 pacer_(new PacedSender(Clock::GetRealTimeClock(),
152 packet_router_.get(),
153 BitrateController::kDefaultStartBitrateKbps,
154 PacedSender::kDefaultPaceMultiplier *
155 BitrateController::kDefaultStartBitrateKbps,
156 0)),
Erik Språng6b8d3552015-09-24 15:06:57 +0200157 remote_bitrate_estimator_(
158 new WrappingBitrateEstimator(remb_.get(), Clock::GetRealTimeClock())),
159 remote_estimator_proxy_(
160 new RemoteEstimatorProxy(Clock::GetRealTimeClock(),
161 packet_router_.get())),
Stefan Holmere5904162015-03-26 11:11:06 +0100162 process_thread_(process_thread),
mflodmane3787022015-10-21 13:24:28 +0200163 call_stats_(call_stats),
stefan847855b2015-09-11 09:52:15 -0700164 pacer_thread_(ProcessThread::Create("PacerThread")),
Stefan Holmere5904162015-03-26 11:11:06 +0100165 // Constructed last as this object calls the provided callback on
166 // construction.
167 bitrate_controller_(
168 BitrateController::CreateBitrateController(Clock::GetRealTimeClock(),
stefan4fbd1452015-09-28 03:57:14 -0700169 this)),
170 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());
174 pacer_thread_->Start();
175
Erik Språng6b8d3552015-09-24 15:06:57 +0200176 process_thread->RegisterModule(remote_estimator_proxy_.get());
andresp@webrtc.org1295dc62014-07-02 13:23:19 +0000177 process_thread->RegisterModule(remote_bitrate_estimator_.get());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000178 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());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000184 process_thread_->DeRegisterModule(bitrate_controller_.get());
andresp@webrtc.org1295dc62014-07-02 13:23:19 +0000185 process_thread_->DeRegisterModule(remote_bitrate_estimator_.get());
Erik Språng6b8d3552015-09-24 15:06:57 +0200186 process_thread_->DeRegisterModule(remote_estimator_proxy_.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());
henrikg91d6ede2015-09-17 00:24:34 -0700190 RTC_DCHECK(!remb_->InUse());
mflodman949c2f02015-10-16 02:31:11 -0700191 RTC_DCHECK(encoders_.empty());
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +0000192}
193
mflodman0c478b32015-10-21 15:52:16 +0200194void CongestionController::AddEncoder(ViEEncoder* encoder) {
mflodman949c2f02015-10-16 02:31:11 -0700195 rtc::CritScope lock(&encoder_crit_);
196 encoders_.push_back(encoder);
197}
198
mflodman0c478b32015-10-21 15:52:16 +0200199void CongestionController::RemoveEncoder(ViEEncoder* encoder) {
mflodman949c2f02015-10-16 02:31:11 -0700200 rtc::CritScope lock(&encoder_crit_);
201 for (auto it = encoders_.begin(); it != encoders_.end(); ++it) {
202 if (*it == encoder) {
203 encoders_.erase(it);
204 return;
205 }
206 }
stefan@webrtc.orga50e6f02015-03-09 10:06:40 +0000207}
208
mflodman0c478b32015-10-21 15:52:16 +0200209void CongestionController::SetBweBitrates(int min_bitrate_bps,
210 int start_bitrate_bps,
211 int max_bitrate_bps) {
stefan4fbd1452015-09-28 03:57:14 -0700212 if (start_bitrate_bps > 0)
213 bitrate_controller_->SetStartBitrate(start_bitrate_bps);
214 bitrate_controller_->SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
215 if (remote_bitrate_estimator_.get())
216 remote_bitrate_estimator_->SetMinBitrate(min_bitrate_bps);
217 if (transport_feedback_adapter_.get())
218 transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate(
219 min_bitrate_bps);
220 min_bitrate_bps_ = min_bitrate_bps;
221}
222
mflodman0c478b32015-10-21 15:52:16 +0200223BitrateController* CongestionController::GetBitrateController() const {
bjornv@webrtc.orgcb89c6f2012-06-05 12:25:35 +0000224 return bitrate_controller_.get();
stefan@webrtc.orgf7288142012-06-05 10:44:00 +0000225}
226
mflodman0c478b32015-10-21 15:52:16 +0200227RemoteBitrateEstimator* CongestionController::GetRemoteBitrateEstimator(
mflodmana20de202015-10-18 22:08:19 -0700228 bool send_side_bwe) const {
229
230 if (send_side_bwe)
231 return remote_estimator_proxy_.get();
232 else
233 return remote_bitrate_estimator_.get();
stefan@webrtc.org9354cc92012-06-07 08:10:14 +0000234}
235
mflodman0c478b32015-10-21 15:52:16 +0200236TransportFeedbackObserver*
237CongestionController::GetTransportFeedbackObserver() {
mflodman949c2f02015-10-16 02:31:11 -0700238 if (transport_feedback_adapter_.get() == nullptr) {
239 transport_feedback_adapter_.reset(new TransportFeedbackAdapter(
240 bitrate_controller_->CreateRtcpBandwidthObserver(),
241 Clock::GetRealTimeClock(), process_thread_));
242 transport_feedback_adapter_->SetBitrateEstimator(
243 new RemoteBitrateEstimatorAbsSendTime(
244 transport_feedback_adapter_.get(), Clock::GetRealTimeClock()));
245 transport_feedback_adapter_->GetBitrateEstimator()->SetMinBitrate(
246 min_bitrate_bps_);
247 call_stats_->RegisterStatsObserver(transport_feedback_adapter_.get());
248 }
249 return transport_feedback_adapter_.get();
250}
251
mflodman0c478b32015-10-21 15:52:16 +0200252int64_t CongestionController::GetPacerQueuingDelayMs() const {
Stefan Holmere5904162015-03-26 11:11:06 +0100253 return pacer_->QueueInMs();
254}
255
mflodmane3787022015-10-21 13:24:28 +0200256// TODO(mflodman): Move out of this class.
mflodman0c478b32015-10-21 15:52:16 +0200257void CongestionController::SetChannelRembStatus(bool sender,
258 bool receiver,
259 RtpRtcp* rtp_module) {
mflodmane3787022015-10-21 13:24:28 +0200260 rtp_module->SetREMBStatus(sender || receiver);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000261 if (sender) {
262 remb_->AddRembSender(rtp_module);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000263 } else {
264 remb_->RemoveRembSender(rtp_module);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000265 }
266 if (receiver) {
267 remb_->AddReceiveChannel(rtp_module);
268 } else {
269 remb_->RemoveReceiveChannel(rtp_module);
270 }
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000271}
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000272
mflodman0c478b32015-10-21 15:52:16 +0200273void CongestionController::SignalNetworkState(NetworkState state) {
stefan457a61d2015-10-14 03:12:59 -0700274 if (state == kNetworkUp) {
275 pacer_->Resume();
276 } else {
277 pacer_->Pause();
278 }
279}
280
mflodman0c478b32015-10-21 15:52:16 +0200281// TODO(mflodman): Move this logic out from CongestionController.
282void CongestionController::OnNetworkChanged(uint32_t target_bitrate_bps,
283 uint8_t fraction_loss,
284 int64_t rtt) {
sprang2f48d942015-11-05 04:25:49 -0800285 uint32_t allocated_bitrate_bps = bitrate_allocator_->OnNetworkChanged(
286 target_bitrate_bps, fraction_loss, rtt);
Stefan Holmere5904162015-03-26 11:11:06 +0100287 int pad_up_to_bitrate_bps = 0;
288 {
mflodman949c2f02015-10-16 02:31:11 -0700289 rtc::CritScope lock(&encoder_crit_);
290 for (const auto& encoder : encoders_)
291 pad_up_to_bitrate_bps += encoder->GetPaddingNeededBps();
Stefan Holmere5904162015-03-26 11:11:06 +0100292 }
sprang2f48d942015-11-05 04:25:49 -0800293 // Allocated bitrate might be higher than bitrate estimate if enforcing min
294 // bitrate, or lower if estimate is higher than the sum of max bitrates, so
295 // set the pacer bitrate to the maximum of the two.
296 uint32_t pacer_bitrate_bps =
297 std::max(target_bitrate_bps, allocated_bitrate_bps);
Stefan Holmere5904162015-03-26 11:11:06 +0100298 pacer_->UpdateBitrate(
sprang2f48d942015-11-05 04:25:49 -0800299 pacer_bitrate_bps / 1000,
300 PacedSender::kDefaultPaceMultiplier * pacer_bitrate_bps / 1000,
Stefan Holmere5904162015-03-26 11:11:06 +0100301 pad_up_to_bitrate_bps / 1000);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000302}
stefanc1aeaf02015-10-15 07:26:07 -0700303
mflodman0c478b32015-10-21 15:52:16 +0200304void CongestionController::OnSentPacket(const rtc::SentPacket& sent_packet) {
stefanc1aeaf02015-10-15 07:26:07 -0700305 if (transport_feedback_adapter_) {
stefanbbe876f2015-10-23 02:05:40 -0700306 transport_feedback_adapter_->OnSentPacket(sent_packet.packet_id,
307 sent_packet.send_time_ms);
stefanc1aeaf02015-10-15 07:26:07 -0700308 }
309}
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000310} // namespace webrtc