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