blob: b0f906487c94a29df0c8ae13e64050977c2aa799 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +00001/*
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
andresp@webrtc.org04253922013-05-14 12:10:58 +000011#include <map>
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000012
sprang@webrtc.org7374da32013-12-03 10:31:59 +000013#include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h"
andresp@webrtc.org04253922013-05-14 12:10:58 +000014#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"
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000017#include "webrtc/system_wrappers/interface/clock.h"
andresp@webrtc.org04253922013-05-14 12:10:58 +000018#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19#include "webrtc/system_wrappers/interface/scoped_ptr.h"
pbos@webrtc.org46f72882013-12-16 12:24:44 +000020#include "webrtc/system_wrappers/interface/trace.h"
andresp@webrtc.org04253922013-05-14 12:10:58 +000021#include "webrtc/typedefs.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000022
23namespace webrtc {
andresp@webrtc.org04253922013-05-14 12:10:58 +000024namespace {
25class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
26 public:
27 RemoteBitrateEstimatorSingleStream(RemoteBitrateObserver* observer,
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +000028 Clock* clock,
29 uint32_t min_bitrate_bps);
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +000030 virtual ~RemoteBitrateEstimatorSingleStream() {}
andresp@webrtc.org04253922013-05-14 12:10:58 +000031
andresp@webrtc.org04253922013-05-14 12:10:58 +000032 // 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.
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +000037 virtual void IncomingPacket(int64_t arrival_time_ms,
38 int payload_size,
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000039 const RTPHeader& header) OVERRIDE;
andresp@webrtc.org04253922013-05-14 12:10:58 +000040
41 // Triggers a new estimate calculation.
42 // Implements the Module interface.
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000043 virtual int32_t Process() OVERRIDE;
44 virtual int32_t TimeUntilNextProcess() OVERRIDE;
andresp@webrtc.org04253922013-05-14 12:10:58 +000045 // Set the current round-trip time experienced by the stream.
46 // Implements the StatsObserver interface.
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000047 virtual void OnRttUpdate(uint32_t rtt) OVERRIDE;
andresp@webrtc.org04253922013-05-14 12:10:58 +000048
49 // Removes all data for |ssrc|.
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000050 virtual void RemoveStream(unsigned int ssrc) OVERRIDE;
andresp@webrtc.org04253922013-05-14 12:10:58 +000051
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.
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +000055 virtual bool LatestEstimate(std::vector<unsigned int>* ssrcs,
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000056 unsigned int* bitrate_bps) const OVERRIDE;
andresp@webrtc.org04253922013-05-14 12:10:58 +000057
jiayl@webrtc.orgd1e7fac2014-02-10 19:12:14 +000058 virtual bool GetStats(
59 ReceiveBandwidthEstimatorStats* output) const OVERRIDE;
60
andresp@webrtc.org04253922013-05-14 12:10:58 +000061 private:
62 typedef std::map<unsigned int, OveruseDetector> SsrcOveruseDetectorMap;
63
64 // Triggers a new estimate calculation.
65 void UpdateEstimate(int64_t time_now);
66
67 void GetSsrcs(std::vector<unsigned int>* ssrcs) const;
68
69 Clock* clock_;
70 SsrcOveruseDetectorMap overuse_detectors_;
sprang@webrtc.org7374da32013-12-03 10:31:59 +000071 RateStatistics incoming_bitrate_;
andresp@webrtc.org04253922013-05-14 12:10:58 +000072 RemoteRateControl remote_rate_;
73 RemoteBitrateObserver* observer_;
74 scoped_ptr<CriticalSectionWrapper> crit_sect_;
75 int64_t last_process_time_;
76};
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000077
78RemoteBitrateEstimatorSingleStream::RemoteBitrateEstimatorSingleStream(
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000079 RemoteBitrateObserver* observer,
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +000080 Clock* clock,
81 uint32_t min_bitrate_bps)
andresp@webrtc.org04253922013-05-14 12:10:58 +000082 : clock_(clock),
sprang@webrtc.org7374da32013-12-03 10:31:59 +000083 incoming_bitrate_(500, 8000),
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +000084 remote_rate_(min_bitrate_bps),
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000085 observer_(observer),
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000086 crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
87 last_process_time_(-1) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000088 assert(observer_);
89}
90
91void RemoteBitrateEstimatorSingleStream::IncomingPacket(
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +000092 int64_t arrival_time_ms,
stefan@webrtc.org376495a2012-11-13 15:02:13 +000093 int payload_size,
stefan@webrtc.orgd8ecee52013-06-04 12:15:40 +000094 const RTPHeader& header) {
95 uint32_t ssrc = header.ssrc;
96 uint32_t rtp_timestamp = header.timestamp +
97 header.extension.transmissionTimeOffset;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +000098 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
106 // group.
107 std::pair<SsrcOveruseDetectorMap::iterator, bool> insert_result =
108 overuse_detectors_.insert(std::make_pair(ssrc, OveruseDetector(
andresp@webrtc.org04253922013-05-14 12:10:58 +0000109 OverUseDetectorOptions())));
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000110 it = insert_result.first;
111 }
112 OveruseDetector* overuse_detector = &it->second;
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000113 incoming_bitrate_.Update(payload_size, arrival_time_ms);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000114 const BandwidthUsage prior_state = overuse_detector->State();
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000115 overuse_detector->Update(payload_size, -1, rtp_timestamp, arrival_time_ms);
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000116 if (overuse_detector->State() == kBwOverusing) {
sprang@webrtc.org7374da32013-12-03 10:31:59 +0000117 unsigned int incoming_bitrate = incoming_bitrate_.Rate(arrival_time_ms);
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000118 if (prior_state != kBwOverusing ||
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000119 remote_rate_.TimeToReduceFurther(arrival_time_ms, incoming_bitrate)) {
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000120 // 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.
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000123 UpdateEstimate(arrival_time_ms);
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000124 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000125 }
126}
127
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000128int32_t RemoteBitrateEstimatorSingleStream::Process() {
129 if (TimeUntilNextProcess() > 0) {
130 return 0;
131 }
132 UpdateEstimate(clock_->TimeInMilliseconds());
133 last_process_time_ = clock_->TimeInMilliseconds();
134 return 0;
135}
136
137int32_t RemoteBitrateEstimatorSingleStream::TimeUntilNextProcess() {
138 if (last_process_time_ < 0) {
139 return 0;
140 }
141 return last_process_time_ + kProcessIntervalMs - clock_->TimeInMilliseconds();
142}
143
144void RemoteBitrateEstimatorSingleStream::UpdateEstimate(int64_t time_now) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000145 CriticalSectionScoped cs(crit_sect_.get());
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000146 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++);
157 } else {
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();
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();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000170 return;
171 }
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000172 double mean_noise_var = sum_noise_var /
173 static_cast<double>(overuse_detectors_.size());
174 const RateControlInput input(bw_state,
sprang@webrtc.org7374da32013-12-03 10:31:59 +0000175 incoming_bitrate_.Rate(time_now),
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000176 mean_noise_var);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000177 const RateControlRegion region = remote_rate_.Update(&input, time_now);
178 unsigned int target_bitrate = remote_rate_.UpdateBandwidthEstimate(time_now);
179 if (remote_rate_.ValidEstimate()) {
stefan@webrtc.org7d324912012-11-19 10:09:20 +0000180 std::vector<unsigned int> ssrcs;
181 GetSsrcs(&ssrcs);
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000182 observer_->OnReceiveBitrateChanged(ssrcs, target_bitrate);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000183 }
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000184 for (it = overuse_detectors_.begin(); it != overuse_detectors_.end(); ++it) {
185 it->second.SetRateControlRegion(region);
186 }
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000187}
188
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000189void RemoteBitrateEstimatorSingleStream::OnRttUpdate(uint32_t rtt) {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000190 CriticalSectionScoped cs(crit_sect_.get());
191 remote_rate_.SetRtt(rtt);
192}
193
194void 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);
198}
199
200bool RemoteBitrateEstimatorSingleStream::LatestEstimate(
stefan@webrtc.org7d324912012-11-19 10:09:20 +0000201 std::vector<unsigned int>* ssrcs,
202 unsigned int* bitrate_bps) const {
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000203 CriticalSectionScoped cs(crit_sect_.get());
stefan@webrtc.org7d324912012-11-19 10:09:20 +0000204 assert(bitrate_bps);
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000205 if (!remote_rate_.ValidEstimate()) {
206 return false;
207 }
stefan@webrtc.org7d324912012-11-19 10:09:20 +0000208 GetSsrcs(ssrcs);
209 if (ssrcs->empty())
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000210 *bitrate_bps = 0;
stefan@webrtc.org7d324912012-11-19 10:09:20 +0000211 else
212 *bitrate_bps = remote_rate_.LatestEstimate();
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000213 return true;
214}
215
jiayl@webrtc.orgd1e7fac2014-02-10 19:12:14 +0000216bool RemoteBitrateEstimatorSingleStream::GetStats(
217 ReceiveBandwidthEstimatorStats* output) const {
218 // Not implemented.
219 return false;
220}
221
stefan@webrtc.org7d324912012-11-19 10:09:20 +0000222void RemoteBitrateEstimatorSingleStream::GetSsrcs(
223 std::vector<unsigned int>* ssrcs) const {
224 assert(ssrcs);
225 ssrcs->resize(overuse_detectors_.size());
226 int i = 0;
227 for (SsrcOveruseDetectorMap::const_iterator it = overuse_detectors_.begin();
228 it != overuse_detectors_.end(); ++it, ++i) {
229 (*ssrcs)[i] = it->first;
230 }
231}
andresp@webrtc.org04253922013-05-14 12:10:58 +0000232} // namespace
stefan@webrtc.org7d324912012-11-19 10:09:20 +0000233
andresp@webrtc.org04253922013-05-14 12:10:58 +0000234RemoteBitrateEstimator* RemoteBitrateEstimatorFactory::Create(
235 RemoteBitrateObserver* observer,
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +0000236 Clock* clock,
237 uint32_t min_bitrate_bps) const {
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000238 WEBRTC_TRACE(kTraceStateInfo, kTraceRemoteBitrateEstimator, -1,
239 "RemoteBitrateEstimatorFactory: Instantiating.");
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +0000240 return new RemoteBitrateEstimatorSingleStream(observer, clock,
241 min_bitrate_bps);
andresp@webrtc.org04253922013-05-14 12:10:58 +0000242}
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000243
244RemoteBitrateEstimator* AbsoluteSendTimeRemoteBitrateEstimatorFactory::Create(
245 RemoteBitrateObserver* observer,
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +0000246 Clock* clock,
247 uint32_t min_bitrate_bps) const {
pbos@webrtc.org46f72882013-12-16 12:24:44 +0000248 WEBRTC_TRACE(kTraceStateInfo, kTraceRemoteBitrateEstimator, -1,
249 "AbsoluteSendTimeRemoteBitrateEstimatorFactory: Instantiating.");
henrik.lundin@webrtc.orgc49a3fa2013-12-13 08:42:42 +0000250 return new RemoteBitrateEstimatorSingleStream(observer, clock,
251 min_bitrate_bps);
solenberg@webrtc.orgf40e9b62013-05-27 16:02:56 +0000252}
andrew@webrtc.orgb015cbe2012-10-22 18:19:23 +0000253} // namespace webrtc