Chromium Code Reviews| 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 |