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           &timestamp_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