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

Side by Side Diff: webrtc/modules/congestion_controller/delay_based_bwe.cc

Issue 2489323002: Add a new overuse estimator for the delay based BWE behind experiment. (Closed)
Patch Set: Rebase Created 4 years, 1 month 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
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 16
16 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
17 #include "webrtc/base/constructormagic.h" 18 #include "webrtc/base/constructormagic.h"
18 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
19 #include "webrtc/base/thread_annotations.h" 20 #include "webrtc/base/thread_annotations.h"
20 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" 21 #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
21 #include "webrtc/modules/pacing/paced_sender.h" 22 #include "webrtc/modules/pacing/paced_sender.h"
22 #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"
23 #include "webrtc/system_wrappers/include/field_trial.h" 24 #include "webrtc/system_wrappers/include/field_trial.h"
24 #include "webrtc/system_wrappers/include/metrics.h" 25 #include "webrtc/system_wrappers/include/metrics.h"
25 #include "webrtc/typedefs.h" 26 #include "webrtc/typedefs.h"
26 27
27 namespace { 28 namespace {
28 constexpr int kTimestampGroupLengthMs = 5; 29 constexpr int kTimestampGroupLengthMs = 5;
29 constexpr int kAbsSendTimeFraction = 18; 30 constexpr int kAbsSendTimeFraction = 18;
30 constexpr int kAbsSendTimeInterArrivalUpshift = 8; 31 constexpr int kAbsSendTimeInterArrivalUpshift = 8;
31 constexpr int kInterArrivalShift = 32 constexpr int kInterArrivalShift =
32 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; 33 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift;
33 constexpr double kTimestampToMs = 34 constexpr double kTimestampToMs =
34 1000.0 / static_cast<double>(1 << kInterArrivalShift); 35 1000.0 / static_cast<double>(1 << kInterArrivalShift);
35 // This ssrc is used to fulfill the current API but will be removed 36 // This ssrc is used to fulfill the current API but will be removed
36 // after the API has been changed. 37 // after the API has been changed.
37 constexpr uint32_t kFixedSsrc = 0; 38 constexpr uint32_t kFixedSsrc = 0;
38 constexpr int kInitialRateWindowMs = 500; 39 constexpr int kInitialRateWindowMs = 500;
39 constexpr int kRateWindowMs = 150; 40 constexpr int kRateWindowMs = 150;
40 41
42 constexpr size_t kDefaultTrendlineWindowSize = 15;
43 constexpr double kDefaultTrendlineSmoothingCoeff = 0.9;
44 constexpr double kDefaultTrendlineThresholdGain = 4.0;
45
41 const char kBitrateEstimateExperiment[] = "WebRTC-ImprovedBitrateEstimate"; 46 const char kBitrateEstimateExperiment[] = "WebRTC-ImprovedBitrateEstimate";
47 const char kBweTrendlineFilterExperiment[] = "WebRTC-BweTrendlineFilter";
42 48
43 bool BitrateEstimateExperimentIsEnabled() { 49 bool BitrateEstimateExperimentIsEnabled() {
44 return webrtc::field_trial::FindFullName(kBitrateEstimateExperiment) == 50 return webrtc::field_trial::FindFullName(kBitrateEstimateExperiment) ==
45 "Enabled"; 51 "Enabled";
46 } 52 }
53
54 bool TrendlineFilterExperimentIsEnabled() {
55 std::string experiment_string =
56 webrtc::field_trial::FindFullName(kBweTrendlineFilterExperiment);
57 // The experiment is enabled iff the field trial string begins with "Enabled".
58 return experiment_string.find("Enabled") == 0;
59 }
60
61 bool ReadTrendlineFilterExperimentParameters(size_t* window_points,
62 double* smoothing_coef,
63 double* threshold_gain) {
64 RTC_DCHECK(TrendlineFilterExperimentIsEnabled());
65 std::string experiment_string =
66 webrtc::field_trial::FindFullName(kBweTrendlineFilterExperiment);
67 int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%zu,%lf,%lf",
68 window_points, smoothing_coef, threshold_gain);
69 if (parsed_values == 3) {
70 RTC_CHECK_GT(*window_points, 1) << "Need at least 2 points to fit a line.";
71 RTC_CHECK(0 <= *smoothing_coef && *smoothing_coef <= 1)
72 << "Coefficient needs to be between 0 and 1 for weighted average.";
73 RTC_CHECK_GT(*threshold_gain, 0) << "Threshold gain needs to be positive.";
74 return true;
75 }
76 LOG(LS_WARNING) << "Failed to parse parameters for BweTrendlineFilter "
77 "experiment from field trial string. Using default.";
78 *window_points = kDefaultTrendlineWindowSize;
79 *smoothing_coef = kDefaultTrendlineSmoothingCoeff;
80 *threshold_gain = kDefaultTrendlineThresholdGain;
81 return false;
82 }
83
47 } // namespace 84 } // namespace
48 85
49 namespace webrtc { 86 namespace webrtc {
87
50 DelayBasedBwe::BitrateEstimator::BitrateEstimator() 88 DelayBasedBwe::BitrateEstimator::BitrateEstimator()
51 : sum_(0), 89 : sum_(0),
52 current_win_ms_(0), 90 current_win_ms_(0),
53 prev_time_ms_(-1), 91 prev_time_ms_(-1),
54 bitrate_estimate_(-1.0f), 92 bitrate_estimate_(-1.0f),
55 bitrate_estimate_var_(50.0f), 93 bitrate_estimate_var_(50.0f),
56 old_estimator_(kBitrateWindowMs, 8000), 94 old_estimator_(kBitrateWindowMs, 8000),
57 in_experiment_(BitrateEstimateExperimentIsEnabled()) {} 95 in_experiment_(BitrateEstimateExperimentIsEnabled()) {}
58 96
59 void DelayBasedBwe::BitrateEstimator::Update(int64_t now_ms, int bytes) { 97 void DelayBasedBwe::BitrateEstimator::Update(int64_t now_ms, int bytes) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 163
126 rtc::Optional<uint32_t> DelayBasedBwe::BitrateEstimator::bitrate_bps() const { 164 rtc::Optional<uint32_t> DelayBasedBwe::BitrateEstimator::bitrate_bps() const {
127 if (bitrate_estimate_ < 0.f) 165 if (bitrate_estimate_ < 0.f)
128 return rtc::Optional<uint32_t>(); 166 return rtc::Optional<uint32_t>();
129 return rtc::Optional<uint32_t>(bitrate_estimate_ * 1000); 167 return rtc::Optional<uint32_t>(bitrate_estimate_ * 1000);
130 } 168 }
131 169
132 DelayBasedBwe::DelayBasedBwe(Clock* clock) 170 DelayBasedBwe::DelayBasedBwe(Clock* clock)
133 : clock_(clock), 171 : clock_(clock),
134 inter_arrival_(), 172 inter_arrival_(),
135 estimator_(), 173 kalman_estimator_(),
174 trendline_estimator_(),
136 detector_(OverUseDetectorOptions()), 175 detector_(OverUseDetectorOptions()),
137 receiver_incoming_bitrate_(), 176 receiver_incoming_bitrate_(),
138 last_update_ms_(-1), 177 last_update_ms_(-1),
139 last_seen_packet_ms_(-1), 178 last_seen_packet_ms_(-1),
140 uma_recorded_(false) { 179 uma_recorded_(false),
180 trendline_window_size_(kDefaultTrendlineWindowSize),
181 trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff),
182 trendline_threshold_gain_(kDefaultTrendlineThresholdGain),
183 in_trendline_experiment_(TrendlineFilterExperimentIsEnabled()) {
184 if (in_trendline_experiment_) {
185 ReadTrendlineFilterExperimentParameters(&trendline_window_size_,
186 &trendline_smoothing_coeff_,
187 &trendline_threshold_gain_);
188 }
141 network_thread_.DetachFromThread(); 189 network_thread_.DetachFromThread();
142 } 190 }
143 191
144 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( 192 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector(
145 const std::vector<PacketInfo>& packet_feedback_vector) { 193 const std::vector<PacketInfo>& packet_feedback_vector) {
146 RTC_DCHECK(network_thread_.CalledOnValidThread()); 194 RTC_DCHECK(network_thread_.CalledOnValidThread());
147 if (!uma_recorded_) { 195 if (!uma_recorded_) {
148 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, 196 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
149 BweNames::kSendSideTransportSeqNum, 197 BweNames::kSendSideTransportSeqNum,
150 BweNames::kBweNamesMax); 198 BweNames::kBweNamesMax);
(...skipping 13 matching lines...) Expand all
164 int64_t now_ms = clock_->TimeInMilliseconds(); 212 int64_t now_ms = clock_->TimeInMilliseconds();
165 213
166 receiver_incoming_bitrate_.Update(info.arrival_time_ms, info.payload_size); 214 receiver_incoming_bitrate_.Update(info.arrival_time_ms, info.payload_size);
167 Result result; 215 Result result;
168 // Reset if the stream has timed out. 216 // Reset if the stream has timed out.
169 if (last_seen_packet_ms_ == -1 || 217 if (last_seen_packet_ms_ == -1 ||
170 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { 218 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) {
171 inter_arrival_.reset( 219 inter_arrival_.reset(
172 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, 220 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
173 kTimestampToMs, true)); 221 kTimestampToMs, true));
174 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); 222 kalman_estimator_.reset(new OveruseEstimator(OverUseDetectorOptions()));
223 trendline_estimator_.reset(new TrendlineEstimator(
224 trendline_window_size_, trendline_smoothing_coeff_,
225 trendline_threshold_gain_));
175 } 226 }
176 last_seen_packet_ms_ = now_ms; 227 last_seen_packet_ms_ = now_ms;
177 228
178 uint32_t send_time_24bits = 229 uint32_t send_time_24bits =
179 static_cast<uint32_t>( 230 static_cast<uint32_t>(
180 ((static_cast<uint64_t>(info.send_time_ms) << kAbsSendTimeFraction) + 231 ((static_cast<uint64_t>(info.send_time_ms) << kAbsSendTimeFraction) +
181 500) / 232 500) /
182 1000) & 233 1000) &
183 0x00FFFFFF; 234 0x00FFFFFF;
184 // Shift up send time to use the full 32 bits that inter_arrival works with, 235 // Shift up send time to use the full 32 bits that inter_arrival works with,
185 // so wrapping works properly. 236 // so wrapping works properly.
186 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; 237 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
187 238
188 uint32_t ts_delta = 0; 239 uint32_t ts_delta = 0;
189 int64_t t_delta = 0; 240 int64_t t_delta = 0;
190 int size_delta = 0; 241 int size_delta = 0;
191 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms, 242 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms,
192 info.payload_size, &ts_delta, &t_delta, 243 info.payload_size, &ts_delta, &t_delta,
193 &size_delta)) { 244 &size_delta)) {
194 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); 245 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
195 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State(), 246 if (in_trendline_experiment_) {
247 trendline_estimator_->Update(t_delta, ts_delta_ms, info.arrival_time_ms);
248 detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms,
249 trendline_estimator_->num_of_deltas(),
196 info.arrival_time_ms); 250 info.arrival_time_ms);
197 detector_.Detect(estimator_->offset(), ts_delta_ms, 251
198 estimator_->num_of_deltas(), info.arrival_time_ms); 252 } else {
253 kalman_estimator_->Update(t_delta, ts_delta_ms, size_delta,
254 detector_.State(), info.arrival_time_ms);
255 detector_.Detect(kalman_estimator_->offset(), ts_delta_ms,
256 kalman_estimator_->num_of_deltas(),
257 info.arrival_time_ms);
258 }
199 } 259 }
200 260
201 int probing_bps = 0; 261 int probing_bps = 0;
202 if (info.probe_cluster_id != PacketInfo::kNotAProbe) { 262 if (info.probe_cluster_id != PacketInfo::kNotAProbe) {
203 probing_bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info); 263 probing_bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info);
204 } 264 }
205 rtc::Optional<uint32_t> acked_bitrate_bps = 265 rtc::Optional<uint32_t> acked_bitrate_bps =
206 receiver_incoming_bitrate_.bitrate_bps(); 266 receiver_incoming_bitrate_.bitrate_bps();
207 // Currently overusing the bandwidth. 267 // Currently overusing the bandwidth.
208 if (detector_.State() == kBwOverusing) { 268 if (detector_.State() == kBwOverusing) {
(...skipping 21 matching lines...) Expand all
230 if (result.updated) 290 if (result.updated)
231 last_update_ms_ = now_ms; 291 last_update_ms_ = now_ms;
232 292
233 return result; 293 return result;
234 } 294 }
235 295
236 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, 296 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms,
237 int64_t now_ms, 297 int64_t now_ms,
238 rtc::Optional<uint32_t> acked_bitrate_bps, 298 rtc::Optional<uint32_t> acked_bitrate_bps,
239 uint32_t* target_bitrate_bps) { 299 uint32_t* target_bitrate_bps) {
240 const RateControlInput input(detector_.State(), acked_bitrate_bps, 300 // TODO(terelius): RateControlInput::noise_var is deprecated and will be
241 estimator_->var_noise()); 301 // removed. In the meantime, we set it to zero.
302 const RateControlInput input(detector_.State(), acked_bitrate_bps, 0);
242 rate_control_.Update(&input, now_ms); 303 rate_control_.Update(&input, now_ms);
243 *target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms); 304 *target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms);
244 return rate_control_.ValidEstimate(); 305 return rate_control_.ValidEstimate();
245 } 306 }
246 307
247 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { 308 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
248 rate_control_.SetRtt(avg_rtt_ms); 309 rate_control_.SetRtt(avg_rtt_ms);
249 } 310 }
250 311
251 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, 312 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
(...skipping 11 matching lines...) Expand all
263 *bitrate_bps = rate_control_.LatestEstimate(); 324 *bitrate_bps = rate_control_.LatestEstimate();
264 return true; 325 return true;
265 } 326 }
266 327
267 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { 328 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
268 // Called from both the configuration thread and the network thread. Shouldn't 329 // Called from both the configuration thread and the network thread. Shouldn't
269 // be called from the network thread in the future. 330 // be called from the network thread in the future.
270 rate_control_.SetMinBitrate(min_bitrate_bps); 331 rate_control_.SetMinBitrate(min_bitrate_bps);
271 } 332 }
272 } // namespace webrtc 333 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698