blob: 38f97fb7e249d1852603bb50f7d82fd99220b03b [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 {
23
andresp@webrtc.org16b75c22014-03-21 14:00:51 +000024class BitrateControllerImpl::RtcpBandwidthObserverImpl
25 : public RtcpBandwidthObserver {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000026 public:
27 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
Yves Gerey665174f2018-06-19 15:03:05 +020028 : owner_(owner) {}
Danil Chapovalov38018ba2017-06-12 16:29:45 +020029 ~RtcpBandwidthObserverImpl() override = default;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000030 // Received RTCP REMB or TMMBR.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000031 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
Danil Chapovalov38018ba2017-06-12 16:29:45 +020032 owner_->OnReceivedEstimatedBitrate(bitrate);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000033 }
34 // Received RTCP receiver block.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000035 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
36 int64_t rtt,
37 int64_t now_ms) override {
Danil Chapovalov38018ba2017-06-12 16:29:45 +020038 owner_->OnReceivedRtcpReceiverReport(report_blocks, rtt, now_ms);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000039 }
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000040
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000041 private:
Danil Chapovalov38018ba2017-06-12 16:29:45 +020042 BitrateControllerImpl* const owner_;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000043};
44
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000045BitrateController* BitrateController::CreateBitrateController(
elad.alon61ce37e2017-03-09 07:09:31 -080046 const Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -070047 BitrateObserver* observer,
48 RtcEventLog* event_log) {
49 return new BitrateControllerImpl(clock, observer, event_log);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000050}
51
ivoc14d5dbe2016-07-04 07:06:55 -070052BitrateController* BitrateController::CreateBitrateController(
elad.alon61ce37e2017-03-09 07:09:31 -080053 const Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -070054 RtcEventLog* event_log) {
55 return CreateBitrateController(clock, nullptr, event_log);
perkjec81bcd2016-05-11 06:01:13 -070056}
57
elad.alon61ce37e2017-03-09 07:09:31 -080058BitrateControllerImpl::BitrateControllerImpl(const Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -070059 BitrateObserver* observer,
60 RtcEventLog* event_log)
andresp@webrtc.org44caf012014-03-26 21:00:21 +000061 : clock_(clock),
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000062 observer_(observer),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000063 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
ivoc14d5dbe2016-07-04 07:06:55 -070064 event_log_(event_log),
65 bandwidth_estimation_(event_log),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000066 reserved_bitrate_bps_(0),
67 last_bitrate_bps_(0),
solenberg@webrtc.org4e656022014-03-26 14:32:47 +000068 last_fraction_loss_(0),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000069 last_rtt_ms_(0),
sprang@webrtc.org8bd2f402015-03-16 14:11:21 +000070 last_reserved_bitrate_bps_(0) {
perkjec81bcd2016-05-11 06:01:13 -070071 // This calls the observer_ if set, which means that the observer provided by
72 // the user must be ready to accept a bitrate update when it constructs the
Stefan Holmere5904162015-03-26 11:11:06 +010073 // controller. We do this to avoid having to keep synchronized initial values
74 // in both the controller and the allocator.
75 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000076}
77
78RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
79 return new RtcpBandwidthObserverImpl(this);
80}
81
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000082void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +010083 {
sprang867fb522015-08-03 04:38:41 -070084 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +010085 bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
86 }
87 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org07bc7342014-03-21 16:51:01 +000088}
89
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000090void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
91 int max_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +010092 {
sprang867fb522015-08-03 04:38:41 -070093 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +010094 bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
95 }
96 MaybeTriggerOnNetworkChanged();
henrik.lundin@webrtc.org845862f2014-03-06 07:19:28 +000097}
98
philipelc6957c72016-04-28 15:52:49 +020099void BitrateControllerImpl::SetBitrates(int start_bitrate_bps,
100 int min_bitrate_bps,
101 int max_bitrate_bps) {
102 {
103 rtc::CritScope cs(&critsect_);
Yves Gerey665174f2018-06-19 15:03:05 +0200104 bandwidth_estimation_.SetBitrates(start_bitrate_bps, min_bitrate_bps,
philipelc6957c72016-04-28 15:52:49 +0200105 max_bitrate_bps);
106 }
107 MaybeTriggerOnNetworkChanged();
108}
109
honghaiz059e1832016-06-24 11:03:55 -0700110void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
111 int min_bitrate_bps,
112 int max_bitrate_bps) {
113 {
114 rtc::CritScope cs(&critsect_);
ivoc14d5dbe2016-07-04 07:06:55 -0700115 bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
honghaiz059e1832016-06-24 11:03:55 -0700116 bandwidth_estimation_.SetBitrates(bitrate_bps, min_bitrate_bps,
117 max_bitrate_bps);
118 }
119 MaybeTriggerOnNetworkChanged();
120}
121
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000122void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000123 {
sprang867fb522015-08-03 04:38:41 -0700124 rtc::CritScope cs(&critsect_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000125 reserved_bitrate_bps_ = reserved_bitrate_bps;
126 }
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000127 MaybeTriggerOnNetworkChanged();
128}
129
Irfan Sheriffb2540bb2016-09-12 12:28:54 -0700130// This is called upon reception of REMB or TMMBR.
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200131void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000132 {
sprang867fb522015-08-03 04:38:41 -0700133 rtc::CritScope cs(&critsect_);
stefanb6b0b922015-09-04 03:04:56 -0700134 bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
135 bitrate);
gaetano.carlucci61050f62016-09-30 06:29:54 -0700136 BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700137 bitrate / 1000);
sprang@webrtc.org9b791972014-12-18 11:53:59 +0000138 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000139 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000140}
141
Stefan Holmer280de9e2016-09-30 10:06:51 +0200142void BitrateControllerImpl::OnDelayBasedBweResult(
143 const DelayBasedBwe::Result& result) {
144 if (!result.updated)
145 return;
philipel0aa9d182016-08-24 02:45:35 -0700146 {
147 rtc::CritScope cs(&critsect_);
Stefan Holmer280de9e2016-09-30 10:06:51 +0200148 if (result.probe) {
149 bandwidth_estimation_.SetSendBitrate(result.target_bitrate_bps);
Stefan Holmer280de9e2016-09-30 10:06:51 +0200150 }
Bjorn Terelius29cb0e72017-11-08 14:41:12 +0100151 // Since SetSendBitrate now resets the delay-based estimate, we have to call
152 // UpdateDelayBasedEstimate after SetSendBitrate.
153 bandwidth_estimation_.UpdateDelayBasedEstimate(clock_->TimeInMilliseconds(),
154 result.target_bitrate_bps);
stefan32f81542016-01-20 07:13:58 -0800155 }
156 MaybeTriggerOnNetworkChanged();
157}
158
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000159int64_t BitrateControllerImpl::TimeUntilNextProcess() {
160 const int64_t kBitrateControllerUpdateIntervalMs = 25;
sprang867fb522015-08-03 04:38:41 -0700161 rtc::CritScope cs(&critsect_);
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000162 int64_t time_since_update_ms =
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000163 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000164 return std::max<int64_t>(
165 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000166}
167
pbosa26ac922016-02-25 04:50:01 -0800168void BitrateControllerImpl::Process() {
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000169 {
sprang867fb522015-08-03 04:38:41 -0700170 rtc::CritScope cs(&critsect_);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000171 bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000172 }
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000173 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000174 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000175}
176
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000177void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200178 const ReportBlockList& report_blocks,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000179 int64_t rtt,
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000180 int64_t now_ms) {
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200181 if (report_blocks.empty())
182 return;
183
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000184 {
sprang867fb522015-08-03 04:38:41 -0700185 rtc::CritScope cs(&critsect_);
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200186 int fraction_lost_aggregate = 0;
187 int total_number_of_packets = 0;
188
189 // Compute the a weighted average of the fraction loss from all report
190 // blocks.
191 for (const RTCPReportBlock& report_block : report_blocks) {
192 std::map<uint32_t, uint32_t>::iterator seq_num_it =
193 ssrc_to_last_received_extended_high_seq_num_.find(
srte3e69e5c2017-08-09 06:13:45 -0700194 report_block.source_ssrc);
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200195
196 int number_of_packets = 0;
197 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end()) {
198 number_of_packets =
srte3e69e5c2017-08-09 06:13:45 -0700199 report_block.extended_highest_sequence_number - seq_num_it->second;
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200200 }
201
srte3e69e5c2017-08-09 06:13:45 -0700202 fraction_lost_aggregate += number_of_packets * report_block.fraction_lost;
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200203 total_number_of_packets += number_of_packets;
204
205 // Update last received for this SSRC.
srte3e69e5c2017-08-09 06:13:45 -0700206 ssrc_to_last_received_extended_high_seq_num_[report_block.source_ssrc] =
207 report_block.extended_highest_sequence_number;
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200208 }
209 if (total_number_of_packets < 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100210 RTC_LOG(LS_WARNING)
211 << "Received report block where extended high sequence "
212 "number goes backwards, ignoring.";
Danil Chapovalov38018ba2017-06-12 16:29:45 +0200213 return;
214 }
215 if (total_number_of_packets == 0)
216 fraction_lost_aggregate = 0;
217 else
218 fraction_lost_aggregate =
219 (fraction_lost_aggregate + total_number_of_packets / 2) /
220 total_number_of_packets;
221 if (fraction_lost_aggregate > 255)
222 return;
223
224 RTC_DCHECK_GE(total_number_of_packets, 0);
225
226 bandwidth_estimation_.UpdateReceiverBlock(fraction_lost_aggregate, rtt,
227 total_number_of_packets, now_ms);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000228 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000229 MaybeTriggerOnNetworkChanged();
230}
231
232void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
perkjec81bcd2016-05-11 06:01:13 -0700233 if (!observer_)
234 return;
235
236 uint32_t bitrate_bps;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000237 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000238 int64_t rtt;
perkjec81bcd2016-05-11 06:01:13 -0700239
240 if (GetNetworkParameters(&bitrate_bps, &fraction_loss, &rtt))
241 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
andresp@webrtc.org16b75c22014-03-21 14:00:51 +0000242}
243
Stefan Holmere5904162015-03-26 11:11:06 +0100244bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
245 uint8_t* fraction_loss,
246 int64_t* rtt) {
sprang867fb522015-08-03 04:38:41 -0700247 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100248 int current_bitrate;
249 bandwidth_estimation_.CurrentEstimate(&current_bitrate, fraction_loss, rtt);
250 *bitrate = current_bitrate;
251 *bitrate -= std::min(*bitrate, reserved_bitrate_bps_);
252 *bitrate =
253 std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
254
255 bool new_bitrate = false;
256 if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
257 *rtt != last_rtt_ms_ ||
258 last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
259 last_bitrate_bps_ = *bitrate;
260 last_fraction_loss_ = *fraction_loss;
261 last_rtt_ms_ = *rtt;
262 last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
263 new_bitrate = true;
264 }
gaetano.carlucci52a57032016-09-14 05:04:36 -0700265
gaetano.carlucci61050f62016-09-30 06:29:54 -0700266 BWE_TEST_LOGGING_PLOT(1, "fraction_loss_%", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700267 (last_fraction_loss_ * 100) / 256);
gaetano.carlucci61050f62016-09-30 06:29:54 -0700268 BWE_TEST_LOGGING_PLOT(1, "rtt_ms", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700269 last_rtt_ms_);
gaetano.carlucci61050f62016-09-30 06:29:54 -0700270 BWE_TEST_LOGGING_PLOT(1, "Target_bitrate_kbps", clock_->TimeInMilliseconds(),
gaetano.carlucci52a57032016-09-14 05:04:36 -0700271 last_bitrate_bps_ / 1000);
272
Stefan Holmere5904162015-03-26 11:11:06 +0100273 return new_bitrate;
274}
275
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000276bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
sprang867fb522015-08-03 04:38:41 -0700277 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100278 int bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000279 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000280 int64_t rtt;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000281 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
Stefan Holmere5904162015-03-26 11:11:06 +0100282 if (bitrate > 0) {
283 bitrate = bitrate - std::min<int>(bitrate, reserved_bitrate_bps_);
284 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
285 *bandwidth = bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000286 return true;
287 }
288 return false;
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000289}
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000290} // namespace webrtc