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 "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
     12 
     13 #include <assert.h>
     14 #include <math.h>
     15 #include <string.h>
     16 
     17 #include <algorithm>
     18 
     19 #include "webrtc/system_wrappers/interface/trace.h"
     20 
     21 namespace webrtc {
     22 
     23 const unsigned int kDefaultRttMs = 200;
     24 
     25 RemoteRateControl::RemoteRateControl(uint32_t min_bitrate_bps)
     26     : min_configured_bit_rate_(min_bitrate_bps),
     27     max_configured_bit_rate_(30000000),
     28     current_bit_rate_(max_configured_bit_rate_),
     29     max_hold_rate_(0),
     30     avg_max_bit_rate_(-1.0f),
     31     var_max_bit_rate_(0.4f),
     32     rate_control_state_(kRcHold),
     33     came_from_state_(kRcDecrease),
     34     rate_control_region_(kRcMaxUnknown),
     35     last_bit_rate_change_(-1),
     36     current_input_(kBwNormal, 0, 1.0),
     37     updated_(false),
     38     time_first_incoming_estimate_(-1),
     39     initialized_bit_rate_(false),
     40     avg_change_period_(1000.0f),
     41     last_change_ms_(-1),
     42     beta_(0.9f),
     43     rtt_(kDefaultRttMs)
     44 {
     45 }
     46 
     47 void RemoteRateControl::Reset() {
     48   *this = RemoteRateControl(min_configured_bit_rate_);
     49   came_from_state_ = kRcHold;
     50 }
     51 
     52 bool RemoteRateControl::ValidEstimate() const {
     53   return initialized_bit_rate_;
     54 }
     55 
     56 bool RemoteRateControl::TimeToReduceFurther(int64_t time_now,
     57     unsigned int incoming_bitrate) const {
     58   const int bitrate_reduction_interval = std::max(std::min(rtt_, 200u), 10u);
     59   if (time_now - last_bit_rate_change_ >= bitrate_reduction_interval) {
     60     return true;
     61   }
     62   if (ValidEstimate()) {
     63     const int threshold = static_cast<int>(1.05 * incoming_bitrate);
     64     const int bitrate_difference = LatestEstimate() - incoming_bitrate;
     65     return bitrate_difference > threshold;
     66   }
     67   return false;
     68 }
     69 
     70 int32_t RemoteRateControl::SetConfiguredBitRates(uint32_t min_bit_rate_bps,
     71                                                  uint32_t max_bit_rate_bps) {
     72   if (min_bit_rate_bps > max_bit_rate_bps) {
     73     return -1;
     74   }
     75   min_configured_bit_rate_ = min_bit_rate_bps;
     76   max_configured_bit_rate_ = max_bit_rate_bps;
     77   current_bit_rate_ = std::min(std::max(min_bit_rate_bps, current_bit_rate_),
     78                                max_bit_rate_bps);
     79   return 0;
     80 }
     81 
     82 uint32_t RemoteRateControl::LatestEstimate() const {
     83   return current_bit_rate_;
     84 }
     85 
     86 uint32_t RemoteRateControl::UpdateBandwidthEstimate(int64_t now_ms) {
     87   current_bit_rate_ = ChangeBitRate(current_bit_rate_,
     88                                     current_input_._incomingBitRate,
     89                                     current_input_._noiseVar,
     90                                     now_ms);
     91   return current_bit_rate_;
     92 }
     93 
     94 void RemoteRateControl::SetRtt(unsigned int rtt) {
     95   rtt_ = rtt;
     96 }
     97 
     98 RateControlRegion RemoteRateControl::Update(const RateControlInput* input,
     99                                             int64_t now_ms) {
    100   assert(input);
    101 
    102   // Set the initial bit rate value to what we're receiving the first half
    103   // second.
    104   if (!initialized_bit_rate_) {
    105     if (time_first_incoming_estimate_ < 0) {
    106       if (input->_incomingBitRate > 0) {
    107         time_first_incoming_estimate_ = now_ms;
    108       }
    109     } else if (now_ms - time_first_incoming_estimate_ > 500 &&
    110                input->_incomingBitRate > 0) {
    111       current_bit_rate_ = input->_incomingBitRate;
    112       initialized_bit_rate_ = true;
    113     }
    114   }
    115 
    116   if (updated_ && current_input_._bwState == kBwOverusing) {
    117     // Only update delay factor and incoming bit rate. We always want to react
    118     // on an over-use.
    119     current_input_._noiseVar = input->_noiseVar;
    120     current_input_._incomingBitRate = input->_incomingBitRate;
    121     return rate_control_region_;
    122   }
    123   updated_ = true;
    124   current_input_ = *input;
    125   return rate_control_region_;
    126 }
    127 
    128 uint32_t RemoteRateControl::ChangeBitRate(uint32_t current_bit_rate,
    129                                           uint32_t incoming_bit_rate,
    130                                           double noise_var,
    131                                           int64_t now_ms) {
    132   if (!updated_) {
    133     return current_bit_rate_;
    134   }
    135   updated_ = false;
    136   UpdateChangePeriod(now_ms);
    137   ChangeState(current_input_, now_ms);
    138   // calculated here because it's used in multiple places
    139   const float incoming_bit_rate_kbps = incoming_bit_rate / 1000.0f;
    140   // Calculate the max bit rate std dev given the normalized
    141   // variance and the current incoming bit rate.
    142   const float std_max_bit_rate = sqrt(var_max_bit_rate_ * avg_max_bit_rate_);
    143   bool recovery = false;
    144   switch (rate_control_state_) {
    145     case kRcHold: {
    146       max_hold_rate_ = std::max(max_hold_rate_, incoming_bit_rate);
    147       break;
    148     }
    149     case kRcIncrease: {
    150       if (avg_max_bit_rate_ >= 0) {
    151         if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 3 * std_max_bit_rate) {
    152           ChangeRegion(kRcMaxUnknown);
    153           avg_max_bit_rate_ = -1.0;
    154         } else if (incoming_bit_rate_kbps > avg_max_bit_rate_ + 2.5 *
    155                    std_max_bit_rate) {
    156           ChangeRegion(kRcAboveMax);
    157         }
    158       }
    159       const uint32_t response_time = static_cast<uint32_t>(avg_change_period_ +
    160           0.5f) + rtt_ + 300;
    161       double alpha = RateIncreaseFactor(now_ms, last_bit_rate_change_,
    162                                         response_time, noise_var);
    163 
    164       current_bit_rate = static_cast<uint32_t>(current_bit_rate * alpha) + 1000;
    165       if (max_hold_rate_ > 0 && beta_ * max_hold_rate_ > current_bit_rate) {
    166         current_bit_rate = static_cast<uint32_t>(beta_ * max_hold_rate_);
    167         avg_max_bit_rate_ = beta_ * max_hold_rate_ / 1000.0f;
    168         ChangeRegion(kRcNearMax);
    169         recovery = true;
    170       }
    171       max_hold_rate_ = 0;
    172       last_bit_rate_change_ = now_ms;
    173       break;
    174     }
    175     case kRcDecrease: {
    176       if (incoming_bit_rate < min_configured_bit_rate_) {
    177         current_bit_rate = min_configured_bit_rate_;
    178       } else {
    179         // Set bit rate to something slightly lower than max
    180         // to get rid of any self-induced delay.
    181         current_bit_rate = static_cast<uint32_t>(beta_ * incoming_bit_rate +
    182             0.5);
    183         if (current_bit_rate > current_bit_rate_) {
    184           // Avoid increasing the rate when over-using.
    185           if (rate_control_region_ != kRcMaxUnknown) {
    186             current_bit_rate = static_cast<uint32_t>(beta_ * avg_max_bit_rate_ *
    187                 1000 + 0.5f);
    188           }
    189           current_bit_rate = std::min(current_bit_rate, current_bit_rate_);
    190         }
    191         ChangeRegion(kRcNearMax);
    192 
    193         if (incoming_bit_rate_kbps < avg_max_bit_rate_ - 3 * std_max_bit_rate) {
    194           avg_max_bit_rate_ = -1.0f;
    195         }
    196 
    197         UpdateMaxBitRateEstimate(incoming_bit_rate_kbps);
    198       }
    199       // Stay on hold until the pipes are cleared.
    200       ChangeState(kRcHold);
    201       last_bit_rate_change_ = now_ms;
    202       break;
    203     }
    204     default:
    205       assert(false);
    206   }
    207   if (!recovery && (incoming_bit_rate > 100000 || current_bit_rate > 150000) &&
    208       current_bit_rate > 1.5 * incoming_bit_rate) {
    209     // Allow changing the bit rate if we are operating at very low rates
    210     // Don't change the bit rate if the send side is too far off
    211     current_bit_rate = current_bit_rate_;
    212     last_bit_rate_change_ = now_ms;
    213   }
    214   return current_bit_rate;
    215 }
    216 
    217 double RemoteRateControl::RateIncreaseFactor(int64_t now_ms,
    218                                              int64_t last_ms,
    219                                              uint32_t reaction_time_ms,
    220                                              double noise_var) const {
    221   // alpha = 1.02 + B ./ (1 + exp(b*(tr - (c1*s2 + c2))))
    222   // Parameters
    223   const double B = 0.0407;
    224   const double b = 0.0025;
    225   const double c1 = -6700.0 / (33 * 33);
    226   const double c2 = 800.0;
    227   const double d = 0.85;
    228 
    229   double alpha = 1.005 + B / (1 + exp( b * (d * reaction_time_ms -
    230       (c1 * noise_var + c2))));
    231 
    232   if (alpha < 1.005) {
    233     alpha = 1.005;
    234   } else if (alpha > 1.3) {
    235     alpha = 1.3;
    236   }
    237 
    238   if (last_ms > -1) {
    239     alpha = pow(alpha, (now_ms - last_ms) / 1000.0);
    240   }
    241 
    242   if (rate_control_region_ == kRcNearMax) {
    243     // We're close to our previous maximum. Try to stabilize the
    244     // bit rate in this region, by increasing in smaller steps.
    245     alpha = alpha - (alpha - 1.0) / 2.0;
    246   } else if (rate_control_region_ == kRcMaxUnknown) {
    247     alpha = alpha + (alpha - 1.0) * 2.0;
    248   }
    249 
    250   return alpha;
    251 }
    252 
    253 void RemoteRateControl::UpdateChangePeriod(int64_t now_ms) {
    254   int64_t change_period = 0;
    255   if (last_change_ms_ > -1) {
    256     change_period = now_ms - last_change_ms_;
    257   }
    258   last_change_ms_ = now_ms;
    259   avg_change_period_ = 0.9f * avg_change_period_ + 0.1f * change_period;
    260 }
    261 
    262 void RemoteRateControl::UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps) {
    263   const float alpha = 0.05f;
    264   if (avg_max_bit_rate_ == -1.0f) {
    265     avg_max_bit_rate_ = incoming_bit_rate_kbps;
    266   } else {
    267     avg_max_bit_rate_ = (1 - alpha) * avg_max_bit_rate_ +
    268         alpha * incoming_bit_rate_kbps;
    269   }
    270   // Estimate the max bit rate variance and normalize the variance
    271   // with the average max bit rate.
    272   const float norm = std::max(avg_max_bit_rate_, 1.0f);
    273   var_max_bit_rate_ = (1 - alpha) * var_max_bit_rate_ +
    274       alpha * (avg_max_bit_rate_ - incoming_bit_rate_kbps) *
    275           (avg_max_bit_rate_ - incoming_bit_rate_kbps) / norm;
    276   // 0.4 ~= 14 kbit/s at 500 kbit/s
    277   if (var_max_bit_rate_ < 0.4f) {
    278     var_max_bit_rate_ = 0.4f;
    279   }
    280   // 2.5f ~= 35 kbit/s at 500 kbit/s
    281   if (var_max_bit_rate_ > 2.5f) {
    282     var_max_bit_rate_ = 2.5f;
    283   }
    284 }
    285 
    286 void RemoteRateControl::ChangeState(const RateControlInput& input,
    287                                     int64_t now_ms) {
    288   switch (current_input_._bwState) {
    289     case kBwNormal:
    290       if (rate_control_state_ == kRcHold) {
    291         last_bit_rate_change_ = now_ms;
    292         ChangeState(kRcIncrease);
    293       }
    294       break;
    295     case kBwOverusing:
    296       if (rate_control_state_ != kRcDecrease) {
    297         ChangeState(kRcDecrease);
    298       }
    299       break;
    300     case kBwUnderusing:
    301       ChangeState(kRcHold);
    302       break;
    303     default:
    304       assert(false);
    305   }
    306 }
    307 
    308 void RemoteRateControl::ChangeRegion(RateControlRegion region) {
    309   rate_control_region_ = region;
    310   switch (rate_control_region_) {
    311     case kRcAboveMax:
    312     case kRcMaxUnknown:
    313       beta_ = 0.9f;
    314       break;
    315     case kRcNearMax:
    316       beta_ = 0.95f;
    317       break;
    318     default:
    319       assert(false);
    320   }
    321 }
    322 
    323 void RemoteRateControl::ChangeState(RateControlState new_state) {
    324   came_from_state_ = rate_control_state_;
    325   rate_control_state_ = new_state;
    326 }
    327 }  // namespace webrtc
    328