1 /*
2 * Copyright (c) 2012 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 "modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
12
13 #include <assert.h>
14
15 #include <cstdint>
16 #include <utility>
17
18 #include "absl/types/optional.h"
19 #include "modules/remote_bitrate_estimator/aimd_rate_control.h"
20 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
21 #include "modules/remote_bitrate_estimator/inter_arrival.h"
22 #include "modules/remote_bitrate_estimator/overuse_detector.h"
23 #include "modules/remote_bitrate_estimator/overuse_estimator.h"
24 #include "rtc_base/checks.h"
25 #include "rtc_base/logging.h"
26 #include "system_wrappers/include/clock.h"
27 #include "system_wrappers/include/metrics.h"
28
29 namespace webrtc {
30 namespace {
OptionalRateFromOptionalBps(absl::optional<int> bitrate_bps)31 absl::optional<DataRate> OptionalRateFromOptionalBps(
32 absl::optional<int> bitrate_bps) {
33 if (bitrate_bps) {
34 return DataRate::BitsPerSec(*bitrate_bps);
35 } else {
36 return absl::nullopt;
37 }
38 }
39 } // namespace
40
41 enum { kTimestampGroupLengthMs = 5 };
42 static const double kTimestampToMs = 1.0 / 90.0;
43
44 struct RemoteBitrateEstimatorSingleStream::Detector {
Detectorwebrtc::RemoteBitrateEstimatorSingleStream::Detector45 explicit Detector(int64_t last_packet_time_ms,
46 const OverUseDetectorOptions& options,
47 bool enable_burst_grouping,
48 const WebRtcKeyValueConfig* key_value_config)
49 : last_packet_time_ms(last_packet_time_ms),
50 inter_arrival(90 * kTimestampGroupLengthMs,
51 kTimestampToMs,
52 enable_burst_grouping),
53 estimator(options),
54 detector(key_value_config) {}
55 int64_t last_packet_time_ms;
56 InterArrival inter_arrival;
57 OveruseEstimator estimator;
58 OveruseDetector detector;
59 };
60
RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver * observer,Clock * clock)61 RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
62 RemoteBitrateObserver* observer,
63 Clock* clock)
64 : clock_(clock),
65 incoming_bitrate_(kBitrateWindowMs, 8000),
66 last_valid_incoming_bitrate_(0),
67 remote_rate_(new AimdRateControl(&field_trials_)),
68 observer_(observer),
69 last_process_time_(-1),
70 process_interval_ms_(kProcessIntervalMs),
71 uma_recorded_(false) {
72 RTC_LOG(LS_INFO) << "RemoteBitrateEstimatorSingleStream: Instantiating.";
73 }
74
~RemoteBitrateEstimatorSingleStream()75 RemoteBitrateEstimatorSingleStream::~RemoteBitrateEstimatorSingleStream() {
76 while (!overuse_detectors_.empty()) {
77 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
78 delete it->second;
79 overuse_detectors_.erase(it);
80 }
81 }
82
IncomingPacket(int64_t arrival_time_ms,size_t payload_size,const RTPHeader & header)83 void RemoteBitrateEstimatorSingleStream::IncomingPacket(
84 int64_t arrival_time_ms,
85 size_t payload_size,
86 const RTPHeader& header) {
87 if (!uma_recorded_) {
88 BweNames type = BweNames::kReceiverTOffset;
89 if (!header.extension.hasTransmissionTimeOffset)
90 type = BweNames::kReceiverNoExtension;
91 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, type, BweNames::kBweNamesMax);
92 uma_recorded_ = true;
93 }
94 uint32_t ssrc = header.ssrc;
95 uint32_t rtp_timestamp =
96 header.timestamp + header.extension.transmissionTimeOffset;
97 int64_t now_ms = clock_->TimeInMilliseconds();
98 MutexLock lock(&mutex_);
99 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.find(ssrc);
100 if (it == overuse_detectors_.end()) {
101 // This is a new SSRC. Adding to map.
102 // TODO(holmer): If the channel changes SSRC the old SSRC will still be
103 // around in this map until the channel is deleted. This is OK since the
104 // callback will no longer be called for the old SSRC. This will be
105 // automatically cleaned up when we have one RemoteBitrateEstimator per REMB
106 // group.
107 std::pair<SsrcOveruseEstimatorMap::iterator, bool> insert_result =
108 overuse_detectors_.insert(
109 std::make_pair(ssrc, new Detector(now_ms, OverUseDetectorOptions(),
110 true, &field_trials_)));
111 it = insert_result.first;
112 }
113 Detector* estimator = it->second;
114 estimator->last_packet_time_ms = now_ms;
115
116 // Check if incoming bitrate estimate is valid, and if it needs to be reset.
117 absl::optional<uint32_t> incoming_bitrate = incoming_bitrate_.Rate(now_ms);
118 if (incoming_bitrate) {
119 last_valid_incoming_bitrate_ = *incoming_bitrate;
120 } else if (last_valid_incoming_bitrate_ > 0) {
121 // Incoming bitrate had a previous valid value, but now not enough data
122 // point are left within the current window. Reset incoming bitrate
123 // estimator so that the window size will only contain new data points.
124 incoming_bitrate_.Reset();
125 last_valid_incoming_bitrate_ = 0;
126 }
127 incoming_bitrate_.Update(payload_size, now_ms);
128
129 const BandwidthUsage prior_state = estimator->detector.State();
130 uint32_t timestamp_delta = 0;
131 int64_t time_delta = 0;
132 int size_delta = 0;
133 if (estimator->inter_arrival.ComputeDeltas(
134 rtp_timestamp, arrival_time_ms, now_ms, payload_size,
135 ×tamp_delta, &time_delta, &size_delta)) {
136 double timestamp_delta_ms = timestamp_delta * kTimestampToMs;
137 estimator->estimator.Update(time_delta, timestamp_delta_ms, size_delta,
138 estimator->detector.State(), now_ms);
139 estimator->detector.Detect(estimator->estimator.offset(),
140 timestamp_delta_ms,
141 estimator->estimator.num_of_deltas(), now_ms);
142 }
143 if (estimator->detector.State() == BandwidthUsage::kBwOverusing) {
144 absl::optional<uint32_t> incoming_bitrate_bps =
145 incoming_bitrate_.Rate(now_ms);
146 if (incoming_bitrate_bps &&
147 (prior_state != BandwidthUsage::kBwOverusing ||
148 GetRemoteRate()->TimeToReduceFurther(
149 Timestamp::Millis(now_ms),
150 DataRate::BitsPerSec(*incoming_bitrate_bps)))) {
151 // The first overuse should immediately trigger a new estimate.
152 // We also have to update the estimate immediately if we are overusing
153 // and the target bitrate is too high compared to what we are receiving.
154 UpdateEstimate(now_ms);
155 }
156 }
157 }
158
Process()159 void RemoteBitrateEstimatorSingleStream::Process() {
160 {
161 MutexLock lock(&mutex_);
162 UpdateEstimate(clock_->TimeInMilliseconds());
163 }
164 last_process_time_ = clock_->TimeInMilliseconds();
165 }
166
TimeUntilNextProcess()167 int64_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
168 if (last_process_time_ < 0) {
169 return 0;
170 }
171 MutexLock lock_(&mutex_);
172 RTC_DCHECK_GT(process_interval_ms_, 0);
173 return last_process_time_ + process_interval_ms_ -
174 clock_->TimeInMilliseconds();
175 }
176
UpdateEstimate(int64_t now_ms)177 void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
178 BandwidthUsage bw_state = BandwidthUsage::kBwNormal;
179 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
180 while (it != overuse_detectors_.end()) {
181 const int64_t time_of_last_received_packet =
182 it->second->last_packet_time_ms;
183 if (time_of_last_received_packet >= 0 &&
184 now_ms - time_of_last_received_packet > kStreamTimeOutMs) {
185 // This over-use detector hasn't received packets for |kStreamTimeOutMs|
186 // milliseconds and is considered stale.
187 delete it->second;
188 overuse_detectors_.erase(it++);
189 } else {
190 // Make sure that we trigger an over-use if any of the over-use detectors
191 // is detecting over-use.
192 if (it->second->detector.State() > bw_state) {
193 bw_state = it->second->detector.State();
194 }
195 ++it;
196 }
197 }
198 // We can't update the estimate if we don't have any active streams.
199 if (overuse_detectors_.empty()) {
200 return;
201 }
202 AimdRateControl* remote_rate = GetRemoteRate();
203
204 const RateControlInput input(
205 bw_state, OptionalRateFromOptionalBps(incoming_bitrate_.Rate(now_ms)));
206 uint32_t target_bitrate =
207 remote_rate->Update(&input, Timestamp::Millis(now_ms)).bps<uint32_t>();
208 if (remote_rate->ValidEstimate()) {
209 process_interval_ms_ = remote_rate->GetFeedbackInterval().ms();
210 RTC_DCHECK_GT(process_interval_ms_, 0);
211 std::vector<uint32_t> ssrcs;
212 GetSsrcs(&ssrcs);
213 if (observer_)
214 observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
215 }
216 }
217
OnRttUpdate(int64_t avg_rtt_ms,int64_t max_rtt_ms)218 void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t avg_rtt_ms,
219 int64_t max_rtt_ms) {
220 MutexLock lock(&mutex_);
221 GetRemoteRate()->SetRtt(TimeDelta::Millis(avg_rtt_ms));
222 }
223
RemoveStream(unsigned int ssrc)224 void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
225 MutexLock lock(&mutex_);
226 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.find(ssrc);
227 if (it != overuse_detectors_.end()) {
228 delete it->second;
229 overuse_detectors_.erase(it);
230 }
231 }
232
LatestEstimate(std::vector<uint32_t> * ssrcs,uint32_t * bitrate_bps) const233 bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
234 std::vector<uint32_t>* ssrcs,
235 uint32_t* bitrate_bps) const {
236 MutexLock lock(&mutex_);
237 assert(bitrate_bps);
238 if (!remote_rate_->ValidEstimate()) {
239 return false;
240 }
241 GetSsrcs(ssrcs);
242 if (ssrcs->empty())
243 *bitrate_bps = 0;
244 else
245 *bitrate_bps = remote_rate_->LatestEstimate().bps<uint32_t>();
246 return true;
247 }
248
GetSsrcs(std::vector<uint32_t> * ssrcs) const249 void RemoteBitrateEstimatorSingleStream::GetSsrcs(
250 std::vector<uint32_t>* ssrcs) const {
251 assert(ssrcs);
252 ssrcs->resize(overuse_detectors_.size());
253 int i = 0;
254 for (SsrcOveruseEstimatorMap::const_iterator it = overuse_detectors_.begin();
255 it != overuse_detectors_.end(); ++it, ++i) {
256 (*ssrcs)[i] = it->first;
257 }
258 }
259
GetRemoteRate()260 AimdRateControl* RemoteBitrateEstimatorSingleStream::GetRemoteRate() {
261 if (!remote_rate_)
262 remote_rate_.reset(new AimdRateControl(&field_trials_));
263 return remote_rate_.get();
264 }
265
SetMinBitrate(int min_bitrate_bps)266 void RemoteBitrateEstimatorSingleStream::SetMinBitrate(int min_bitrate_bps) {
267 MutexLock lock(&mutex_);
268 remote_rate_->SetMinBitrate(DataRate::BitsPerSec(min_bitrate_bps));
269 }
270
271 } // namespace webrtc
272