• 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 #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 
RemoteRateControl(uint32_t min_bitrate_bps)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 
Reset()47 void RemoteRateControl::Reset() {
48   *this = RemoteRateControl(min_configured_bit_rate_);
49   came_from_state_ = kRcHold;
50 }
51 
ValidEstimate() const52 bool RemoteRateControl::ValidEstimate() const {
53   return initialized_bit_rate_;
54 }
55 
TimeToReduceFurther(int64_t time_now,unsigned int incoming_bitrate) const56 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 
SetConfiguredBitRates(uint32_t min_bit_rate_bps,uint32_t max_bit_rate_bps)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 
LatestEstimate() const82 uint32_t RemoteRateControl::LatestEstimate() const {
83   return current_bit_rate_;
84 }
85 
UpdateBandwidthEstimate(int64_t now_ms)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 
SetRtt(unsigned int rtt)94 void RemoteRateControl::SetRtt(unsigned int rtt) {
95   rtt_ = rtt;
96 }
97 
Update(const RateControlInput * input,int64_t now_ms)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 
ChangeBitRate(uint32_t current_bit_rate,uint32_t incoming_bit_rate,double noise_var,int64_t now_ms)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 
RateIncreaseFactor(int64_t now_ms,int64_t last_ms,uint32_t reaction_time_ms,double noise_var) const217 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 
UpdateChangePeriod(int64_t now_ms)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 
UpdateMaxBitRateEstimate(float incoming_bit_rate_kbps)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 
ChangeState(const RateControlInput & input,int64_t now_ms)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 
ChangeRegion(RateControlRegion region)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 
ChangeState(RateControlState new_state)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