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 "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h"
12
13 #include <utility>
14
15 #include "webrtc/base/constructormagic.h"
16 #include "webrtc/base/logging.h"
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/base/thread_annotations.h"
19 #include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
20 #include "webrtc/modules/remote_bitrate_estimator/inter_arrival.h"
21 #include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
22 #include "webrtc/modules/remote_bitrate_estimator/overuse_estimator.h"
23 #include "webrtc/system_wrappers/include/clock.h"
24 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
25 #include "webrtc/typedefs.h"
26
27 namespace webrtc {
28
29 enum { kTimestampGroupLengthMs = 5 };
30 static const double kTimestampToMs = 1.0 / 90.0;
31
32 struct RemoteBitrateEstimatorSingleStream::Detector {
Detectorwebrtc::RemoteBitrateEstimatorSingleStream::Detector33 explicit Detector(int64_t last_packet_time_ms,
34 const OverUseDetectorOptions& options,
35 bool enable_burst_grouping)
36 : last_packet_time_ms(last_packet_time_ms),
37 inter_arrival(90 * kTimestampGroupLengthMs,
38 kTimestampToMs,
39 enable_burst_grouping),
40 estimator(options),
41 detector(options) {}
42 int64_t last_packet_time_ms;
43 InterArrival inter_arrival;
44 OveruseEstimator estimator;
45 OveruseDetector detector;
46 };
47
RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver * observer,Clock * clock)48 RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
49 RemoteBitrateObserver* observer,
50 Clock* clock)
51 : clock_(clock),
52 incoming_bitrate_(kBitrateWindowMs, 8000),
53 remote_rate_(new AimdRateControl()),
54 observer_(observer),
55 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
56 last_process_time_(-1),
57 process_interval_ms_(kProcessIntervalMs) {
58 assert(observer_);
59 LOG(LS_INFO) << "RemoteBitrateEstimatorSingleStream: Instantiating.";
60 }
61
~RemoteBitrateEstimatorSingleStream()62 RemoteBitrateEstimatorSingleStream::~RemoteBitrateEstimatorSingleStream() {
63 while (!overuse_detectors_.empty()) {
64 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
65 delete it->second;
66 overuse_detectors_.erase(it);
67 }
68 }
69
IncomingPacket(int64_t arrival_time_ms,size_t payload_size,const RTPHeader & header,bool was_paced)70 void RemoteBitrateEstimatorSingleStream::IncomingPacket(int64_t arrival_time_ms,
71 size_t payload_size,
72 const RTPHeader& header,
73 bool was_paced) {
74 uint32_t ssrc = header.ssrc;
75 uint32_t rtp_timestamp = header.timestamp +
76 header.extension.transmissionTimeOffset;
77 int64_t now_ms = clock_->TimeInMilliseconds();
78 CriticalSectionScoped cs(crit_sect_.get());
79 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.find(ssrc);
80 if (it == overuse_detectors_.end()) {
81 // This is a new SSRC. Adding to map.
82 // TODO(holmer): If the channel changes SSRC the old SSRC will still be
83 // around in this map until the channel is deleted. This is OK since the
84 // callback will no longer be called for the old SSRC. This will be
85 // automatically cleaned up when we have one RemoteBitrateEstimator per REMB
86 // group.
87 std::pair<SsrcOveruseEstimatorMap::iterator, bool> insert_result =
88 overuse_detectors_.insert(std::make_pair(
89 ssrc, new Detector(now_ms, OverUseDetectorOptions(), true)));
90 it = insert_result.first;
91 }
92 Detector* estimator = it->second;
93 estimator->last_packet_time_ms = now_ms;
94 incoming_bitrate_.Update(payload_size, now_ms);
95 const BandwidthUsage prior_state = estimator->detector.State();
96 uint32_t timestamp_delta = 0;
97 int64_t time_delta = 0;
98 int size_delta = 0;
99 if (estimator->inter_arrival.ComputeDeltas(rtp_timestamp, arrival_time_ms,
100 payload_size, ×tamp_delta,
101 &time_delta, &size_delta)) {
102 double timestamp_delta_ms = timestamp_delta * kTimestampToMs;
103 estimator->estimator.Update(time_delta, timestamp_delta_ms, size_delta,
104 estimator->detector.State());
105 estimator->detector.Detect(estimator->estimator.offset(),
106 timestamp_delta_ms,
107 estimator->estimator.num_of_deltas(), now_ms);
108 }
109 if (estimator->detector.State() == kBwOverusing) {
110 uint32_t incoming_bitrate_bps = incoming_bitrate_.Rate(now_ms);
111 if (prior_state != kBwOverusing ||
112 remote_rate_->TimeToReduceFurther(now_ms, incoming_bitrate_bps)) {
113 // The first overuse should immediately trigger a new estimate.
114 // We also have to update the estimate immediately if we are overusing
115 // and the target bitrate is too high compared to what we are receiving.
116 UpdateEstimate(now_ms);
117 }
118 }
119 }
120
Process()121 int32_t RemoteBitrateEstimatorSingleStream::Process() {
122 if (TimeUntilNextProcess() > 0) {
123 return 0;
124 }
125 {
126 CriticalSectionScoped cs(crit_sect_.get());
127 UpdateEstimate(clock_->TimeInMilliseconds());
128 }
129 last_process_time_ = clock_->TimeInMilliseconds();
130 return 0;
131 }
132
TimeUntilNextProcess()133 int64_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
134 if (last_process_time_ < 0) {
135 return 0;
136 }
137 {
138 CriticalSectionScoped cs_(crit_sect_.get());
139 return last_process_time_ + process_interval_ms_ -
140 clock_->TimeInMilliseconds();
141 }
142 }
143
UpdateEstimate(int64_t now_ms)144 void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
145 BandwidthUsage bw_state = kBwNormal;
146 double sum_var_noise = 0.0;
147 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.begin();
148 while (it != overuse_detectors_.end()) {
149 const int64_t time_of_last_received_packet =
150 it->second->last_packet_time_ms;
151 if (time_of_last_received_packet >= 0 &&
152 now_ms - time_of_last_received_packet > kStreamTimeOutMs) {
153 // This over-use detector hasn't received packets for |kStreamTimeOutMs|
154 // milliseconds and is considered stale.
155 delete it->second;
156 overuse_detectors_.erase(it++);
157 } else {
158 sum_var_noise += it->second->estimator.var_noise();
159 // Make sure that we trigger an over-use if any of the over-use detectors
160 // is detecting over-use.
161 if (it->second->detector.State() > bw_state) {
162 bw_state = it->second->detector.State();
163 }
164 ++it;
165 }
166 }
167 // We can't update the estimate if we don't have any active streams.
168 if (overuse_detectors_.empty()) {
169 remote_rate_.reset(new AimdRateControl());
170 return;
171 }
172 double mean_noise_var = sum_var_noise /
173 static_cast<double>(overuse_detectors_.size());
174 const RateControlInput input(bw_state,
175 incoming_bitrate_.Rate(now_ms),
176 mean_noise_var);
177 remote_rate_->Update(&input, now_ms);
178 unsigned int target_bitrate = remote_rate_->UpdateBandwidthEstimate(now_ms);
179 if (remote_rate_->ValidEstimate()) {
180 process_interval_ms_ = remote_rate_->GetFeedbackInterval();
181 std::vector<unsigned int> ssrcs;
182 GetSsrcs(&ssrcs);
183 observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
184 }
185 }
186
OnRttUpdate(int64_t avg_rtt_ms,int64_t max_rtt_ms)187 void RemoteBitrateEstimatorSingleStream::OnRttUpdate(int64_t avg_rtt_ms,
188 int64_t max_rtt_ms) {
189 CriticalSectionScoped cs(crit_sect_.get());
190 remote_rate_->SetRtt(avg_rtt_ms);
191 }
192
RemoveStream(unsigned int ssrc)193 void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
194 CriticalSectionScoped cs(crit_sect_.get());
195 SsrcOveruseEstimatorMap::iterator it = overuse_detectors_.find(ssrc);
196 if (it != overuse_detectors_.end()) {
197 delete it->second;
198 overuse_detectors_.erase(it);
199 }
200 }
201
LatestEstimate(std::vector<unsigned int> * ssrcs,unsigned int * bitrate_bps) const202 bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
203 std::vector<unsigned int>* ssrcs,
204 unsigned int* bitrate_bps) const {
205 CriticalSectionScoped cs(crit_sect_.get());
206 assert(bitrate_bps);
207 if (!remote_rate_->ValidEstimate()) {
208 return false;
209 }
210 GetSsrcs(ssrcs);
211 if (ssrcs->empty())
212 *bitrate_bps = 0;
213 else
214 *bitrate_bps = remote_rate_->LatestEstimate();
215 return true;
216 }
217
GetStats(ReceiveBandwidthEstimatorStats * output) const218 bool RemoteBitrateEstimatorSingleStream::GetStats(
219 ReceiveBandwidthEstimatorStats* output) const {
220 // Not implemented.
221 return false;
222 }
223
GetSsrcs(std::vector<unsigned int> * ssrcs) const224 void RemoteBitrateEstimatorSingleStream::GetSsrcs(
225 std::vector<unsigned int>* ssrcs) const {
226 assert(ssrcs);
227 ssrcs->resize(overuse_detectors_.size());
228 int i = 0;
229 for (SsrcOveruseEstimatorMap::const_iterator it = overuse_detectors_.begin();
230 it != overuse_detectors_.end(); ++it, ++i) {
231 (*ssrcs)[i] = it->first;
232 }
233 }
234
SetMinBitrate(int min_bitrate_bps)235 void RemoteBitrateEstimatorSingleStream::SetMinBitrate(int min_bitrate_bps) {
236 CriticalSectionScoped cs(crit_sect_.get());
237 remote_rate_->SetMinBitrate(min_bitrate_bps);
238 }
239
240 } // namespace webrtc
241