1 /*
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
12 #include "modules/bitrate_controller/bitrate_controller_impl.h"
13
14 #include <algorithm>
15 #include <utility>
16
17 #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"
21
22 namespace webrtc {
23
24 class BitrateControllerImpl::RtcpBandwidthObserverImpl
25 : public RtcpBandwidthObserver {
26 public:
RtcpBandwidthObserverImpl(BitrateControllerImpl * owner)27 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
28 : owner_(owner) {
29 }
30 ~RtcpBandwidthObserverImpl() override = default;
31 // Received RTCP REMB or TMMBR.
OnReceivedEstimatedBitrate(uint32_t bitrate)32 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
33 owner_->OnReceivedEstimatedBitrate(bitrate);
34 }
35 // Received RTCP receiver block.
OnReceivedRtcpReceiverReport(const ReportBlockList & report_blocks,int64_t rtt,int64_t now_ms)36 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
37 int64_t rtt,
38 int64_t now_ms) override {
39 owner_->OnReceivedRtcpReceiverReport(report_blocks, rtt, now_ms);
40 }
41
42 private:
43 BitrateControllerImpl* const owner_;
44 };
45
CreateBitrateController(const Clock * clock,BitrateObserver * observer,RtcEventLog * event_log)46 BitrateController* BitrateController::CreateBitrateController(
47 const Clock* clock,
48 BitrateObserver* observer,
49 RtcEventLog* event_log) {
50 return new BitrateControllerImpl(clock, observer, event_log);
51 }
52
CreateBitrateController(const Clock * clock,RtcEventLog * event_log)53 BitrateController* BitrateController::CreateBitrateController(
54 const Clock* clock,
55 RtcEventLog* event_log) {
56 return CreateBitrateController(clock, nullptr, event_log);
57 }
58
BitrateControllerImpl(const Clock * clock,BitrateObserver * observer,RtcEventLog * event_log)59 BitrateControllerImpl::BitrateControllerImpl(const Clock* clock,
60 BitrateObserver* observer,
61 RtcEventLog* event_log)
62 : clock_(clock),
63 observer_(observer),
64 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
65 event_log_(event_log),
66 bandwidth_estimation_(event_log),
67 reserved_bitrate_bps_(0),
68 last_bitrate_bps_(0),
69 last_fraction_loss_(0),
70 last_rtt_ms_(0),
71 last_reserved_bitrate_bps_(0) {
72 // This calls the observer_ if set, which means that the observer provided by
73 // the user must be ready to accept a bitrate update when it constructs the
74 // controller. We do this to avoid having to keep synchronized initial values
75 // in both the controller and the allocator.
76 MaybeTriggerOnNetworkChanged();
77 }
78
CreateRtcpBandwidthObserver()79 RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
80 return new RtcpBandwidthObserverImpl(this);
81 }
82
SetStartBitrate(int start_bitrate_bps)83 void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
84 {
85 rtc::CritScope cs(&critsect_);
86 bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
87 }
88 MaybeTriggerOnNetworkChanged();
89 }
90
SetMinMaxBitrate(int min_bitrate_bps,int max_bitrate_bps)91 void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
92 int max_bitrate_bps) {
93 {
94 rtc::CritScope cs(&critsect_);
95 bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
96 }
97 MaybeTriggerOnNetworkChanged();
98 }
99
SetBitrates(int start_bitrate_bps,int min_bitrate_bps,int max_bitrate_bps)100 void BitrateControllerImpl::SetBitrates(int start_bitrate_bps,
101 int min_bitrate_bps,
102 int max_bitrate_bps) {
103 {
104 rtc::CritScope cs(&critsect_);
105 bandwidth_estimation_.SetBitrates(start_bitrate_bps,
106 min_bitrate_bps,
107 max_bitrate_bps);
108 }
109 MaybeTriggerOnNetworkChanged();
110 }
111
ResetBitrates(int bitrate_bps,int min_bitrate_bps,int max_bitrate_bps)112 void BitrateControllerImpl::ResetBitrates(int bitrate_bps,
113 int min_bitrate_bps,
114 int max_bitrate_bps) {
115 {
116 rtc::CritScope cs(&critsect_);
117 bandwidth_estimation_ = SendSideBandwidthEstimation(event_log_);
118 bandwidth_estimation_.SetBitrates(bitrate_bps, min_bitrate_bps,
119 max_bitrate_bps);
120 }
121 MaybeTriggerOnNetworkChanged();
122 }
123
SetReservedBitrate(uint32_t reserved_bitrate_bps)124 void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
125 {
126 rtc::CritScope cs(&critsect_);
127 reserved_bitrate_bps_ = reserved_bitrate_bps;
128 }
129 MaybeTriggerOnNetworkChanged();
130 }
131
132 // This is called upon reception of REMB or TMMBR.
OnReceivedEstimatedBitrate(uint32_t bitrate)133 void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
134 {
135 rtc::CritScope cs(&critsect_);
136 bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
137 bitrate);
138 BWE_TEST_LOGGING_PLOT(1, "REMB_kbps", clock_->TimeInMilliseconds(),
139 bitrate / 1000);
140 }
141 MaybeTriggerOnNetworkChanged();
142 }
143
OnDelayBasedBweResult(const DelayBasedBwe::Result & result)144 void BitrateControllerImpl::OnDelayBasedBweResult(
145 const DelayBasedBwe::Result& result) {
146 if (!result.updated)
147 return;
148 {
149 rtc::CritScope cs(&critsect_);
150 if (result.probe) {
151 bandwidth_estimation_.SetSendBitrate(result.target_bitrate_bps);
152 }
153 // Since SetSendBitrate now resets the delay-based estimate, we have to call
154 // UpdateDelayBasedEstimate after SetSendBitrate.
155 bandwidth_estimation_.UpdateDelayBasedEstimate(clock_->TimeInMilliseconds(),
156 result.target_bitrate_bps);
157 }
158 MaybeTriggerOnNetworkChanged();
159 }
160
TimeUntilNextProcess()161 int64_t BitrateControllerImpl::TimeUntilNextProcess() {
162 const int64_t kBitrateControllerUpdateIntervalMs = 25;
163 rtc::CritScope cs(&critsect_);
164 int64_t time_since_update_ms =
165 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
166 return std::max<int64_t>(
167 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
168 }
169
Process()170 void BitrateControllerImpl::Process() {
171 {
172 rtc::CritScope cs(&critsect_);
173 bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
174 }
175 MaybeTriggerOnNetworkChanged();
176 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
177 }
178
OnReceivedRtcpReceiverReport(const ReportBlockList & report_blocks,int64_t rtt,int64_t now_ms)179 void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
180 const ReportBlockList& report_blocks,
181 int64_t rtt,
182 int64_t now_ms) {
183 if (report_blocks.empty())
184 return;
185
186 {
187 rtc::CritScope cs(&critsect_);
188 int fraction_lost_aggregate = 0;
189 int total_number_of_packets = 0;
190
191 // Compute the a weighted average of the fraction loss from all report
192 // blocks.
193 for (const RTCPReportBlock& report_block : report_blocks) {
194 std::map<uint32_t, uint32_t>::iterator seq_num_it =
195 ssrc_to_last_received_extended_high_seq_num_.find(
196 report_block.source_ssrc);
197
198 int number_of_packets = 0;
199 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end()) {
200 number_of_packets =
201 report_block.extended_highest_sequence_number - seq_num_it->second;
202 }
203
204 fraction_lost_aggregate += number_of_packets * report_block.fraction_lost;
205 total_number_of_packets += number_of_packets;
206
207 // Update last received for this SSRC.
208 ssrc_to_last_received_extended_high_seq_num_[report_block.source_ssrc] =
209 report_block.extended_highest_sequence_number;
210 }
211 if (total_number_of_packets < 0) {
212 RTC_LOG(LS_WARNING)
213 << "Received report block where extended high sequence "
214 "number goes backwards, ignoring.";
215 return;
216 }
217 if (total_number_of_packets == 0)
218 fraction_lost_aggregate = 0;
219 else
220 fraction_lost_aggregate =
221 (fraction_lost_aggregate + total_number_of_packets / 2) /
222 total_number_of_packets;
223 if (fraction_lost_aggregate > 255)
224 return;
225
226 RTC_DCHECK_GE(total_number_of_packets, 0);
227
228 bandwidth_estimation_.UpdateReceiverBlock(fraction_lost_aggregate, rtt,
229 total_number_of_packets, now_ms);
230 }
231 MaybeTriggerOnNetworkChanged();
232 }
233
MaybeTriggerOnNetworkChanged()234 void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
235 if (!observer_)
236 return;
237
238 uint32_t bitrate_bps;
239 uint8_t fraction_loss;
240 int64_t rtt;
241
242 if (GetNetworkParameters(&bitrate_bps, &fraction_loss, &rtt))
243 observer_->OnNetworkChanged(bitrate_bps, fraction_loss, rtt);
244 }
245
GetNetworkParameters(uint32_t * bitrate,uint8_t * fraction_loss,int64_t * rtt)246 bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
247 uint8_t* fraction_loss,
248 int64_t* rtt) {
249 rtc::CritScope cs(&critsect_);
250 int current_bitrate;
251 bandwidth_estimation_.CurrentEstimate(¤t_bitrate, fraction_loss, rtt);
252 *bitrate = current_bitrate;
253 *bitrate -= std::min(*bitrate, reserved_bitrate_bps_);
254 *bitrate =
255 std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
256
257 bool new_bitrate = false;
258 if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
259 *rtt != last_rtt_ms_ ||
260 last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
261 last_bitrate_bps_ = *bitrate;
262 last_fraction_loss_ = *fraction_loss;
263 last_rtt_ms_ = *rtt;
264 last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
265 new_bitrate = true;
266 }
267
268 BWE_TEST_LOGGING_PLOT(1, "fraction_loss_%", clock_->TimeInMilliseconds(),
269 (last_fraction_loss_ * 100) / 256);
270 BWE_TEST_LOGGING_PLOT(1, "rtt_ms", clock_->TimeInMilliseconds(),
271 last_rtt_ms_);
272 BWE_TEST_LOGGING_PLOT(1, "Target_bitrate_kbps", clock_->TimeInMilliseconds(),
273 last_bitrate_bps_ / 1000);
274
275 return new_bitrate;
276 }
277
AvailableBandwidth(uint32_t * bandwidth) const278 bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
279 rtc::CritScope cs(&critsect_);
280 int bitrate;
281 uint8_t fraction_loss;
282 int64_t rtt;
283 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
284 if (bitrate > 0) {
285 bitrate = bitrate - std::min<int>(bitrate, reserved_bitrate_bps_);
286 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
287 *bandwidth = bitrate;
288 return true;
289 }
290 return false;
291 }
292 } // namespace webrtc
293