• 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 <map>
12 
13 #include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
14 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
15 #include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
16 #include "webrtc/modules/remote_bitrate_estimator/remote_rate_control.h"
17 #include "webrtc/system_wrappers/interface/clock.h"
18 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19 #include "webrtc/system_wrappers/interface/logging.h"
20 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
21 #include "webrtc/typedefs.h"
22 
23 namespace webrtc {
24 namespace {
25 class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
26  public:
27   RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
28                                      Clock* clock,
29                                      uint32_t min_bitrate_bps);
~RemoteBitrateEstimatorSingleStream()30   virtual ~RemoteBitrateEstimatorSingleStream() {}
31 
32   // Called for each incoming packet. If this is a new SSRC, a new
33   // BitrateControl will be created. Updates the incoming payload bitrate
34   // estimate and the over-use detector. If an over-use is detected the
35   // remote bitrate estimate will be updated. Note that |payload_size| is the
36   // packet size excluding headers.
37   virtual void IncomingPacket(int64_t arrival_time_ms,
38                               int payload_size,
39                               const RTPHeader& header) OVERRIDE;
40 
41   // Triggers a new estimate calculation.
42   // Implements the Module interface.
43   virtual int32_t Process() OVERRIDE;
44   virtual int32_t TimeUntilNextProcess() OVERRIDE;
45   // Set the current round-trip time experienced by the stream.
46   // Implements the StatsObserver interface.
47   virtual void OnRttUpdate(uint32_t rtt) OVERRIDE;
48 
49   // Removes all data for |ssrc|.
50   virtual void RemoveStream(unsigned int ssrc) OVERRIDE;
51 
52   // Returns true if a valid estimate exists and sets |bitrate_bps| to the
53   // estimated payload bitrate in bits per second. |ssrcs| is the list of ssrcs
54   // currently being received and of which the bitrate estimate is based upon.
55   virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs,
56                               unsigned int* bitrate_bps) const OVERRIDE;
57 
58   virtual bool GetStats(
59       ReceiveBandwidthEstimatorStats* output) const OVERRIDE;
60 
61  private:
62   // Map from SSRC to over-use detector and last incoming packet time in
63   // milliseconds, taken from clock_.
64   typedef std::map<unsigned int, std::pair<OveruseDetector, int64_t> >
65       SsrcOveruseDetectorMap;
66 
GetDetector(const SsrcOveruseDetectorMap::iterator it)67   static OveruseDetector* GetDetector(
68       const SsrcOveruseDetectorMap::iterator it) {
69     return &it->second.first;
70   }
71 
GetPacketTimeMs(const SsrcOveruseDetectorMap::iterator it)72   static int64_t GetPacketTimeMs(const SsrcOveruseDetectorMap::iterator it) {
73     return it->second.second;
74   }
75 
SetPacketTimeMs(SsrcOveruseDetectorMap::iterator it,int64_t time_ms)76   static void SetPacketTimeMs(SsrcOveruseDetectorMap::iterator it,
77                               int64_t time_ms) {
78     it->second.second = time_ms;
79   }
80 
81   // Triggers a new estimate calculation.
82   void UpdateEstimate(int64_t now_ms);
83 
84   void GetSsrcs(std::vector<unsigned int>* ssrcs) const;
85 
86   Clock* clock_;
87   SsrcOveruseDetectorMap overuse_detectors_;
88   RateStatistics incoming_bitrate_;
89   RemoteRateControl remote_rate_;
90   RemoteBitrateObserver* observer_;
91   scoped_ptr<CriticalSectionWrapper> crit_sect_;
92   int64_t last_process_time_;
93 };
94 
RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver * observer,Clock * clock,uint32_t min_bitrate_bps)95 RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
96     RemoteBitrateObserver* observer,
97     Clock* clock,
98     uint32_t min_bitrate_bps)
99     : clock_(clock),
100       incoming_bitrate_(500, 8000),
101       remote_rate_(min_bitrate_bps),
102       observer_(observer),
103       crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
104       last_process_time_(-1) {
105   assert(observer_);
106 }
107 
IncomingPacket(int64_t arrival_time_ms,int payload_size,const RTPHeader & header)108 void RemoteBitrateEstimatorSingleStream::IncomingPacket(
109     int64_t arrival_time_ms,
110     int payload_size,
111     const RTPHeader& header) {
112   uint32_t ssrc = header.ssrc;
113   uint32_t rtp_timestamp = header.timestamp +
114       header.extension.transmissionTimeOffset;
115   int64_t now_ms = clock_->TimeInMilliseconds();
116   CriticalSectionScoped cs(crit_sect_.get());
117   SsrcOveruseDetectorMap::iterator it = overuse_detectors_.find(ssrc);
118   if (it == overuse_detectors_.end()) {
119     // This is a new SSRC. Adding to map.
120     // TODO(holmer): If the channel changes SSRC the old SSRC will still be
121     // around in this map until the channel is deleted. This is OK since the
122     // callback will no longer be called for the old SSRC. This will be
123     // automatically cleaned up when we have one RemoteBitrateEstimator per REMB
124     // group.
125     std::pair<SsrcOveruseDetectorMap::iterator, bool> insert_result =
126         overuse_detectors_.insert(std::make_pair(ssrc,
127             std::make_pair(OveruseDetector(OverUseDetectorOptions()), now_ms)));
128     it = insert_result.first;
129   }
130   SetPacketTimeMs(it, now_ms);
131   OveruseDetector* overuse_detector = GetDetector(it);
132   incoming_bitrate_.Update(payload_size, now_ms);
133   const BandwidthUsage prior_state = overuse_detector->State();
134   overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time_ms);
135   if (overuse_detector->State() == kBwOverusing) {
136     unsigned int incoming_bitrate = incoming_bitrate_.Rate(now_ms);
137     if (prior_state != kBwOverusing ||
138         remote_rate_.TimeToReduceFurther(now_ms, incoming_bitrate)) {
139       // The first overuse should immediately trigger a new estimate.
140       // We also have to update the estimate immediately if we are overusing
141       // and the target bitrate is too high compared to what we are receiving.
142       UpdateEstimate(now_ms);
143     }
144   }
145 }
146 
Process()147 int32_t RemoteBitrateEstimatorSingleStream::Process() {
148   if (TimeUntilNextProcess() > 0) {
149     return 0;
150   }
151   int64_t now_ms = clock_->TimeInMilliseconds();
152   UpdateEstimate(now_ms);
153   last_process_time_ = now_ms;
154   return 0;
155 }
156 
TimeUntilNextProcess()157 int32_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
158   if (last_process_time_ < 0) {
159     return 0;
160   }
161   return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds();
162 }
163 
UpdateEstimate(int64_t now_ms)164 void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t now_ms) {
165   CriticalSectionScoped cs(crit_sect_.get());
166   BandwidthUsage bw_state = kBwNormal;
167   double sum_noise_var = 0.0;
168   SsrcOveruseDetectorMap::iterator it = overuse_detectors_.begin();
169   while (it != overuse_detectors_.end()) {
170     if (GetPacketTimeMs(it) >= 0 &&
171         now_ms - GetPacketTimeMs(it) > kStreamTimeOutMs) {
172       // This over-use detector hasn't received packets for |kStreamTimeOutMs|
173       // milliseconds and is considered stale.
174       overuse_detectors_.erase(it++);
175     } else {
176       OveruseDetector* overuse_detector = GetDetector(it);
177       sum_noise_var += overuse_detector->NoiseVar();
178       // Make sure that we trigger an over-use if any of the over-use detectors
179       // is detecting over-use.
180       if (overuse_detector->State() > bw_state) {
181         bw_state = overuse_detector->State();
182       }
183       ++it;
184     }
185   }
186   // We can't update the estimate if we don't have any active streams.
187   if (overuse_detectors_.empty()) {
188     remote_rate_.Reset();
189     return;
190   }
191   double mean_noise_var = sum_noise_var /
192       static_cast<double>(overuse_detectors_.size());
193   const RateControlInput input(bw_state,
194                                incoming_bitrate_.Rate(now_ms),
195                                mean_noise_var);
196   const RateControlRegion region = remote_rate_.Update(&input, now_ms);
197   unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(now_ms);
198   if (remote_rate_.ValidEstimate()) {
199     std::vector<unsigned int> ssrcs;
200     GetSsrcs(&ssrcs);
201     observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
202   }
203   for (it = overuse_detectors_.begin(); it != overuse_detectors_.end(); ++it) {
204     GetDetector(it)->SetRateControlRegion(region);
205   }
206 }
207 
OnRttUpdate(uint32_t rtt)208 void RemoteBitrateEstimatorSingleStream::OnRttUpdate(uint32_t rtt) {
209   CriticalSectionScoped cs(crit_sect_.get());
210   remote_rate_.SetRtt(rtt);
211 }
212 
RemoveStream(unsigned int ssrc)213 void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
214   CriticalSectionScoped cs(crit_sect_.get());
215   // Ignoring the return value which is the number of elements erased.
216   overuse_detectors_.erase(ssrc);
217 }
218 
LatestEstimate(std::vector<unsigned int> * ssrcs,unsigned int * bitrate_bps) const219 bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
220     std::vector<unsigned int>* ssrcs,
221     unsigned int* bitrate_bps) const {
222   CriticalSectionScoped cs(crit_sect_.get());
223   assert(bitrate_bps);
224   if (!remote_rate_.ValidEstimate()) {
225     return false;
226   }
227   GetSsrcs(ssrcs);
228   if (ssrcs->empty())
229     *bitrate_bps = 0;
230   else
231     *bitrate_bps = remote_rate_.LatestEstimate();
232   return true;
233 }
234 
GetStats(ReceiveBandwidthEstimatorStats * output) const235 bool RemoteBitrateEstimatorSingleStream::GetStats(
236     ReceiveBandwidthEstimatorStats* output) const {
237   // Not implemented.
238   return false;
239 }
240 
GetSsrcs(std::vector<unsigned int> * ssrcs) const241 void RemoteBitrateEstimatorSingleStream::GetSsrcs(
242     std::vector<unsigned int>* ssrcs) const {
243   assert(ssrcs);
244   ssrcs->resize(overuse_detectors_.size());
245   int i = 0;
246   for (SsrcOveruseDetectorMap::const_iterator it = overuse_detectors_.begin();
247       it != overuse_detectors_.end(); ++it, ++i) {
248     (*ssrcs)[i] = it->first;
249   }
250 }
251 }  // namespace
252 
Create(RemoteBitrateObserver * observer,Clock * clock,RateControlType control_type,uint32_t min_bitrate_bps) const253 RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create(
254     RemoteBitrateObserver* observer,
255     Clock* clock,
256     RateControlType control_type,
257     uint32_t min_bitrate_bps) const {
258   LOG(LS_INFO) << "RemoteBitrateEstimatorFactory: Instantiating.";
259   return new RemoteBitrateEstimatorSingleStream(observer, clock,
260                                                 min_bitrate_bps);
261 }
262 
Create(RemoteBitrateObserver * observer,Clock * clock,RateControlType control_type,uint32_t min_bitrate_bps) const263 RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create(
264     RemoteBitrateObserver* observer,
265     Clock* clock,
266     RateControlType control_type,
267     uint32_t min_bitrate_bps) const {
268   LOG(LS_INFO) << "AbsoluteSendTimeRemoteBitrateEstimatorFactory: "
269       "Instantiating.";
270   return new RemoteBitrateEstimatorSingleStream(observer, clock,
271                                                 min_bitrate_bps);
272 }
273 }  // namespace webrtc
274