blob: 586d8da301d68d1c54f58bc5e47dba9e1b9cc33e [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
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000014#include <algorithm>
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000015#include <utility>
16
pbos@webrtc.org2e10b8e2013-07-16 12:54:53 +000017#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000018
19namespace webrtc {
20
andresp@webrtc.org16b75c22014-03-21 14:00:51 +000021class BitrateControllerImpl::RtcpBandwidthObserverImpl
22 : public RtcpBandwidthObserver {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000023 public:
24 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner)
25 : owner_(owner) {
26 }
27 virtual ~RtcpBandwidthObserverImpl() {
28 }
29 // Received RTCP REMB or TMMBR.
stefan@webrtc.orgedeea912014-12-08 19:46:23 +000030 virtual void OnReceivedEstimatedBitrate(uint32_t bitrate) OVERRIDE {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000031 owner_->OnReceivedEstimatedBitrate(bitrate);
32 }
33 // Received RTCP receiver block.
34 virtual void OnReceivedRtcpReceiverReport(
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000035 const ReportBlockList& report_blocks,
pkasting@chromium.org16825b12015-01-12 21:51:21 +000036 int64_t rtt,
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000037 int64_t now_ms) OVERRIDE {
38 if (report_blocks.empty())
39 return;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000040
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000041 int fraction_lost_aggregate = 0;
42 int total_number_of_packets = 0;
43
44 // Compute the a weighted average of the fraction loss from all report
45 // blocks.
46 for (ReportBlockList::const_iterator it = report_blocks.begin();
47 it != report_blocks.end(); ++it) {
48 std::map<uint32_t, uint32_t>::iterator seq_num_it =
49 ssrc_to_last_received_extended_high_seq_num_.find(it->sourceSSRC);
50
51 int number_of_packets = 0;
52 if (seq_num_it != ssrc_to_last_received_extended_high_seq_num_.end())
53 number_of_packets = it->extendedHighSeqNum -
54 seq_num_it->second;
55
56 fraction_lost_aggregate += number_of_packets * it->fractionLost;
57 total_number_of_packets += number_of_packets;
58
59 // Update last received for this SSRC.
60 ssrc_to_last_received_extended_high_seq_num_[it->sourceSSRC] =
61 it->extendedHighSeqNum;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000062 }
stefan@webrtc.org28a331e2013-09-17 07:49:56 +000063 if (total_number_of_packets == 0)
64 fraction_lost_aggregate = 0;
65 else
66 fraction_lost_aggregate = (fraction_lost_aggregate +
67 total_number_of_packets / 2) / total_number_of_packets;
68 if (fraction_lost_aggregate > 255)
69 return;
70
71 owner_->OnReceivedRtcpReceiverReport(fraction_lost_aggregate, rtt,
72 total_number_of_packets, now_ms);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000073 }
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000074
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000075 private:
76 std::map<uint32_t, uint32_t> ssrc_to_last_received_extended_high_seq_num_;
77 BitrateControllerImpl* owner_;
78};
79
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +000080BitrateController* BitrateController::CreateBitrateController(
andresp@webrtc.org44caf012014-03-26 21:00:21 +000081 Clock* clock,
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000082 BitrateObserver* observer) {
83 return new BitrateControllerImpl(clock, observer);
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +000084}
85
sprang@webrtc.org9b791972014-12-18 11:53:59 +000086BitrateControllerImpl::BitrateControllerImpl(Clock* clock,
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000087 BitrateObserver* observer)
andresp@webrtc.org44caf012014-03-26 21:00:21 +000088 : clock_(clock),
stefan@webrtc.org792f1a12015-03-04 12:24:26 +000089 observer_(observer),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000090 last_bitrate_update_ms_(clock_->TimeInMilliseconds()),
91 critsect_(CriticalSectionWrapper::CreateCriticalSection()),
solenberg@webrtc.org4e656022014-03-26 14:32:47 +000092 bandwidth_estimation_(),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000093 reserved_bitrate_bps_(0),
94 last_bitrate_bps_(0),
solenberg@webrtc.org4e656022014-03-26 14:32:47 +000095 last_fraction_loss_(0),
andresp@webrtc.org44caf012014-03-26 21:00:21 +000096 last_rtt_ms_(0),
sprang@webrtc.org9b791972014-12-18 11:53:59 +000097 last_reserved_bitrate_bps_(0),
98 remb_suppressor_(new RembSuppressor(clock)) {
99}
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000100
101BitrateControllerImpl::~BitrateControllerImpl() {
102 delete critsect_;
103}
104
105RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() {
106 return new RtcpBandwidthObserverImpl(this);
107}
108
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000109void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000110 CriticalSectionScoped cs(critsect_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000111 bandwidth_estimation_.SetSendBitrate(start_bitrate_bps);
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000112}
113
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000114void BitrateControllerImpl::SetMinMaxBitrate(int min_bitrate_bps,
115 int max_bitrate_bps) {
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000116 CriticalSectionScoped cs(critsect_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000117 bandwidth_estimation_.SetMinMaxBitrate(min_bitrate_bps, max_bitrate_bps);
henrik.lundin@webrtc.org845862f2014-03-06 07:19:28 +0000118}
119
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000120void BitrateControllerImpl::SetReservedBitrate(uint32_t reserved_bitrate_bps) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000121 {
122 CriticalSectionScoped cs(critsect_);
123 reserved_bitrate_bps_ = reserved_bitrate_bps;
124 }
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000125 MaybeTriggerOnNetworkChanged();
126}
127
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000128void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000129 {
130 CriticalSectionScoped cs(critsect_);
131 if (remb_suppressor_->SuppresNewRemb(bitrate)) {
132 return;
133 }
134 bandwidth_estimation_.UpdateReceiverEstimate(bitrate);
sprang@webrtc.org9b791972014-12-18 11:53:59 +0000135 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000136 MaybeTriggerOnNetworkChanged();
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000137}
138
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000139int64_t BitrateControllerImpl::TimeUntilNextProcess() {
140 const int64_t kBitrateControllerUpdateIntervalMs = 25;
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000141 CriticalSectionScoped cs(critsect_);
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000142 int64_t time_since_update_ms =
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000143 clock_->TimeInMilliseconds() - last_bitrate_update_ms_;
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000144 return std::max<int64_t>(
145 kBitrateControllerUpdateIntervalMs - time_since_update_ms, 0);
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000146}
147
148int32_t BitrateControllerImpl::Process() {
149 if (TimeUntilNextProcess() > 0)
150 return 0;
151 {
152 CriticalSectionScoped cs(critsect_);
153 bandwidth_estimation_.UpdateEstimate(clock_->TimeInMilliseconds());
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000154 }
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000155 MaybeTriggerOnNetworkChanged();
andresp@webrtc.org44caf012014-03-26 21:00:21 +0000156 last_bitrate_update_ms_ = clock_->TimeInMilliseconds();
157 return 0;
158}
159
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000160void BitrateControllerImpl::OnReceivedRtcpReceiverReport(
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000161 uint8_t fraction_loss,
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000162 int64_t rtt,
stefan@webrtc.orgedeea912014-12-08 19:46:23 +0000163 int number_of_packets,
164 int64_t now_ms) {
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000165 {
166 CriticalSectionScoped cs(critsect_);
167 bandwidth_estimation_.UpdateReceiverBlock(fraction_loss, rtt,
168 number_of_packets, now_ms);
169 }
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000170 MaybeTriggerOnNetworkChanged();
171}
172
173void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() {
174 uint32_t bitrate;
175 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000176 int64_t rtt;
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000177 bool new_bitrate = false;
178 {
179 CriticalSectionScoped cs(critsect_);
180 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
181 bitrate -= std::min(bitrate, reserved_bitrate_bps_);
182 bitrate = std::max(bitrate, bandwidth_estimation_.GetMinBitrate());
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000183
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000184 if (bitrate != last_bitrate_bps_ || fraction_loss != last_fraction_loss_ ||
185 rtt != last_rtt_ms_ ||
186 last_reserved_bitrate_bps_ != reserved_bitrate_bps_) {
187 last_bitrate_bps_ = bitrate;
188 last_fraction_loss_ = fraction_loss;
189 last_rtt_ms_ = rtt;
190 last_reserved_bitrate_bps_ = reserved_bitrate_bps_;
191 new_bitrate = true;
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000192 }
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000193 }
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000194 if (new_bitrate)
195 observer_->OnNetworkChanged(bitrate, fraction_loss, rtt);
andresp@webrtc.org16b75c22014-03-21 14:00:51 +0000196}
197
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000198bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const {
andresp@webrtc.org16b75c22014-03-21 14:00:51 +0000199 CriticalSectionScoped cs(critsect_);
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000200 uint32_t bitrate;
201 uint8_t fraction_loss;
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000202 int64_t rtt;
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000203 bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt);
204 if (bitrate) {
solenberg@webrtc.org4e656022014-03-26 14:32:47 +0000205 *bandwidth = bitrate - std::min(bitrate, reserved_bitrate_bps_);
stefan@webrtc.org792f1a12015-03-04 12:24:26 +0000206 *bandwidth = std::max(*bandwidth, bandwidth_estimation_.GetMinBitrate());
andresp@webrtc.org07bc7342014-03-21 16:51:01 +0000207 return true;
208 }
209 return false;
pwestin@webrtc.orga2cd7322012-04-23 08:32:47 +0000210}
henrik.lundin@webrtc.org29dd0de2013-10-21 14:00:01 +0000211
sprang@webrtc.org9b791972014-12-18 11:53:59 +0000212void BitrateControllerImpl::SetBitrateSent(uint32_t bitrate_sent_bps) {
213 CriticalSectionScoped cs(critsect_);
214 remb_suppressor_->SetBitrateSent(bitrate_sent_bps);
215}
216
217void BitrateControllerImpl::SetCodecMode(webrtc::VideoCodecMode mode) {
218 CriticalSectionScoped cs(critsect_);
219 remb_suppressor_->SetEnabled(mode == kScreensharing);
220}
221
pwestin@webrtc.org1cd11622012-04-19 12:13:52 +0000222} // namespace webrtc