2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
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"
25 class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
27 RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
29 uint32_t min_bitrate_bps);
30 virtual ~RemoteBitrateEstimatorSingleStream() {}
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,
39 const RTPHeader& header) OVERRIDE;
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;
49 // Removes all data for |ssrc|.
50 virtual void RemoveStream(unsigned int ssrc) OVERRIDE;
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;
58 virtual bool GetStats(
59 ReceiveBandwidthEstimatorStats* output) const OVERRIDE;
62 typedef std::map<unsigned int, OveruseDetector> SsrcOveruseDetectorMap;
64 // Triggers a new estimate calculation.
65 void UpdateEstimate(int64_t time_now);
67 void GetSsrcs(std::vector<unsigned int>* ssrcs) const;
70 SsrcOveruseDetectorMap overuse_detectors_;
71 RateStatistics incoming_bitrate_;
72 RemoteRateControl remote_rate_;
73 RemoteBitrateObserver* observer_;
74 scoped_ptr<CriticalSectionWrapper> crit_sect_;
75 int64_t last_process_time_;
78 RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
79 RemoteBitrateObserver* observer,
81 uint32_t min_bitrate_bps)
83 incoming_bitrate_(500, 8000),
84 remote_rate_(min_bitrate_bps),
86 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
87 last_process_time_(-1) {
91 void RemoteBitrateEstimatorSingleStream::IncomingPacket(
92 int64_t arrival_time_ms,
94 const RTPHeader& header) {
95 uint32_t ssrc = header.ssrc;
96 uint32_t rtp_timestamp = header.timestamp +
97 header.extension.transmissionTimeOffset;
98 CriticalSectionScoped cs(crit_sect_.get());
99 SsrcOveruseDetectorMap::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
107 std::pair<SsrcOveruseDetectorMap::iterator, bool> insert_result =
108 overuse_detectors_.insert(std::make_pair(ssrc, OveruseDetector(
109 OverUseDetectorOptions())));
110 it = insert_result.first;
112 OveruseDetector* overuse_detector = &it->second;
113 incoming_bitrate_.Update(payload_size, arrival_time_ms);
114 const BandwidthUsage prior_state = overuse_detector->State();
115 overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time_ms);
116 if (overuse_detector->State() == kBwOverusing) {
117 unsigned int incoming_bitrate = incoming_bitrate_.Rate(arrival_time_ms);
118 if (prior_state != kBwOverusing ||
119 remote_rate_.TimeToReduceFurther(arrival_time_ms, incoming_bitrate)) {
120 // The first overuse should immediately trigger a new estimate.
121 // We also have to update the estimate immediately if we are overusing
122 // and the target bitrate is too high compared to what we are receiving.
123 UpdateEstimate(arrival_time_ms);
128 int32_t RemoteBitrateEstimatorSingleStream::Process() {
129 if (TimeUntilNextProcess() > 0) {
132 UpdateEstimate(clock_->TimeInMilliseconds());
133 last_process_time_ = clock_->TimeInMilliseconds();
137 int32_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
138 if (last_process_time_ < 0) {
141 return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds();
144 void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t time_now) {
145 CriticalSectionScoped cs(crit_sect_.get());
146 BandwidthUsage bw_state = kBwNormal;
147 double sum_noise_var = 0.0;
148 SsrcOveruseDetectorMap::iterator it = overuse_detectors_.begin();
149 while (it != overuse_detectors_.end()) {
150 const int64_t time_of_last_received_packet =
151 it->second.time_of_last_received_packet();
152 if (time_of_last_received_packet >= 0 &&
153 time_now - time_of_last_received_packet > kStreamTimeOutMs) {
154 // This over-use detector hasn't received packets for |kStreamTimeOutMs|
155 // milliseconds and is considered stale.
156 overuse_detectors_.erase(it++);
158 sum_noise_var += it->second.NoiseVar();
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.State() > bw_state) {
162 bw_state = it->second.State();
167 // We can't update the estimate if we don't have any active streams.
168 if (overuse_detectors_.empty()) {
169 remote_rate_.Reset();
172 double mean_noise_var = sum_noise_var /
173 static_cast<double>(overuse_detectors_.size());
174 const RateControlInput input(bw_state,
175 incoming_bitrate_.Rate(time_now),
177 const RateControlRegion region = remote_rate_.Update(&input, time_now);
178 unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(time_now);
179 if (remote_rate_.ValidEstimate()) {
180 std::vector<unsigned int> ssrcs;
182 observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
184 for (it = overuse_detectors_.begin(); it != overuse_detectors_.end(); ++it) {
185 it->second.SetRateControlRegion(region);
189 void RemoteBitrateEstimatorSingleStream::OnRttUpdate(uint32_t rtt) {
190 CriticalSectionScoped cs(crit_sect_.get());
191 remote_rate_.SetRtt(rtt);
194 void RemoteBitrateEstimatorSingleStream::RemoveStream(unsigned int ssrc) {
195 CriticalSectionScoped cs(crit_sect_.get());
196 // Ignoring the return value which is the number of elements erased.
197 overuse_detectors_.erase(ssrc);
200 bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
201 std::vector<unsigned int>* ssrcs,
202 unsigned int* bitrate_bps) const {
203 CriticalSectionScoped cs(crit_sect_.get());
205 if (!remote_rate_.ValidEstimate()) {
212 *bitrate_bps = remote_rate_.LatestEstimate();
216 bool RemoteBitrateEstimatorSingleStream::GetStats(
217 ReceiveBandwidthEstimatorStats* output) const {
222 void RemoteBitrateEstimatorSingleStream::GetSsrcs(
223 std::vector<unsigned int>* ssrcs) const {
225 ssrcs->resize(overuse_detectors_.size());
227 for (SsrcOveruseDetectorMap::const_iterator it = overuse_detectors_.begin();
228 it != overuse_detectors_.end(); ++it, ++i) {
229 (*ssrcs)[i] = it->first;
234 RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create(
235 RemoteBitrateObserver* observer,
237 RateControlType control_type,
238 uint32_t min_bitrate_bps) const {
239 LOG(LS_INFO) << "RemoteBitrateEstimatorFactory: Instantiating.";
240 return new RemoteBitrateEstimatorSingleStream(observer, clock,
244 RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create(
245 RemoteBitrateObserver* observer,
247 RateControlType control_type,
248 uint32_t min_bitrate_bps) const {
249 LOG(LS_INFO) << "AbsoluteSendTimeRemoteBitrateEstimatorFactory: "
251 return new RemoteBitrateEstimatorSingleStream(observer, clock,
254 } // namespace webrtc