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