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 19namespace webrtc { 20 21class BitrateControllerImpl::RtcpBandwidthObserverImpl 22 : public RtcpBandwidthObserver { 23 public: 24 explicit RtcpBandwidthObserverImpl(BitrateControllerImpl* owner) 25 : owner_(owner) { 26 } 27 virtual ~RtcpBandwidthObserverImpl() { 28 } 29 // Received RTCP REMB or TMMBR. 30 void OnReceivedEstimatedBitrate(uint32_t bitrate) override { 31 owner_->OnReceivedEstimatedBitrate(bitrate); 32 } 33 // Received RTCP receiver block. 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 79BitrateController* BitrateController::CreateBitrateController( 80 Clock* clock, 81 BitrateObserver* observer) { 82 return new BitrateControllerImpl(clock, observer); 83} 84 85BitrateControllerImpl::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 103RtcpBandwidthObserver* BitrateControllerImpl::CreateRtcpBandwidthObserver() { 104 return new RtcpBandwidthObserverImpl(this); 105} 106 107void BitrateControllerImpl::SetStartBitrate(int start_bitrate_bps) { 108 { 109 rtc::CritScope cs(&critsect_); 110 bandwidth_estimation_.SetSendBitrate(start_bitrate_bps); 111 } 112 MaybeTriggerOnNetworkChanged(); 113} 114 115void 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 124void 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 132void BitrateControllerImpl::SetEventLog(RtcEventLog* event_log) { 133 rtc::CritScope cs(&critsect_); 134 bandwidth_estimation_.SetEventLog(event_log); 135} 136 137void BitrateControllerImpl::OnReceivedEstimatedBitrate(uint32_t bitrate) { 138 { 139 rtc::CritScope cs(&critsect_); 140 bandwidth_estimation_.UpdateReceiverEstimate(clock_->TimeInMilliseconds(), 141 bitrate); 142 } 143 MaybeTriggerOnNetworkChanged(); 144} 145 146int64_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 155int32_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 167void 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 180void 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 188bool 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 212bool 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