blob: 87dc502b28ff9d10c5c908a8eb0a21aabec8441c [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"
Irfan Sheriffb2540bb2016-09-12 12:28:54 -070021#include "webrtc/modules/congestion_controller/include/congestion_controller.h"
philipel863a8262016-06-17 09:21:34 -070022#include "webrtc/modules/pacing/paced_sender.h"
23#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
24#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
stefan64636dd2016-08-03 00:29:03 -070025#include "webrtc/system_wrappers/include/metrics.h"
philipel863a8262016-06-17 09:21:34 -070026#include "webrtc/typedefs.h"
27
28namespace {
philipel7522a282016-08-16 10:59:36 +020029constexpr int kTimestampGroupLengthMs = 5;
30constexpr int kAbsSendTimeFraction = 18;
31constexpr int kAbsSendTimeInterArrivalUpshift = 8;
32constexpr int kInterArrivalShift =
33 kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift;
34constexpr double kTimestampToMs =
philipel863a8262016-06-17 09:21:34 -070035 1000.0 / static_cast<double>(1 << kInterArrivalShift);
philipel7522a282016-08-16 10:59:36 +020036// This ssrc is used to fulfill the current API but will be removed
37// after the API has been changed.
38constexpr uint32_t kFixedSsrc = 0;
philipel863a8262016-06-17 09:21:34 -070039} // namespace
40
41namespace webrtc {
42
stefan5e12d362016-07-11 01:44:02 -070043DelayBasedBwe::DelayBasedBwe(RemoteBitrateObserver* observer, Clock* clock)
44 : clock_(clock),
45 observer_(observer),
philipel863a8262016-06-17 09:21:34 -070046 inter_arrival_(),
47 estimator_(),
48 detector_(OverUseDetectorOptions()),
49 incoming_bitrate_(kBitrateWindowMs, 8000),
philipel863a8262016-06-17 09:21:34 -070050 last_update_ms_(-1),
philipel7522a282016-08-16 10:59:36 +020051 last_seen_packet_ms_(-1),
stefan64636dd2016-08-03 00:29:03 -070052 uma_recorded_(false) {
philipel863a8262016-06-17 09:21:34 -070053 RTC_DCHECK(observer_);
philipel863a8262016-06-17 09:21:34 -070054 network_thread_.DetachFromThread();
55}
56
philipel863a8262016-06-17 09:21:34 -070057void DelayBasedBwe::IncomingPacketFeedbackVector(
58 const std::vector<PacketInfo>& packet_feedback_vector) {
59 RTC_DCHECK(network_thread_.CalledOnValidThread());
stefan64636dd2016-08-03 00:29:03 -070060 if (!uma_recorded_) {
asapersson1d02d3e2016-09-09 22:40:25 -070061 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
62 BweNames::kSendSideTransportSeqNum,
63 BweNames::kBweNamesMax);
stefan64636dd2016-08-03 00:29:03 -070064 uma_recorded_ = true;
65 }
philipel863a8262016-06-17 09:21:34 -070066 for (const auto& packet_info : packet_feedback_vector) {
philipel7522a282016-08-16 10:59:36 +020067 IncomingPacketInfo(packet_info);
philipel863a8262016-06-17 09:21:34 -070068 }
69}
70
philipel7522a282016-08-16 10:59:36 +020071void DelayBasedBwe::IncomingPacketInfo(const PacketInfo& info) {
stefan5e12d362016-07-11 01:44:02 -070072 int64_t now_ms = clock_->TimeInMilliseconds();
philipel863a8262016-06-17 09:21:34 -070073
philipel7522a282016-08-16 10:59:36 +020074 incoming_bitrate_.Update(info.payload_size, info.arrival_time_ms);
Irfan Sheriffb2540bb2016-09-12 12:28:54 -070075 bool delay_based_bwe_changed = false;
philipel863a8262016-06-17 09:21:34 -070076 uint32_t target_bitrate_bps = 0;
philipel863a8262016-06-17 09:21:34 -070077 {
78 rtc::CritScope lock(&crit_);
79
philipel7522a282016-08-16 10:59:36 +020080 // Reset if the stream has timed out.
81 if (last_seen_packet_ms_ == -1 ||
82 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) {
83 inter_arrival_.reset(new InterArrival(
84 (kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
85 kTimestampToMs, true));
86 estimator_.reset(new OveruseEstimator(OverUseDetectorOptions()));
philipel863a8262016-06-17 09:21:34 -070087 }
philipel7522a282016-08-16 10:59:36 +020088 last_seen_packet_ms_ = now_ms;
89
philipel7522a282016-08-16 10:59:36 +020090 uint32_t send_time_24bits =
91 static_cast<uint32_t>(((static_cast<uint64_t>(info.send_time_ms)
92 << kAbsSendTimeFraction) +
93 500) /
94 1000) &
95 0x00FFFFFF;
96 // Shift up send time to use the full 32 bits that inter_arrival works with,
97 // so wrapping works properly.
98 uint32_t timestamp = send_time_24bits << kAbsSendTimeInterArrivalUpshift;
99
100 uint32_t ts_delta = 0;
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,
stefan5e12d362016-07-11 01:44:02 -0700105 &size_delta)) {
philipel863a8262016-06-17 09:21:34 -0700106 double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
gaetano.carlucci52a57032016-09-14 05:04:36 -0700107 estimator_->Update(t_delta, ts_delta_ms, size_delta, detector_.State(),
108 info.arrival_time_ms);
philipel863a8262016-06-17 09:21:34 -0700109 detector_.Detect(estimator_->offset(), ts_delta_ms,
philipel7522a282016-08-16 10:59:36 +0200110 estimator_->num_of_deltas(), info.arrival_time_ms);
philipel863a8262016-06-17 09:21:34 -0700111 }
112
Irfan Sheriffb2540bb2016-09-12 12:28:54 -0700113 int probing_bps = 0;
114 if (info.probe_cluster_id != PacketInfo::kNotAProbe) {
115 probing_bps =
116 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(info);
philipel863a8262016-06-17 09:21:34 -0700117 }
118
Irfan Sheriffb2540bb2016-09-12 12:28:54 -0700119 // 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);
philipel863a8262016-06-17 09:21:34 -0700140 }
141 }
philipel7522a282016-08-16 10:59:36 +0200142
Irfan Sheriffb2540bb2016-09-12 12:28:54 -0700143 if (delay_based_bwe_changed) {
philipel863a8262016-06-17 09:21:34 -0700144 last_update_ms_ = now_ms;
philipel7522a282016-08-16 10:59:36 +0200145 observer_->OnReceiveBitrateChanged({kFixedSsrc}, target_bitrate_bps);
philipel863a8262016-06-17 09:21:34 -0700146 }
147}
148
Irfan Sheriffb2540bb2016-09-12 12:28:54 -0700149bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms,
150 int64_t now_ms,
151 uint32_t* target_bitrate_bps) {
152 // The first overuse should immediately trigger a new estimate.
153 // 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.
155 const RateControlInput input(detector_.State(),
156 incoming_bitrate_.Rate(arrival_time_ms),
157 estimator_->var_noise());
158 remote_rate_.Update(&input, now_ms);
159 *target_bitrate_bps = remote_rate_.UpdateBandwidthEstimate(now_ms);
160 return remote_rate_.ValidEstimate();
161}
162
philipel863a8262016-06-17 09:21:34 -0700163void DelayBasedBwe::Process() {}
164
165int64_t DelayBasedBwe::TimeUntilNextProcess() {
166 const int64_t kDisabledModuleTime = 1000;
167 return kDisabledModuleTime;
168}
169
philipel863a8262016-06-17 09:21:34 -0700170void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
171 rtc::CritScope lock(&crit_);
172 remote_rate_.SetRtt(avg_rtt_ms);
173}
174
philipel7522a282016-08-16 10:59:36 +0200175void DelayBasedBwe::RemoveStream(uint32_t ssrc) {}
philipel863a8262016-06-17 09:21:34 -0700176
177bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
178 uint32_t* bitrate_bps) const {
179 // Currently accessed from both the process thread (see
180 // ModuleRtpRtcpImpl::Process()) and the configuration thread (see
181 // Call::GetStats()). Should in the future only be accessed from a single
182 // thread.
183 RTC_DCHECK(ssrcs);
184 RTC_DCHECK(bitrate_bps);
185 rtc::CritScope lock(&crit_);
philipel7522a282016-08-16 10:59:36 +0200186 if (!remote_rate_.ValidEstimate())
philipel863a8262016-06-17 09:21:34 -0700187 return false;
philipel7522a282016-08-16 10:59:36 +0200188
189 *ssrcs = {kFixedSsrc};
190 *bitrate_bps = remote_rate_.LatestEstimate();
philipel863a8262016-06-17 09:21:34 -0700191 return true;
192}
193
194void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
195 // Called from both the configuration thread and the network thread. Shouldn't
196 // be called from the network thread in the future.
197 rtc::CritScope lock(&crit_);
198 remote_rate_.SetMinBitrate(min_bitrate_bps);
199}
200} // namespace webrtc