• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &timestamp_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