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
23namespace webrtc {
24namespace {
25class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
26 public:
27  RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
28                                     Clock* clock,
29                                     uint32_t min_bitrate_bps);
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
67  static OveruseDetector* GetDetector(
68      const SsrcOveruseDetectorMap::iterator it) {
69    return &it->second.first;
70  }
71
72  static int64_t GetPacketTimeMs(const SsrcOveruseDetectorMap::iterator it) {
73    return it->second.second;
74  }
75
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
95RemoteBitrateEstimatorSingleStream::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
108void 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
147int32_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
157int32_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
158  if (last_process_time_ < 0) {
159    return 0;
160  }
161  return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds();
162}
163
164void 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
208void RemoteBitrateEstimatorSingleStream::OnRttUpdate(uint32_t rtt) {
209  CriticalSectionScoped cs(crit_sect_.get());
210  remote_rate_.SetRtt(rtt);
211}
212
213void 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
219bool 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
235bool RemoteBitrateEstimatorSingleStream::GetStats(
236    ReceiveBandwidthEstimatorStats* output) const {
237  // Not implemented.
238  return false;
239}
240
241void 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
253RemoteBitrateEstimator* 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
263RemoteBitrateEstimator* 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