• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <utility>
16 
17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18 
19 namespace webrtc {
20 
21 class BitrateControllerImpl::RtcpBandwidthObserverImpl
22     : public RtcpBandwidthObserver {
23  public:
RtcpBandwidthObserverImpl(BitrateControllerImpl * owner)24   explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
25       : owner_(owner) {
26   }
~RtcpBandwidthObserverImpl()27   virtual ~RtcpBandwidthObserverImpl() {
28   }
29   // Received RTCP REMB or TMMBR.
OnReceivedEstimatedBitrate(uint32_t bitrate)30   void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
31     owner_->OnReceivedEstimatedBitrate(bitrate);
32   }
33   // Received RTCP receiver block.
OnReceivedRtcpReceiverReport(const ReportBlockList & report_blocks,int64_t rtt,int64_t now_ms)34   void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
35                                     int64_t rtt,
36                                     int64_t now_ms) override {
37     if (report_blocks.empty())
38       return;
39 
40     int fraction_lost_aggregate = 0;
41     int total_number_of_packets = 0;
42 
43     // Compute the a weighted average of the fraction loss from all report
44     // blocks.
45     for (ReportBlockList::const_iterator it = report_blocks.begin();
46         it != report_blocks.end(); ++it) {
47       std::map<uint32_t, uint32_t>::iterator seq_num_it =
48           ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
49 
50       int number_of_packets = 0;
51       if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
52         number_of_packets = it->extendedHighSeqNum -
53             seq_num_it->second;
54 
55       fraction_lost_aggregate += number_of_packets * it->fractionLost;
56       total_number_of_packets += number_of_packets;
57 
58       // Update last received for this SSRC.
59       ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
60           it->extendedHighSeqNum;
61     }
62     if (total_number_of_packets == 0)
63       fraction_lost_aggregate = 0;
64     else
65       fraction_lost_aggregate  = (fraction_lost_aggregate +
66           total_number_of_packets / 2) / total_number_of_packets;
67     if (fraction_lost_aggregate > 255)
68       return;
69 
70     owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
71                                          total_number_of_packets, now_ms);
72   }
73 
74  private:
75   std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
76   BitrateControllerImpl* owner_;
77 };
78 
CreateBitrateController(Clock * clock,BitrateObserver * observer)79 BitrateController* BitrateController::CreateBitrateController(
80     Clock* clock,
81     BitrateObserver* observer) {
82   return new BitrateControllerImpl(clock, observer);
83 }
84 
BitrateControllerImpl(Clock * clock,BitrateObserver * observer)85 BitrateControllerImpl::BitrateControllerImpl(Clock* clock,
86                                              BitrateObserver* observer)
87     : clock_(clock),
88       observer_(observer),
89       last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
90       bandwidth_estimation_(),
91       reserved_bitrate_bps_(0),
92       last_bitrate_bps_(0),
93       last_fraction_loss_(0),
94       last_rtt_ms_(0),
95       last_reserved_bitrate_bps_(0) {
96   // This calls the observer_, which means that the observer provided by the
97   // user must be ready to accept a bitrate update when it constructs the
98   // controller. We do this to avoid having to keep synchronized initial values
99   // in both the controller and the allocator.
100   MaybeTriggerOnNetworkChanged();
101 }
102 
CreateRtcpBandwidthObserver()103 RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
104   return new RtcpBandwidthObserverImpl(this);
105 }
106 
SetStartBitrate(int start_bitrate_bps)107 void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
108   {
109     rtc::CritScope cs(&critsect_);
110     bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
111   }
112   MaybeTriggerOnNetworkChanged();
113 }
114 
SetMinMaxBitrate(int min_bitrate_bps,int max_bitrate_bps)115 void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
116                                              int max_bitrate_bps) {
117   {
118     rtc::CritScope cs(&critsect_);
119     bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, 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 
SetEventLog(RtcEventLog * event_log)132 void BitrateControllerImpl::SetEventLog(RtcEventLog* event_log) {
133   rtc::CritScope cs(&critsect_);
134   bandwidth_estimation_.SetEventLog(event_log);
135 }
136 
OnReceivedEstimatedBitrate(uint32_t bitrate)137 void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
138   {
139     rtc::CritScope cs(&critsect_);
140     bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
141                                                  bitrate);
142   }
143   MaybeTriggerOnNetworkChanged();
144 }
145 
TimeUntilNextProcess()146 int64_t BitrateControllerImpl::TimeUntilNextProcess() {
147   const int64_t kBitrateControllerUpdateIntervalMs = 25;
148   rtc::CritScope cs(&critsect_);
149   int64_t time_since_update_ms =
150       clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
151   return std::max<int64_t>(
152       kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
153 }
154 
Process()155 int32_t BitrateControllerImpl::Process() {
156   if (TimeUntilNextProcess() > 0)
157     return 0;
158   {
159     rtc::CritScope cs(&critsect_);
160     bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
161   }
162   MaybeTriggerOnNetworkChanged();
163   last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
164   return 0;
165 }
166 
OnReceivedRtcpReceiverReport(uint8_t fraction_loss,int64_t rtt,int number_of_packets,int64_t now_ms)167 void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
168     uint8_t fraction_loss,
169     int64_t rtt,
170     int number_of_packets,
171     int64_t now_ms) {
172   {
173     rtc::CritScope cs(&critsect_);
174     bandwidth_estimation_.UpdateReceiverBlock(fraction_loss, rtt,
175                                               number_of_packets, now_ms);
176   }
177   MaybeTriggerOnNetworkChanged();
178 }
179 
MaybeTriggerOnNetworkChanged()180 void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
181   uint32_t bitrate;
182   uint8_t fraction_loss;
183   int64_t rtt;
184   if (GetNetworkParameters(&bitrate, &fraction_loss, &rtt))
185     observer_->OnNetworkChanged(bitrate, fraction_loss, rtt);
186 }
187 
GetNetworkParameters(uint32_t * bitrate,uint8_t * fraction_loss,int64_t * rtt)188 bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
189                                                  uint8_t* fraction_loss,
190                                                  int64_t* rtt) {
191   rtc::CritScope cs(&critsect_);
192   int current_bitrate;
193   bandwidth_estimation_.CurrentEstimate(&current_bitrate, fraction_loss, rtt);
194   *bitrate = current_bitrate;
195   *bitrate -= std::min(*bitrate, reserved_bitrate_bps_);
196   *bitrate =
197       std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
198 
199   bool new_bitrate = false;
200   if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
201       *rtt != last_rtt_ms_ ||
202       last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
203     last_bitrate_bps_ = *bitrate;
204     last_fraction_loss_ = *fraction_loss;
205     last_rtt_ms_ = *rtt;
206     last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
207     new_bitrate = true;
208   }
209   return new_bitrate;
210 }
211 
AvailableBandwidth(uint32_t * bandwidth) const212 bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
213   rtc::CritScope cs(&critsect_);
214   int bitrate;
215   uint8_t fraction_loss;
216   int64_t rtt;
217   bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
218   if (bitrate > 0) {
219     bitrate = bitrate - std::min<int>(bitrate, reserved_bitrate_bps_);
220     bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
221     *bandwidth = bitrate;
222     return true;
223   }
224   return false;
225 }
226 }  // namespace webrtc
227