blob: 43c6e172b9327c67babed1f228497cd1e32ba8db [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(
33 const uint32_t ssrc,
34 const uint8_t fraction_loss,
35 const uint32_t rtt,
36 const uint32_t last_received_extended_high_seq_num,
pbos@webrtc.org4fac8a42013-07-31 15:16:20 +000037 const uint32_t now_ms) OVERRIDE {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000038 uint32_t number_of_packets = 0;
39 std::map<uint32_t, uint32_t>::iterator it =
40 ssrc_to_last_received_extended_high_seq_num_.find(ssrc);
41
42 if (it != ssrc_to_last_received_extended_high_seq_num_.end()) {
43 number_of_packets = last_received_extended_high_seq_num - it->second;
44 }
45 // Update last received for this SSRC.
46 ssrc_to_last_received_extended_high_seq_num_[ssrc] =
47 last_received_extended_high_seq_num;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000048 owner_->OnReceivedRtcpReceiverReport(fraction_loss, rtt, number_of_packets,
49 now_ms);
50 }
51 private:
52 std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
53 BitrateControllerImpl* owner_;
54};
55
56BitrateController* BitrateController::CreateBitrateController() {
57 return new BitrateControllerImpl();
58}
59
60BitrateControllerImpl::BitrateControllerImpl()
61 : critsect_(CriticalSectionWrapper::CreateCriticalSection()) {
62}
63
64BitrateControllerImpl::~BitrateControllerImpl() {
stefan@webrtc.org1281dc02012-08-13 16:13:09 +000065 BitrateObserverConfList::iterator it =
pwestin@webrtc.orge9727cd2012-05-03 11:32:25 +000066 bitrate_observers_.begin();
67 while (it != bitrate_observers_.end()) {
68 delete it->second;
69 bitrate_observers_.erase(it);
70 it = bitrate_observers_.begin();
71 }
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000072 delete critsect_;
73}
74
75RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
76 return new RtcpBandwidthObserverImpl(this);
77}
78
stefan@webrtc.org1281dc02012-08-13 16:13:09 +000079BitrateControllerImpl::BitrateObserverConfList::iterator
80BitrateControllerImpl::FindObserverConfigurationPair(const BitrateObserver*
81 observer) {
82 BitrateObserverConfList::iterator it = bitrate_observers_.begin();
83 for (; it != bitrate_observers_.end(); ++it) {
84 if (it->first == observer) {
85 return it;
86 }
87 }
88 return bitrate_observers_.end();
89}
90
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000091void BitrateControllerImpl::SetBitrateObserver(
92 BitrateObserver* observer,
93 const uint32_t start_bitrate,
94 const uint32_t min_bitrate,
95 const uint32_t max_bitrate) {
96 CriticalSectionScoped cs(critsect_);
97
stefan@webrtc.org1281dc02012-08-13 16:13:09 +000098 BitrateObserverConfList::iterator it = FindObserverConfigurationPair(
99 observer);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000100
101 if (it != bitrate_observers_.end()) {
102 // Update current configuration.
103 it->second->start_bitrate_ = start_bitrate;
104 it->second->min_bitrate_ = min_bitrate;
105 it->second->max_bitrate_ = max_bitrate;
106 } else {
107 // Add new settings.
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000108 bitrate_observers_.push_back(BitrateObserverConfiguration(observer,
109 new BitrateConfiguration(start_bitrate, min_bitrate, max_bitrate)));
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000110 }
111 uint32_t sum_start_bitrate = 0;
112 uint32_t sum_min_bitrate = 0;
113 uint32_t sum_max_bitrate = 0;
114
115 // Summarize all configurations.
116 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
117 sum_start_bitrate += it->second->start_bitrate_;
118 sum_min_bitrate += it->second->min_bitrate_;
119 sum_max_bitrate += it->second->max_bitrate_;
120 }
121 // Only change start bitrate if we have exactly one observer. By definition
122 // you can only have one start bitrate, once we have our first estimate we
123 // will adapt from there.
124 if (bitrate_observers_.size() == 1) {
125 bandwidth_estimation_.SetSendBitrate(sum_start_bitrate);
126 }
127 bandwidth_estimation_.SetMinMaxBitrate(sum_min_bitrate,
128 sum_max_bitrate);
129}
130
131void BitrateControllerImpl::RemoveBitrateObserver(BitrateObserver* observer) {
132 CriticalSectionScoped cs(critsect_);
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000133 BitrateObserverConfList::iterator it = FindObserverConfigurationPair(
134 observer);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000135 if (it != bitrate_observers_.end()) {
136 delete it->second;
137 bitrate_observers_.erase(it);
138 }
139}
140
141void BitrateControllerImpl::OnReceivedEstimatedBitrate(const uint32_t bitrate) {
142 uint32_t new_bitrate = 0;
143 uint8_t fraction_lost = 0;
144 uint16_t rtt = 0;
145 CriticalSectionScoped cs(critsect_);
146 if (bandwidth_estimation_.UpdateBandwidthEstimate(bitrate,
147 &new_bitrate,
148 &fraction_lost,
149 &rtt)) {
150 OnNetworkChanged(new_bitrate, fraction_lost, rtt);
151 }
152}
153
154void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
155 const uint8_t fraction_loss,
156 const uint32_t rtt,
157 const int number_of_packets,
158 const uint32_t now_ms) {
159 uint32_t new_bitrate = 0;
160 uint8_t loss = fraction_loss;
161 CriticalSectionScoped cs(critsect_);
162 if (bandwidth_estimation_.UpdatePacketLoss(number_of_packets, rtt, now_ms,
163 &loss, &new_bitrate)) {
164 OnNetworkChanged(new_bitrate, loss, rtt);
165 }
166}
167
168// We have the lock here.
169void BitrateControllerImpl::OnNetworkChanged(const uint32_t bitrate,
170 const uint8_t fraction_loss,
171 const uint32_t rtt) {
172 // Sanity check.
173 uint32_t number_of_observers = bitrate_observers_.size();
174 if (number_of_observers == 0) {
175 return;
176 }
177 uint32_t sum_min_bitrates = 0;
stefan@webrtc.org1281dc02012-08-13 16:13:09 +0000178 BitrateObserverConfList::iterator it;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000179 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
180 sum_min_bitrates += it->second->min_bitrate_;
181 }
182 if (bitrate <= sum_min_bitrates) {
183 // Min bitrate to all observers.
184 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end();
185 ++it) {
186 it->first->OnNetworkChanged(it->second->min_bitrate_, fraction_loss,
187 rtt);
188 }
189 // Set sum of min to current send bitrate.
190 bandwidth_estimation_.SetSendBitrate(sum_min_bitrates);
191 return;
192 }
193 uint32_t bitrate_per_observer = (bitrate - sum_min_bitrates) /
194 number_of_observers;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000195 // Use map to sort list based on max bitrate.
196 ObserverSortingMap list_max_bitrates;
197 for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) {
198 list_max_bitrates.insert(std::pair<uint32_t, ObserverConfiguration*>(
199 it->second->max_bitrate_,
200 new ObserverConfiguration(it->first, it->second->min_bitrate_)));
201 }
202 ObserverSortingMap::iterator max_it = list_max_bitrates.begin();
203 while (max_it != list_max_bitrates.end()) {
204 number_of_observers--;
205 uint32_t observer_allowance = max_it->second->min_bitrate_ +
206 bitrate_per_observer;
207 if (max_it->first < observer_allowance) {
208 // We have more than enough for this observer.
209 // Carry the remainder forward.
210 uint32_t remainder = observer_allowance - max_it->first;
211 if (number_of_observers != 0) {
212 bitrate_per_observer += remainder / number_of_observers;
213 }
214 max_it->second->observer_->OnNetworkChanged(max_it->first, fraction_loss,
215 rtt);
216 } else {
217 max_it->second->observer_->OnNetworkChanged(observer_allowance,
218 fraction_loss, rtt);
219 }
220 delete max_it->second;
221 list_max_bitrates.erase(max_it);
222 // Prepare next iteration.
223 max_it = list_max_bitrates.begin();
224 }
225}
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000226
227bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
228 return bandwidth_estimation_.AvailableBandwidth(bandwidth);
229}
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000230} // namespace webrtc