Home | History | Annotate | Download | only in bitrate_controller
      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:
     24   explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
     25       : owner_(owner) {
     26   }
     27   virtual ~RtcpBandwidthObserverImpl() {
     28   }
     29   // Received RTCP REMB or TMMBR.
     30   virtual void OnReceivedEstimatedBitrate(const uint32_t bitrate) OVERRIDE {
     31     owner_->OnReceivedEstimatedBitrate(bitrate);
     32   }
     33   // Received RTCP receiver block.
     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 
     80 BitrateController* BitrateController::CreateBitrateController(
     81     Clock* clock,
     82     bool enforce_min_bitrate) {
     83   return new BitrateControllerImpl(clock, enforce_min_bitrate);
     84 }
     85 
     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 
    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 
    111 RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
    112   return new RtcpBandwidthObserverImpl(this);
    113 }
    114 
    115 BitrateControllerImpl::BitrateObserverConfList::iterator
    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 
    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 
    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 
    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 
    208 void BitrateControllerImpl::EnforceMinBitrate(bool enforce_min_bitrate) {
    209   CriticalSectionScoped cs(critsect_);
    210   enforce_min_bitrate_ = enforce_min_bitrate;
    211   UpdateMinMaxBitrate();
    212 }
    213 
    214 void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
    215   CriticalSectionScoped cs(critsect_);
    216   reserved_bitrate_bps_ = reserved_bitrate_bps;
    217   MaybeTriggerOnNetworkChanged();
    218 }
    219 
    220 void BitrateControllerImpl::OnReceivedEstimatedBitrate(const uint32_t bitrate) {
    221   CriticalSectionScoped cs(critsect_);
    222   bandwidth_estimation_.UpdateReceiverEstimate(bitrate);
    223   MaybeTriggerOnNetworkChanged();
    224 }
    225 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    367 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