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(&current_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