blob: 86b016c18a75cb65b965e31354e19b78725beb64 [file] [log] [blame]
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +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 */
11
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020012#include "modules/bitrate_controller/bitrate_controller_impl.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000013
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000014#include <algorithm>
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000015#include <utility>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
18#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
19#include "rtc_base/checks.h"
20#include "rtc_base/logging.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000021
22namespace webrtc {
Sebastian Jansson7c1744d2018-10-08 11:00:50 +020023namespace {
24absl::optional<DataRate> ToOptionalDataRate(int send_bitrate_bps) {
25 if (send_bitrate_bps > 0)
26 return DataRate::bps(send_bitrate_bps);
27 return absl::nullopt;
28}
29DataRate MaxRate(int max_bitrate_bps) {
30 if (max_bitrate_bps == -1)
31 return DataRate::Infinity();
32 return DataRate::bps(max_bitrate_bps);
33}
34} // namespace
andresp@webrtc.org16b75c22014-03-21 14:00:51 +000035class BitrateControllerImpl::RtcpBandwidthObserverImpl
36 : public RtcpBandwidthObserver {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000037 public:
38 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
Yves Gerey665174f2018-06-19 15:03:05 +020039 : owner_(owner) {}
Danil Chapovalov38018ba2017-06-12 16:29:45 +020040 ~RtcpBandwidthObserverImpl() override = default;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000041 // Received RTCP REMB or TMMBR.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000042 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
Danil Chapovalov38018ba2017-06-12 16:29:45 +020043 owner_->OnReceivedEstimatedBitrate(bitrate);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000044 }
45 // Received RTCP receiver block.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000046 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
47 int64_t rtt,
48 int64_t now_ms) override {
Danil Chapovalov38018ba2017-06-12 16:29:45 +020049 owner_->OnReceivedRtcpReceiverReport(report_blocks, rtt, now_ms);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000050 }
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000051
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000052 private:
Danil Chapovalov38018ba2017-06-12 16:29:45 +020053 BitrateControllerImpl* const owner_;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000054};
55
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000056BitrateController* BitrateController::CreateBitrateController(
elad.alon61ce37e2017-03-09 07:09:31 -080057 const Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -070058 BitrateObserver* observer,
59 RtcEventLog* event_log) {
60 return new BitrateControllerImpl(clock, observer, event_log);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000061}
62
ivoc14d5dbe2016-07-04 07:06:55 -070063BitrateController* BitrateController::CreateBitrateController(
elad.alon61ce37e2017-03-09 07:09:31 -080064 const Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -070065 RtcEventLog* event_log) {
66 return CreateBitrateController(clock, nullptr, event_log);
perkjec81bcd2016-05-11 06:01:13 -070067}
68
elad.alon61ce37e2017-03-09 07:09:31 -080069BitrateControllerImpl::BitrateControllerImpl(const Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -070070 BitrateObserver* observer,
71 RtcEventLog* event_log)
andresp@webrtc.org44caf012014-03-26 21:00:21 +000072 : clock_(clock),
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000073 observer_(observer),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000074 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
ivoc14d5dbe2016-07-04 07:06:55 -070075 event_log_(event_log),
76 bandwidth_estimation_(event_log),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000077 last_bitrate_bps_(0),
solenberg@webrtc.org4e656022014-03-26 14:32:47 +000078 last_fraction_loss_(0),
Sebastian Jansson803e3ff2018-08-06 19:14:37 +020079 last_rtt_ms_(0) {
perkjec81bcd2016-05-11 06:01:13 -070080 // This calls the observer_ if set, which means that the observer provided by
81 // the user must be ready to accept a bitrate update when it constructs the
Stefan Holmere5904162015-03-26 11:11:06 +010082 // controller. We do this to avoid having to keep synchronized initial values
83 // in both the controller and the allocator.
84 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000085}
86
87RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
88 return new RtcpBandwidthObserverImpl(this);
89}
90
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000091void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +010092 {
sprang867fb522015-08-03 04:38:41 -070093 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 11:00:50 +020094 bandwidth_estimation_.SetSendBitrate(
95 DataRate::bps(start_bitrate_bps),
96 Timestamp::ms(clock_->TimeInMilliseconds()));
Stefan Holmere5904162015-03-26 11:11:06 +010097 }
98 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org07bc7342014-03-21 16:51:01 +000099}
100
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000101void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
102 int max_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +0100103 {
sprang867fb522015-08-03 04:38:41 -0700104 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200105 bandwidth_estimation_.SetMinMaxBitrate(DataRate::bps(min_bitrate_bps),
106 DataRate::bps(max_bitrate_bps));
Stefan Holmere5904162015-03-26 11:11:06 +0100107 }
108 MaybeTriggerOnNetworkChanged();
henrik.lundin@webrtc.org845862f2014-03-06 07:19:28 +0000109}
110
philipelc6957c72016-04-28 15:52:49 +0200111void BitrateControllerImpl::SetBitrates(int start_bitrate_bps,
112 int min_bitrate_bps,
113 int max_bitrate_bps) {
114 {
115 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200116 bandwidth_estimation_.SetBitrates(
117 ToOptionalDataRate(start_bitrate_bps), DataRate::bps(min_bitrate_bps),
118 MaxRate(max_bitrate_bps), Timestamp::ms(clock_->TimeInMilliseconds()));
philipelc6957c72016-04-28 15:52:49 +0200119 }
120 MaybeTriggerOnNetworkChanged();
121}
122
honghaiz059e1832016-06-24 11:03:55 -0700123void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
124 int min_bitrate_bps,
125 int max_bitrate_bps) {
126 {
127 rtc::CritScope cs(&critsect_);
ivoc14d5dbe2016-07-04 07:06:55 -0700128 bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200129 bandwidth_estimation_.SetBitrates(
130 ToOptionalDataRate(bitrate_bps), DataRate::bps(min_bitrate_bps),
131 MaxRate(max_bitrate_bps), Timestamp::ms(clock_->TimeInMilliseconds()));
honghaiz059e1832016-06-24 11:03:55 -0700132 }
133 MaybeTriggerOnNetworkChanged();
134}
135
Irfan Sheriffb2540bb2016-09-12 12:28:54 -0700136// This is called upon reception of REMB or TMMBR.
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200137void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000138 {
sprang867fb522015-08-03 04:38:41 -0700139 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200140 bandwidth_estimation_.UpdateReceiverEstimate(
141 Timestamp::ms(clock_->TimeInMilliseconds()), DataRate::bps(bitrate));
gaetano.carlucci61050f62016-09-30 06:29:54 -0700142 BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700143 bitrate / 1000);
sprang@webrtc.org9b791972014-12-18 11:53:59 +0000144 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000145 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000146}
147
Stefan Holmer280de9e2016-09-30 10:06:51 +0200148void BitrateControllerImpl::OnDelayBasedBweResult(
149 const DelayBasedBwe::Result& result) {
150 if (!result.updated)
151 return;
philipel0aa9d182016-08-24 02:45:35 -0700152 {
153 rtc::CritScope cs(&critsect_);
Stefan Holmer280de9e2016-09-30 10:06:51 +0200154 if (result.probe) {
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200155 bandwidth_estimation_.SetSendBitrate(
156 DataRate::bps(result.target_bitrate_bps),
157 Timestamp::ms(clock_->TimeInMilliseconds()));
Stefan Holmer280de9e2016-09-30 10:06:51 +0200158 }
Bjorn Terelius29cb0e72017-11-08 14:41:12 +0100159 // Since SetSendBitrate now resets the delay-based estimate, we have to call
160 // UpdateDelayBasedEstimate after SetSendBitrate.
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200161 bandwidth_estimation_.UpdateDelayBasedEstimate(
162 Timestamp::ms(clock_->TimeInMilliseconds()),
163 DataRate::bps(result.target_bitrate_bps));
stefan32f81542016-01-20 07:13:58 -0800164 }
165 MaybeTriggerOnNetworkChanged();
166}
167
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000168int64_t BitrateControllerImpl::TimeUntilNextProcess() {
169 const int64_t kBitrateControllerUpdateIntervalMs = 25;
sprang867fb522015-08-03 04:38:41 -0700170 rtc::CritScope cs(&critsect_);
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000171 int64_t time_since_update_ms =
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000172 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000173 return std::max<int64_t>(
174 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000175}
176
pbosa26ac922016-02-25 04:50:01 -0800177void BitrateControllerImpl::Process() {
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000178 {
sprang867fb522015-08-03 04:38:41 -0700179 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200180 bandwidth_estimation_.UpdateEstimate(
181 Timestamp::ms(clock_->TimeInMilliseconds()));
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000182 }
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000183 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000184 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000185}
186
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000187void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200188 const ReportBlockList& report_blocks,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000189 int64_t rtt,
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000190 int64_t now_ms) {
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200191 if (report_blocks.empty())
192 return;
193
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000194 {
sprang867fb522015-08-03 04:38:41 -0700195 rtc::CritScope cs(&critsect_);
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200196 int fraction_lost_aggregate = 0;
197 int total_number_of_packets = 0;
198
199 // Compute the a weighted average of the fraction loss from all report
200 // blocks.
201 for (const RTCPReportBlock& report_block : report_blocks) {
202 std::map<uint32_t, uint32_t>::iterator seq_num_it =
203 ssrc_to_last_received_extended_high_seq_num_.find(
srte3e69e5c2017-08-09 06:13:45 -0700204 report_block.source_ssrc);
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200205
206 int number_of_packets = 0;
207 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end()) {
208 number_of_packets =
srte3e69e5c2017-08-09 06:13:45 -0700209 report_block.extended_highest_sequence_number - seq_num_it->second;
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200210 }
211
srte3e69e5c2017-08-09 06:13:45 -0700212 fraction_lost_aggregate += number_of_packets * report_block.fraction_lost;
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200213 total_number_of_packets += number_of_packets;
214
215 // Update last received for this SSRC.
srte3e69e5c2017-08-09 06:13:45 -0700216 ssrc_to_last_received_extended_high_seq_num_[report_block.source_ssrc] =
217 report_block.extended_highest_sequence_number;
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200218 }
219 if (total_number_of_packets < 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100220 RTC_LOG(LS_WARNING)
221 << "Received report block where extended high sequence "
222 "number goes backwards, ignoring.";
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200223 return;
224 }
225 if (total_number_of_packets == 0)
226 fraction_lost_aggregate = 0;
227 else
228 fraction_lost_aggregate =
229 (fraction_lost_aggregate + total_number_of_packets / 2) /
230 total_number_of_packets;
231 if (fraction_lost_aggregate > 255)
232 return;
233
234 RTC_DCHECK_GE(total_number_of_packets, 0);
235
Sebastian Jansson7c1744d2018-10-08 11:00:50 +0200236 bandwidth_estimation_.UpdateReceiverBlock(
237 fraction_lost_aggregate, TimeDelta::ms(rtt), total_number_of_packets,
238 Timestamp::ms(now_ms));
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000239 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000240 MaybeTriggerOnNetworkChanged();
241}
242
243void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
perkjec81bcd2016-05-11 06:01:13 -0700244 if (!observer_)
245 return;
246
247 uint32_t bitrate_bps;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000248 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000249 int64_t rtt;
perkjec81bcd2016-05-11 06:01:13 -0700250
251 if (GetNetworkParameters(&bitrate_bps, &fraction_loss, &rtt))
252 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
andresp@webrtc.org16b75c22014-03-21 14:00:51 +0000253}
254
Stefan Holmere5904162015-03-26 11:11:06 +0100255bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
256 uint8_t* fraction_loss,
257 int64_t* rtt) {
sprang867fb522015-08-03 04:38:41 -0700258 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100259 int current_bitrate;
260 bandwidth_estimation_.CurrentEstimate(&current_bitrate, fraction_loss, rtt);
261 *bitrate = current_bitrate;
Stefan Holmere5904162015-03-26 11:11:06 +0100262 *bitrate =
263 std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
264
265 bool new_bitrate = false;
266 if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
Sebastian Jansson803e3ff2018-08-06 19:14:37 +0200267 *rtt != last_rtt_ms_) {
Stefan Holmere5904162015-03-26 11:11:06 +0100268 last_bitrate_bps_ = *bitrate;
269 last_fraction_loss_ = *fraction_loss;
270 last_rtt_ms_ = *rtt;
Stefan Holmere5904162015-03-26 11:11:06 +0100271 new_bitrate = true;
272 }
gaetano.carlucci52a57032016-09-14 05:04:36 -0700273
gaetano.carlucci61050f62016-09-30 06:29:54 -0700274 BWE_TEST_LOGGING_PLOT(1, "fraction_loss_%", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700275 (last_fraction_loss_ * 100) / 256);
gaetano.carlucci61050f62016-09-30 06:29:54 -0700276 BWE_TEST_LOGGING_PLOT(1, "rtt_ms", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700277 last_rtt_ms_);
gaetano.carlucci61050f62016-09-30 06:29:54 -0700278 BWE_TEST_LOGGING_PLOT(1, "Target_bitrate_kbps", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700279 last_bitrate_bps_ / 1000);
280
Stefan Holmere5904162015-03-26 11:11:06 +0100281 return new_bitrate;
282}
283
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000284bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
sprang867fb522015-08-03 04:38:41 -0700285 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100286 int bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000287 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000288 int64_t rtt;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000289 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
Stefan Holmere5904162015-03-26 11:11:06 +0100290 if (bitrate > 0) {
Stefan Holmere5904162015-03-26 11:11:06 +0100291 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
292 *bandwidth = bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000293 return true;
294 }
295 return false;
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000296}
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000297} // namespace webrtc