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
12 #include "webrtc/modules/bitrate_controller/bitrate_controller_impl.h"
13
14 #include <algorithm>
15 #include <utility>
16
17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18
19 namespace webrtc {
20
21 class BitrateControllerImpl::RtcpBandwidthObserverImpl
22 : public RtcpBandwidthObserver {
23 public:
RtcpBandwidthObserverImpl(BitrateControllerImpl * owner)24 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
25 : owner_(owner) {
26 }
~RtcpBandwidthObserverImpl()27 virtual ~RtcpBandwidthObserverImpl() {
28 }
29 // Received RTCP REMB or TMMBR.
OnReceivedEstimatedBitrate(uint32_t bitrate)30 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
31 owner_->OnReceivedEstimatedBitrate(bitrate);
32 }
33 // Received RTCP receiver block.
OnReceivedRtcpReceiverReport(const ReportBlockList & report_blocks,int64_t rtt,int64_t now_ms)34 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
35 int64_t rtt,
36 int64_t now_ms) override {
37 if (report_blocks.empty())
38 return;
39
40 int fraction_lost_aggregate = 0;
41 int total_number_of_packets = 0;
42
43 // Compute the a weighted average of the fraction loss from all report
44 // blocks.
45 for (ReportBlockList::const_iterator it = report_blocks.begin();
46 it != report_blocks.end(); ++it) {
47 std::map<uint32_t, uint32_t>::iterator seq_num_it =
48 ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
49
50 int number_of_packets = 0;
51 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
52 number_of_packets = it->extendedHighSeqNum -
53 seq_num_it->second;
54
55 fraction_lost_aggregate += number_of_packets * it->fractionLost;
56 total_number_of_packets += number_of_packets;
57
58 // Update last received for this SSRC.
59 ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
60 it->extendedHighSeqNum;
61 }
62 if (total_number_of_packets == 0)
63 fraction_lost_aggregate = 0;
64 else
65 fraction_lost_aggregate = (fraction_lost_aggregate +
66 total_number_of_packets / 2) / total_number_of_packets;
67 if (fraction_lost_aggregate > 255)
68 return;
69
70 owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
71 total_number_of_packets, now_ms);
72 }
73
74 private:
75 std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
76 BitrateControllerImpl* owner_;
77 };
78
CreateBitrateController(Clock * clock,BitrateObserver * observer)79 BitrateController* BitrateController::CreateBitrateController(
80 Clock* clock,
81 BitrateObserver* observer) {
82 return new BitrateControllerImpl(clock, observer);
83 }
84
BitrateControllerImpl(Clock * clock,BitrateObserver * observer)85 BitrateControllerImpl::BitrateControllerImpl(Clock* clock,
86 BitrateObserver* observer)
87 : clock_(clock),
88 observer_(observer),
89 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
90 bandwidth_estimation_(),
91 reserved_bitrate_bps_(0),
92 last_bitrate_bps_(0),
93 last_fraction_loss_(0),
94 last_rtt_ms_(0),
95 last_reserved_bitrate_bps_(0) {
96 // This calls the observer_, which means that the observer provided by the
97 // user must be ready to accept a bitrate update when it constructs the
98 // controller. We do this to avoid having to keep synchronized initial values
99 // in both the controller and the allocator.
100 MaybeTriggerOnNetworkChanged();
101 }
102
CreateRtcpBandwidthObserver()103 RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
104 return new RtcpBandwidthObserverImpl(this);
105 }
106
SetStartBitrate(int start_bitrate_bps)107 void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
108 {
109 rtc::CritScope cs(&critsect_);
110 bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
111 }
112 MaybeTriggerOnNetworkChanged();
113 }
114
SetMinMaxBitrate(int min_bitrate_bps,int max_bitrate_bps)115 void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
116 int max_bitrate_bps) {
117 {
118 rtc::CritScope cs(&critsect_);
119 bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
120 }
121 MaybeTriggerOnNetworkChanged();
122 }
123
SetReservedBitrate(uint32_t reserved_bitrate_bps)124 void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
125 {
126 rtc::CritScope cs(&critsect_);
127 reserved_bitrate_bps_ = reserved_bitrate_bps;
128 }
129 MaybeTriggerOnNetworkChanged();
130 }
131
SetEventLog(RtcEventLog * event_log)132 void BitrateControllerImpl::SetEventLog(RtcEventLog* event_log) {
133 rtc::CritScope cs(&critsect_);
134 bandwidth_estimation_.SetEventLog(event_log);
135 }
136
OnReceivedEstimatedBitrate(uint32_t bitrate)137 void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
138 {
139 rtc::CritScope cs(&critsect_);
140 bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(),
141 bitrate);
142 }
143 MaybeTriggerOnNetworkChanged();
144 }
145
TimeUntilNextProcess()146 int64_t BitrateControllerImpl::TimeUntilNextProcess() {
147 const int64_t kBitrateControllerUpdateIntervalMs = 25;
148 rtc::CritScope cs(&critsect_);
149 int64_t time_since_update_ms =
150 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
151 return std::max<int64_t>(
152 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
153 }
154
Process()155 int32_t BitrateControllerImpl::Process() {
156 if (TimeUntilNextProcess() > 0)
157 return 0;
158 {
159 rtc::CritScope cs(&critsect_);
160 bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
161 }
162 MaybeTriggerOnNetworkChanged();
163 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
164 return 0;
165 }
166
OnReceivedRtcpReceiverReport(uint8_t fraction_loss,int64_t rtt,int number_of_packets,int64_t now_ms)167 void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
168 uint8_t fraction_loss,
169 int64_t rtt,
170 int number_of_packets,
171 int64_t now_ms) {
172 {
173 rtc::CritScope cs(&critsect_);
174 bandwidth_estimation_.UpdateReceiverBlock(fraction_loss, rtt,
175 number_of_packets, now_ms);
176 }
177 MaybeTriggerOnNetworkChanged();
178 }
179
MaybeTriggerOnNetworkChanged()180 void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
181 uint32_t bitrate;
182 uint8_t fraction_loss;
183 int64_t rtt;
184 if (GetNetworkParameters(&bitrate, &fraction_loss, &rtt))
185 observer_->OnNetworkChanged(bitrate, fraction_loss, rtt);
186 }
187
GetNetworkParameters(uint32_t * bitrate,uint8_t * fraction_loss,int64_t * rtt)188 bool BitrateControllerImpl::GetNetworkParameters(uint32_t* bitrate,
189 uint8_t* fraction_loss,
190 int64_t* rtt) {
191 rtc::CritScope cs(&critsect_);
192 int current_bitrate;
193 bandwidth_estimation_.CurrentEstimate(¤t_bitrate, fraction_loss, rtt);
194 *bitrate = current_bitrate;
195 *bitrate -= std::min(*bitrate, reserved_bitrate_bps_);
196 *bitrate =
197 std::max<uint32_t>(*bitrate, bandwidth_estimation_.GetMinBitrate());
198
199 bool new_bitrate = false;
200 if (*bitrate != last_bitrate_bps_ || *fraction_loss != last_fraction_loss_ ||
201 *rtt != last_rtt_ms_ ||
202 last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
203 last_bitrate_bps_ = *bitrate;
204 last_fraction_loss_ = *fraction_loss;
205 last_rtt_ms_ = *rtt;
206 last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
207 new_bitrate = true;
208 }
209 return new_bitrate;
210 }
211
AvailableBandwidth(uint32_t * bandwidth) const212 bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
213 rtc::CritScope cs(&critsect_);
214 int bitrate;
215 uint8_t fraction_loss;
216 int64_t rtt;
217 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
218 if (bitrate > 0) {
219 bitrate = bitrate - std::min<int>(bitrate, reserved_bitrate_bps_);
220 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
221 *bandwidth = bitrate;
222 return true;
223 }
224 return false;
225 }
226 } // namespace webrtc
227