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> | 13 #include <math.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
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/system_wrappers/include/critical_section_wrapper.h" | |
25 #include "webrtc/system_wrappers/include/metrics.h" | 24 #include "webrtc/system_wrappers/include/metrics.h" |
26 #include "webrtc/typedefs.h" | 25 #include "webrtc/typedefs.h" |
27 | 26 |
28 namespace { | 27 namespace { |
29 constexpr int kTimestampGroupLengthMs = 5; | 28 constexpr int kTimestampGroupLengthMs = 5; |
30 constexpr int kAbsSendTimeFraction = 18; | 29 constexpr int kAbsSendTimeFraction = 18; |
31 constexpr int kAbsSendTimeInterArrivalUpshift = 8; | 30 constexpr int kAbsSendTimeInterArrivalUpshift = 8; |
32 constexpr int kInterArrivalShift = | 31 constexpr int kInterArrivalShift = |
33 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; | 32 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift; |
34 constexpr double kTimestampToMs = | 33 constexpr double kTimestampToMs = |
35 1000.0 / static_cast<double>(1 << kInterArrivalShift); | 34 1000.0 / static_cast<double>(1 << kInterArrivalShift); |
36 // 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 |
37 // after the API has been changed. | 36 // after the API has been changed. |
38 constexpr uint32_t kFixedSsrc = 0; | 37 constexpr uint32_t kFixedSsrc = 0; |
39 } // namespace | 38 } // namespace |
40 | 39 |
41 namespace webrtc { | 40 namespace webrtc { |
42 | 41 |
43 DelayBasedBwe::DelayBasedBwe(RemoteBitrateObserver* observer, Clock* clock) | 42 DelayBasedBwe::DelayBasedBwe(Clock* clock) |
44 : clock_(clock), | 43 : clock_(clock), |
45 observer_(observer), | |
46 inter_arrival_(), | 44 inter_arrival_(), |
47 estimator_(), | 45 estimator_(), |
48 detector_(OverUseDetectorOptions()), | 46 detector_(OverUseDetectorOptions()), |
49 incoming_bitrate_(kBitrateWindowMs, 8000), | 47 incoming_bitrate_(kBitrateWindowMs, 8000), |
50 last_update_ms_(-1), | 48 last_update_ms_(-1), |
51 last_seen_packet_ms_(-1), | 49 last_seen_packet_ms_(-1), |
52 uma_recorded_(false) { | 50 uma_recorded_(false) { |
53 RTC_DCHECK(observer_); | |
54 network_thread_.DetachFromThread(); | 51 network_thread_.DetachFromThread(); |
55 } | 52 } |
56 | 53 |
57 void DelayBasedBwe::IncomingPacketFeedbackVector( | 54 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( |
58 const std::vector<PacketInfo>& packet_feedback_vector) { | 55 const std::vector<PacketInfo>& packet_feedback_vector) { |
59 RTC_DCHECK(network_thread_.CalledOnValidThread()); | 56 RTC_DCHECK(network_thread_.CalledOnValidThread()); |
60 if (!uma_recorded_) { | 57 if (!uma_recorded_) { |
61 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, | 58 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, |
62 BweNames::kSendSideTransportSeqNum, | 59 BweNames::kSendSideTransportSeqNum, |
63 BweNames::kBweNamesMax); | 60 BweNames::kBweNamesMax); |
64 uma_recorded_ = true; | 61 uma_recorded_ = true; |
65 } | 62 } |
| 63 Result aggregated_result; |
66 for (const auto& packet_info : packet_feedback_vector) { | 64 for (const auto& packet_info : packet_feedback_vector) { |
67 IncomingPacketInfo(packet_info); | 65 Result result = IncomingPacketInfo(packet_info); |
| 66 if (result.updated) |
| 67 aggregated_result = result; |
68 } | 68 } |
| 69 return aggregated_result; |
69 } | 70 } |
70 | 71 |
71 void DelayBasedBwe::IncomingPacketInfo(const PacketInfo& info) { | 72 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo( |
| 73 const PacketInfo& info) { |
72 int64_t now_ms = clock_->TimeInMilliseconds(); | 74 int64_t now_ms = clock_->TimeInMilliseconds(); |
73 | 75 |
74 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms); | 76 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms); |
75 bool delay_based_bwe_changed = false; | 77 Result result; |
76 uint32_t target_bitrate_bps = 0; | 78 // Reset if the stream has timed out. |
77 { | 79 if (last_seen_packet_ms_ == -1 || |
78 rtc::CritScope lock(&crit_); | 80 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { |
| 81 inter_arrival_.reset( |
| 82 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000, |
| 83 kTimestampToMs, true)); |
| 84 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); |
| 85 } |
| 86 last_seen_packet_ms_ = now_ms; |
79 | 87 |
80 // Reset if the stream has timed out. | 88 uint32_t send_time_24bits = |
81 if (last_seen_packet_ms_ == -1 || | 89 static_cast<uint32_t>( |
82 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { | 90 ((static_cast<uint64_t>(info.send_time_ms) << kAbsSendTimeFraction) + |
83 inter_arrival_.reset(new InterArrival( | 91 500) / |
84 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000, | 92 1000) & |
85 kTimestampToMs, true)); | 93 0x00FFFFFF; |
86 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions())); | 94 // Shift up send time to use the full 32 bits that inter_arrival works with, |
87 } | 95 // so wrapping works properly. |
88 last_seen_packet_ms_ = now_ms; | 96 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; |
89 | 97 |
90 uint32_t send_time_24bits = | 98 uint32_t ts_delta = 0; |
91 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms) | 99 int64_t t_delta = 0; |
92 << kAbsSendTimeFraction) + | 100 int size_delta = 0; |
93 500) / | 101 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms, |
94 1000) & | 102 info.payload_size, &ts_delta, &t_delta, |
95 0x00FFFFFF; | 103 &size_delta)) { |
96 // Shift up send time to use the full 32 bits that inter_arrival works with, | 104 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); |
97 // so wrapping works properly. | 105 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State(), |
98 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift; | 106 info.arrival_time_ms); |
99 | 107 detector_.Detect(estimator_->offset(), ts_delta_ms, |
100 uint32_t ts_delta = 0; | 108 estimator_->num_of_deltas(), info.arrival_time_ms); |
101 int64_t t_delta = 0; | |
102 int size_delta = 0; | |
103 if (inter_arrival_->ComputeDeltas(timestamp, info.arrival_time_ms, now_ms, | |
104 info.payload_size, &ts_delta, &t_delta, | |
105 &size_delta)) { | |
106 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift); | |
107 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State(), | |
108 info.arrival_time_ms); | |
109 detector_.Detect(estimator_->offset(), ts_delta_ms, | |
110 estimator_->num_of_deltas(), info.arrival_time_ms); | |
111 } | |
112 | |
113 int probing_bps = 0; | |
114 if (info.probe_cluster_id != PacketInfo::kNotAProbe) { | |
115 probing_bps = | |
116 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info); | |
117 } | |
118 | |
119 // Currently overusing the bandwidth. | |
120 if (detector_.State() == kBwOverusing) { | |
121 rtc::Optional<uint32_t> incoming_rate = | |
122 incoming_bitrate_.Rate(info.arrival_time_ms); | |
123 if (incoming_rate && | |
124 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) { | |
125 delay_based_bwe_changed = | |
126 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps); | |
127 } | |
128 } else if (probing_bps > 0) { | |
129 // No overuse, but probing measured a bitrate. | |
130 remote_rate_.SetEstimate(probing_bps, info.arrival_time_ms); | |
131 observer_->OnProbeBitrate(probing_bps); | |
132 delay_based_bwe_changed = | |
133 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps); | |
134 } | |
135 if (!delay_based_bwe_changed && | |
136 (last_update_ms_ == -1 || | |
137 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval())) { | |
138 delay_based_bwe_changed = | |
139 UpdateEstimate(info.arrival_time_ms, now_ms, &target_bitrate_bps); | |
140 } | |
141 } | 109 } |
142 | 110 |
143 if (delay_based_bwe_changed) { | 111 int probing_bps = 0; |
| 112 if (info.probe_cluster_id != PacketInfo::kNotAProbe) { |
| 113 probing_bps = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info); |
| 114 } |
| 115 |
| 116 // Currently overusing the bandwidth. |
| 117 if (detector_.State() == kBwOverusing) { |
| 118 rtc::Optional<uint32_t> incoming_rate = |
| 119 incoming_bitrate_.Rate(info.arrival_time_ms); |
| 120 if (incoming_rate && |
| 121 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) { |
| 122 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, |
| 123 &result.target_bitrate_bps); |
| 124 } |
| 125 } else if (probing_bps > 0) { |
| 126 // No overuse, but probing measured a bitrate. |
| 127 remote_rate_.SetEstimate(probing_bps, info.arrival_time_ms); |
| 128 result.probe = true; |
| 129 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, |
| 130 &result.target_bitrate_bps); |
| 131 } |
| 132 rtc::Optional<uint32_t> incoming_rate = |
| 133 incoming_bitrate_.Rate(info.arrival_time_ms); |
| 134 if (!result.updated && |
| 135 (last_update_ms_ == -1 || |
| 136 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval())) { |
| 137 result.updated = UpdateEstimate(info.arrival_time_ms, now_ms, |
| 138 &result.target_bitrate_bps); |
| 139 } |
| 140 if (result.updated) |
144 last_update_ms_ = now_ms; | 141 last_update_ms_ = now_ms; |
145 observer_->OnReceiveBitrateChanged({kFixedSsrc}, target_bitrate_bps); | 142 |
146 } | 143 return result; |
147 } | 144 } |
148 | 145 |
149 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, | 146 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, |
150 int64_t now_ms, | 147 int64_t now_ms, |
151 uint32_t* target_bitrate_bps) { | 148 uint32_t* target_bitrate_bps) { |
152 // The first overuse should immediately trigger a new estimate. | 149 // The first overuse should immediately trigger a new estimate. |
153 // We also have to update the estimate immediately if we are overusing | 150 // We also have to update the estimate immediately if we are overusing |
154 // and the target bitrate is too high compared to what we are receiving. | 151 // and the target bitrate is too high compared to what we are receiving. |
155 const RateControlInput input(detector_.State(), | 152 const RateControlInput input(detector_.State(), |
156 incoming_bitrate_.Rate(arrival_time_ms), | 153 incoming_bitrate_.Rate(arrival_time_ms), |
157 estimator_->var_noise()); | 154 estimator_->var_noise()); |
158 remote_rate_.Update(&input, now_ms); | 155 remote_rate_.Update(&input, now_ms); |
159 *target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms); | 156 *target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms); |
160 return remote_rate_.ValidEstimate(); | 157 return remote_rate_.ValidEstimate(); |
161 } | 158 } |
162 | 159 |
163 void DelayBasedBwe::Process() {} | |
164 | |
165 int64_t DelayBasedBwe::TimeUntilNextProcess() { | |
166 const int64_t kDisabledModuleTime = 1000; | |
167 return kDisabledModuleTime; | |
168 } | |
169 | |
170 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 160 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
171 rtc::CritScope lock(&crit_); | |
172 remote_rate_.SetRtt(avg_rtt_ms); | 161 remote_rate_.SetRtt(avg_rtt_ms); |
173 } | 162 } |
174 | 163 |
175 void DelayBasedBwe::RemoveStream(uint32_t ssrc) {} | |
176 | |
177 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, | 164 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, |
178 uint32_t* bitrate_bps) const { | 165 uint32_t* bitrate_bps) const { |
179 // Currently accessed from both the process thread (see | 166 // Currently accessed from both the process thread (see |
180 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see | 167 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see |
181 // Call::GetStats()). Should in the future only be accessed from a single | 168 // Call::GetStats()). Should in the future only be accessed from a single |
182 // thread. | 169 // thread. |
183 RTC_DCHECK(ssrcs); | 170 RTC_DCHECK(ssrcs); |
184 RTC_DCHECK(bitrate_bps); | 171 RTC_DCHECK(bitrate_bps); |
185 rtc::CritScope lock(&crit_); | |
186 if (!remote_rate_.ValidEstimate()) | 172 if (!remote_rate_.ValidEstimate()) |
187 return false; | 173 return false; |
188 | 174 |
189 *ssrcs = {kFixedSsrc}; | 175 *ssrcs = {kFixedSsrc}; |
190 *bitrate_bps = remote_rate_.LatestEstimate(); | 176 *bitrate_bps = remote_rate_.LatestEstimate(); |
191 return true; | 177 return true; |
192 } | 178 } |
193 | 179 |
194 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { | 180 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { |
195 // Called from both the configuration thread and the network thread. Shouldn't | 181 // Called from both the configuration thread and the network thread. Shouldn't |
196 // be called from the network thread in the future. | 182 // be called from the network thread in the future. |
197 rtc::CritScope lock(&crit_); | |
198 remote_rate_.SetMinBitrate(min_bitrate_bps); | 183 remote_rate_.SetMinBitrate(min_bitrate_bps); |
199 } | 184 } |
200 } // namespace webrtc | 185 } // namespace webrtc |
OLD | NEW |