Home | History | Annotate | Download | only in remote_bitrate_estimator
      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 #include <map>
     12 
     13 #include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
     14 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
     15 #include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
     16 #include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
     17 #include "webrtc/system_wrappers/interface/clock.h"
     18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     19 #include "webrtc/system_wrappers/interface/logging.h"
     20 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
     21 #include "webrtc/typedefs.h"
     22 
     23 namespace webrtc {
     24 namespace {
     25 class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
     26  public:
     27   RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
     28                                      Clock* clock,
     29                                      uint32_t min_bitrate_bps);
     30   virtual ~RemoteBitrateEstimatorSingleStream() {}
     31 
     32   // Called for each incoming packet. If this is a new SSRC, a new
     33   // BitrateControl will be created. Updates the incoming payload bitrate
     34   // estimate and the over-use detector. If an over-use is detected the
     35   // remote bitrate estimate will be updated. Note that |payload_size| is the
     36   // packet size excluding headers.
     37   virtual void IncomingPacket(int64_t arrival_time_ms,
     38                               int payload_size,
     39                               const RTPHeader& header) OVERRIDE;
     40 
     41   // Triggers a new estimate calculation.
     42   // Implements the Module interface.
     43   virtual int32_t Process() OVERRIDE;
     44   virtual int32_t TimeUntilNextProcess() OVERRIDE;
     45   // Set the current round-trip time experienced by the stream.
     46   // Implements the StatsObserver interface.
     47   virtual void OnRttUpdate(uint32_t rtt) OVERRIDE;
     48 
     49   // Removes all data for |ssrc|.
     50   virtual void RemoveStream(unsigned int ssrc) OVERRIDE;
     51 
     52   // Returns true if a valid estimate exists and sets |bitrate_bps| to the
     53   // estimated payload bitrate in bits per second. |ssrcs| is the list of ssrcs
     54   // currently being received and of which the bitrate estimate is based upon.
     55   virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs,
     56                               unsigned int* bitrate_bps) const OVERRIDE;
     57 
     58   virtual bool GetStats(
     59       ReceiveBandwidthEstimatorStats* output) const OVERRIDE;
     60 
     61  private:
     62   // Map from SSRC to over-use detector and last incoming packet time in
     63   // milliseconds, taken from clock_.
     64   typedef std::map<unsigned int, std::pair<OveruseDetector, int64_t> >
     65       SsrcOveruseDetectorMap;
     66 
     67   static OveruseDetector* GetDetector(
     68       const SsrcOveruseDetectorMap::iterator it) {
     69     return &it->second.first;
     70   }
     71 
     72   static int64_t GetPacketTimeMs(const SsrcOveruseDetectorMap::iterator it) {
     73     return it->second.second;
     74   }
     75 
     76   static void SetPacketTimeMs(SsrcOveruseDetectorMap::iterator it,
     77                               int64_t time_ms) {
     78     it->second.second = time_ms;
     79   }
     80 
     81   // Triggers a new estimate calculation.
     82   void UpdateEstimate(int64_t now_ms);
     83 
     84   void GetSsrcs(std::vector<unsigned int>* ssrcs) const;
     85 
     86   Clock* clock_;
     87   SsrcOveruseDetectorMap overuse_detectors_;
     88   RateStatistics incoming_bitrate_;
     89   RemoteRateControl remote_rate_;
     90   RemoteBitrateObserver* observer_;
     91   scoped_ptr<CriticalSectionWrapper> crit_sect_;
     92   int64_t last_process_time_;
     93 };
     94 
     95 RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
     96     RemoteBitrateObserver* observer,
     97     Clock* clock,
     98     uint32_t min_bitrate_bps)
     99     : clock_(clock),
    100       incoming_bitrate_(500, 8000),
    101       remote_rate_(min_bitrate_bps),
    102       observer_(observer),
    103       crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
    104       last_process_time_(-1) {
    105   assert(observer_);
    106 }
    107 
    108 void RemoteBitrateEstimatorSingleStream::IncomingPacket(
    109     int64_t arrival_time_ms,
    110     int payload_size,
    111     const RTPHeader& header) {
    112   uint32_t ssrc = header.ssrc;
    113   uint32_t rtp_timestamp = header.timestamp +
    114       header.extension.transmissionTimeOffset;
    115   int64_t now_ms = clock_->TimeInMilliseconds();
    116   CriticalSectionScoped cs(crit_sect_.get());
    117   SsrcOveruseDetectorMap::iterator it = overuse_detectors_.find(ssrc);
    118   if (it == overuse_detectors_.end()) {
    119     // This is a new SSRC. Adding to map.
    120     // TODO(holmer): If the channel changes SSRC the old SSRC will still be
    121     // around in this map until the channel is deleted. This is OK since the
    122     // callback will no longer be called for the old SSRC. This will be
    123     // automatically cleaned up when we have one RemoteBitrateEstimator per REMB
    124     // group.
    125     std::pair<SsrcOveruseDetectorMap::iterator, bool> insert_result =
    126         overuse_detectors_.insert(std::make_pair(ssrc,
    127             std::make_pair(OveruseDetector(OverUseDetectorOptions()), now_ms)));
    128     it = insert_result.first;
    129   }
    130   SetPacketTimeMs(it, now_ms);
    131   OveruseDetector* overuse_detector = GetDetector(it);
    132   incoming_bitrate_.Update(payload_size, now_ms);
    133   const BandwidthUsage prior_state = overuse_detector->State();
    134   overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time_ms);
    135   if (overuse_detector->State() == kBwOverusing) {
    136     unsigned int incoming_bitrate = incoming_bitrate_.Rate(now_ms);
    137     if (prior_state != kBwOverusing ||
    138         remote_rate_.TimeToReduceFurther(now_ms, incoming_bitrate)) {
    139       // The first overuse should immediately trigger a new estimate.
    140       // We also have to update the estimate immediately if we are overusing
    141       // and the target bitrate is too high compared to what we are receiving.
    142       UpdateEstimate(now_ms);
    143     }
    144   }
    145 }
    146 
    147 int32_t RemoteBitrateEstimatorSingleStream::Process() {
    148   if (TimeUntilNextProcess() > 0) {
    149     return 0;
    150   }
    151   int64_t now_ms = clock_->TimeInMilliseconds();
    152   UpdateEstimate(now_ms);
    153   last_process_time_ = now_ms;
    154   return 0;
    155 }
    156 
    157 int32_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
    158   if (last_process_time_ < 0) {
    159     return 0;
    160   }
    161   return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds();
    162 }
    163 
    164 void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
    165   CriticalSectionScoped cs(crit_sect_.get());
    166   BandwidthUsage bw_state = kBwNormal;
    167   double sum_noise_var = 0.0;
    168   SsrcOveruseDetectorMap::iterator it = overuse_detectors_.begin();
    169   while (it != overuse_detectors_.end()) {
    170     if (GetPacketTimeMs(it) >= 0 &&
    171         now_ms - GetPacketTimeMs(it) > kStreamTimeOutMs) {
    172       // This over-use detector hasn't received packets for |kStreamTimeOutMs|
    173       // milliseconds and is considered stale.
    174       overuse_detectors_.erase(it++);
    175     } else {
    176       OveruseDetector* overuse_detector = GetDetector(it);
    177       sum_noise_var += overuse_detector->NoiseVar();
    178       // Make sure that we trigger an over-use if any of the over-use detectors
    179       // is detecting over-use.
    180       if (overuse_detector->State() > bw_state) {
    181         bw_state = overuse_detector->State();
    182       }
    183       ++it;
    184     }
    185   }
    186   // We can't update the estimate if we don't have any active streams.
    187   if (overuse_detectors_.empty()) {
    188     remote_rate_.Reset();
    189     return;
    190   }
    191   double mean_noise_var = sum_noise_var /
    192       static_cast<double>(overuse_detectors_.size());
    193   const RateControlInput input(bw_state,
    194                                incoming_bitrate_.Rate(now_ms),
    195                                mean_noise_var);
    196   const RateControlRegion region = remote_rate_.Update(&input, now_ms);
    197   unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(now_ms);
    198   if (remote_rate_.ValidEstimate()) {
    199     std::vector<unsigned int> ssrcs;
    200     GetSsrcs(&ssrcs);
    201     observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
    202   }
    203   for (it = overuse_detectors_.begin(); it != overuse_detectors_.end(); ++it) {
    204     GetDetector(it)->SetRateControlRegion(region);
    205   }
    206 }
    207 
    208 void RemoteBitrateEstimatorSingleStream::OnRttUpdate(uint32_t rtt) {
    209   CriticalSectionScoped cs(crit_sect_.get());
    210   remote_rate_.SetRtt(rtt);
    211 }
    212 
    213 void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
    214   CriticalSectionScoped cs(crit_sect_.get());
    215   // Ignoring the return value which is the number of elements erased.
    216   overuse_detectors_.erase(ssrc);
    217 }
    218 
    219 bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
    220     std::vector<unsigned int>* ssrcs,
    221     unsigned int* bitrate_bps) const {
    222   CriticalSectionScoped cs(crit_sect_.get());
    223   assert(bitrate_bps);
    224   if (!remote_rate_.ValidEstimate()) {
    225     return false;
    226   }
    227   GetSsrcs(ssrcs);
    228   if (ssrcs->empty())
    229     *bitrate_bps = 0;
    230   else
    231     *bitrate_bps = remote_rate_.LatestEstimate();
    232   return true;
    233 }
    234 
    235 bool RemoteBitrateEstimatorSingleStream::GetStats(
    236     ReceiveBandwidthEstimatorStats* output) const {
    237   // Not implemented.
    238   return false;
    239 }
    240 
    241 void RemoteBitrateEstimatorSingleStream::GetSsrcs(
    242     std::vector<unsigned int>* ssrcs) const {
    243   assert(ssrcs);
    244   ssrcs->resize(overuse_detectors_.size());
    245   int i = 0;
    246   for (SsrcOveruseDetectorMap::const_iterator it = overuse_detectors_.begin();
    247       it != overuse_detectors_.end(); ++it, ++i) {
    248     (*ssrcs)[i] = it->first;
    249   }
    250 }
    251 }  // namespace
    252 
    253 RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create(
    254     RemoteBitrateObserver* observer,
    255     Clock* clock,
    256     RateControlType control_type,
    257     uint32_t min_bitrate_bps) const {
    258   LOG(LS_INFO) << "RemoteBitrateEstimatorFactory: Instantiating.";
    259   return new RemoteBitrateEstimatorSingleStream(observer, clock,
    260                                                 min_bitrate_bps);
    261 }
    262 
    263 RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create(
    264     RemoteBitrateObserver* observer,
    265     Clock* clock,
    266     RateControlType control_type,
    267     uint32_t min_bitrate_bps) const {
    268   LOG(LS_INFO) << "AbsoluteSendTimeRemoteBitrateEstimatorFactory: "
    269       "Instantiating.";
    270   return new RemoteBitrateEstimatorSingleStream(observer, clock,
    271                                                 min_bitrate_bps);
    272 }
    273 }  // namespace webrtc
    274