blob: c99bd53218698d21982294238d4321bfec90bada [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
pbos@webrtc.org2e10b8e2013-07-16 12:54:53 +000012#include "webrtc/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>
jbauchf91e6d02016-01-24 23:05:21 -080015#include <map>
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000016#include <utility>
17
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010018#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000019
20namespace webrtc {
21
andresp@webrtc.org16b75c22014-03-21 14:00:51 +000022class BitrateControllerImpl::RtcpBandwidthObserverImpl
23 : public RtcpBandwidthObserver {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000024 public:
25 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
26 : owner_(owner) {
27 }
28 virtual ~RtcpBandwidthObserverImpl() {
29 }
30 // Received RTCP REMB or TMMBR.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000031 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000032 owner_->OnReceivedEstimatedBitrate(bitrate);
33 }
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 {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000038 if (report_blocks.empty())
39 return;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000040
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000041 int fraction_lost_aggregate = 0;
42 int total_number_of_packets = 0;
43
44 // Compute the a weighted average of the fraction loss from all report
45 // blocks.
46 for (ReportBlockList::const_iterator it = report_blocks.begin();
47 it != report_blocks.end(); ++it) {
48 std::map<uint32_t, uint32_t>::iterator seq_num_it =
49 ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
50
51 int number_of_packets = 0;
52 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
53 number_of_packets = it->extendedHighSeqNum -
54 seq_num_it->second;
55
56 fraction_lost_aggregate += number_of_packets * it->fractionLost;
57 total_number_of_packets += number_of_packets;
58
59 // Update last received for this SSRC.
60 ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
61 it->extendedHighSeqNum;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000062 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000063 if (total_number_of_packets == 0)
64 fraction_lost_aggregate = 0;
65 else
66 fraction_lost_aggregate = (fraction_lost_aggregate +
67 total_number_of_packets / 2) / total_number_of_packets;
68 if (fraction_lost_aggregate > 255)
69 return;
70
71 owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
72 total_number_of_packets, now_ms);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000073 }
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000074
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000075 private:
76 std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
77 BitrateControllerImpl* owner_;
78};
79
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000080BitrateController* BitrateController::CreateBitrateController(
andresp@webrtc.org44caf012014-03-26 21:00:21 +000081 Clock* clock,
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000082 BitrateObserver* observer) {
83 return new BitrateControllerImpl(clock, observer);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000084}
85
perkjec81bcd2016-05-11 06:01:13 -070086BitrateController* BitrateController::CreateBitrateController(Clock* clock) {
87 return new BitrateControllerImpl(clock, nullptr);
88}
89
sprang@webrtc.org9b791972014-12-18 11:53:59 +000090BitrateControllerImpl::BitrateControllerImpl(Clock* clock,
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000091 BitrateObserver* observer)
andresp@webrtc.org44caf012014-03-26 21:00:21 +000092 : clock_(clock),
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000093 observer_(observer),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000094 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
solenberg@webrtc.org4e656022014-03-26 14:32:47 +000095 bandwidth_estimation_(),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000096 reserved_bitrate_bps_(0),
97 last_bitrate_bps_(0),
solenberg@webrtc.org4e656022014-03-26 14:32:47 +000098 last_fraction_loss_(0),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000099 last_rtt_ms_(0),
sprang@webrtc.org8bd2f402015-03-16 14:11:21 +0000100 last_reserved_bitrate_bps_(0) {
perkjec81bcd2016-05-11 06:01:13 -0700101 // This calls the observer_ if set, which means that the observer provided by
102 // the user must be ready to accept a bitrate update when it constructs the
Stefan Holmere5904162015-03-26 11:11:06 +0100103 // controller. We do this to avoid having to keep synchronized initial values
104 // in both the controller and the allocator.
105 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000106}
107
108RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
109 return new RtcpBandwidthObserverImpl(this);
110}
111
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000112void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +0100113 {
sprang867fb522015-08-03 04:38:41 -0700114 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100115 bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
116 }
117 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000118}
119
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000120void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
121 int max_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +0100122 {
sprang867fb522015-08-03 04:38:41 -0700123 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100124 bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
125 }
126 MaybeTriggerOnNetworkChanged();
henrik.lundin@webrtc.org845862f2014-03-06 07:19:28 +0000127}
128
philipelc6957c72016-04-28 15:52:49 +0200129void BitrateControllerImpl::SetBitrates(int start_bitrate_bps,
130 int min_bitrate_bps,
131 int max_bitrate_bps) {
132 {
133 rtc::CritScope cs(&critsect_);
134 bandwidth_estimation_.SetBitrates(start_bitrate_bps,
135 min_bitrate_bps,
136 max_bitrate_bps);
137 }
138 MaybeTriggerOnNetworkChanged();
139}
140
honghaiz059e1832016-06-24 11:03:55 -0700141void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
142 int min_bitrate_bps,
143 int max_bitrate_bps) {
144 {
145 rtc::CritScope cs(&critsect_);
146 bandwidth_estimation_ = SendSideBandwidthEstimation();
147 bandwidth_estimation_.SetBitrates(bitrate_bps, min_bitrate_bps,
148 max_bitrate_bps);
149 }
150 MaybeTriggerOnNetworkChanged();
151}
152
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000153void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000154 {
sprang867fb522015-08-03 04:38:41 -0700155 rtc::CritScope cs(&critsect_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000156 reserved_bitrate_bps_ = reserved_bitrate_bps;
157 }
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000158 MaybeTriggerOnNetworkChanged();
159}
160
terelius006d93d2015-11-05 12:02:15 -0800161void BitrateControllerImpl::SetEventLog(RtcEventLog* event_log) {
162 rtc::CritScope cs(&critsect_);
163 bandwidth_estimation_.SetEventLog(event_log);
164}
165
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000166void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000167 {
sprang867fb522015-08-03 04:38:41 -0700168 rtc::CritScope cs(&critsect_);
stefanb6b0b922015-09-04 03:04:56 -0700169 bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
170 bitrate);
sprang@webrtc.org9b791972014-12-18 11:53:59 +0000171 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000172 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000173}
174
stefan32f81542016-01-20 07:13:58 -0800175void BitrateControllerImpl::UpdateDelayBasedEstimate(uint32_t bitrate_bps) {
176 {
177 rtc::CritScope cs(&critsect_);
178 bandwidth_estimation_.UpdateDelayBasedEstimate(clock_->TimeInMilliseconds(),
179 bitrate_bps);
180 }
181 MaybeTriggerOnNetworkChanged();
182}
183
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000184int64_t BitrateControllerImpl::TimeUntilNextProcess() {
185 const int64_t kBitrateControllerUpdateIntervalMs = 25;
sprang867fb522015-08-03 04:38:41 -0700186 rtc::CritScope cs(&critsect_);
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000187 int64_t time_since_update_ms =
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000188 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000189 return std::max<int64_t>(
190 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000191}
192
pbosa26ac922016-02-25 04:50:01 -0800193void BitrateControllerImpl::Process() {
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000194 if (TimeUntilNextProcess() > 0)
pbosa26ac922016-02-25 04:50:01 -0800195 return;
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000196 {
sprang867fb522015-08-03 04:38:41 -0700197 rtc::CritScope cs(&critsect_);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000198 bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000199 }
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000200 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000201 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000202}
203
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000204void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000205 uint8_t fraction_loss,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000206 int64_t rtt,
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000207 int number_of_packets,
208 int64_t now_ms) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000209 {
sprang867fb522015-08-03 04:38:41 -0700210 rtc::CritScope cs(&critsect_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000211 bandwidth_estimation_.UpdateReceiverBlock(fraction_loss, rtt,
212 number_of_packets, now_ms);
213 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000214 MaybeTriggerOnNetworkChanged();
215}
216
217void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
perkjec81bcd2016-05-11 06:01:13 -0700218 if (!observer_)
219 return;
220
221 uint32_t bitrate_bps;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000222 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000223 int64_t rtt;
perkjec81bcd2016-05-11 06:01:13 -0700224
225 if (GetNetworkParameters(&bitrate_bps, &fraction_loss, &rtt))
226 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
andresp@webrtc.org16b75c22014-03-21 14:00:51 +0000227}
228
Stefan Holmere5904162015-03-26 11:11:06 +0100229bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
230 uint8_t* fraction_loss,
231 int64_t* rtt) {
sprang867fb522015-08-03 04:38:41 -0700232 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100233 int current_bitrate;
234 bandwidth_estimation_.CurrentEstimate(&current_bitrate, fraction_loss, rtt);
235 *bitrate = current_bitrate;
236 *bitrate -= std::min(*bitrate, reserved_bitrate_bps_);
237 *bitrate =
238 std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
239
240 bool new_bitrate = false;
241 if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
242 *rtt != last_rtt_ms_ ||
243 last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
244 last_bitrate_bps_ = *bitrate;
245 last_fraction_loss_ = *fraction_loss;
246 last_rtt_ms_ = *rtt;
247 last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
248 new_bitrate = true;
249 }
250 return new_bitrate;
251}
252
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000253bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
sprang867fb522015-08-03 04:38:41 -0700254 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100255 int bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000256 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000257 int64_t rtt;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000258 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
Stefan Holmere5904162015-03-26 11:11:06 +0100259 if (bitrate > 0) {
260 bitrate = bitrate - std::min<int>(bitrate, reserved_bitrate_bps_);
261 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
262 *bandwidth = bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000263 return true;
264 }
265 return false;
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000266}
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000267} // namespace webrtc