Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: webrtc/modules/remote_bitrate_estimator/mimd_rate_control.cc

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

Powered by Google App Engine
This is Rietveld 408576698