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 17 matching lines...) Expand all Loading... | |
28 constexpr int kTimestampGroupLengthMs = 5; | 28 constexpr int kTimestampGroupLengthMs = 5; |
29 constexpr int kAbsSendTimeFraction = 18; | 29 constexpr int kAbsSendTimeFraction = 18; |
30 constexpr int kAbsSendTimeInterArrivalUpshift = 8; | 30 constexpr int kAbsSendTimeInterArrivalUpshift = 8; |
31 constexpr int kInterArrivalShift = | 31 constexpr int kInterArrivalShift = |
32 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; | 32 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; |
33 constexpr double kTimestampToMs = | 33 constexpr double kTimestampToMs = |
34 1000.0 / static_cast<double>(1 << kInterArrivalShift); | 34 1000.0 / static_cast<double>(1 << kInterArrivalShift); |
35 // This ssrc is used to fulfill the current API but will be removed | 35 // This ssrc is used to fulfill the current API but will be removed |
36 // after the API has been changed. | 36 // after the API has been changed. |
37 constexpr uint32_t kFixedSsrc = 0; | 37 constexpr uint32_t kFixedSsrc = 0; |
38 constexpr int kRateWindowMs = 150; | |
39 | |
38 } // namespace | 40 } // namespace |
39 | 41 |
40 namespace webrtc { | 42 namespace webrtc { |
43 DelayBasedBwe::BitrateEstimator::BitrateEstimator() | |
44 : sum_(0), | |
45 count_(0), | |
46 current_win_ms_(0), | |
47 prev_time_ms_(-1), | |
48 bitrate_estimate_(300.0f), | |
49 bitrate_estimate_std_(2000.0f) {} | |
50 | |
51 void DelayBasedBwe::BitrateEstimator::Update(int64_t now_ms, int bytes) { | |
52 std::pair<float, int> bitrate_sample = UpdateWindow(now_ms, bytes); | |
terelius
2016/10/25 12:51:19
Are we using the bitrate_sample.second anywhere?
stefan-webrtc
2016/10/26 11:23:17
Yes, line 57 :)
terelius
2016/10/26 13:05:02
Acknowledged.
| |
53 if (bitrate_sample.first <= 0.0f) | |
54 return; | |
55 // Define the sample uncertainty as a function of how far away it is from the | |
56 // current estimate, and how many payloads it is based on. | |
57 float sample_uncertainty = std::max(5 * (5 - bitrate_sample.second), 1) * | |
58 (bitrate_estimate_ - bitrate_sample.first); | |
59 float sample_var = std::max(sample_uncertainty * sample_uncertainty, 1.0f); | |
60 // Update a bayesian estimate of the rate, weighting it lower if the sample | |
61 // uncertainty is large. | |
62 // The bitrate estimate uncertainty is increased with each update to model | |
63 // the possibility that the bitrate can change over time. | |
64 float bitrate_estimate_std = bitrate_estimate_std_ + 60.0f; | |
65 float bitrate_estimate_var = bitrate_estimate_std * bitrate_estimate_std; | |
66 float denom = 1.0f / sample_var + 1.0f / bitrate_estimate_var; | |
67 bitrate_estimate_std_ = sqrt(1.0f / denom); | |
terelius
2016/10/25 11:42:14
Maybe we could skip the sqrt and the denom computa
stefan-webrtc
2016/10/26 11:23:17
Done.
| |
68 bitrate_estimate_ = (sample_var * bitrate_estimate_ + | |
69 bitrate_estimate_var * bitrate_sample.first) / | |
70 (sample_var + bitrate_estimate_var); | |
terelius
2016/10/25 11:42:13
I think this is supposed to be the old estimate va
terelius
2016/10/25 12:51:19
Nvm, it is based on the old variance.
| |
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 std::pair<float, int> bitrate_sample(-1.0f, count_); | |
86 if (current_win_ms_ >= kRateWindowMs) { | |
terelius
2016/10/25 12:51:19
If we receive packets at 1Mbps and then receive no
stefan-webrtc
2016/10/26 11:23:17
Yes, you are right. I guess the option would be to
terelius
2016/10/26 13:05:02
Maybe current_win_ms_ %= kRateWindowMs instead of
| |
87 bitrate_sample.first = 8.0f * sum_ / static_cast<float>(kRateWindowMs); | |
88 current_win_ms_ -= kRateWindowMs; | |
89 sum_ = 0; | |
90 count_ = 0; | |
91 } | |
92 sum_ += bytes; | |
93 ++count_; | |
94 prev_time_ms_ = now_ms; | |
95 return bitrate_sample; | |
96 } | |
97 | |
98 int DelayBasedBwe::BitrateEstimator::bitrate_bps() const { | |
99 return bitrate_estimate_ * 1000; | |
100 } | |
41 | 101 |
42 DelayBasedBwe::DelayBasedBwe(Clock* clock) | 102 DelayBasedBwe::DelayBasedBwe(Clock* clock) |
43 : clock_(clock), | 103 : clock_(clock), |
44 inter_arrival_(), | 104 inter_arrival_(), |
45 estimator_(), | 105 estimator_(), |
46 detector_(OverUseDetectorOptions()), | 106 detector_(OverUseDetectorOptions()), |
47 receiver_incoming_bitrate_(kBitrateWindowMs, 8000), | 107 receiver_incoming_bitrate_(), |
48 last_update_ms_(-1), | 108 last_update_ms_(-1), |
49 last_seen_packet_ms_(-1), | 109 last_seen_packet_ms_(-1), |
50 uma_recorded_(false) { | 110 uma_recorded_(false) { |
51 network_thread_.DetachFromThread(); | 111 network_thread_.DetachFromThread(); |
52 } | 112 } |
53 | 113 |
54 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( | 114 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( |
55 const std::vector<PacketInfo>& packet_feedback_vector) { | 115 const std::vector<PacketInfo>& packet_feedback_vector) { |
56 RTC_DCHECK(network_thread_.CalledOnValidThread()); | 116 RTC_DCHECK(network_thread_.CalledOnValidThread()); |
57 if (!uma_recorded_) { | 117 if (!uma_recorded_) { |
58 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, | 118 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, |
59 BweNames::kSendSideTransportSeqNum, | 119 BweNames::kSendSideTransportSeqNum, |
60 BweNames::kBweNamesMax); | 120 BweNames::kBweNamesMax); |
61 uma_recorded_ = true; | 121 uma_recorded_ = true; |
62 } | 122 } |
63 Result aggregated_result; | 123 Result aggregated_result; |
64 for (const auto& packet_info : packet_feedback_vector) { | 124 for (const auto& packet_info : packet_feedback_vector) { |
65 Result result = IncomingPacketInfo(packet_info); | 125 Result result = IncomingPacketInfo(packet_info); |
66 if (result.updated) | 126 if (result.updated) |
67 aggregated_result = result; | 127 aggregated_result = result; |
68 } | 128 } |
69 return aggregated_result; | 129 return aggregated_result; |
70 } | 130 } |
71 | 131 |
72 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo( | 132 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo( |
73 const PacketInfo& info) { | 133 const PacketInfo& info) { |
74 int64_t now_ms = clock_->TimeInMilliseconds(); | 134 int64_t now_ms = clock_->TimeInMilliseconds(); |
75 | 135 |
76 receiver_incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms); | 136 receiver_incoming_bitrate_.Update(info.arrival_time_ms, info.payload_size); |
77 Result result; | 137 Result result; |
78 // Reset if the stream has timed out. | 138 // Reset if the stream has timed out. |
79 if (last_seen_packet_ms_ == -1 || | 139 if (last_seen_packet_ms_ == -1 || |
80 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { | 140 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { |
81 inter_arrival_.reset( | 141 inter_arrival_.reset( |
82 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, | 142 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, |
83 kTimestampToMs, true)); | 143 kTimestampToMs, true)); |
84 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); | 144 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); |
85 } | 145 } |
86 last_seen_packet_ms_ = now_ms; | 146 last_seen_packet_ms_ = now_ms; |
(...skipping 19 matching lines...) Expand all Loading... | |
106 info.arrival_time_ms); | 166 info.arrival_time_ms); |
107 detector_.Detect(estimator_->offset(), ts_delta_ms, | 167 detector_.Detect(estimator_->offset(), ts_delta_ms, |
108 estimator_->num_of_deltas(), info.arrival_time_ms); | 168 estimator_->num_of_deltas(), info.arrival_time_ms); |
109 } | 169 } |
110 | 170 |
111 int probing_bps = 0; | 171 int probing_bps = 0; |
112 if (info.probe_cluster_id != PacketInfo::kNotAProbe) { | 172 if (info.probe_cluster_id != PacketInfo::kNotAProbe) { |
113 probing_bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info); | 173 probing_bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info); |
114 } | 174 } |
115 | 175 |
176 int acked_bitrate_bps = receiver_incoming_bitrate_.bitrate_bps(); | |
116 // Currently overusing the bandwidth. | 177 // Currently overusing the bandwidth. |
117 if (detector_.State() == kBwOverusing) { | 178 if (detector_.State() == kBwOverusing) { |
118 rtc::Optional<uint32_t> incoming_rate = | 179 if (rate_control_.TimeToReduceFurther(now_ms, acked_bitrate_bps)) { |
119 receiver_incoming_bitrate_.Rate(info.arrival_time_ms); | 180 result.updated = |
120 if (incoming_rate && | 181 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
121 rate_control_.TimeToReduceFurther(now_ms, *incoming_rate)) { | 182 &result.target_bitrate_bps); |
122 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, | |
123 &result.target_bitrate_bps); | |
124 } | 183 } |
125 } else if (probing_bps > 0) { | 184 } else if (probing_bps > 0) { |
126 // No overuse, but probing measured a bitrate. | 185 // No overuse, but probing measured a bitrate. |
127 rate_control_.SetEstimate(probing_bps, info.arrival_time_ms); | 186 rate_control_.SetEstimate(probing_bps, info.arrival_time_ms); |
128 result.probe = true; | 187 result.probe = true; |
129 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, | 188 result.updated = |
130 &result.target_bitrate_bps); | 189 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
190 &result.target_bitrate_bps); | |
131 } | 191 } |
132 rtc::Optional<uint32_t> incoming_rate = | |
133 receiver_incoming_bitrate_.Rate(info.arrival_time_ms); | |
134 if (!result.updated && | 192 if (!result.updated && |
135 (last_update_ms_ == -1 || | 193 (last_update_ms_ == -1 || |
136 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { | 194 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { |
137 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, | 195 result.updated = |
138 &result.target_bitrate_bps); | 196 UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps, |
197 &result.target_bitrate_bps); | |
139 } | 198 } |
140 if (result.updated) | 199 if (result.updated) |
141 last_update_ms_ = now_ms; | 200 last_update_ms_ = now_ms; |
142 | 201 |
143 return result; | 202 return result; |
144 } | 203 } |
145 | 204 |
146 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, | 205 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, |
147 int64_t now_ms, | 206 int64_t now_ms, |
207 int acked_bitrate_bps, | |
148 uint32_t* target_bitrate_bps) { | 208 uint32_t* target_bitrate_bps) { |
149 // The first overuse should immediately trigger a new estimate. | 209 if (acked_bitrate_bps <= 0) |
150 // We also have to update the estimate immediately if we are overusing | 210 return false; |
151 // and the target bitrate is too high compared to what we are receiving. | |
152 const RateControlInput input(detector_.State(), | 211 const RateControlInput input(detector_.State(), |
153 receiver_incoming_bitrate_.Rate(arrival_time_ms), | 212 rtc::Optional<uint32_t>(acked_bitrate_bps), |
154 estimator_->var_noise()); | 213 estimator_->var_noise()); |
155 rate_control_.Update(&input, now_ms); | 214 rate_control_.Update(&input, now_ms); |
156 *target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms); | 215 *target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms); |
157 return rate_control_.ValidEstimate(); | 216 return rate_control_.ValidEstimate(); |
158 } | 217 } |
159 | 218 |
160 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 219 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
161 rate_control_.SetRtt(avg_rtt_ms); | 220 rate_control_.SetRtt(avg_rtt_ms); |
162 } | 221 } |
163 | 222 |
(...skipping 12 matching lines...) Expand all Loading... | |
176 *bitrate_bps = rate_control_.LatestEstimate(); | 235 *bitrate_bps = rate_control_.LatestEstimate(); |
177 return true; | 236 return true; |
178 } | 237 } |
179 | 238 |
180 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { | 239 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { |
181 // Called from both the configuration thread and the network thread. Shouldn't | 240 // Called from both the configuration thread and the network thread. Shouldn't |
182 // be called from the network thread in the future. | 241 // be called from the network thread in the future. |
183 rate_control_.SetMinBitrate(min_bitrate_bps); | 242 rate_control_.SetMinBitrate(min_bitrate_bps); |
184 } | 243 } |
185 } // namespace webrtc | 244 } // namespace webrtc |
OLD | NEW |