blob: 05d967bd1d2ac61d4d5ded75a50fb269801397f6 [file] [log] [blame]
pwestin@webrtc.org1cd11622012-04-19 12:13:521/*
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 04:47:3112#include "modules/bitrate_controller/bitrate_controller_impl.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:5213
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:0114#include <algorithm>
pwestin@webrtc.org1cd11622012-04-19 12:13:5215#include <utility>
16
Mirko Bonadei92ea95e2017-09-15 04:47:3117#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:5221
22namespace webrtc {
Sebastian Jansson7c1744d2018-10-08 09:00:5023namespace {
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:5135class BitrateControllerImpl::RtcpBandwidthObserverImpl
36 : public RtcpBandwidthObserver {
pwestin@webrtc.org1cd11622012-04-19 12:13:5237 public:
38 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
Yves Gerey665174f2018-06-19 13:03:0539 : owner_(owner) {}
Danil Chapovalov38018ba2017-06-12 14:29:4540 ~RtcpBandwidthObserverImpl() override = default;
pwestin@webrtc.org1cd11622012-04-19 12:13:5241 // Received RTCP REMB or TMMBR.
kjellander@webrtc.org14665ff2015-03-04 12:58:3542 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
Danil Chapovalov38018ba2017-06-12 14:29:4543 owner_->OnReceivedEstimatedBitrate(bitrate);
pwestin@webrtc.org1cd11622012-04-19 12:13:5244 }
45 // Received RTCP receiver block.
kjellander@webrtc.org14665ff2015-03-04 12:58:3546 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
47 int64_t rtt,
48 int64_t now_ms) override {
Danil Chapovalov38018ba2017-06-12 14:29:4549 owner_->OnReceivedRtcpReceiverReport(report_blocks, rtt, now_ms);
pwestin@webrtc.org1cd11622012-04-19 12:13:5250 }
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:0151
pwestin@webrtc.org1cd11622012-04-19 12:13:5252 private:
Danil Chapovalov38018ba2017-06-12 14:29:4553 BitrateControllerImpl* const owner_;
pwestin@webrtc.org1cd11622012-04-19 12:13:5254};
55
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:0156BitrateController* BitrateController::CreateBitrateController(
Sebastian Janssonaa01f272019-01-30 10:28:5957 Clock* clock,
ivoc14d5dbe2016-07-04 14:06:5558 BitrateObserver* observer,
59 RtcEventLog* event_log) {
60 return new BitrateControllerImpl(clock, observer, event_log);
pwestin@webrtc.org1cd11622012-04-19 12:13:5261}
62
ivoc14d5dbe2016-07-04 14:06:5563BitrateController* BitrateController::CreateBitrateController(
Sebastian Janssonaa01f272019-01-30 10:28:5964 Clock* clock,
ivoc14d5dbe2016-07-04 14:06:5565 RtcEventLog* event_log) {
66 return CreateBitrateController(clock, nullptr, event_log);
perkjec81bcd2016-05-11 13:01:1367}
68
Sebastian Janssonaa01f272019-01-30 10:28:5969BitrateControllerImpl::BitrateControllerImpl(Clock* clock,
ivoc14d5dbe2016-07-04 14:06:5570 BitrateObserver* observer,
71 RtcEventLog* event_log)
andresp@webrtc.org44caf012014-03-26 21:00:2172 : clock_(clock),
stefan@webrtc.org792f1a12015-03-04 12:24:2673 observer_(observer),
andresp@webrtc.org44caf012014-03-26 21:00:2174 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
ivoc14d5dbe2016-07-04 14:06:5575 event_log_(event_log),
76 bandwidth_estimation_(event_log),
andresp@webrtc.org44caf012014-03-26 21:00:2177 last_bitrate_bps_(0),
solenberg@webrtc.org4e656022014-03-26 14:32:4778 last_fraction_loss_(0),
Sebastian Jansson803e3ff2018-08-06 17:14:3779 last_rtt_ms_(0) {
perkjec81bcd2016-05-11 13:01:1380 // 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 10:11:0682 // 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:5285}
86
87RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
88 return new RtcpBandwidthObserverImpl(this);
89}
90
stefan@webrtc.org792f1a12015-03-04 12:24:2691void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
Stefan Holmere5904162015-03-26 10:11:0692 {
sprang867fb522015-08-03 11:38:4193 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 09:00:5094 bandwidth_estimation_.SetSendBitrate(
95 DataRate::bps(start_bitrate_bps),
96 Timestamp::ms(clock_->TimeInMilliseconds()));
Stefan Holmere5904162015-03-26 10:11:0697 }
98 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org07bc7342014-03-21 16:51:0199}
100
stefan@webrtc.org792f1a12015-03-04 12:24:26101void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
102 int max_bitrate_bps) {
Stefan Holmere5904162015-03-26 10:11:06103 {
sprang867fb522015-08-03 11:38:41104 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 09:00:50105 bandwidth_estimation_.SetMinMaxBitrate(DataRate::bps(min_bitrate_bps),
106 DataRate::bps(max_bitrate_bps));
Stefan Holmere5904162015-03-26 10:11:06107 }
108 MaybeTriggerOnNetworkChanged();
henrik.lundin@webrtc.org845862f2014-03-06 07:19:28109}
110
philipelc6957c72016-04-28 13:52:49111void 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 09:00:50116 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 13:52:49119 }
120 MaybeTriggerOnNetworkChanged();
121}
122
honghaiz059e1832016-06-24 18:03:55123void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
124 int min_bitrate_bps,
125 int max_bitrate_bps) {
126 {
127 rtc::CritScope cs(&critsect_);
ivoc14d5dbe2016-07-04 14:06:55128 bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
Sebastian Jansson7c1744d2018-10-08 09:00:50129 bandwidth_estimation_.SetBitrates(
130 ToOptionalDataRate(bitrate_bps), DataRate::bps(min_bitrate_bps),
131 MaxRate(max_bitrate_bps), Timestamp::ms(clock_->TimeInMilliseconds()));
honghaiz059e1832016-06-24 18:03:55132 }
133 MaybeTriggerOnNetworkChanged();
134}
135
Irfan Sheriffb2540bb2016-09-12 19:28:54136// This is called upon reception of REMB or TMMBR.
Danil Chapovalov38018ba2017-06-12 14:29:45137void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
stefan@webrtc.org792f1a12015-03-04 12:24:26138 {
sprang867fb522015-08-03 11:38:41139 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 09:00:50140 bandwidth_estimation_.UpdateReceiverEstimate(
141 Timestamp::ms(clock_->TimeInMilliseconds()), DataRate::bps(bitrate));
gaetano.carlucci61050f62016-09-30 13:29:54142 BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 12:04:36143 bitrate / 1000);
sprang@webrtc.org9b791972014-12-18 11:53:59144 }
andresp@webrtc.org07bc7342014-03-21 16:51:01145 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52146}
147
Stefan Holmer280de9e2016-09-30 08:06:51148void BitrateControllerImpl::OnDelayBasedBweResult(
149 const DelayBasedBwe::Result& result) {
150 if (!result.updated)
151 return;
philipel0aa9d182016-08-24 09:45:35152 {
153 rtc::CritScope cs(&critsect_);
Stefan Holmer280de9e2016-09-30 08:06:51154 if (result.probe) {
Sebastian Jansson7c1744d2018-10-08 09:00:50155 bandwidth_estimation_.SetSendBitrate(
Sebastian Janssonb6787bc2018-11-19 17:01:17156 result.target_bitrate, Timestamp::ms(clock_->TimeInMilliseconds()));
Stefan Holmer280de9e2016-09-30 08:06:51157 }
Bjorn Terelius29cb0e72017-11-08 13:41:12158 // Since SetSendBitrate now resets the delay-based estimate, we have to call
159 // UpdateDelayBasedEstimate after SetSendBitrate.
Sebastian Jansson7c1744d2018-10-08 09:00:50160 bandwidth_estimation_.UpdateDelayBasedEstimate(
Sebastian Janssonb6787bc2018-11-19 17:01:17161 Timestamp::ms(clock_->TimeInMilliseconds()), result.target_bitrate);
stefan32f81542016-01-20 15:13:58162 }
163 MaybeTriggerOnNetworkChanged();
164}
165
pkasting@chromium.org0b1534c2014-12-15 22:09:40166int64_t BitrateControllerImpl::TimeUntilNextProcess() {
167 const int64_t kBitrateControllerUpdateIntervalMs = 25;
sprang867fb522015-08-03 11:38:41168 rtc::CritScope cs(&critsect_);
pkasting@chromium.org0b1534c2014-12-15 22:09:40169 int64_t time_since_update_ms =
andresp@webrtc.org44caf012014-03-26 21:00:21170 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
pkasting@chromium.org0b1534c2014-12-15 22:09:40171 return std::max<int64_t>(
172 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
andresp@webrtc.org44caf012014-03-26 21:00:21173}
174
pbosa26ac922016-02-25 12:50:01175void BitrateControllerImpl::Process() {
andresp@webrtc.org44caf012014-03-26 21:00:21176 {
sprang867fb522015-08-03 11:38:41177 rtc::CritScope cs(&critsect_);
Sebastian Jansson7c1744d2018-10-08 09:00:50178 bandwidth_estimation_.UpdateEstimate(
179 Timestamp::ms(clock_->TimeInMilliseconds()));
andresp@webrtc.org44caf012014-03-26 21:00:21180 }
stefan@webrtc.org792f1a12015-03-04 12:24:26181 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org44caf012014-03-26 21:00:21182 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
andresp@webrtc.org44caf012014-03-26 21:00:21183}
184
pwestin@webrtc.org1cd11622012-04-19 12:13:52185void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
Danil Chapovalov38018ba2017-06-12 14:29:45186 const ReportBlockList& report_blocks,
pkasting@chromium.org16825b12015-01-12 21:51:21187 int64_t rtt,
stefan@webrtc.orgedeea912014-12-08 19:46:23188 int64_t now_ms) {
Danil Chapovalov38018ba2017-06-12 14:29:45189 if (report_blocks.empty())
190 return;
191
stefan@webrtc.org792f1a12015-03-04 12:24:26192 {
sprang867fb522015-08-03 11:38:41193 rtc::CritScope cs(&critsect_);
Danil Chapovalov38018ba2017-06-12 14:29:45194 int fraction_lost_aggregate = 0;
195 int total_number_of_packets = 0;
196
197 // Compute the a weighted average of the fraction loss from all report
198 // blocks.
199 for (const RTCPReportBlock& report_block : report_blocks) {
200 std::map<uint32_t, uint32_t>::iterator seq_num_it =
201 ssrc_to_last_received_extended_high_seq_num_.find(
srte3e69e5c2017-08-09 13:13:45202 report_block.source_ssrc);
Danil Chapovalov38018ba2017-06-12 14:29:45203
204 int number_of_packets = 0;
205 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end()) {
206 number_of_packets =
srte3e69e5c2017-08-09 13:13:45207 report_block.extended_highest_sequence_number - seq_num_it->second;
Danil Chapovalov38018ba2017-06-12 14:29:45208 }
209
srte3e69e5c2017-08-09 13:13:45210 fraction_lost_aggregate += number_of_packets * report_block.fraction_lost;
Danil Chapovalov38018ba2017-06-12 14:29:45211 total_number_of_packets += number_of_packets;
212
213 // Update last received for this SSRC.
srte3e69e5c2017-08-09 13:13:45214 ssrc_to_last_received_extended_high_seq_num_[report_block.source_ssrc] =
215 report_block.extended_highest_sequence_number;
Danil Chapovalov38018ba2017-06-12 14:29:45216 }
217 if (total_number_of_packets < 0) {
Mirko Bonadei675513b2017-11-09 10:09:25218 RTC_LOG(LS_WARNING)
219 << "Received report block where extended high sequence "
220 "number goes backwards, ignoring.";
Danil Chapovalov38018ba2017-06-12 14:29:45221 return;
222 }
223 if (total_number_of_packets == 0)
224 fraction_lost_aggregate = 0;
225 else
226 fraction_lost_aggregate =
227 (fraction_lost_aggregate + total_number_of_packets / 2) /
228 total_number_of_packets;
229 if (fraction_lost_aggregate > 255)
230 return;
231
232 RTC_DCHECK_GE(total_number_of_packets, 0);
233
Sebastian Jansson7c1744d2018-10-08 09:00:50234 bandwidth_estimation_.UpdateReceiverBlock(
235 fraction_lost_aggregate, TimeDelta::ms(rtt), total_number_of_packets,
236 Timestamp::ms(now_ms));
stefan@webrtc.org792f1a12015-03-04 12:24:26237 }
andresp@webrtc.org07bc7342014-03-21 16:51:01238 MaybeTriggerOnNetworkChanged();
239}
240
241void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
perkjec81bcd2016-05-11 13:01:13242 if (!observer_)
243 return;
244
245 uint32_t bitrate_bps;
andresp@webrtc.org07bc7342014-03-21 16:51:01246 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21247 int64_t rtt;
perkjec81bcd2016-05-11 13:01:13248
249 if (GetNetworkParameters(&bitrate_bps, &fraction_loss, &rtt))
250 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
andresp@webrtc.org16b75c22014-03-21 14:00:51251}
252
Stefan Holmere5904162015-03-26 10:11:06253bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
254 uint8_t* fraction_loss,
255 int64_t* rtt) {
sprang867fb522015-08-03 11:38:41256 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 10:11:06257 int current_bitrate;
258 bandwidth_estimation_.CurrentEstimate(&current_bitrate, fraction_loss, rtt);
259 *bitrate = current_bitrate;
Stefan Holmere5904162015-03-26 10:11:06260 *bitrate =
261 std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
262
263 bool new_bitrate = false;
264 if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
Sebastian Jansson803e3ff2018-08-06 17:14:37265 *rtt != last_rtt_ms_) {
Stefan Holmere5904162015-03-26 10:11:06266 last_bitrate_bps_ = *bitrate;
267 last_fraction_loss_ = *fraction_loss;
268 last_rtt_ms_ = *rtt;
Stefan Holmere5904162015-03-26 10:11:06269 new_bitrate = true;
270 }
gaetano.carlucci52a57032016-09-14 12:04:36271
gaetano.carlucci61050f62016-09-30 13:29:54272 BWE_TEST_LOGGING_PLOT(1, "fraction_loss_%", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 12:04:36273 (last_fraction_loss_ * 100) / 256);
gaetano.carlucci61050f62016-09-30 13:29:54274 BWE_TEST_LOGGING_PLOT(1, "rtt_ms", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 12:04:36275 last_rtt_ms_);
gaetano.carlucci61050f62016-09-30 13:29:54276 BWE_TEST_LOGGING_PLOT(1, "Target_bitrate_kbps", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 12:04:36277 last_bitrate_bps_ / 1000);
278
Stefan Holmere5904162015-03-26 10:11:06279 return new_bitrate;
280}
281
pwestin@webrtc.orga2cd7322012-04-23 08:32:47282bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
sprang867fb522015-08-03 11:38:41283 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 10:11:06284 int bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01285 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21286 int64_t rtt;
andresp@webrtc.org07bc7342014-03-21 16:51:01287 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
Stefan Holmere5904162015-03-26 10:11:06288 if (bitrate > 0) {
Stefan Holmere5904162015-03-26 10:11:06289 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
290 *bandwidth = bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01291 return true;
292 }
293 return false;
pwestin@webrtc.orga2cd7322012-04-23 08:32:47294}
pwestin@webrtc.org1cd11622012-04-19 12:13:52295} // namespace webrtc