blob: 20cc3aceec375ebb32efb745794d558fa276f5f7 [file] [log] [blame]
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +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 */
11
pbos@webrtc.org2e10b8e2013-07-16 12:54:53 +000012#include "webrtc/modules/bitrate_controller/bitrate_controller_impl.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000013
14#include <utility>
15
pbos@webrtc.org2e10b8e2013-07-16 12:54:53 +000016#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000017
18namespace webrtc {
19
20class RtcpBandwidthObserverImpl : public RtcpBandwidthObserver {
21 public:
22 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
23 : owner_(owner) {
24 }
25 virtual ~RtcpBandwidthObserverImpl() {
26 }
27 // Received RTCP REMB or TMMBR.
pbos@webrtc.org4fac8a42013-07-31 15:16:20 +000028 virtual void OnReceivedEstimatedBitrate(const uint32_t bitrate) OVERRIDE {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000029 owner_->OnReceivedEstimatedBitrate(bitrate);
30 }
31 // Received RTCP receiver block.
32 virtual void OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000033 const ReportBlockList& report_blocks,
34 uint16_t rtt,
35 int64_t now_ms) OVERRIDE {
36 if (report_blocks.empty())
37 return;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000038
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000039 int fraction_lost_aggregate = 0;
40 int total_number_of_packets = 0;
41
42 // Compute the a weighted average of the fraction loss from all report
43 // blocks.
44 for (ReportBlockList::const_iterator it = report_blocks.begin();
45 it != report_blocks.end(); ++it) {
46 std::map<uint32_t, uint32_t>::iterator seq_num_it =
47 ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
48
49 int number_of_packets = 0;
50 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
51 number_of_packets = it->extendedHighSeqNum -
52 seq_num_it->second;
53
54 fraction_lost_aggregate += number_of_packets * it->fractionLost;
55 total_number_of_packets += number_of_packets;
56
57 // Update last received for this SSRC.
58 ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
59 it->extendedHighSeqNum;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000060 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000061 if (total_number_of_packets == 0)
62 fraction_lost_aggregate = 0;
63 else
64 fraction_lost_aggregate = (fraction_lost_aggregate +
65 total_number_of_packets / 2) / total_number_of_packets;
66 if (fraction_lost_aggregate > 255)
67 return;
68
69 owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
70 total_number_of_packets, now_ms);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000071 }
72 private:
73 std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
74 BitrateControllerImpl* owner_;
75};
76
77BitrateController* BitrateController::CreateBitrateController() {
78 return new BitrateControllerImpl();
79}
80
81BitrateControllerImpl::BitrateControllerImpl()
82 : critsect_(CriticalSectionWrapper::CreateCriticalSection()) {
83}
84
85BitrateControllerImpl::~BitrateControllerImpl() {
stefan@webrtc.org1281dc02012-08-13 16:13:09 +000086 BitrateObserverConfList::iterator it =
pwestin@webrtc.orge9727cd2012-05-03 11:32:25 +000087 bitrate_observers_.begin();
88 while (it != bitrate_observers_.end()) {
89 delete it->second;
90 bitrate_observers_.erase(it);
91 it = bitrate_observers_.begin();
92 }
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000093 delete critsect_;
94}
95
96RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
97 return new RtcpBandwidthObserverImpl(this);
98}
99
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000100BitrateControllerImpl::BitrateObserverConfList::iterator
101BitrateControllerImpl::FindObserverConfigurationPair(const BitrateObserver*
102 observer) {
103 BitrateObserverConfList::iterator it = bitrate_observers_.begin();
104 for (; it != bitrate_observers_.end(); ++it) {
105 if (it->first == observer) {
106 return it;
107 }
108 }
109 return bitrate_observers_.end();
110}
111
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000112void BitrateControllerImpl::SetBitrateObserver(
113 BitrateObserver* observer,
114 const uint32_t start_bitrate,
115 const uint32_t min_bitrate,
116 const uint32_t max_bitrate) {
117 CriticalSectionScoped cs(critsect_);
118
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000119 BitrateObserverConfList::iterator it = FindObserverConfigurationPair(
120 observer);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000121
122 if (it != bitrate_observers_.end()) {
123 // Update current configuration.
124 it->second->start_bitrate_ = start_bitrate;
125 it->second->min_bitrate_ = min_bitrate;
126 it->second->max_bitrate_ = max_bitrate;
127 } else {
128 // Add new settings.
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000129 bitrate_observers_.push_back(BitrateObserverConfiguration(observer,
130 new BitrateConfiguration(start_bitrate, min_bitrate, max_bitrate)));
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000131 }
132 uint32_t sum_start_bitrate = 0;
133 uint32_t sum_min_bitrate = 0;
134 uint32_t sum_max_bitrate = 0;
135
136 // Summarize all configurations.
137 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
138 sum_start_bitrate += it->second->start_bitrate_;
139 sum_min_bitrate += it->second->min_bitrate_;
140 sum_max_bitrate += it->second->max_bitrate_;
141 }
142 // Only change start bitrate if we have exactly one observer. By definition
143 // you can only have one start bitrate, once we have our first estimate we
144 // will adapt from there.
145 if (bitrate_observers_.size() == 1) {
146 bandwidth_estimation_.SetSendBitrate(sum_start_bitrate);
147 }
148 bandwidth_estimation_.SetMinMaxBitrate(sum_min_bitrate,
149 sum_max_bitrate);
150}
151
152void BitrateControllerImpl::RemoveBitrateObserver(BitrateObserver* observer) {
153 CriticalSectionScoped cs(critsect_);
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000154 BitrateObserverConfList::iterator it = FindObserverConfigurationPair(
155 observer);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000156 if (it != bitrate_observers_.end()) {
157 delete it->second;
158 bitrate_observers_.erase(it);
159 }
160}
161
162void BitrateControllerImpl::OnReceivedEstimatedBitrate(const uint32_t bitrate) {
163 uint32_t new_bitrate = 0;
164 uint8_t fraction_lost = 0;
165 uint16_t rtt = 0;
166 CriticalSectionScoped cs(critsect_);
167 if (bandwidth_estimation_.UpdateBandwidthEstimate(bitrate,
168 &new_bitrate,
169 &fraction_lost,
170 &rtt)) {
171 OnNetworkChanged(new_bitrate, fraction_lost, rtt);
172 }
173}
174
175void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
176 const uint8_t fraction_loss,
177 const uint32_t rtt,
178 const int number_of_packets,
179 const uint32_t now_ms) {
180 uint32_t new_bitrate = 0;
181 uint8_t loss = fraction_loss;
182 CriticalSectionScoped cs(critsect_);
183 if (bandwidth_estimation_.UpdatePacketLoss(number_of_packets, rtt, now_ms,
184 &loss, &new_bitrate)) {
185 OnNetworkChanged(new_bitrate, loss, rtt);
186 }
187}
188
189// We have the lock here.
190void BitrateControllerImpl::OnNetworkChanged(const uint32_t bitrate,
191 const uint8_t fraction_loss,
192 const uint32_t rtt) {
193 // Sanity check.
194 uint32_t number_of_observers = bitrate_observers_.size();
195 if (number_of_observers == 0) {
196 return;
197 }
198 uint32_t sum_min_bitrates = 0;
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000199 BitrateObserverConfList::iterator it;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000200 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
201 sum_min_bitrates += it->second->min_bitrate_;
202 }
203 if (bitrate <= sum_min_bitrates) {
204 // Min bitrate to all observers.
205 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end();
206 ++it) {
207 it->first->OnNetworkChanged(it->second->min_bitrate_, fraction_loss,
208 rtt);
209 }
210 // Set sum of min to current send bitrate.
211 bandwidth_estimation_.SetSendBitrate(sum_min_bitrates);
212 return;
213 }
214 uint32_t bitrate_per_observer = (bitrate - sum_min_bitrates) /
215 number_of_observers;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000216 // Use map to sort list based on max bitrate.
217 ObserverSortingMap list_max_bitrates;
218 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
219 list_max_bitrates.insert(std::pair<uint32_t, ObserverConfiguration*>(
220 it->second->max_bitrate_,
221 new ObserverConfiguration(it->first, it->second->min_bitrate_)));
222 }
223 ObserverSortingMap::iterator max_it = list_max_bitrates.begin();
224 while (max_it != list_max_bitrates.end()) {
225 number_of_observers--;
226 uint32_t observer_allowance = max_it->second->min_bitrate_ +
227 bitrate_per_observer;
228 if (max_it->first < observer_allowance) {
229 // We have more than enough for this observer.
230 // Carry the remainder forward.
231 uint32_t remainder = observer_allowance - max_it->first;
232 if (number_of_observers != 0) {
233 bitrate_per_observer += remainder / number_of_observers;
234 }
235 max_it->second->observer_->OnNetworkChanged(max_it->first, fraction_loss,
236 rtt);
237 } else {
238 max_it->second->observer_->OnNetworkChanged(observer_allowance,
239 fraction_loss, rtt);
240 }
241 delete max_it->second;
242 list_max_bitrates.erase(max_it);
243 // Prepare next iteration.
244 max_it = list_max_bitrates.begin();
245 }
246}
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000247
248bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
249 return bandwidth_estimation_.AvailableBandwidth(bandwidth);
250}
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000251} // namespace webrtc