| 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 |
| 11 #include "webrtc/modules/congestion_controller/delay_based_bwe.h" | 11 #include "webrtc/modules/congestion_controller/delay_based_bwe.h" |
| 12 | 12 |
| 13 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <cmath> | 14 #include <cmath> |
| 15 #include <string> | 15 #include <string> |
| 16 | 16 |
| 17 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
| 18 #include "webrtc/base/constructormagic.h" | 18 #include "webrtc/base/constructormagic.h" |
| 19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
| 20 #include "webrtc/base/thread_annotations.h" | 20 #include "webrtc/base/thread_annotations.h" |
| 21 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" | 21 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" |
| 22 #include "webrtc/modules/pacing/paced_sender.h" | 22 #include "webrtc/modules/pacing/paced_sender.h" |
| 23 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat
or.h" | 23 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat
or.h" |
| 24 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" |
| 24 #include "webrtc/system_wrappers/include/field_trial.h" | 25 #include "webrtc/system_wrappers/include/field_trial.h" |
| 25 #include "webrtc/system_wrappers/include/metrics.h" | 26 #include "webrtc/system_wrappers/include/metrics.h" |
| 26 #include "webrtc/typedefs.h" | 27 #include "webrtc/typedefs.h" |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 constexpr int kTimestampGroupLengthMs = 5; | 30 constexpr int kTimestampGroupLengthMs = 5; |
| 30 constexpr int kAbsSendTimeFraction = 18; | 31 constexpr int kAbsSendTimeFraction = 18; |
| 31 constexpr int kAbsSendTimeInterArrivalUpshift = 8; | 32 constexpr int kAbsSendTimeInterArrivalUpshift = 8; |
| 32 constexpr int kInterArrivalShift = | 33 constexpr int kInterArrivalShift = |
| 33 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; | 34 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; |
| 34 constexpr double kTimestampToMs = | 35 constexpr double kTimestampToMs = |
| 35 1000.0 / static_cast<double>(1 << kInterArrivalShift); | 36 1000.0 / static_cast<double>(1 << kInterArrivalShift); |
| 36 // This ssrc is used to fulfill the current API but will be removed | 37 // This ssrc is used to fulfill the current API but will be removed |
| 37 // after the API has been changed. | 38 // after the API has been changed. |
| 38 constexpr uint32_t kFixedSsrc = 0; | 39 constexpr uint32_t kFixedSsrc = 0; |
| 39 constexpr int kInitialRateWindowMs = 500; | 40 constexpr int kInitialRateWindowMs = 500; |
| 40 constexpr int kRateWindowMs = 150; | 41 constexpr int kRateWindowMs = 150; |
| 41 | 42 |
| 43 // Parameters for linear least squares fit of regression line to noisy data. |
| 42 constexpr size_t kDefaultTrendlineWindowSize = 15; | 44 constexpr size_t kDefaultTrendlineWindowSize = 15; |
| 43 constexpr double kDefaultTrendlineSmoothingCoeff = 0.9; | 45 constexpr double kDefaultTrendlineSmoothingCoeff = 0.9; |
| 44 constexpr double kDefaultTrendlineThresholdGain = 4.0; | 46 constexpr double kDefaultTrendlineThresholdGain = 4.0; |
| 45 | 47 |
| 48 // Parameters for Theil-Sen robust fitting of line to noisy data. |
| 49 constexpr size_t kDefaultMedianSlopeWindowSize = 20; |
| 50 constexpr double kDefaultMedianSlopeThresholdGain = 4.0; |
| 51 |
| 46 const char kBitrateEstimateExperiment[] = "WebRTC-ImprovedBitrateEstimate"; | 52 const char kBitrateEstimateExperiment[] = "WebRTC-ImprovedBitrateEstimate"; |
| 47 const char kBweTrendlineFilterExperiment[] = "WebRTC-BweTrendlineFilter"; | 53 const char kBweTrendlineFilterExperiment[] = "WebRTC-BweTrendlineFilter"; |
| 54 const char kBweMedianSlopeFilterExperiment[] = "WebRTC-BweMedianSlopeFilter"; |
| 48 | 55 |
| 49 bool BitrateEstimateExperimentIsEnabled() { | 56 bool BitrateEstimateExperimentIsEnabled() { |
| 50 return webrtc::field_trial::FindFullName(kBitrateEstimateExperiment) == | 57 return webrtc::field_trial::FindFullName(kBitrateEstimateExperiment) == |
| 51 "Enabled"; | 58 "Enabled"; |
| 52 } | 59 } |
| 53 | 60 |
| 54 bool TrendlineFilterExperimentIsEnabled() { | 61 bool TrendlineFilterExperimentIsEnabled() { |
| 55 std::string experiment_string = | 62 std::string experiment_string = |
| 56 webrtc::field_trial::FindFullName(kBweTrendlineFilterExperiment); | 63 webrtc::field_trial::FindFullName(kBweTrendlineFilterExperiment); |
| 57 // The experiment is enabled iff the field trial string begins with "Enabled". | 64 // The experiment is enabled iff the field trial string begins with "Enabled". |
| 58 return experiment_string.find("Enabled") == 0; | 65 return experiment_string.find("Enabled") == 0; |
| 59 } | 66 } |
| 60 | 67 |
| 61 bool ReadTrendlineFilterExperimentParameters(size_t* window_points, | 68 bool MedianSlopeFilterExperimentIsEnabled() { |
| 69 std::string experiment_string = |
| 70 webrtc::field_trial::FindFullName(kBweMedianSlopeFilterExperiment); |
| 71 // The experiment is enabled iff the field trial string begins with "Enabled". |
| 72 return experiment_string.find("Enabled") == 0; |
| 73 } |
| 74 |
| 75 bool ReadTrendlineFilterExperimentParameters(size_t* window_size, |
| 62 double* smoothing_coef, | 76 double* smoothing_coef, |
| 63 double* threshold_gain) { | 77 double* threshold_gain) { |
| 64 RTC_DCHECK(TrendlineFilterExperimentIsEnabled()); | 78 RTC_DCHECK(TrendlineFilterExperimentIsEnabled()); |
| 79 RTC_DCHECK(!MedianSlopeFilterExperimentIsEnabled()); |
| 80 RTC_DCHECK(window_size != nullptr); |
| 81 RTC_DCHECK(smoothing_coef != nullptr); |
| 82 RTC_DCHECK(threshold_gain != nullptr); |
| 65 std::string experiment_string = | 83 std::string experiment_string = |
| 66 webrtc::field_trial::FindFullName(kBweTrendlineFilterExperiment); | 84 webrtc::field_trial::FindFullName(kBweTrendlineFilterExperiment); |
| 67 int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%zu,%lf,%lf", | 85 int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%zu,%lf,%lf", |
| 68 window_points, smoothing_coef, threshold_gain); | 86 window_size, smoothing_coef, threshold_gain); |
| 69 if (parsed_values == 3) { | 87 if (parsed_values == 3) { |
| 70 RTC_CHECK_GT(*window_points, 1) << "Need at least 2 points to fit a line."; | 88 RTC_CHECK_GT(*window_size, 1) << "Need at least 2 points to fit a line."; |
| 71 RTC_CHECK(0 <= *smoothing_coef && *smoothing_coef <= 1) | 89 RTC_CHECK(0 <= *smoothing_coef && *smoothing_coef <= 1) |
| 72 << "Coefficient needs to be between 0 and 1 for weighted average."; | 90 << "Coefficient needs to be between 0 and 1 for weighted average."; |
| 73 RTC_CHECK_GT(*threshold_gain, 0) << "Threshold gain needs to be positive."; | 91 RTC_CHECK_GT(*threshold_gain, 0) << "Threshold gain needs to be positive."; |
| 74 return true; | 92 return true; |
| 75 } | 93 } |
| 76 LOG(LS_WARNING) << "Failed to parse parameters for BweTrendlineFilter " | 94 LOG(LS_WARNING) << "Failed to parse parameters for BweTrendlineFilter " |
| 77 "experiment from field trial string. Using default."; | 95 "experiment from field trial string. Using default."; |
| 78 *window_points = kDefaultTrendlineWindowSize; | 96 *window_size = kDefaultTrendlineWindowSize; |
| 79 *smoothing_coef = kDefaultTrendlineSmoothingCoeff; | 97 *smoothing_coef = kDefaultTrendlineSmoothingCoeff; |
| 80 *threshold_gain = kDefaultTrendlineThresholdGain; | 98 *threshold_gain = kDefaultTrendlineThresholdGain; |
| 81 return false; | 99 return false; |
| 82 } | 100 } |
| 83 | 101 |
| 102 bool ReadMedianSlopeFilterExperimentParameters(size_t* window_size, |
| 103 double* threshold_gain) { |
| 104 RTC_DCHECK(!TrendlineFilterExperimentIsEnabled()); |
| 105 RTC_DCHECK(MedianSlopeFilterExperimentIsEnabled()); |
| 106 RTC_DCHECK(window_size != nullptr); |
| 107 RTC_DCHECK(threshold_gain != nullptr); |
| 108 std::string experiment_string = |
| 109 webrtc::field_trial::FindFullName(kBweMedianSlopeFilterExperiment); |
| 110 int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%zu,%lf", |
| 111 window_size, threshold_gain); |
| 112 if (parsed_values == 2) { |
| 113 RTC_CHECK_GT(*window_size, 1) << "Need at least 2 points to fit a line."; |
| 114 RTC_CHECK_GT(*threshold_gain, 0) << "Threshold gain needs to be positive."; |
| 115 return true; |
| 116 } |
| 117 LOG(LS_WARNING) << "Failed to parse parameters for BweMedianSlopeFilter " |
| 118 "experiment from field trial string. Using default."; |
| 119 *window_size = kDefaultMedianSlopeWindowSize; |
| 120 *threshold_gain = kDefaultMedianSlopeThresholdGain; |
| 121 return false; |
| 122 } |
| 84 } // namespace | 123 } // namespace |
| 85 | 124 |
| 86 namespace webrtc { | 125 namespace webrtc { |
| 87 | 126 |
| 88 DelayBasedBwe::BitrateEstimator::BitrateEstimator() | 127 DelayBasedBwe::BitrateEstimator::BitrateEstimator() |
| 89 : sum_(0), | 128 : sum_(0), |
| 90 current_win_ms_(0), | 129 current_win_ms_(0), |
| 91 prev_time_ms_(-1), | 130 prev_time_ms_(-1), |
| 92 bitrate_estimate_(-1.0f), | 131 bitrate_estimate_(-1.0f), |
| 93 bitrate_estimate_var_(50.0f), | 132 bitrate_estimate_var_(50.0f), |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 return bitrate_sample; | 200 return bitrate_sample; |
| 162 } | 201 } |
| 163 | 202 |
| 164 rtc::Optional<uint32_t> DelayBasedBwe::BitrateEstimator::bitrate_bps() const { | 203 rtc::Optional<uint32_t> DelayBasedBwe::BitrateEstimator::bitrate_bps() const { |
| 165 if (bitrate_estimate_ < 0.f) | 204 if (bitrate_estimate_ < 0.f) |
| 166 return rtc::Optional<uint32_t>(); | 205 return rtc::Optional<uint32_t>(); |
| 167 return rtc::Optional<uint32_t>(bitrate_estimate_ * 1000); | 206 return rtc::Optional<uint32_t>(bitrate_estimate_ * 1000); |
| 168 } | 207 } |
| 169 | 208 |
| 170 DelayBasedBwe::DelayBasedBwe(Clock* clock) | 209 DelayBasedBwe::DelayBasedBwe(Clock* clock) |
| 171 : clock_(clock), | 210 : in_trendline_experiment_(TrendlineFilterExperimentIsEnabled()), |
| 211 in_median_slope_experiment_(MedianSlopeFilterExperimentIsEnabled()), |
| 212 clock_(clock), |
| 172 inter_arrival_(), | 213 inter_arrival_(), |
| 173 kalman_estimator_(), | 214 kalman_estimator_(), |
| 174 trendline_estimator_(), | 215 trendline_estimator_(), |
| 175 detector_(OverUseDetectorOptions()), | 216 detector_(OverUseDetectorOptions()), |
| 176 receiver_incoming_bitrate_(), | 217 receiver_incoming_bitrate_(), |
| 177 last_update_ms_(-1), | 218 last_update_ms_(-1), |
| 178 last_seen_packet_ms_(-1), | 219 last_seen_packet_ms_(-1), |
| 179 uma_recorded_(false), | 220 uma_recorded_(false), |
| 180 trendline_window_size_(kDefaultTrendlineWindowSize), | 221 trendline_window_size_(kDefaultTrendlineWindowSize), |
| 181 trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), | 222 trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), |
| 182 trendline_threshold_gain_(kDefaultTrendlineThresholdGain), | 223 trendline_threshold_gain_(kDefaultTrendlineThresholdGain), |
| 183 in_trendline_experiment_(TrendlineFilterExperimentIsEnabled()), | 224 probing_interval_estimator_(&rate_control_), |
| 184 probing_interval_estimator_(&rate_control_) { | 225 median_slope_window_size_(kDefaultMedianSlopeWindowSize), |
| 226 median_slope_threshold_gain_(kDefaultMedianSlopeThresholdGain) { |
| 185 if (in_trendline_experiment_) { | 227 if (in_trendline_experiment_) { |
| 186 ReadTrendlineFilterExperimentParameters(&trendline_window_size_, | 228 ReadTrendlineFilterExperimentParameters(&trendline_window_size_, |
| 187 &trendline_smoothing_coeff_, | 229 &trendline_smoothing_coeff_, |
| 188 &trendline_threshold_gain_); | 230 &trendline_threshold_gain_); |
| 189 } | 231 } |
| 232 if (in_median_slope_experiment_) { |
| 233 ReadMedianSlopeFilterExperimentParameters(&trendline_window_size_, |
| 234 &trendline_threshold_gain_); |
| 235 } |
| 236 |
| 190 network_thread_.DetachFromThread(); | 237 network_thread_.DetachFromThread(); |
| 191 } | 238 } |
| 192 | 239 |
| 193 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( | 240 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( |
| 194 const std::vector<PacketInfo>& packet_feedback_vector) { | 241 const std::vector<PacketInfo>& packet_feedback_vector) { |
| 195 RTC_DCHECK(network_thread_.CalledOnValidThread()); | 242 RTC_DCHECK(network_thread_.CalledOnValidThread()); |
| 196 if (!uma_recorded_) { | 243 if (!uma_recorded_) { |
| 197 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, | 244 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, |
| 198 BweNames::kSendSideTransportSeqNum, | 245 BweNames::kSendSideTransportSeqNum, |
| 199 BweNames::kBweNamesMax); | 246 BweNames::kBweNamesMax); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 217 // Reset if the stream has timed out. | 264 // Reset if the stream has timed out. |
| 218 if (last_seen_packet_ms_ == -1 || | 265 if (last_seen_packet_ms_ == -1 || |
| 219 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { | 266 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { |
| 220 inter_arrival_.reset( | 267 inter_arrival_.reset( |
| 221 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, | 268 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, |
| 222 kTimestampToMs, true)); | 269 kTimestampToMs, true)); |
| 223 kalman_estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); | 270 kalman_estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); |
| 224 trendline_estimator_.reset(new TrendlineEstimator( | 271 trendline_estimator_.reset(new TrendlineEstimator( |
| 225 trendline_window_size_, trendline_smoothing_coeff_, | 272 trendline_window_size_, trendline_smoothing_coeff_, |
| 226 trendline_threshold_gain_)); | 273 trendline_threshold_gain_)); |
| 274 median_slope_estimator_.reset(new MedianSlopeEstimator( |
| 275 median_slope_window_size_, median_slope_threshold_gain_)); |
| 227 } | 276 } |
| 228 last_seen_packet_ms_ = now_ms; | 277 last_seen_packet_ms_ = now_ms; |
| 229 | 278 |
| 230 uint32_t send_time_24bits = | 279 uint32_t send_time_24bits = |
| 231 static_cast<uint32_t>( | 280 static_cast<uint32_t>( |
| 232 ((static_cast<uint64_t>(info.send_time_ms) << kAbsSendTimeFraction) + | 281 ((static_cast<uint64_t>(info.send_time_ms) << kAbsSendTimeFraction) + |
| 233 500) / | 282 500) / |
| 234 1000) & | 283 1000) & |
| 235 0x00FFFFFF; | 284 0x00FFFFFF; |
| 236 // Shift up send time to use the full 32 bits that inter_arrival works with, | 285 // Shift up send time to use the full 32 bits that inter_arrival works with, |
| 237 // so wrapping works properly. | 286 // so wrapping works properly. |
| 238 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; | 287 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; |
| 239 | 288 |
| 240 uint32_t ts_delta = 0; | 289 uint32_t ts_delta = 0; |
| 241 int64_t t_delta = 0; | 290 int64_t t_delta = 0; |
| 242 int size_delta = 0; | 291 int size_delta = 0; |
| 243 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms, | 292 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms, |
| 244 info.payload_size, &ts_delta, &t_delta, | 293 info.payload_size, &ts_delta, &t_delta, |
| 245 &size_delta)) { | 294 &size_delta)) { |
| 246 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); | 295 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); |
| 247 if (in_trendline_experiment_) { | 296 if (in_trendline_experiment_) { |
| 248 trendline_estimator_->Update(t_delta, ts_delta_ms, info.arrival_time_ms); | 297 trendline_estimator_->Update(t_delta, ts_delta_ms, info.arrival_time_ms); |
| 249 detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms, | 298 detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms, |
| 250 trendline_estimator_->num_of_deltas(), | 299 trendline_estimator_->num_of_deltas(), |
| 251 info.arrival_time_ms); | 300 info.arrival_time_ms); |
| 252 | 301 } else if (in_median_slope_experiment_) { |
| 302 median_slope_estimator_->Update(t_delta, ts_delta_ms, |
| 303 info.arrival_time_ms); |
| 304 detector_.Detect(median_slope_estimator_->trendline_slope(), ts_delta_ms, |
| 305 median_slope_estimator_->num_of_deltas(), |
| 306 info.arrival_time_ms); |
| 253 } else { | 307 } else { |
| 254 kalman_estimator_->Update(t_delta, ts_delta_ms, size_delta, | 308 kalman_estimator_->Update(t_delta, ts_delta_ms, size_delta, |
| 255 detector_.State(), info.arrival_time_ms); | 309 detector_.State(), info.arrival_time_ms); |
| 256 detector_.Detect(kalman_estimator_->offset(), ts_delta_ms, | 310 detector_.Detect(kalman_estimator_->offset(), ts_delta_ms, |
| 257 kalman_estimator_->num_of_deltas(), | 311 kalman_estimator_->num_of_deltas(), |
| 258 info.arrival_time_ms); | 312 info.arrival_time_ms); |
| 259 } | 313 } |
| 260 } | 314 } |
| 261 | 315 |
| 262 int probing_bps = 0; | 316 int probing_bps = 0; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 281 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, | 335 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
| 282 &result.target_bitrate_bps); | 336 &result.target_bitrate_bps); |
| 283 } | 337 } |
| 284 if (!result.updated && | 338 if (!result.updated && |
| 285 (last_update_ms_ == -1 || | 339 (last_update_ms_ == -1 || |
| 286 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { | 340 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { |
| 287 result.updated = | 341 result.updated = |
| 288 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, | 342 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
| 289 &result.target_bitrate_bps); | 343 &result.target_bitrate_bps); |
| 290 } | 344 } |
| 291 if (result.updated) | 345 if (result.updated) { |
| 292 last_update_ms_ = now_ms; | 346 last_update_ms_ = now_ms; |
| 347 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, |
| 348 result.target_bitrate_bps); |
| 349 } |
| 293 | 350 |
| 294 return result; | 351 return result; |
| 295 } | 352 } |
| 296 | 353 |
| 297 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, | 354 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, |
| 298 int64_t now_ms, | 355 int64_t now_ms, |
| 299 rtc::Optional<uint32_t> acked_bitrate_bps, | 356 rtc::Optional<uint32_t> acked_bitrate_bps, |
| 300 uint32_t* target_bitrate_bps) { | 357 uint32_t* target_bitrate_bps) { |
| 301 // TODO(terelius): RateControlInput::noise_var is deprecated and will be | 358 // TODO(terelius): RateControlInput::noise_var is deprecated and will be |
| 302 // removed. In the meantime, we set it to zero. | 359 // removed. In the meantime, we set it to zero. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 329 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { | 386 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { |
| 330 // Called from both the configuration thread and the network thread. Shouldn't | 387 // Called from both the configuration thread and the network thread. Shouldn't |
| 331 // be called from the network thread in the future. | 388 // be called from the network thread in the future. |
| 332 rate_control_.SetMinBitrate(min_bitrate_bps); | 389 rate_control_.SetMinBitrate(min_bitrate_bps); |
| 333 } | 390 } |
| 334 | 391 |
| 335 int64_t DelayBasedBwe::GetProbingIntervalMs() const { | 392 int64_t DelayBasedBwe::GetProbingIntervalMs() const { |
| 336 return probing_interval_estimator_.GetIntervalMs(); | 393 return probing_interval_estimator_.GetIntervalMs(); |
| 337 } | 394 } |
| 338 } // namespace webrtc | 395 } // namespace webrtc |
| OLD | NEW |