blob: bc2f1f63e6d38c186d9e5c89df7b9d1fe60741ae [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
stefand48717b2016-08-22 08:50:31 -070018#include "webrtc/base/checks.h"
19#include "webrtc/base/logging.h"
gaetano.carlucci52a57032016-09-14 05:04:36 -070020#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010021#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000022
23namespace webrtc {
24
andresp@webrtc.org16b75c22014-03-21 14:00:51 +000025class BitrateControllerImpl::RtcpBandwidthObserverImpl
26 : public RtcpBandwidthObserver {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000027 public:
28 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
29 : owner_(owner) {
30 }
31 virtual ~RtcpBandwidthObserverImpl() {
32 }
33 // Received RTCP REMB or TMMBR.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000034 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
Irfan Sheriffb2540bb2016-09-12 12:28:54 -070035 owner_->OnReceiverEstimatedBitrate(bitrate);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000036 }
37 // Received RTCP receiver block.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000038 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
39 int64_t rtt,
40 int64_t now_ms) override {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000041 if (report_blocks.empty())
42 return;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000043
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000044 int fraction_lost_aggregate = 0;
45 int total_number_of_packets = 0;
46
47 // Compute the a weighted average of the fraction loss from all report
48 // blocks.
stefand48717b2016-08-22 08:50:31 -070049 for (const RTCPReportBlock& report_block : report_blocks) {
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000050 std::map<uint32_t, uint32_t>::iterator seq_num_it =
stefand48717b2016-08-22 08:50:31 -070051 ssrc_to_last_received_extended_high_seq_num_.find(
52 report_block.sourceSSRC);
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000053
54 int number_of_packets = 0;
stefand48717b2016-08-22 08:50:31 -070055 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end()) {
56 number_of_packets =
57 report_block.extendedHighSeqNum - seq_num_it->second;
58 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000059
stefand48717b2016-08-22 08:50:31 -070060 fraction_lost_aggregate += number_of_packets * report_block.fractionLost;
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000061 total_number_of_packets += number_of_packets;
62
63 // Update last received for this SSRC.
stefand48717b2016-08-22 08:50:31 -070064 ssrc_to_last_received_extended_high_seq_num_[report_block.sourceSSRC] =
65 report_block.extendedHighSeqNum;
66 }
67 if (total_number_of_packets < 0) {
68 LOG(LS_WARNING) << "Received report block where extended high sequence "
69 "number goes backwards, ignoring.";
70 return;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000071 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000072 if (total_number_of_packets == 0)
73 fraction_lost_aggregate = 0;
74 else
75 fraction_lost_aggregate = (fraction_lost_aggregate +
76 total_number_of_packets / 2) / total_number_of_packets;
77 if (fraction_lost_aggregate > 255)
78 return;
79
stefand48717b2016-08-22 08:50:31 -070080 RTC_DCHECK_GE(total_number_of_packets, 0);
81
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000082 owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
83 total_number_of_packets, now_ms);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000084 }
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000085
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000086 private:
87 std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
88 BitrateControllerImpl* owner_;
89};
90
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000091BitrateController* BitrateController::CreateBitrateController(
andresp@webrtc.org44caf012014-03-26 21:00:21 +000092 Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -070093 BitrateObserver* observer,
94 RtcEventLog* event_log) {
95 return new BitrateControllerImpl(clock, observer, event_log);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000096}
97
ivoc14d5dbe2016-07-04 07:06:55 -070098BitrateController* BitrateController::CreateBitrateController(
99 Clock* clock,
100 RtcEventLog* event_log) {
101 return CreateBitrateController(clock, nullptr, event_log);
perkjec81bcd2016-05-11 06:01:13 -0700102}
103
sprang@webrtc.org9b791972014-12-18 11:53:59 +0000104BitrateControllerImpl::BitrateControllerImpl(Clock* clock,
ivoc14d5dbe2016-07-04 07:06:55 -0700105 BitrateObserver* observer,
106 RtcEventLog* event_log)
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000107 : clock_(clock),
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000108 observer_(observer),
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000109 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
ivoc14d5dbe2016-07-04 07:06:55 -0700110 event_log_(event_log),
111 bandwidth_estimation_(event_log),
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000112 reserved_bitrate_bps_(0),
113 last_bitrate_bps_(0),
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000114 last_fraction_loss_(0),
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000115 last_rtt_ms_(0),
sprang@webrtc.org8bd2f402015-03-16 14:11:21 +0000116 last_reserved_bitrate_bps_(0) {
perkjec81bcd2016-05-11 06:01:13 -0700117 // This calls the observer_ if set, which means that the observer provided by
118 // the user must be ready to accept a bitrate update when it constructs the
Stefan Holmere5904162015-03-26 11:11:06 +0100119 // controller. We do this to avoid having to keep synchronized initial values
120 // in both the controller and the allocator.
121 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000122}
123
124RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
125 return new RtcpBandwidthObserverImpl(this);
126}
127
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000128void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +0100129 {
sprang867fb522015-08-03 04:38:41 -0700130 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100131 bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
132 }
133 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000134}
135
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000136void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
137 int max_bitrate_bps) {
Stefan Holmere5904162015-03-26 11:11:06 +0100138 {
sprang867fb522015-08-03 04:38:41 -0700139 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100140 bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
141 }
142 MaybeTriggerOnNetworkChanged();
henrik.lundin@webrtc.org845862f2014-03-06 07:19:28 +0000143}
144
philipelc6957c72016-04-28 15:52:49 +0200145void BitrateControllerImpl::SetBitrates(int start_bitrate_bps,
146 int min_bitrate_bps,
147 int max_bitrate_bps) {
148 {
149 rtc::CritScope cs(&critsect_);
150 bandwidth_estimation_.SetBitrates(start_bitrate_bps,
151 min_bitrate_bps,
152 max_bitrate_bps);
153 }
154 MaybeTriggerOnNetworkChanged();
155}
156
honghaiz059e1832016-06-24 11:03:55 -0700157void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
158 int min_bitrate_bps,
159 int max_bitrate_bps) {
160 {
161 rtc::CritScope cs(&critsect_);
ivoc14d5dbe2016-07-04 07:06:55 -0700162 bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
honghaiz059e1832016-06-24 11:03:55 -0700163 bandwidth_estimation_.SetBitrates(bitrate_bps, min_bitrate_bps,
164 max_bitrate_bps);
165 }
166 MaybeTriggerOnNetworkChanged();
167}
168
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000169void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000170 {
sprang867fb522015-08-03 04:38:41 -0700171 rtc::CritScope cs(&critsect_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000172 reserved_bitrate_bps_ = reserved_bitrate_bps;
173 }
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000174 MaybeTriggerOnNetworkChanged();
175}
176
Irfan Sheriffb2540bb2016-09-12 12:28:54 -0700177// This is called upon reception of REMB or TMMBR.
178void BitrateControllerImpl::OnReceiverEstimatedBitrate(uint32_t bitrate) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000179 {
sprang867fb522015-08-03 04:38:41 -0700180 rtc::CritScope cs(&critsect_);
stefanb6b0b922015-09-04 03:04:56 -0700181 bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
182 bitrate);
gaetano.carlucci52a57032016-09-14 05:04:36 -0700183 BWE_TEST_LOGGING_PLOT(1, "REMB[kbps]", clock_->TimeInMilliseconds(),
184 bitrate / 1000);
sprang@webrtc.org9b791972014-12-18 11:53:59 +0000185 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000186 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000187}
188
stefan5ec85fb2016-09-29 04:19:38 -0700189void BitrateControllerImpl::OnProbeBitrate(uint32_t bitrate_bps) {
philipel0aa9d182016-08-24 02:45:35 -0700190 {
191 rtc::CritScope cs(&critsect_);
stefan5ec85fb2016-09-29 04:19:38 -0700192 bandwidth_estimation_.SetSendBitrate(bitrate_bps);
193 }
194 MaybeTriggerOnNetworkChanged();
195}
196
197// TODO(isheriff): Perhaps need new interface for invocation from DelayBasedBwe.
198void BitrateControllerImpl::OnReceiveBitrateChanged(
199 const std::vector<uint32_t>& ssrcs,
200 uint32_t bitrate_bps) {
201 {
202 rtc::CritScope cs(&critsect_);
203 bandwidth_estimation_.UpdateDelayBasedEstimate(clock_->TimeInMilliseconds(),
204 bitrate_bps);
stefan32f81542016-01-20 07:13:58 -0800205 }
206 MaybeTriggerOnNetworkChanged();
207}
208
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000209int64_t BitrateControllerImpl::TimeUntilNextProcess() {
210 const int64_t kBitrateControllerUpdateIntervalMs = 25;
sprang867fb522015-08-03 04:38:41 -0700211 rtc::CritScope cs(&critsect_);
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000212 int64_t time_since_update_ms =
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000213 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000214 return std::max<int64_t>(
215 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000216}
217
pbosa26ac922016-02-25 04:50:01 -0800218void BitrateControllerImpl::Process() {
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000219 if (TimeUntilNextProcess() > 0)
pbosa26ac922016-02-25 04:50:01 -0800220 return;
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000221 {
sprang867fb522015-08-03 04:38:41 -0700222 rtc::CritScope cs(&critsect_);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000223 bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000224 }
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000225 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000226 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000227}
228
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000229void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000230 uint8_t fraction_loss,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000231 int64_t rtt,
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000232 int number_of_packets,
233 int64_t now_ms) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000234 {
sprang867fb522015-08-03 04:38:41 -0700235 rtc::CritScope cs(&critsect_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000236 bandwidth_estimation_.UpdateReceiverBlock(fraction_loss, rtt,
237 number_of_packets, now_ms);
238 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000239 MaybeTriggerOnNetworkChanged();
240}
241
242void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
perkjec81bcd2016-05-11 06:01:13 -0700243 if (!observer_)
244 return;
245
246 uint32_t bitrate_bps;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000247 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000248 int64_t rtt;
perkjec81bcd2016-05-11 06:01:13 -0700249
250 if (GetNetworkParameters(&bitrate_bps, &fraction_loss, &rtt))
251 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
andresp@webrtc.org16b75c22014-03-21 14:00:51 +0000252}
253
Stefan Holmere5904162015-03-26 11:11:06 +0100254bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
255 uint8_t* fraction_loss,
256 int64_t* rtt) {
sprang867fb522015-08-03 04:38:41 -0700257 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100258 int current_bitrate;
259 bandwidth_estimation_.CurrentEstimate(&current_bitrate, fraction_loss, rtt);
260 *bitrate = current_bitrate;
261 *bitrate -= std::min(*bitrate, reserved_bitrate_bps_);
262 *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_ ||
267 *rtt != last_rtt_ms_ ||
268 last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
269 last_bitrate_bps_ = *bitrate;
270 last_fraction_loss_ = *fraction_loss;
271 last_rtt_ms_ = *rtt;
272 last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
273 new_bitrate = true;
274 }
gaetano.carlucci52a57032016-09-14 05:04:36 -0700275
276 BWE_TEST_LOGGING_PLOT(1, "fraction_loss_[%%]", clock_->TimeInMilliseconds(),
277 (last_fraction_loss_ * 100) / 256);
278 BWE_TEST_LOGGING_PLOT(1, "rtt[ms]", clock_->TimeInMilliseconds(),
279 last_rtt_ms_);
280 BWE_TEST_LOGGING_PLOT(1, "Target_bitrate[kbps]", clock_->TimeInMilliseconds(),
281 last_bitrate_bps_ / 1000);
282
Stefan Holmere5904162015-03-26 11:11:06 +0100283 return new_bitrate;
284}
285
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000286bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
sprang867fb522015-08-03 04:38:41 -0700287 rtc::CritScope cs(&critsect_);
Stefan Holmere5904162015-03-26 11:11:06 +0100288 int bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000289 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000290 int64_t rtt;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000291 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
Stefan Holmere5904162015-03-26 11:11:06 +0100292 if (bitrate > 0) {
293 bitrate = bitrate - std::min<int>(bitrate, reserved_bitrate_bps_);
294 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
295 *bandwidth = bitrate;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000296 return true;
297 }
298 return false;
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000299}
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000300} // namespace webrtc