• Home
  • History
  • Annotate
  • 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/interface/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(const uint32_t bitrate)30   virtual void OnReceivedEstimatedBitrate(const uint32_t bitrate) OVERRIDE {
31     owner_->OnReceivedEstimatedBitrate(bitrate);
32   }
33   // Received RTCP receiver block.
OnReceivedRtcpReceiverReport(const ReportBlockList & report_blocks,uint16_t rtt,int64_t now_ms)34   virtual void OnReceivedRtcpReceiverReport(
35       const ReportBlockList& report_blocks,
36       uint16_t rtt,
37       int64_t now_ms) OVERRIDE {
38     if (report_blocks.empty())
39       return;
40 
41     int fraction_lost_aggregate = 0;
42     int total_number_of_packets = 0;
43 
44     // Compute the a weighted average of the fraction loss from all report
45     // blocks.
46     for (ReportBlockList::const_iterator it = report_blocks.begin();
47         it != report_blocks.end(); ++it) {
48       std::map<uint32_t, uint32_t>::iterator seq_num_it =
49           ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
50 
51       int number_of_packets = 0;
52       if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
53         number_of_packets = it->extendedHighSeqNum -
54             seq_num_it->second;
55 
56       fraction_lost_aggregate += number_of_packets * it->fractionLost;
57       total_number_of_packets += number_of_packets;
58 
59       // Update last received for this SSRC.
60       ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
61           it->extendedHighSeqNum;
62     }
63     if (total_number_of_packets == 0)
64       fraction_lost_aggregate = 0;
65     else
66       fraction_lost_aggregate  = (fraction_lost_aggregate +
67           total_number_of_packets / 2) / total_number_of_packets;
68     if (fraction_lost_aggregate > 255)
69       return;
70 
71     owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
72                                          total_number_of_packets, now_ms);
73   }
74 
75  private:
76   std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
77   BitrateControllerImpl* owner_;
78 };
79 
CreateBitrateController(Clock * clock,bool enforce_min_bitrate)80 BitrateController* BitrateController::CreateBitrateController(
81     Clock* clock,
82     bool enforce_min_bitrate) {
83   return new BitrateControllerImpl(clock, enforce_min_bitrate);
84 }
85 
BitrateControllerImpl(Clock * clock,bool enforce_min_bitrate)86 BitrateControllerImpl::BitrateControllerImpl(Clock* clock, bool enforce_min_bitrate)
87     : clock_(clock),
88       last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
89       critsect_(CriticalSectionWrapper::CreateCriticalSection()),
90       bandwidth_estimation_(),
91       bitrate_observers_(),
92       enforce_min_bitrate_(enforce_min_bitrate),
93       reserved_bitrate_bps_(0),
94       last_bitrate_bps_(0),
95       last_fraction_loss_(0),
96       last_rtt_ms_(0),
97       last_enforce_min_bitrate_(!enforce_min_bitrate_),
98       bitrate_observers_modified_(false),
99       last_reserved_bitrate_bps_(0) {}
100 
~BitrateControllerImpl()101 BitrateControllerImpl::~BitrateControllerImpl() {
102   BitrateObserverConfList::iterator it = bitrate_observers_.begin();
103   while (it != bitrate_observers_.end()) {
104     delete it->second;
105     bitrate_observers_.erase(it);
106     it = bitrate_observers_.begin();
107   }
108   delete critsect_;
109 }
110 
CreateRtcpBandwidthObserver()111 RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
112   return new RtcpBandwidthObserverImpl(this);
113 }
114 
115 BitrateControllerImpl::BitrateObserverConfList::iterator
FindObserverConfigurationPair(const BitrateObserver * observer)116 BitrateControllerImpl::FindObserverConfigurationPair(const BitrateObserver*
117                                                      observer) {
118   BitrateObserverConfList::iterator it = bitrate_observers_.begin();
119   for (; it != bitrate_observers_.end(); ++it) {
120     if (it->first == observer) {
121       return it;
122     }
123   }
124   return bitrate_observers_.end();
125 }
126 
SetBitrateObserver(BitrateObserver * observer,const uint32_t start_bitrate,const uint32_t min_bitrate,const uint32_t max_bitrate)127 void BitrateControllerImpl::SetBitrateObserver(
128     BitrateObserver* observer,
129     const uint32_t start_bitrate,
130     const uint32_t min_bitrate,
131     const uint32_t max_bitrate) {
132   CriticalSectionScoped cs(critsect_);
133 
134   BitrateObserverConfList::iterator it = FindObserverConfigurationPair(
135       observer);
136 
137   if (it != bitrate_observers_.end()) {
138     // Update current configuration.
139     it->second->start_bitrate_ = start_bitrate;
140     it->second->min_bitrate_ = min_bitrate;
141     it->second->max_bitrate_ = max_bitrate;
142     // Set the send-side bandwidth to the max of the sum of start bitrates and
143     // the current estimate, so that if the user wants to immediately use more
144     // bandwidth, that can be enforced.
145     uint32_t sum_start_bitrate = 0;
146     BitrateObserverConfList::iterator it;
147     for (it = bitrate_observers_.begin(); it != bitrate_observers_.end();
148          ++it) {
149       sum_start_bitrate += it->second->start_bitrate_;
150     }
151     uint32_t current_estimate;
152     uint8_t loss;
153     uint32_t rtt;
154     bandwidth_estimation_.CurrentEstimate(&current_estimate, &loss, &rtt);
155     bandwidth_estimation_.SetSendBitrate(std::max(sum_start_bitrate,
156                                                   current_estimate));
157   } else {
158     // Add new settings.
159     bitrate_observers_.push_back(BitrateObserverConfiguration(observer,
160         new BitrateConfiguration(start_bitrate, min_bitrate, max_bitrate)));
161     bitrate_observers_modified_ = true;
162 
163     // TODO(andresp): This is a ugly way to set start bitrate.
164     //
165     // Only change start bitrate if we have exactly one observer. By definition
166     // you can only have one start bitrate, once we have our first estimate we
167     // will adapt from there.
168     if (bitrate_observers_.size() == 1) {
169       bandwidth_estimation_.SetSendBitrate(start_bitrate);
170     }
171   }
172 
173   UpdateMinMaxBitrate();
174 }
175 
UpdateMinMaxBitrate()176 void BitrateControllerImpl::UpdateMinMaxBitrate() {
177   uint32_t sum_min_bitrate = 0;
178   uint32_t sum_max_bitrate = 0;
179   BitrateObserverConfList::iterator it;
180   for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
181     sum_min_bitrate += it->second->min_bitrate_;
182     sum_max_bitrate += it->second->max_bitrate_;
183   }
184   if (sum_max_bitrate == 0) {
185     // No max configured use 1Gbit/s.
186     sum_max_bitrate = 1000000000;
187   }
188   if (enforce_min_bitrate_ == false) {
189     // If not enforcing min bitrate, allow the bandwidth estimation to
190     // go as low as 10 kbps.
191     sum_min_bitrate = std::min(sum_min_bitrate, 10000u);
192   }
193   bandwidth_estimation_.SetMinMaxBitrate(sum_min_bitrate,
194                                          sum_max_bitrate);
195 }
196 
RemoveBitrateObserver(BitrateObserver * observer)197 void BitrateControllerImpl::RemoveBitrateObserver(BitrateObserver* observer) {
198   CriticalSectionScoped cs(critsect_);
199   BitrateObserverConfList::iterator it = FindObserverConfigurationPair(
200       observer);
201   if (it != bitrate_observers_.end()) {
202     delete it->second;
203     bitrate_observers_.erase(it);
204     bitrate_observers_modified_ = true;
205   }
206 }
207 
EnforceMinBitrate(bool enforce_min_bitrate)208 void BitrateControllerImpl::EnforceMinBitrate(bool enforce_min_bitrate) {
209   CriticalSectionScoped cs(critsect_);
210   enforce_min_bitrate_ = enforce_min_bitrate;
211   UpdateMinMaxBitrate();
212 }
213 
SetReservedBitrate(uint32_t reserved_bitrate_bps)214 void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
215   CriticalSectionScoped cs(critsect_);
216   reserved_bitrate_bps_ = reserved_bitrate_bps;
217   MaybeTriggerOnNetworkChanged();
218 }
219 
OnReceivedEstimatedBitrate(const uint32_t bitrate)220 void BitrateControllerImpl::OnReceivedEstimatedBitrate(const uint32_t bitrate) {
221   CriticalSectionScoped cs(critsect_);
222   bandwidth_estimation_.UpdateReceiverEstimate(bitrate);
223   MaybeTriggerOnNetworkChanged();
224 }
225 
TimeUntilNextProcess()226 int32_t BitrateControllerImpl::TimeUntilNextProcess() {
227   enum { kBitrateControllerUpdateIntervalMs = 25 };
228   CriticalSectionScoped cs(critsect_);
229   int time_since_update_ms =
230       clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
231   return std::max(0, kBitrateControllerUpdateIntervalMs - time_since_update_ms);
232 }
233 
Process()234 int32_t BitrateControllerImpl::Process() {
235   if (TimeUntilNextProcess() > 0)
236     return 0;
237   {
238     CriticalSectionScoped cs(critsect_);
239     bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
240     MaybeTriggerOnNetworkChanged();
241   }
242   last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
243   return 0;
244 }
245 
OnReceivedRtcpReceiverReport(const uint8_t fraction_loss,const uint32_t rtt,const int number_of_packets,const uint32_t now_ms)246 void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
247     const uint8_t fraction_loss,
248     const uint32_t rtt,
249     const int number_of_packets,
250     const uint32_t now_ms) {
251   CriticalSectionScoped cs(critsect_);
252   bandwidth_estimation_.UpdateReceiverBlock(
253       fraction_loss, rtt, number_of_packets, now_ms);
254   MaybeTriggerOnNetworkChanged();
255 }
256 
MaybeTriggerOnNetworkChanged()257 void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
258   uint32_t bitrate;
259   uint8_t fraction_loss;
260   uint32_t rtt;
261   bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
262   bitrate -= std::min(bitrate, reserved_bitrate_bps_);
263 
264   if (bitrate_observers_modified_ ||
265       bitrate != last_bitrate_bps_ ||
266       fraction_loss != last_fraction_loss_ ||
267       rtt != last_rtt_ms_ ||
268       last_enforce_min_bitrate_ != enforce_min_bitrate_ ||
269       last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
270     last_bitrate_bps_ = bitrate;
271     last_fraction_loss_ = fraction_loss;
272     last_rtt_ms_ = rtt;
273     last_enforce_min_bitrate_ = enforce_min_bitrate_;
274     last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
275     bitrate_observers_modified_ = false;
276     OnNetworkChanged(bitrate, fraction_loss, rtt);
277   }
278 }
279 
OnNetworkChanged(const uint32_t bitrate,const uint8_t fraction_loss,const uint32_t rtt)280 void BitrateControllerImpl::OnNetworkChanged(const uint32_t bitrate,
281                                              const uint8_t fraction_loss,
282                                              const uint32_t rtt) {
283   // Sanity check.
284   if (bitrate_observers_.empty())
285     return;
286 
287   uint32_t sum_min_bitrates = 0;
288   BitrateObserverConfList::iterator it;
289   for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
290     sum_min_bitrates += it->second->min_bitrate_;
291   }
292   if (bitrate <= sum_min_bitrates)
293     return LowRateAllocation(bitrate, fraction_loss, rtt, sum_min_bitrates);
294   else
295     return NormalRateAllocation(bitrate, fraction_loss, rtt, sum_min_bitrates);
296 }
297 
NormalRateAllocation(uint32_t bitrate,uint8_t fraction_loss,uint32_t rtt,uint32_t sum_min_bitrates)298 void BitrateControllerImpl::NormalRateAllocation(uint32_t bitrate,
299                                                  uint8_t fraction_loss,
300                                                  uint32_t rtt,
301                                                  uint32_t sum_min_bitrates) {
302   uint32_t number_of_observers = bitrate_observers_.size();
303   uint32_t bitrate_per_observer = (bitrate - sum_min_bitrates) /
304       number_of_observers;
305   // Use map to sort list based on max bitrate.
306   ObserverSortingMap list_max_bitrates;
307   BitrateObserverConfList::iterator it;
308   for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
309     list_max_bitrates.insert(std::pair<uint32_t, ObserverConfiguration*>(
310         it->second->max_bitrate_,
311         new ObserverConfiguration(it->first, it->second->min_bitrate_)));
312   }
313   ObserverSortingMap::iterator max_it = list_max_bitrates.begin();
314   while (max_it != list_max_bitrates.end()) {
315     number_of_observers--;
316     uint32_t observer_allowance = max_it->second->min_bitrate_ +
317         bitrate_per_observer;
318     if (max_it->first < observer_allowance) {
319       // We have more than enough for this observer.
320       // Carry the remainder forward.
321       uint32_t remainder = observer_allowance - max_it->first;
322       if (number_of_observers != 0) {
323         bitrate_per_observer += remainder / number_of_observers;
324       }
325       max_it->second->observer_->OnNetworkChanged(max_it->first, fraction_loss,
326                                                   rtt);
327     } else {
328       max_it->second->observer_->OnNetworkChanged(observer_allowance,
329                                                   fraction_loss, rtt);
330     }
331     delete max_it->second;
332     list_max_bitrates.erase(max_it);
333     // Prepare next iteration.
334     max_it = list_max_bitrates.begin();
335   }
336 }
337 
LowRateAllocation(uint32_t bitrate,uint8_t fraction_loss,uint32_t rtt,uint32_t sum_min_bitrates)338 void BitrateControllerImpl::LowRateAllocation(uint32_t bitrate,
339                                               uint8_t fraction_loss,
340                                               uint32_t rtt,
341                                               uint32_t sum_min_bitrates) {
342   if (enforce_min_bitrate_) {
343     // Min bitrate to all observers.
344     BitrateControllerImpl::BitrateObserverConfList::iterator it;
345     for (it = bitrate_observers_.begin(); it != bitrate_observers_.end();
346          ++it) {
347       it->first->OnNetworkChanged(it->second->min_bitrate_, fraction_loss, rtt);
348     }
349     // Set sum of min to current send bitrate.
350     bandwidth_estimation_.SetSendBitrate(sum_min_bitrates);
351   } else {
352     // Allocate up to |min_bitrate_| to one observer at a time, until
353     // |bitrate| is depleted.
354     uint32_t remainder = bitrate;
355     BitrateControllerImpl::BitrateObserverConfList::iterator it;
356     for (it = bitrate_observers_.begin(); it != bitrate_observers_.end();
357          ++it) {
358       uint32_t allocation = std::min(remainder, it->second->min_bitrate_);
359       it->first->OnNetworkChanged(allocation, fraction_loss, rtt);
360       remainder -= allocation;
361     }
362     // Set |bitrate| to current send bitrate.
363     bandwidth_estimation_.SetSendBitrate(bitrate);
364   }
365 }
366 
AvailableBandwidth(uint32_t * bandwidth) const367 bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
368   CriticalSectionScoped cs(critsect_);
369   uint32_t bitrate;
370   uint8_t fraction_loss;
371   uint32_t rtt;
372   bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
373   if (bitrate) {
374     *bandwidth = bitrate - std::min(bitrate, reserved_bitrate_bps_);
375     return true;
376   }
377   return false;
378 }
379 
380 }  // namespace webrtc
381