blob: 3a9537ee3e6275b382ee27a786b04db72ac4f3a9 [file] [log] [blame]
philipel863a8262016-06-17 09:21:34 -07001/*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/modules/congestion_controller/delay_based_bwe.h"
12
13#include <math.h>
14
15#include <algorithm>
16
17#include "webrtc/base/checks.h"
18#include "webrtc/base/constructormagic.h"
19#include "webrtc/base/logging.h"
20#include "webrtc/base/thread_annotations.h"
21#include "webrtc/modules/pacing/paced_sender.h"
22#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
23#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
24#include "webrtc/typedefs.h"
25
26namespace {
27enum {
28 kTimestampGroupLengthMs = 5,
29 kAbsSendTimeFraction = 18,
30 kAbsSendTimeInterArrivalUpshift = 8,
31 kInterArrivalShift = kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift,
32 kInitialProbingIntervalMs = 2000,
33 kMinClusterSize = 4,
34 kMaxProbePackets = 15,
35 kExpectedNumberOfProbes = 3
36};
37
38static const double kTimestampToMs =
39 1000.0 / static_cast<double>(1 << kInterArrivalShift);
40
41template <typename K, typename V>
42std::vector<K> Keys(const std::map<K, V>& map) {
43 std::vector<K> keys;
44 keys.reserve(map.size());
45 for (typename std::map<K, V>::const_iterator it = map.begin();
46 it != map.end(); ++it) {
47 keys.push_back(it->first);
48 }
49 return keys;
50}
51
52uint32_t ConvertMsTo24Bits(int64_t time_ms) {
53 uint32_t time_24_bits =
54 static_cast<uint32_t>(
55 ((static_cast<uint64_t>(time_ms) << kAbsSendTimeFraction) + 500) /
56 1000) &
57 0x00FFFFFF;
58 return time_24_bits;
59}
60} // namespace
61
62namespace webrtc {
63
64void DelayBasedBwe::AddCluster(std::list<Cluster>* clusters, Cluster* cluster) {
65 cluster->send_mean_ms /= static_cast<float>(cluster->count);
66 cluster->recv_mean_ms /= static_cast<float>(cluster->count);
67 cluster->mean_size /= cluster->count;
68 clusters->push_back(*cluster);
69}
70
71DelayBasedBwe::DelayBasedBwe(RemoteBitrateObserver* observer)
72 : observer_(observer),
73 inter_arrival_(),
74 estimator_(),
75 detector_(OverUseDetectorOptions()),
76 incoming_bitrate_(kBitrateWindowMs, 8000),
77 total_probes_received_(0),
78 first_packet_time_ms_(-1),
79 last_update_ms_(-1),
80 ssrcs_() {
81 RTC_DCHECK(observer_);
82 // NOTE! The BitrateEstimatorTest relies on this EXACT log line.
83 LOG(LS_INFO) << "RemoteBitrateEstimatorAbsSendTime: Instantiating.";
84 network_thread_.DetachFromThread();
85}
86
87void DelayBasedBwe::ComputeClusters(std::list<Cluster>* clusters) const {
88 Cluster current;
89 int64_t prev_send_time = -1;
90 int64_t prev_recv_time = -1;
91 int last_probe_cluster_id = -1;
92 for (std::list<Probe>::const_iterator it = probes_.begin();
93 it != probes_.end(); ++it) {
94 if (last_probe_cluster_id == -1)
95 last_probe_cluster_id = it->cluster_id;
96 if (prev_send_time >= 0) {
97 int send_delta_ms = it->send_time_ms - prev_send_time;
98 int recv_delta_ms = it->recv_time_ms - prev_recv_time;
99 if (send_delta_ms >= 1 && recv_delta_ms >= 1) {
100 ++current.num_above_min_delta;
101 }
102 if (it->cluster_id != last_probe_cluster_id) {
103 if (current.count >= kMinClusterSize)
104 AddCluster(clusters, &current);
105 current = Cluster();
106 }
107 current.send_mean_ms += send_delta_ms;
108 current.recv_mean_ms += recv_delta_ms;
109 current.mean_size += it->payload_size;
110 ++current.count;
111 last_probe_cluster_id = it->cluster_id;
112 }
113 prev_send_time = it->send_time_ms;
114 prev_recv_time = it->recv_time_ms;
115 }
116 if (current.count >= kMinClusterSize)
117 AddCluster(clusters, &current);
118}
119
120std::list<DelayBasedBwe::Cluster>::const_iterator DelayBasedBwe::FindBestProbe(
121 const std::list<Cluster>& clusters) const {
122 int highest_probe_bitrate_bps = 0;
123 std::list<Cluster>::const_iterator best_it = clusters.end();
124 for (std::list<Cluster>::const_iterator it = clusters.begin();
125 it != clusters.end(); ++it) {
126 if (it->send_mean_ms == 0 || it->recv_mean_ms == 0)
127 continue;
128 int send_bitrate_bps = it->mean_size * 8 * 1000 / it->send_mean_ms;
129 int recv_bitrate_bps = it->mean_size * 8 * 1000 / it->recv_mean_ms;
130 if (it->num_above_min_delta > it->count / 2 &&
131 (it->recv_mean_ms - it->send_mean_ms <= 2.0f &&
132 it->send_mean_ms - it->recv_mean_ms <= 5.0f)) {
133 int probe_bitrate_bps =
134 std::min(it->GetSendBitrateBps(), it->GetRecvBitrateBps());
135 if (probe_bitrate_bps > highest_probe_bitrate_bps) {
136 highest_probe_bitrate_bps = probe_bitrate_bps;
137 best_it = it;
138 }
139 } else {
140 LOG(LS_INFO) << "Probe failed, sent at " << send_bitrate_bps
141 << " bps, received at " << recv_bitrate_bps
142 << " bps. Mean send delta: " << it->send_mean_ms
143 << " ms, mean recv delta: " << it->recv_mean_ms
144 << " ms, num probes: " << it->count;
145 break;
146 }
147 }
148 return best_it;
149}
150
151DelayBasedBwe::ProbeResult DelayBasedBwe::ProcessClusters(int64_t now_ms) {
152 std::list<Cluster> clusters;
153 ComputeClusters(&clusters);
154 if (clusters.empty()) {
155 // If we reach the max number of probe packets and still have no clusters,
156 // we will remove the oldest one.
157 if (probes_.size() >= kMaxProbePackets)
158 probes_.pop_front();
159 return ProbeResult::kNoUpdate;
160 }
161
162 std::list<Cluster>::const_iterator best_it = FindBestProbe(clusters);
163 if (best_it != clusters.end()) {
164 int probe_bitrate_bps =
165 std::min(best_it->GetSendBitrateBps(), best_it->GetRecvBitrateBps());
166 // Make sure that a probe sent on a lower bitrate than our estimate can't
167 // reduce the estimate.
168 if (IsBitrateImproving(probe_bitrate_bps)) {
169 LOG(LS_INFO) << "Probe successful, sent at "
170 << best_it->GetSendBitrateBps() << " bps, received at "
171 << best_it->GetRecvBitrateBps()
172 << " bps. Mean send delta: " << best_it->send_mean_ms
173 << " ms, mean recv delta: " << best_it->recv_mean_ms
174 << " ms, num probes: " << best_it->count;
175 remote_rate_.SetEstimate(probe_bitrate_bps, now_ms);
176 return ProbeResult::kBitrateUpdated;
177 }
178 }
179
180 // Not probing and received non-probe packet, or finished with current set
181 // of probes.
182 if (clusters.size() >= kExpectedNumberOfProbes)
183 probes_.clear();
184 return ProbeResult::kNoUpdate;
185}
186
187bool DelayBasedBwe::IsBitrateImproving(int new_bitrate_bps) const {
188 bool initial_probe = !remote_rate_.ValidEstimate() && new_bitrate_bps > 0;
189 bool bitrate_above_estimate =
190 remote_rate_.ValidEstimate() &&
191 new_bitrate_bps > static_cast<int>(remote_rate_.LatestEstimate());
192 return initial_probe || bitrate_above_estimate;
193}
194
195void DelayBasedBwe::IncomingPacketFeedbackVector(
196 const std::vector<PacketInfo>& packet_feedback_vector) {
197 RTC_DCHECK(network_thread_.CalledOnValidThread());
198 for (const auto& packet_info : packet_feedback_vector) {
199 IncomingPacketInfo(packet_info.arrival_time_ms,
200 ConvertMsTo24Bits(packet_info.send_time_ms),
pbos2169d8b2016-06-20 11:53:02 -0700201 packet_info.payload_size, 0,
philipel863a8262016-06-17 09:21:34 -0700202 packet_info.probe_cluster_id);
203 }
204}
205
206void DelayBasedBwe::IncomingPacket(int64_t arrival_time_ms,
207 size_t payload_size,
pbos2169d8b2016-06-20 11:53:02 -0700208 const RTPHeader& header) {
philipel863a8262016-06-17 09:21:34 -0700209 RTC_DCHECK(network_thread_.CalledOnValidThread());
210 if (!header.extension.hasAbsoluteSendTime) {
211 // NOTE! The BitrateEstimatorTest relies on this EXACT log line.
212 LOG(LS_WARNING) << "RemoteBitrateEstimatorAbsSendTime: Incoming packet "
213 "is missing absolute send time extension!";
214 return;
215 }
216 IncomingPacketInfo(arrival_time_ms, header.extension.absoluteSendTime,
pbos2169d8b2016-06-20 11:53:02 -0700217 payload_size, header.ssrc, PacketInfo::kNotAProbe);
philipel863a8262016-06-17 09:21:34 -0700218}
219
220void DelayBasedBwe::IncomingPacket(int64_t arrival_time_ms,
221 size_t payload_size,
222 const RTPHeader& header,
philipel863a8262016-06-17 09:21:34 -0700223 int probe_cluster_id) {
224 RTC_DCHECK(network_thread_.CalledOnValidThread());
225 if (!header.extension.hasAbsoluteSendTime) {
226 // NOTE! The BitrateEstimatorTest relies on this EXACT log line.
227 LOG(LS_WARNING) << "RemoteBitrateEstimatorAbsSendTime: Incoming packet "
228 "is missing absolute send time extension!";
229 return;
230 }
231 IncomingPacketInfo(arrival_time_ms, header.extension.absoluteSendTime,
pbos2169d8b2016-06-20 11:53:02 -0700232 payload_size, header.ssrc, probe_cluster_id);
philipel863a8262016-06-17 09:21:34 -0700233}
234
235void DelayBasedBwe::IncomingPacketInfo(int64_t arrival_time_ms,
236 uint32_t send_time_24bits,
237 size_t payload_size,
238 uint32_t ssrc,
philipel863a8262016-06-17 09:21:34 -0700239 int probe_cluster_id) {
240 assert(send_time_24bits < (1ul << 24));
241 // Shift up send time to use the full 32 bits that inter_arrival works with,
242 // so wrapping works properly.
243 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
244 int64_t send_time_ms = static_cast<int64_t>(timestamp) * kTimestampToMs;
245
246 int64_t now_ms = arrival_time_ms;
247 // TODO(holmer): SSRCs are only needed for REMB, should be broken out from
248 // here.
249 incoming_bitrate_.Update(payload_size, now_ms);
250
251 if (first_packet_time_ms_ == -1)
252 first_packet_time_ms_ = arrival_time_ms;
253
254 uint32_t ts_delta = 0;
255 int64_t t_delta = 0;
256 int size_delta = 0;
257
258 bool update_estimate = false;
259 uint32_t target_bitrate_bps = 0;
260 std::vector<uint32_t> ssrcs;
261 {
262 rtc::CritScope lock(&crit_);
263
264 TimeoutStreams(now_ms);
265 RTC_DCHECK(inter_arrival_.get());
266 RTC_DCHECK(estimator_.get());
267 ssrcs_[ssrc] = now_ms;
268
269 // For now only try to detect probes while we don't have a valid estimate,
270 // and make sure the packet was paced. We currently assume that only packets
271 // larger than 200 bytes are paced by the sender.
272 if (probe_cluster_id != PacketInfo::kNotAProbe &&
273 payload_size > PacedSender::kMinProbePacketSize &&
274 (!remote_rate_.ValidEstimate() ||
275 now_ms - first_packet_time_ms_ < kInitialProbingIntervalMs)) {
276 // TODO(holmer): Use a map instead to get correct order?
277 if (total_probes_received_ < kMaxProbePackets) {
278 int send_delta_ms = -1;
279 int recv_delta_ms = -1;
280 if (!probes_.empty()) {
281 send_delta_ms = send_time_ms - probes_.back().send_time_ms;
282 recv_delta_ms = arrival_time_ms - probes_.back().recv_time_ms;
283 }
284 LOG(LS_INFO) << "Probe packet received: send time=" << send_time_ms
285 << " ms, recv time=" << arrival_time_ms
286 << " ms, send delta=" << send_delta_ms
287 << " ms, recv delta=" << recv_delta_ms << " ms.";
288 }
289 probes_.push_back(
290 Probe(send_time_ms, arrival_time_ms, payload_size, probe_cluster_id));
291 ++total_probes_received_;
292 // Make sure that a probe which updated the bitrate immediately has an
293 // effect by calling the OnReceiveBitrateChanged callback.
294 if (ProcessClusters(now_ms) == ProbeResult::kBitrateUpdated)
295 update_estimate = true;
296 }
297 if (inter_arrival_->ComputeDeltas(timestamp, arrival_time_ms, payload_size,
298 &ts_delta, &t_delta, &size_delta)) {
299 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
300 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State());
301 detector_.Detect(estimator_->offset(), ts_delta_ms,
302 estimator_->num_of_deltas(), arrival_time_ms);
303 }
304
305 if (!update_estimate) {
306 // Check if it's time for a periodic update or if we should update because
307 // of an over-use.
308 if (last_update_ms_ == -1 ||
309 now_ms - last_update_ms_ > remote_rate_.GetFeedbackInterval()) {
310 update_estimate = true;
311 } else if (detector_.State() == kBwOverusing) {
312 rtc::Optional<uint32_t> incoming_rate = incoming_bitrate_.Rate(now_ms);
313 if (incoming_rate &&
314 remote_rate_.TimeToReduceFurther(now_ms, *incoming_rate)) {
315 update_estimate = true;
316 }
317 }
318 }
319
320 if (update_estimate) {
321 // The first overuse should immediately trigger a new estimate.
322 // We also have to update the estimate immediately if we are overusing
323 // and the target bitrate is too high compared to what we are receiving.
324 const RateControlInput input(detector_.State(),
325 incoming_bitrate_.Rate(now_ms),
326 estimator_->var_noise());
327 remote_rate_.Update(&input, now_ms);
328 target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms);
329 update_estimate = remote_rate_.ValidEstimate();
330 ssrcs = Keys(ssrcs_);
331 }
332 }
333 if (update_estimate) {
334 last_update_ms_ = now_ms;
335 observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate_bps);
336 }
337}
338
339void DelayBasedBwe::Process() {}
340
341int64_t DelayBasedBwe::TimeUntilNextProcess() {
342 const int64_t kDisabledModuleTime = 1000;
343 return kDisabledModuleTime;
344}
345
346void DelayBasedBwe::TimeoutStreams(int64_t now_ms) {
347 for (Ssrcs::iterator it = ssrcs_.begin(); it != ssrcs_.end();) {
348 if ((now_ms - it->second) > kStreamTimeOutMs) {
349 ssrcs_.erase(it++);
350 } else {
351 ++it;
352 }
353 }
354 if (ssrcs_.empty()) {
355 // We can't update the estimate if we don't have any active streams.
356 inter_arrival_.reset(
357 new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
358 kTimestampToMs, true));
359 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions()));
360 // We deliberately don't reset the first_packet_time_ms_ here for now since
361 // we only probe for bandwidth in the beginning of a call right now.
362 }
363}
364
365void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
366 rtc::CritScope lock(&crit_);
367 remote_rate_.SetRtt(avg_rtt_ms);
368}
369
370void DelayBasedBwe::RemoveStream(uint32_t ssrc) {
371 rtc::CritScope lock(&crit_);
372 ssrcs_.erase(ssrc);
373}
374
375bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
376 uint32_t* bitrate_bps) const {
377 // Currently accessed from both the process thread (see
378 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see
379 // Call::GetStats()). Should in the future only be accessed from a single
380 // thread.
381 RTC_DCHECK(ssrcs);
382 RTC_DCHECK(bitrate_bps);
383 rtc::CritScope lock(&crit_);
384 if (!remote_rate_.ValidEstimate()) {
385 return false;
386 }
387 *ssrcs = Keys(ssrcs_);
388 if (ssrcs_.empty()) {
389 *bitrate_bps = 0;
390 } else {
391 *bitrate_bps = remote_rate_.LatestEstimate();
392 }
393 return true;
394}
395
396void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
397 // Called from both the configuration thread and the network thread. Shouldn't
398 // be called from the network thread in the future.
399 rtc::CritScope lock(&crit_);
400 remote_rate_.SetMinBitrate(min_bitrate_bps);
401}
402} // namespace webrtc