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 if (delayed_feedback) { |
| 198 ++consecutive_delayed_feedbacks_; | 196 ++consecutive_delayed_feedbacks_; |
| 199 } else { | 197 } else { |
| 200 consecutive_delayed_feedbacks_ = 0; | 198 consecutive_delayed_feedbacks_ = 0; |
| 201 } | 199 } |
| 202 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { | 200 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { |
| 203 aggregated_result = OnLongFeedbackDelay( | 201 consecutive_delayed_feedbacks_ = 0; |
| 202 return OnLongFeedbackDelay( | |
| 204 sorted_packet_feedback_vector.back().arrival_time_ms); | 203 sorted_packet_feedback_vector.back().arrival_time_ms); |
| 205 consecutive_delayed_feedbacks_ = 0; | |
| 206 } | 204 } |
| 207 return aggregated_result; | 205 return MaybeUpdateEstimate(overusing); |
|
terelius
2017/04/11 14:21:38
Wouldn't it be easier and cleaner to just not call
michaelt
2017/04/11 14:48:12
Hmm i don't have a strong opinion here.
On one ha
| |
| 208 } | 206 } |
| 209 | 207 |
| 210 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( | 208 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( |
| 211 int64_t arrival_time_ms) { | 209 int64_t arrival_time_ms) { |
| 212 // Estimate should always be valid since a start bitrate always is set in the | 210 // 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, | 211 // Call constructor. An alternative would be to return an empty Result here, |
| 214 // or to estimate the throughput based on the feedback we received. | 212 // or to estimate the throughput based on the feedback we received. |
| 215 RTC_DCHECK(rate_control_.ValidEstimate()); | 213 RTC_DCHECK(rate_control_.ValidEstimate()); |
| 216 rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, | 214 rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, |
| 217 arrival_time_ms); | 215 arrival_time_ms); |
| 218 Result result; | 216 Result result; |
| 219 result.updated = true; | 217 result.updated = true; |
| 220 result.probe = false; | 218 result.probe = false; |
| 221 result.target_bitrate_bps = rate_control_.LatestEstimate(); | 219 result.target_bitrate_bps = rate_control_.LatestEstimate(); |
| 222 LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to " | 220 LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to " |
| 223 << result.target_bitrate_bps; | 221 << result.target_bitrate_bps; |
| 224 return result; | 222 return result; |
| 225 } | 223 } |
| 226 | 224 |
| 227 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedback( | 225 void DelayBasedBwe::IncomingPacketFeedback( |
| 228 const PacketFeedback& packet_feedback) { | 226 const PacketFeedback& packet_feedback) { |
| 229 int64_t now_ms = clock_->TimeInMilliseconds(); | 227 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 230 | 228 |
| 231 receiver_incoming_bitrate_.Update(packet_feedback.arrival_time_ms, | 229 receiver_incoming_bitrate_.Update(packet_feedback.arrival_time_ms, |
| 232 packet_feedback.payload_size); | 230 packet_feedback.payload_size); |
| 233 Result result; | 231 Result result; |
| 234 // Reset if the stream has timed out. | 232 // Reset if the stream has timed out. |
| 235 if (last_seen_packet_ms_ == -1 || | 233 if (last_seen_packet_ms_ == -1 || |
| 236 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { | 234 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { |
| 237 inter_arrival_.reset( | 235 inter_arrival_.reset( |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 260 if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms, | 258 if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms, |
| 261 now_ms, packet_feedback.payload_size, | 259 now_ms, packet_feedback.payload_size, |
| 262 &ts_delta, &t_delta, &size_delta)) { | 260 &ts_delta, &t_delta, &size_delta)) { |
| 263 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); | 261 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); |
| 264 trendline_estimator_->Update(t_delta, ts_delta_ms, | 262 trendline_estimator_->Update(t_delta, ts_delta_ms, |
| 265 packet_feedback.arrival_time_ms); | 263 packet_feedback.arrival_time_ms); |
| 266 detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms, | 264 detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms, |
| 267 trendline_estimator_->num_of_deltas(), | 265 trendline_estimator_->num_of_deltas(), |
| 268 packet_feedback.arrival_time_ms); | 266 packet_feedback.arrival_time_ms); |
| 269 } | 267 } |
| 270 | |
| 271 int probing_bps = 0; | |
| 272 if (packet_feedback.pacing_info.probe_cluster_id != | 268 if (packet_feedback.pacing_info.probe_cluster_id != |
| 273 PacedPacketInfo::kNotAProbe) { | 269 PacedPacketInfo::kNotAProbe) { |
| 274 probing_bps = | 270 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); |
| 275 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); | |
| 276 } | 271 } |
| 272 } | |
| 273 | |
| 274 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(bool overusing) { | |
| 275 Result result; | |
| 277 rtc::Optional<uint32_t> acked_bitrate_bps = | 276 rtc::Optional<uint32_t> acked_bitrate_bps = |
| 278 receiver_incoming_bitrate_.bitrate_bps(); | 277 receiver_incoming_bitrate_.bitrate_bps(); |
| 278 int64_t now_ms = clock_->TimeInMilliseconds(); | |
| 279 rtc::Optional<int> probe_bitrate_bps = | |
| 280 probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps(); | |
| 279 // Currently overusing the bandwidth. | 281 // Currently overusing the bandwidth. |
| 280 if (detector_.State() == BandwidthUsage::kBwOverusing) { | 282 if (overusing) { |
| 281 if (acked_bitrate_bps && | 283 if (acked_bitrate_bps && |
| 282 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { | 284 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { |
| 283 result.updated = | 285 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing, |
| 284 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | 286 &result.target_bitrate_bps); |
| 285 acked_bitrate_bps, &result.target_bitrate_bps); | |
| 286 } | 287 } |
| 287 } else if (probing_bps > 0) { | 288 } else { |
| 288 // No overuse, but probing measured a bitrate. | 289 if (probe_bitrate_bps) { |
| 289 rate_control_.SetEstimate(probing_bps, packet_feedback.arrival_time_ms); | 290 rate_control_.SetEstimate(*probe_bitrate_bps, now_ms); |
| 290 result.probe = true; | 291 result.probe = true; |
| 291 result.updated = | 292 } |
| 292 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | 293 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing, |
| 293 acked_bitrate_bps, &result.target_bitrate_bps); | 294 &result.target_bitrate_bps); |
| 294 } | |
| 295 if (!result.updated && | |
| 296 (last_update_ms_ == -1 || | |
| 297 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { | |
| 298 result.updated = | |
| 299 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | |
| 300 acked_bitrate_bps, &result.target_bitrate_bps); | |
| 301 } | 295 } |
| 302 if (result.updated) { | 296 if (result.updated) { |
| 303 last_update_ms_ = now_ms; | |
| 304 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, | 297 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, |
| 305 result.target_bitrate_bps); | 298 result.target_bitrate_bps); |
| 306 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ || | 299 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ || |
| 307 detector_.State() != last_logged_state_)) { | 300 detector_.State() != last_logged_state_)) { |
| 308 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps, | 301 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps, |
| 309 detector_.State()); | 302 detector_.State()); |
| 310 last_logged_bitrate_ = result.target_bitrate_bps; | 303 last_logged_bitrate_ = result.target_bitrate_bps; |
| 311 last_logged_state_ = detector_.State(); | 304 last_logged_state_ = detector_.State(); |
| 312 } | 305 } |
| 313 } | 306 } |
| 314 | |
| 315 return result; | 307 return result; |
| 316 } | 308 } |
| 317 | 309 |
| 318 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, | 310 bool DelayBasedBwe::UpdateEstimate(int64_t now_ms, |
| 319 int64_t now_ms, | |
| 320 rtc::Optional<uint32_t> acked_bitrate_bps, | 311 rtc::Optional<uint32_t> acked_bitrate_bps, |
| 312 bool overusing, | |
| 321 uint32_t* target_bitrate_bps) { | 313 uint32_t* target_bitrate_bps) { |
| 322 // TODO(terelius): RateControlInput::noise_var is deprecated and will be | 314 // TODO(terelius): RateControlInput::noise_var is deprecated and will be |
| 323 // removed. In the meantime, we set it to zero. | 315 // removed. In the meantime, we set it to zero. |
| 324 const RateControlInput input(detector_.State(), acked_bitrate_bps, 0); | 316 const RateControlInput input( |
| 317 overusing ? BandwidthUsage::kBwOverusing : detector_.State(), | |
| 318 acked_bitrate_bps, 0); | |
| 325 *target_bitrate_bps = rate_control_.Update(&input, now_ms); | 319 *target_bitrate_bps = rate_control_.Update(&input, now_ms); |
| 326 return rate_control_.ValidEstimate(); | 320 return rate_control_.ValidEstimate(); |
| 327 } | 321 } |
| 328 | 322 |
| 329 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 323 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
| 330 rate_control_.SetRtt(avg_rtt_ms); | 324 rate_control_.SetRtt(avg_rtt_ms); |
| 331 } | 325 } |
| 332 | 326 |
| 333 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, | 327 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, |
| 334 uint32_t* bitrate_bps) const { | 328 uint32_t* bitrate_bps) const { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 354 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { | 348 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { |
| 355 // Called from both the configuration thread and the network thread. Shouldn't | 349 // Called from both the configuration thread and the network thread. Shouldn't |
| 356 // be called from the network thread in the future. | 350 // be called from the network thread in the future. |
| 357 rate_control_.SetMinBitrate(min_bitrate_bps); | 351 rate_control_.SetMinBitrate(min_bitrate_bps); |
| 358 } | 352 } |
| 359 | 353 |
| 360 int64_t DelayBasedBwe::GetProbingIntervalMs() const { | 354 int64_t DelayBasedBwe::GetProbingIntervalMs() const { |
| 361 return probing_interval_estimator_.GetIntervalMs(); | 355 return probing_interval_estimator_.GetIntervalMs(); |
| 362 } | 356 } |
| 363 } // namespace webrtc | 357 } // namespace webrtc |
| OLD | NEW |