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 <math.h> | |
14 | |
15 #include <algorithm> | 13 #include <algorithm> |
| 14 #include <cmath> |
16 | 15 |
17 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
18 #include "webrtc/base/constructormagic.h" | 17 #include "webrtc/base/constructormagic.h" |
19 #include "webrtc/base/logging.h" | 18 #include "webrtc/base/logging.h" |
20 #include "webrtc/base/thread_annotations.h" | 19 #include "webrtc/base/thread_annotations.h" |
21 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" | 20 #include "webrtc/modules/congestion_controller/include/congestion_controller.h" |
22 #include "webrtc/modules/pacing/paced_sender.h" | 21 #include "webrtc/modules/pacing/paced_sender.h" |
23 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat
or.h" | 22 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimat
or.h" |
24 #include "webrtc/system_wrappers/include/metrics.h" | 23 #include "webrtc/system_wrappers/include/metrics.h" |
25 #include "webrtc/typedefs.h" | 24 #include "webrtc/typedefs.h" |
26 | 25 |
27 namespace { | 26 namespace { |
28 constexpr int kTimestampGroupLengthMs = 5; | 27 constexpr int kTimestampGroupLengthMs = 5; |
29 constexpr int kAbsSendTimeFraction = 18; | 28 constexpr int kAbsSendTimeFraction = 18; |
30 constexpr int kAbsSendTimeInterArrivalUpshift = 8; | 29 constexpr int kAbsSendTimeInterArrivalUpshift = 8; |
31 constexpr int kInterArrivalShift = | 30 constexpr int kInterArrivalShift = |
32 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; | 31 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; |
33 constexpr double kTimestampToMs = | 32 constexpr double kTimestampToMs = |
34 1000.0 / static_cast<double>(1 << kInterArrivalShift); | 33 1000.0 / static_cast<double>(1 << kInterArrivalShift); |
35 // This ssrc is used to fulfill the current API but will be removed | 34 // This ssrc is used to fulfill the current API but will be removed |
36 // after the API has been changed. | 35 // after the API has been changed. |
37 constexpr uint32_t kFixedSsrc = 0; | 36 constexpr uint32_t kFixedSsrc = 0; |
| 37 constexpr int kRateWindowMs = 150; |
| 38 |
38 } // namespace | 39 } // namespace |
39 | 40 |
40 namespace webrtc { | 41 namespace webrtc { |
| 42 DelayBasedBwe::BitrateEstimator::BitrateEstimator() |
| 43 : sum_(0), |
| 44 count_(0), |
| 45 current_win_ms_(0), |
| 46 prev_time_ms_(-1), |
| 47 bitrate_estimate_(300.0f), |
| 48 bitrate_estimate_var_(4e6) {} |
| 49 |
| 50 void DelayBasedBwe::BitrateEstimator::Update(int64_t now_ms, int bytes) { |
| 51 std::pair<float, int> bitrate_sample = UpdateWindow(now_ms, bytes); |
| 52 if (bitrate_sample.first < 0.0f) |
| 53 return; |
| 54 // Define the sample uncertainty as a function of how far away it is from the |
| 55 // current estimate, and how many payloads it is based on. |
| 56 float sample_uncertainty = |
| 57 std::max(std::max(5 * (5 - bitrate_sample.second), 1) * |
| 58 std::abs(bitrate_estimate_ - bitrate_sample.first), |
| 59 1.0f); |
| 60 float sample_var = sample_uncertainty * sample_uncertainty; |
| 61 // Update a bayesian estimate of the rate, weighting it lower if the sample |
| 62 // uncertainty is large. |
| 63 // The bitrate estimate uncertainty is increased with each update to model |
| 64 // that the bitrate changes over time. |
| 65 float pred_bitrate_estimate_var = bitrate_estimate_var_ + 20000.0f; |
| 66 bitrate_estimate_ = (sample_var * bitrate_estimate_ + |
| 67 pred_bitrate_estimate_var * bitrate_sample.first) / |
| 68 (sample_var + pred_bitrate_estimate_var); |
| 69 bitrate_estimate_var_ = sample_var * pred_bitrate_estimate_var / |
| 70 (sample_var + pred_bitrate_estimate_var); |
| 71 } |
| 72 |
| 73 std::pair<float, int> DelayBasedBwe::BitrateEstimator::UpdateWindow( |
| 74 int64_t now_ms, |
| 75 int bytes) { |
| 76 // Reset if time moves backwards. |
| 77 if (now_ms < prev_time_ms_) { |
| 78 prev_time_ms_ = -1; |
| 79 sum_ = 0; |
| 80 count_ = 0; |
| 81 current_win_ms_ = 0; |
| 82 } |
| 83 if (prev_time_ms_ >= 0) { |
| 84 current_win_ms_ += now_ms - prev_time_ms_; |
| 85 // Reset if nothing has been received for more than a full window. |
| 86 if (now_ms - prev_time_ms_ > kRateWindowMs) { |
| 87 sum_ = 0; |
| 88 count_ = 0; |
| 89 current_win_ms_ %= kRateWindowMs; |
| 90 } |
| 91 } |
| 92 prev_time_ms_ = now_ms; |
| 93 std::pair<float, int> bitrate_sample(-1.0f, count_); |
| 94 if (current_win_ms_ >= kRateWindowMs) { |
| 95 bitrate_sample.first = 8.0f * sum_ / static_cast<float>(kRateWindowMs); |
| 96 current_win_ms_ -= kRateWindowMs; |
| 97 sum_ = 0; |
| 98 count_ = 0; |
| 99 } |
| 100 sum_ += bytes; |
| 101 ++count_; |
| 102 return bitrate_sample; |
| 103 } |
| 104 |
| 105 int DelayBasedBwe::BitrateEstimator::bitrate_bps() const { |
| 106 return bitrate_estimate_ * 1000; |
| 107 } |
41 | 108 |
42 DelayBasedBwe::DelayBasedBwe(Clock* clock) | 109 DelayBasedBwe::DelayBasedBwe(Clock* clock) |
43 : clock_(clock), | 110 : clock_(clock), |
44 inter_arrival_(), | 111 inter_arrival_(), |
45 estimator_(), | 112 estimator_(), |
46 detector_(OverUseDetectorOptions()), | 113 detector_(OverUseDetectorOptions()), |
47 receiver_incoming_bitrate_(kBitrateWindowMs, 8000), | 114 receiver_incoming_bitrate_(), |
48 last_update_ms_(-1), | 115 last_update_ms_(-1), |
49 last_seen_packet_ms_(-1), | 116 last_seen_packet_ms_(-1), |
50 uma_recorded_(false) { | 117 uma_recorded_(false) { |
51 network_thread_.DetachFromThread(); | 118 network_thread_.DetachFromThread(); |
52 } | 119 } |
53 | 120 |
54 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( | 121 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( |
55 const std::vector<PacketInfo>& packet_feedback_vector) { | 122 const std::vector<PacketInfo>& packet_feedback_vector) { |
56 RTC_DCHECK(network_thread_.CalledOnValidThread()); | 123 RTC_DCHECK(network_thread_.CalledOnValidThread()); |
57 if (!uma_recorded_) { | 124 if (!uma_recorded_) { |
58 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, | 125 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, |
59 BweNames::kSendSideTransportSeqNum, | 126 BweNames::kSendSideTransportSeqNum, |
60 BweNames::kBweNamesMax); | 127 BweNames::kBweNamesMax); |
61 uma_recorded_ = true; | 128 uma_recorded_ = true; |
62 } | 129 } |
63 Result aggregated_result; | 130 Result aggregated_result; |
64 for (const auto& packet_info : packet_feedback_vector) { | 131 for (const auto& packet_info : packet_feedback_vector) { |
65 Result result = IncomingPacketInfo(packet_info); | 132 Result result = IncomingPacketInfo(packet_info); |
66 if (result.updated) | 133 if (result.updated) |
67 aggregated_result = result; | 134 aggregated_result = result; |
68 } | 135 } |
69 return aggregated_result; | 136 return aggregated_result; |
70 } | 137 } |
71 | 138 |
72 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo( | 139 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo( |
73 const PacketInfo& info) { | 140 const PacketInfo& info) { |
74 int64_t now_ms = clock_->TimeInMilliseconds(); | 141 int64_t now_ms = clock_->TimeInMilliseconds(); |
75 | 142 |
76 receiver_incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms); | 143 receiver_incoming_bitrate_.Update(info.arrival_time_ms, info.payload_size); |
77 Result result; | 144 Result result; |
78 // Reset if the stream has timed out. | 145 // Reset if the stream has timed out. |
79 if (last_seen_packet_ms_ == -1 || | 146 if (last_seen_packet_ms_ == -1 || |
80 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { | 147 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { |
81 inter_arrival_.reset( | 148 inter_arrival_.reset( |
82 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, | 149 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, |
83 kTimestampToMs, true)); | 150 kTimestampToMs, true)); |
84 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); | 151 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); |
85 } | 152 } |
86 last_seen_packet_ms_ = now_ms; | 153 last_seen_packet_ms_ = now_ms; |
(...skipping 19 matching lines...) Expand all Loading... |
106 info.arrival_time_ms); | 173 info.arrival_time_ms); |
107 detector_.Detect(estimator_->offset(), ts_delta_ms, | 174 detector_.Detect(estimator_->offset(), ts_delta_ms, |
108 estimator_->num_of_deltas(), info.arrival_time_ms); | 175 estimator_->num_of_deltas(), info.arrival_time_ms); |
109 } | 176 } |
110 | 177 |
111 int probing_bps = 0; | 178 int probing_bps = 0; |
112 if (info.probe_cluster_id != PacketInfo::kNotAProbe) { | 179 if (info.probe_cluster_id != PacketInfo::kNotAProbe) { |
113 probing_bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info); | 180 probing_bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info); |
114 } | 181 } |
115 | 182 |
| 183 int acked_bitrate_bps = receiver_incoming_bitrate_.bitrate_bps(); |
116 // Currently overusing the bandwidth. | 184 // Currently overusing the bandwidth. |
117 if (detector_.State() == kBwOverusing) { | 185 if (detector_.State() == kBwOverusing) { |
118 rtc::Optional<uint32_t> incoming_rate = | 186 if (rate_control_.TimeToReduceFurther(now_ms, acked_bitrate_bps)) { |
119 receiver_incoming_bitrate_.Rate(info.arrival_time_ms); | 187 result.updated = |
120 if (incoming_rate && | 188 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
121 rate_control_.TimeToReduceFurther(now_ms, *incoming_rate)) { | 189 &result.target_bitrate_bps); |
122 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, | |
123 &result.target_bitrate_bps); | |
124 } | 190 } |
125 } else if (probing_bps > 0) { | 191 } else if (probing_bps > 0) { |
126 // No overuse, but probing measured a bitrate. | 192 // No overuse, but probing measured a bitrate. |
127 rate_control_.SetEstimate(probing_bps, info.arrival_time_ms); | 193 rate_control_.SetEstimate(probing_bps, info.arrival_time_ms); |
128 result.probe = true; | 194 result.probe = true; |
129 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, | 195 result.updated = |
130 &result.target_bitrate_bps); | 196 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
| 197 &result.target_bitrate_bps); |
131 } | 198 } |
132 if (!result.updated && | 199 if (!result.updated && |
133 (last_update_ms_ == -1 || | 200 (last_update_ms_ == -1 || |
134 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { | 201 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { |
135 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, | 202 result.updated = |
136 &result.target_bitrate_bps); | 203 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
| 204 &result.target_bitrate_bps); |
137 } | 205 } |
138 if (result.updated) | 206 if (result.updated) |
139 last_update_ms_ = now_ms; | 207 last_update_ms_ = now_ms; |
140 | 208 |
141 return result; | 209 return result; |
142 } | 210 } |
143 | 211 |
144 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, | 212 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, |
145 int64_t now_ms, | 213 int64_t now_ms, |
| 214 int acked_bitrate_bps, |
146 uint32_t* target_bitrate_bps) { | 215 uint32_t* target_bitrate_bps) { |
147 // The first overuse should immediately trigger a new estimate. | 216 if (acked_bitrate_bps <= 0) |
148 // We also have to update the estimate immediately if we are overusing | 217 return false; |
149 // and the target bitrate is too high compared to what we are receiving. | |
150 const RateControlInput input(detector_.State(), | 218 const RateControlInput input(detector_.State(), |
151 receiver_incoming_bitrate_.Rate(arrival_time_ms), | 219 rtc::Optional<uint32_t>(acked_bitrate_bps), |
152 estimator_->var_noise()); | 220 estimator_->var_noise()); |
153 rate_control_.Update(&input, now_ms); | 221 rate_control_.Update(&input, now_ms); |
154 *target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms); | 222 *target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms); |
155 return rate_control_.ValidEstimate(); | 223 return rate_control_.ValidEstimate(); |
156 } | 224 } |
157 | 225 |
158 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 226 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
159 rate_control_.SetRtt(avg_rtt_ms); | 227 rate_control_.SetRtt(avg_rtt_ms); |
160 } | 228 } |
161 | 229 |
(...skipping 12 matching lines...) Expand all Loading... |
174 *bitrate_bps = rate_control_.LatestEstimate(); | 242 *bitrate_bps = rate_control_.LatestEstimate(); |
175 return true; | 243 return true; |
176 } | 244 } |
177 | 245 |
178 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { | 246 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { |
179 // Called from both the configuration thread and the network thread. Shouldn't | 247 // Called from both the configuration thread and the network thread. Shouldn't |
180 // be called from the network thread in the future. | 248 // be called from the network thread in the future. |
181 rate_control_.SetMinBitrate(min_bitrate_bps); | 249 rate_control_.SetMinBitrate(min_bitrate_bps); |
182 } | 250 } |
183 } // namespace webrtc | 251 } // namespace webrtc |
OLD | NEW |