OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 return rtc::Optional<uint32_t>(bitrate_estimate_ * 1000); | 146 return rtc::Optional<uint32_t>(bitrate_estimate_ * 1000); |
147 } | 147 } |
148 | 148 |
149 DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock) | 149 DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock) |
150 : event_log_(event_log), | 150 : event_log_(event_log), |
151 clock_(clock), | 151 clock_(clock), |
152 inter_arrival_(), | 152 inter_arrival_(), |
153 trendline_estimator_(), | 153 trendline_estimator_(), |
154 detector_(), | 154 detector_(), |
155 receiver_incoming_bitrate_(), | 155 receiver_incoming_bitrate_(), |
156 last_update_ms_(-1), | |
157 last_seen_packet_ms_(-1), | 156 last_seen_packet_ms_(-1), |
158 uma_recorded_(false), | 157 uma_recorded_(false), |
159 probe_bitrate_estimator_(event_log), | 158 probe_bitrate_estimator_(event_log), |
160 trendline_window_size_(kDefaultTrendlineWindowSize), | 159 trendline_window_size_(kDefaultTrendlineWindowSize), |
161 trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), | 160 trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), |
162 trendline_threshold_gain_(kDefaultTrendlineThresholdGain), | 161 trendline_threshold_gain_(kDefaultTrendlineThresholdGain), |
163 probing_interval_estimator_(&rate_control_), | 162 probing_interval_estimator_(&rate_control_), |
164 consecutive_delayed_feedbacks_(0), | 163 consecutive_delayed_feedbacks_(0), |
165 last_logged_bitrate_(0), | 164 last_logged_bitrate_(0), |
166 last_logged_state_(BandwidthUsage::kBwNormal) { | 165 last_logged_state_(BandwidthUsage::kBwNormal) { |
(...skipping 10 matching lines...) Expand all Loading... | |
177 std::vector<PacketFeedback> sorted_packet_feedback_vector; | 176 std::vector<PacketFeedback> sorted_packet_feedback_vector; |
178 SortPacketFeedbackVector(packet_feedback_vector, | 177 SortPacketFeedbackVector(packet_feedback_vector, |
179 &sorted_packet_feedback_vector); | 178 &sorted_packet_feedback_vector); |
180 | 179 |
181 if (!uma_recorded_) { | 180 if (!uma_recorded_) { |
182 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, | 181 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, |
183 BweNames::kSendSideTransportSeqNum, | 182 BweNames::kSendSideTransportSeqNum, |
184 BweNames::kBweNamesMax); | 183 BweNames::kBweNamesMax); |
185 uma_recorded_ = true; | 184 uma_recorded_ = true; |
186 } | 185 } |
187 Result aggregated_result; | 186 bool overusing = false; |
188 bool delayed_feedback = true; | 187 bool delayed_feedback = true; |
189 for (const auto& packet_feedback : sorted_packet_feedback_vector) { | 188 for (const auto& packet_feedback : sorted_packet_feedback_vector) { |
190 if (packet_feedback.send_time_ms < 0) | 189 if (packet_feedback.send_time_ms < 0) |
191 continue; | 190 continue; |
192 delayed_feedback = false; | 191 delayed_feedback = false; |
193 Result result = IncomingPacketFeedback(packet_feedback); | 192 IncomingPacketFeedback(packet_feedback); |
194 if (result.updated) | 193 overusing |= detector_.State() == BandwidthUsage::kBwOverusing; |
195 aggregated_result = result; | |
196 } | 194 } |
197 if (delayed_feedback) { | 195 return MaybeUpdateEstimate(overusing, delayed_feedback); |
198 ++consecutive_delayed_feedbacks_; | |
199 } else { | |
200 consecutive_delayed_feedbacks_ = 0; | |
201 } | |
202 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { | |
203 aggregated_result = OnLongFeedbackDelay( | |
204 sorted_packet_feedback_vector.back().arrival_time_ms); | |
205 consecutive_delayed_feedbacks_ = 0; | |
206 } | |
207 return aggregated_result; | |
208 } | 196 } |
209 | 197 |
210 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( | 198 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( |
211 int64_t arrival_time_ms) { | 199 int64_t arrival_time_ms) { |
212 // Estimate should always be valid since a start bitrate always is set in the | 200 // Estimate should always be valid since a start bitrate always is set in the |
213 // Call constructor. An alternative would be to return an empty Result here, | 201 // Call constructor. An alternative would be to return an empty Result here, |
214 // or to estimate the throughput based on the feedback we received. | 202 // or to estimate the throughput based on the feedback we received. |
215 RTC_DCHECK(rate_control_.ValidEstimate()); | 203 RTC_DCHECK(rate_control_.ValidEstimate()); |
216 rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, | 204 rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, |
217 arrival_time_ms); | 205 arrival_time_ms); |
218 Result result; | 206 Result result; |
219 result.updated = true; | 207 result.updated = true; |
220 result.probe = false; | 208 result.probe = false; |
221 result.target_bitrate_bps = rate_control_.LatestEstimate(); | 209 result.target_bitrate_bps = rate_control_.LatestEstimate(); |
222 LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to " | 210 LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to " |
223 << result.target_bitrate_bps; | 211 << result.target_bitrate_bps; |
224 return result; | 212 return result; |
225 } | 213 } |
226 | 214 |
227 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedback( | 215 void DelayBasedBwe::IncomingPacketFeedback( |
228 const PacketFeedback& packet_feedback) { | 216 const PacketFeedback& packet_feedback) { |
229 int64_t now_ms = clock_->TimeInMilliseconds(); | 217 int64_t now_ms = clock_->TimeInMilliseconds(); |
230 | 218 |
231 receiver_incoming_bitrate_.Update(packet_feedback.arrival_time_ms, | 219 receiver_incoming_bitrate_.Update(packet_feedback.arrival_time_ms, |
232 packet_feedback.payload_size); | 220 packet_feedback.payload_size); |
233 Result result; | 221 Result result; |
234 // Reset if the stream has timed out. | 222 // Reset if the stream has timed out. |
235 if (last_seen_packet_ms_ == -1 || | 223 if (last_seen_packet_ms_ == -1 || |
236 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { | 224 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { |
237 inter_arrival_.reset( | 225 inter_arrival_.reset( |
(...skipping 22 matching lines...) Expand all Loading... | |
260 if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms, | 248 if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms, |
261 now_ms, packet_feedback.payload_size, | 249 now_ms, packet_feedback.payload_size, |
262 &ts_delta, &t_delta, &size_delta)) { | 250 &ts_delta, &t_delta, &size_delta)) { |
263 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); | 251 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); |
264 trendline_estimator_->Update(t_delta, ts_delta_ms, | 252 trendline_estimator_->Update(t_delta, ts_delta_ms, |
265 packet_feedback.arrival_time_ms); | 253 packet_feedback.arrival_time_ms); |
266 detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms, | 254 detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms, |
267 trendline_estimator_->num_of_deltas(), | 255 trendline_estimator_->num_of_deltas(), |
268 packet_feedback.arrival_time_ms); | 256 packet_feedback.arrival_time_ms); |
269 } | 257 } |
270 | |
271 int probing_bps = 0; | |
272 if (packet_feedback.pacing_info.probe_cluster_id != | 258 if (packet_feedback.pacing_info.probe_cluster_id != |
273 PacedPacketInfo::kNotAProbe) { | 259 PacedPacketInfo::kNotAProbe) { |
274 probing_bps = | 260 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); |
275 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); | |
276 } | 261 } |
277 rtc::Optional<uint32_t> acked_bitrate_bps = | 262 } |
278 receiver_incoming_bitrate_.bitrate_bps(); | 263 |
279 // Currently overusing the bandwidth. | 264 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate( |
280 if (detector_.State() == BandwidthUsage::kBwOverusing) { | 265 bool overusing, |
281 if (acked_bitrate_bps && | 266 bool delayed_feedback) { |
282 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { | 267 Result result; |
283 result.updated = | 268 int64_t now_ms = clock_->TimeInMilliseconds(); |
284 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | 269 if (delayed_feedback) { |
terelius
2017/04/11 14:21:38
If delayed and normal feedback are handled by mutu
| |
285 acked_bitrate_bps, &result.target_bitrate_bps); | 270 ++consecutive_delayed_feedbacks_; |
271 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { | |
272 consecutive_delayed_feedbacks_ = 0; | |
273 return OnLongFeedbackDelay(now_ms); | |
286 } | 274 } |
287 } else if (probing_bps > 0) { | 275 } else { |
288 // No overuse, but probing measured a bitrate. | 276 consecutive_delayed_feedbacks_ = 0; |
289 rate_control_.SetEstimate(probing_bps, packet_feedback.arrival_time_ms); | 277 rtc::Optional<uint32_t> acked_bitrate_bps = |
290 result.probe = true; | 278 receiver_incoming_bitrate_.bitrate_bps(); |
291 result.updated = | 279 rtc::Optional<int> probe_bitrate_bps = |
292 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | 280 probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps(); |
293 acked_bitrate_bps, &result.target_bitrate_bps); | 281 // Currently overusing the bandwidth. |
294 } | 282 if (overusing) { |
295 if (!result.updated && | 283 if (acked_bitrate_bps && |
296 (last_update_ms_ == -1 || | 284 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { |
297 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { | 285 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing, |
298 result.updated = | 286 &result.target_bitrate_bps); |
299 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | 287 } |
300 acked_bitrate_bps, &result.target_bitrate_bps); | 288 } else { |
301 } | 289 if (probe_bitrate_bps) { |
302 if (result.updated) { | 290 rate_control_.SetEstimate(*probe_bitrate_bps, now_ms); |
303 last_update_ms_ = now_ms; | 291 result.probe = true; |
304 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, | 292 } |
305 result.target_bitrate_bps); | 293 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing, |
306 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ || | 294 &result.target_bitrate_bps); |
307 detector_.State() != last_logged_state_)) { | 295 } |
308 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps, | 296 if (result.updated) { |
309 detector_.State()); | 297 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, |
310 last_logged_bitrate_ = result.target_bitrate_bps; | 298 result.target_bitrate_bps); |
311 last_logged_state_ = detector_.State(); | 299 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ || |
300 detector_.State() != last_logged_state_)) { | |
301 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps, | |
302 detector_.State()); | |
303 last_logged_bitrate_ = result.target_bitrate_bps; | |
304 last_logged_state_ = detector_.State(); | |
305 } | |
312 } | 306 } |
313 } | 307 } |
314 | |
315 return result; | 308 return result; |
316 } | 309 } |
317 | 310 |
318 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, | 311 bool DelayBasedBwe::UpdateEstimate(int64_t now_ms, |
319 int64_t now_ms, | |
320 rtc::Optional<uint32_t> acked_bitrate_bps, | 312 rtc::Optional<uint32_t> acked_bitrate_bps, |
313 bool overusing, | |
321 uint32_t* target_bitrate_bps) { | 314 uint32_t* target_bitrate_bps) { |
322 // TODO(terelius): RateControlInput::noise_var is deprecated and will be | 315 // TODO(terelius): RateControlInput::noise_var is deprecated and will be |
323 // removed. In the meantime, we set it to zero. | 316 // removed. In the meantime, we set it to zero. |
324 const RateControlInput input(detector_.State(), acked_bitrate_bps, 0); | 317 const RateControlInput input( |
318 overusing ? BandwidthUsage::kBwOverusing : detector_.State(), | |
319 acked_bitrate_bps, 0); | |
325 *target_bitrate_bps = rate_control_.Update(&input, now_ms); | 320 *target_bitrate_bps = rate_control_.Update(&input, now_ms); |
326 return rate_control_.ValidEstimate(); | 321 return rate_control_.ValidEstimate(); |
327 } | 322 } |
328 | 323 |
329 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 324 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
330 rate_control_.SetRtt(avg_rtt_ms); | 325 rate_control_.SetRtt(avg_rtt_ms); |
331 } | 326 } |
332 | 327 |
333 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, | 328 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, |
334 uint32_t* bitrate_bps) const { | 329 uint32_t* bitrate_bps) const { |
(...skipping 19 matching lines...) Expand all Loading... | |
354 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { | 349 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { |
355 // Called from both the configuration thread and the network thread. Shouldn't | 350 // Called from both the configuration thread and the network thread. Shouldn't |
356 // be called from the network thread in the future. | 351 // be called from the network thread in the future. |
357 rate_control_.SetMinBitrate(min_bitrate_bps); | 352 rate_control_.SetMinBitrate(min_bitrate_bps); |
358 } | 353 } |
359 | 354 |
360 int64_t DelayBasedBwe::GetProbingIntervalMs() const { | 355 int64_t DelayBasedBwe::GetProbingIntervalMs() const { |
361 return probing_interval_estimator_.GetIntervalMs(); | 356 return probing_interval_estimator_.GetIntervalMs(); |
362 } | 357 } |
363 } // namespace webrtc | 358 } // namespace webrtc |
OLD | NEW |