diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc b/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc index 3810406464..d777536b96 100644 --- a/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc +++ b/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc @@ -132,22 +132,39 @@ void BitrateControllerImpl::SetBitrateObserver( // Add new settings. bitrate_observers_.push_back(BitrateObserverConfiguration(observer, new BitrateConfiguration(start_bitrate, min_bitrate, max_bitrate))); + bitrate_observers_modified_ = true; + + // TODO(andresp): This is a ugly way to set start bitrate. + // + // Only change start bitrate if we have exactly one observer. By definition + // you can only have one start bitrate, once we have our first estimate we + // will adapt from there. + if (bitrate_observers_.size() == 1) { + bandwidth_estimation_.SetSendBitrate(start_bitrate); + } } + + UpdateMinMaxBitrate(); +} + +void BitrateControllerImpl::UpdateMinMaxBitrate() { uint32_t sum_start_bitrate = 0; uint32_t sum_min_bitrate = 0; uint32_t sum_max_bitrate = 0; - - // Summarize all configurations. + BitrateObserverConfList::iterator it; for (it = bitrate_observers_.begin(); it != bitrate_observers_.end(); ++it) { sum_start_bitrate += it->second->start_bitrate_; sum_min_bitrate += it->second->min_bitrate_; sum_max_bitrate += it->second->max_bitrate_; } - // Only change start bitrate if we have exactly one observer. By definition - // you can only have one start bitrate, once we have our first estimate we - // will adapt from there. - if (bitrate_observers_.size() == 1) { - bandwidth_estimation_.SetSendBitrate(sum_start_bitrate); + if (sum_max_bitrate == 0) { + // No max configured use 1Gbit/s. + sum_max_bitrate = 1000000000; + } + if (enforce_min_bitrate_ == false) { + // If not enforcing min bitrate, allow the bandwidth estimation to + // go as low as 10 kbps. + sum_min_bitrate = std::min(sum_min_bitrate, 10000u); } bandwidth_estimation_.SetMinMaxBitrate(sum_min_bitrate, sum_max_bitrate); @@ -160,30 +177,20 @@ void BitrateControllerImpl::RemoveBitrateObserver(BitrateObserver* observer) { if (it != bitrate_observers_.end()) { delete it->second; bitrate_observers_.erase(it); + bitrate_observers_modified_ = true; } } void BitrateControllerImpl::EnforceMinBitrate(bool enforce_min_bitrate) { CriticalSectionScoped cs(critsect_); enforce_min_bitrate_ = enforce_min_bitrate; -} - -void BitrateControllerImpl::SetBweMinBitrate(uint32_t min_bitrate) { - CriticalSectionScoped cs(critsect_); - bandwidth_estimation_.SetMinBitrate(min_bitrate); + UpdateMinMaxBitrate(); } void BitrateControllerImpl::OnReceivedEstimatedBitrate(const uint32_t bitrate) { - uint32_t new_bitrate = 0; - uint8_t fraction_lost = 0; - uint16_t rtt = 0; CriticalSectionScoped cs(critsect_); - if (bandwidth_estimation_.UpdateBandwidthEstimate(bitrate, - &new_bitrate, - &fraction_lost, - &rtt)) { - OnNetworkChanged(new_bitrate, fraction_lost, rtt); - } + bandwidth_estimation_.UpdateReceiverEstimate(bitrate); + MaybeTriggerOnNetworkChanged(); } void BitrateControllerImpl::OnReceivedRtcpReceiverReport( @@ -191,12 +198,27 @@ void BitrateControllerImpl::OnReceivedRtcpReceiverReport( const uint32_t rtt, const int number_of_packets, const uint32_t now_ms) { - uint32_t new_bitrate = 0; - uint8_t loss = fraction_loss; CriticalSectionScoped cs(critsect_); - if (bandwidth_estimation_.UpdatePacketLoss(number_of_packets, rtt, now_ms, - &loss, &new_bitrate)) { - OnNetworkChanged(new_bitrate, loss, rtt); + bandwidth_estimation_.UpdateReceiverBlock( + fraction_loss, rtt, number_of_packets, now_ms); + MaybeTriggerOnNetworkChanged(); +} + +void BitrateControllerImpl::MaybeTriggerOnNetworkChanged() { + uint32_t bitrate; + uint8_t fraction_loss; + uint32_t rtt; + bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt); + + if (bitrate_observers_modified_ || bitrate != last_bitrate_ || + fraction_loss != last_fraction_loss_ || rtt != last_rtt_ || + last_enforce_min_bitrate_ != enforce_min_bitrate_) { + last_bitrate_ = bitrate; + last_fraction_loss_ = fraction_loss; + last_rtt_ = rtt; + last_enforce_min_bitrate_ = enforce_min_bitrate_; + bitrate_observers_modified_ = false; + OnNetworkChanged(bitrate, fraction_loss, rtt); } } @@ -289,7 +311,15 @@ void BitrateControllerImpl::LowRateAllocation(uint32_t bitrate, bool BitrateControllerImpl::AvailableBandwidth(uint32_t* bandwidth) const { CriticalSectionScoped cs(critsect_); - return bandwidth_estimation_.AvailableBandwidth(bandwidth); + uint32_t bitrate; + uint8_t fraction_loss; + uint32_t rtt; + bandwidth_estimation_.CurrentEstimate(&bitrate, &fraction_loss, &rtt); + if (bitrate) { + *bandwidth = bitrate; + return true; + } + return false; } } // namespace webrtc diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_impl.h b/webrtc/modules/bitrate_controller/bitrate_controller_impl.h index 4e40997022..f9d2354ca1 100644 --- a/webrtc/modules/bitrate_controller/bitrate_controller_impl.h +++ b/webrtc/modules/bitrate_controller/bitrate_controller_impl.h @@ -45,8 +45,6 @@ class BitrateControllerImpl : public BitrateController { virtual void EnforceMinBitrate(bool enforce_min_bitrate) OVERRIDE; - virtual void SetBweMinBitrate(uint32_t min_bitrate) OVERRIDE; - private: class RtcpBandwidthObserverImpl; @@ -75,6 +73,7 @@ class BitrateControllerImpl : public BitrateController { BitrateObserverConfiguration; typedef std::list BitrateObserverConfList; + void UpdateMinMaxBitrate() EXCLUSIVE_LOCKS_REQUIRED(*critsect_); // Called by BitrateObserver's direct from the RTCP module. void OnReceivedEstimatedBitrate(const uint32_t bitrate); @@ -84,6 +83,8 @@ class BitrateControllerImpl : public BitrateController { const int number_of_packets, const uint32_t now_ms); + void MaybeTriggerOnNetworkChanged() EXCLUSIVE_LOCKS_REQUIRED(*critsect_); + void OnNetworkChanged(const uint32_t bitrate, const uint8_t fraction_loss, // 0 - 255. const uint32_t rtt) @@ -110,6 +111,11 @@ class BitrateControllerImpl : public BitrateController { SendSideBandwidthEstimation bandwidth_estimation_ GUARDED_BY(*critsect_); BitrateObserverConfList bitrate_observers_ GUARDED_BY(*critsect_); bool enforce_min_bitrate_ GUARDED_BY(*critsect_); + uint32_t last_bitrate_ GUARDED_BY(*critsect_); + uint8_t last_fraction_loss_ GUARDED_BY(*critsect_); + uint32_t last_rtt_ GUARDED_BY(*critsect_); + bool last_enforce_min_bitrate_ GUARDED_BY(*critsect_); + bool bitrate_observers_modified_ GUARDED_BY(*critsect_); }; } // namespace webrtc #endif // WEBRTC_MODULES_BITRATE_CONTROLLER_BITRATE_CONTROLLER_IMPL_H_ diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc index 30f85a81cb..c53928b239 100644 --- a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc +++ b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc @@ -92,9 +92,9 @@ TEST_F(BitrateControllerTest, OneBitrateObserverOneRtcpObserver) { webrtc::ReportBlockList report_blocks; report_blocks.push_back(CreateReportBlock(1, 2, 0, 1)); bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1); - EXPECT_EQ(0u, bitrate_observer.last_bitrate_); + EXPECT_EQ(200000u, bitrate_observer.last_bitrate_); EXPECT_EQ(0, bitrate_observer.last_fraction_loss_); - EXPECT_EQ(0u, bitrate_observer.last_rtt_); + EXPECT_EQ(50u, bitrate_observer.last_rtt_); // Test bitrate increase 8% per second. report_blocks.clear(); @@ -161,9 +161,9 @@ TEST_F(BitrateControllerTest, OneBitrateObserverTwoRtcpObservers) { bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1); second_bandwidth_observer->OnReceivedRtcpReceiverReport( report_blocks, 100, 1); - EXPECT_EQ(0u, bitrate_observer.last_bitrate_); + EXPECT_EQ(200000u, bitrate_observer.last_bitrate_); EXPECT_EQ(0, bitrate_observer.last_fraction_loss_); - EXPECT_EQ(0u, bitrate_observer.last_rtt_); + EXPECT_EQ(100u, bitrate_observer.last_rtt_); // Test bitrate increase 8% per second. report_blocks.clear(); @@ -323,11 +323,6 @@ TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) { webrtc::ReportBlockList report_blocks; report_blocks.push_back(CreateReportBlock(1, 2, 0, 1)); bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1); - - // Test bitrate increase 8% per second, distributed equally. - report_blocks.clear(); - report_blocks.push_back(CreateReportBlock(1, 2, 0, 21)); - bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001); EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_); EXPECT_EQ(50u, bitrate_observer_1.last_rtt_); @@ -336,21 +331,22 @@ TEST_F(BitrateControllerTest, TwoBitrateObserversOneRtcpObserver) { EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_); EXPECT_EQ(50u, bitrate_observer_2.last_rtt_); + // Test bitrate increase 8% per second, distributed equally. report_blocks.clear(); - report_blocks.push_back(CreateReportBlock(1, 2, 0, 41)); - bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 21)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 1001); EXPECT_EQ(112500u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(212500u, bitrate_observer_2.last_bitrate_); report_blocks.clear(); - report_blocks.push_back(CreateReportBlock(1, 2, 0, 61)); - bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 41)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 2001); EXPECT_EQ(126000u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(226000u, bitrate_observer_2.last_bitrate_); report_blocks.clear(); - report_blocks.push_back(CreateReportBlock(1, 2, 0, 81)); - bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 4001); + report_blocks.push_back(CreateReportBlock(1, 2, 0, 61)); + bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, 3001); EXPECT_EQ(140580u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(240580u, bitrate_observer_2.last_bitrate_); @@ -434,8 +430,12 @@ TEST_F(BitrateControllerTestNoEnforceMin, OneBitrateObserver) { EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_); // Low REMB. - bandwidth_observer_->OnReceivedEstimatedBitrate(1000); - EXPECT_EQ(1000u, bitrate_observer_1.last_bitrate_); + bandwidth_observer_->OnReceivedEstimatedBitrate(10000); + EXPECT_EQ(10000u, bitrate_observer_1.last_bitrate_); + + // Keeps at least 10 kbps. + bandwidth_observer_->OnReceivedEstimatedBitrate(9000); + EXPECT_EQ(10000u, bitrate_observer_1.last_bitrate_); controller_->RemoveBitrateObserver(&bitrate_observer_1); } @@ -469,9 +469,15 @@ TEST_F(BitrateControllerTestNoEnforceMin, ThreeBitrateObservers) { EXPECT_EQ(200000u, bitrate_observer_3.last_bitrate_); // Remainder. // Low REMB. - bandwidth_observer_->OnReceivedEstimatedBitrate(1000); + bandwidth_observer_->OnReceivedEstimatedBitrate(10000); // Verify that the first observer gets all the rate, and the rest get zero. - EXPECT_EQ(1000u, bitrate_observer_1.last_bitrate_); + EXPECT_EQ(10000u, bitrate_observer_1.last_bitrate_); + EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_); + EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_); + + // Verify it keeps an estimate of at least 10kbps. + bandwidth_observer_->OnReceivedEstimatedBitrate(9000); + EXPECT_EQ(10000u, bitrate_observer_1.last_bitrate_); EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_); EXPECT_EQ(0u, bitrate_observer_3.last_bitrate_); diff --git a/webrtc/modules/bitrate_controller/include/bitrate_controller.h b/webrtc/modules/bitrate_controller/include/bitrate_controller.h index 3117bfd6f2..0f74367658 100644 --- a/webrtc/modules/bitrate_controller/include/bitrate_controller.h +++ b/webrtc/modules/bitrate_controller/include/bitrate_controller.h @@ -73,10 +73,6 @@ class BitrateController { // Changes the mode that was set in the constructor. virtual void EnforceMinBitrate(bool enforce_min_bitrate) = 0; - - // Changes the minimum configured bitrate of the send-side bandwidth - // estimator. - virtual void SetBweMinBitrate(uint32_t min_bitrate) = 0; }; } // namespace webrtc #endif // WEBRTC_MODULES_BITRATE_CONTROLLER_INCLUDE_BITRATE_CONTROLLER_H_ diff --git a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc index a089590bde..52eec8fe2d 100644 --- a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc +++ b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc @@ -10,11 +10,41 @@ #include "webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h" -#include // sqrt() +#include #include "webrtc/system_wrappers/interface/trace.h" namespace webrtc { +namespace { +enum { kBweIncreaseIntervalMs = 1000 }; +enum { kBweDecreaseIntervalMs = 300 }; +enum { kLimitNumPackets = 20 }; +enum { kAvgPacketSizeBytes = 1000 }; + +// Calculate the rate that TCP-Friendly Rate Control (TFRC) would apply. +// The formula in RFC 3448, Section 3.1, is used. +uint32_t CalcTfrcBps(uint16_t rtt, uint8_t loss) { + if (rtt == 0 || loss == 0) { + // Input variables out of range. + return 0; + } + double R = static_cast(rtt) / 1000; // RTT in seconds. + int b = 1; // Number of packets acknowledged by a single TCP acknowledgement: + // recommended = 1. + double t_RTO = 4.0 * R; // TCP retransmission timeout value in seconds + // recommended = 4*R. + double p = static_cast(loss) / 255; // Packet loss rate in [0, 1). + double s = static_cast(kAvgPacketSizeBytes); + + // Calculate send rate in bytes/second. + double X = + s / (R * std::sqrt(2 * b * p / 3) + + (t_RTO * (3 * std::sqrt(3 * b * p / 8) * p * (1 + 32 * p * p)))); + + // Convert to bits/second. + return (static_cast(X * 8)); +} +} SendSideBandwidthEstimation::SendSideBandwidthEstimation() : accumulate_lost_packets_Q8_(0), @@ -30,190 +60,121 @@ SendSideBandwidthEstimation::SendSideBandwidthEstimation() SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {} -void SendSideBandwidthEstimation::SetSendBitrate(const uint32_t bitrate) { +void SendSideBandwidthEstimation::SetSendBitrate(uint32_t bitrate) { bitrate_ = bitrate; } -void SendSideBandwidthEstimation::SetMinMaxBitrate(const uint32_t min_bitrate, - const uint32_t max_bitrate) { +void SendSideBandwidthEstimation::SetMinMaxBitrate(uint32_t min_bitrate, + uint32_t max_bitrate) { min_bitrate_configured_ = min_bitrate; - if (max_bitrate == 0) { - // no max configured use 1Gbit/s - max_bitrate_configured_ = 1000000000; - } else { - max_bitrate_configured_ = max_bitrate; - } + max_bitrate_configured_ = max_bitrate; } void SendSideBandwidthEstimation::SetMinBitrate(uint32_t min_bitrate) { min_bitrate_configured_ = min_bitrate; } -bool SendSideBandwidthEstimation::UpdateBandwidthEstimate( - const uint32_t bandwidth, - uint32_t* new_bitrate, - uint8_t* fraction_lost, - uint16_t* rtt) { - *new_bitrate = 0; - bwe_incoming_ = bandwidth; - - if (bitrate_ == 0) { - // SendSideBandwidthEstimation off - return false; - } - if (bwe_incoming_ > 0 && bitrate_ > bwe_incoming_) { - bitrate_ = bwe_incoming_; - *new_bitrate = bitrate_; - *fraction_lost = last_fraction_loss_; - *rtt = last_round_trip_time_; - return true; - } - return false; +void SendSideBandwidthEstimation::CurrentEstimate(uint32_t* bitrate, + uint8_t* loss, + uint32_t* rtt) const { + *bitrate = bitrate_; + *loss = last_fraction_loss_; + *rtt = last_round_trip_time_; } -bool SendSideBandwidthEstimation::UpdatePacketLoss( - const int number_of_packets, - const uint32_t rtt, - const uint32_t now_ms, - uint8_t* loss, - uint32_t* new_bitrate) { - if (bitrate_ == 0) { - // SendSideBandwidthEstimation off - return false; - } +void SendSideBandwidthEstimation::UpdateReceiverEstimate(uint32_t bandwidth) { + bwe_incoming_ = bandwidth; + CapBitrateToThresholds(); +} + +void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, + uint32_t rtt, + int number_of_packets, + uint32_t now_ms) { // Update RTT. last_round_trip_time_ = rtt; // Check sequence number diff and weight loss report if (number_of_packets > 0) { // Calculate number of lost packets. - const int num_lost_packets_Q8 = *loss * number_of_packets; + const int num_lost_packets_Q8 = fraction_loss * number_of_packets; // Accumulate reports. accumulate_lost_packets_Q8_ += num_lost_packets_Q8; accumulate_expected_packets_ += number_of_packets; // Report loss if the total report is based on sufficiently many packets. if (accumulate_expected_packets_ >= kLimitNumPackets) { - *loss = accumulate_lost_packets_Q8_ / accumulate_expected_packets_; + last_fraction_loss_ = + accumulate_lost_packets_Q8_ / accumulate_expected_packets_; - // Reset accumulators + // Reset accumulators. accumulate_lost_packets_Q8_ = 0; accumulate_expected_packets_ = 0; } else { - // Report zero loss until we have enough data to estimate - // the loss rate. - return false; + // Early return without updating estimate. + return; } } - // Keep for next time. - last_fraction_loss_ = *loss; - uint32_t bitrate = 0; - if (!ShapeSimple(*loss, rtt, now_ms, &bitrate)) { - // No change. - return false; - } - bitrate_ = bitrate; - *new_bitrate = bitrate; - return true; + UpdateEstimate(now_ms); } -bool SendSideBandwidthEstimation::AvailableBandwidth( - uint32_t* bandwidth) const { - if (bitrate_ == 0) { - return false; - } - *bandwidth = bitrate_; - return true; -} +void SendSideBandwidthEstimation::UpdateEstimate(uint32_t now_ms) { + if (last_fraction_loss_ <= 5) { + // Loss < 2%: Limit the rate increases to once a kBweIncreaseIntervalMs. + if ((now_ms - time_last_increase_) >= kBweIncreaseIntervalMs) { + time_last_increase_ = now_ms; -/* - * Calculate the rate that TCP-Friendly Rate Control (TFRC) would apply. - * The formula in RFC 3448, Section 3.1, is used. - */ -uint32_t SendSideBandwidthEstimation::CalcTFRCbps(uint16_t rtt, uint8_t loss) { - if (rtt == 0 || loss == 0) { - // input variables out of range - return 0; - } - double R = static_cast(rtt) / 1000; // RTT in seconds - int b = 1; // number of packets acknowledged by a single TCP acknowledgement; - // recommended = 1 - double t_RTO = 4.0 * R; // TCP retransmission timeout value in seconds - // recommended = 4*R - double p = static_cast(loss) / 255; // packet loss rate in [0, 1) - double s = static_cast(kAvgPacketSizeBytes); + // Increase rate by 8%. + bitrate_ = static_cast(bitrate_ * 1.08 + 0.5); - // calculate send rate in bytes/second - double X = s / (R * sqrt(2 * b * p / 3) + - (t_RTO * (3 * sqrt(3 * b * p / 8) * p * (1 + 32 * p * p)))); - - return (static_cast(X * 8)); // bits/second -} - -bool SendSideBandwidthEstimation::ShapeSimple(const uint8_t loss, - const uint32_t rtt, - const uint32_t now_ms, - uint32_t* bitrate) { - uint32_t new_bitrate = 0; - - // Limit the rate increases to once a kBWEIncreaseIntervalMs. - if (loss <= 5) { - if ((now_ms - time_last_increase_) < kBWEIncreaseIntervalMs) { - return false; + // Add 1 kbps extra, just to make sure that we do not get stuck + // (gives a little extra increase at low rates, negligible at higher + // rates). + bitrate_ += 1000; } - time_last_increase_ = now_ms; - } - // Limit the rate decreases to once a kBWEDecreaseIntervalMs + rtt. - if (loss > 26) { - if ((now_ms - time_last_decrease_) < kBWEDecreaseIntervalMs + rtt) { - return false; - } - time_last_decrease_ = now_ms; - } - if (loss > 5 && loss <= 26) { - // 2% - 10% - new_bitrate = bitrate_; - } else if (loss > 26) { - // 26/256 ~= 10% - // reduce rate: newRate = rate * (1 - 0.5*lossRate) - // packetLoss = 256*lossRate - new_bitrate = static_cast((bitrate_ * - static_cast(512 - loss)) / 512.0); - // Calculate what rate TFRC would apply in this situation - // scale loss to Q0 (back to [0, 255]) - uint32_t tfrc_bitrate = CalcTFRCbps(rtt, loss); - if (tfrc_bitrate > new_bitrate) { - // do not reduce further if rate is below TFRC rate - new_bitrate = tfrc_bitrate; - } + } else if (last_fraction_loss_ <= 26) { + // Loss between 2% - 10%: Do nothing. + } else { - // increase rate by 8% - new_bitrate = static_cast(bitrate_ * 1.08 + 0.5); + // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs + + // rtt. + if ((now_ms - time_last_decrease_) >= + static_cast(kBweDecreaseIntervalMs + last_round_trip_time_)) { + time_last_decrease_ = now_ms; - // add 1 kbps extra, just to make sure that we do not get stuck - // (gives a little extra increase at low rates, negligible at higher rates) - new_bitrate += 1000; + // Reduce rate: + // newRate = rate * (1 - 0.5*lossRate); + // where packetLoss = 256*lossRate; + bitrate_ = static_cast( + (bitrate_ * static_cast(512 - last_fraction_loss_)) / 512.0); + + // Calculate what rate TFRC would apply in this situation and to not + // reduce further than it. + bitrate_ = std::max( + bitrate_, CalcTfrcBps(last_round_trip_time_, last_fraction_loss_)); + } } - CapBitrateToThresholds(&new_bitrate); - *bitrate = new_bitrate; - return true; + + CapBitrateToThresholds(); } -void SendSideBandwidthEstimation::CapBitrateToThresholds( - uint32_t* new_bitrate) { - if (bwe_incoming_ > 0 && *new_bitrate > bwe_incoming_) { - *new_bitrate = bwe_incoming_; +void SendSideBandwidthEstimation::CapBitrateToThresholds() { + if (bwe_incoming_ > 0 && bitrate_ > bwe_incoming_) { + bitrate_ = bwe_incoming_; } - if (*new_bitrate > max_bitrate_configured_) { - *new_bitrate = max_bitrate_configured_; + if (bitrate_ > max_bitrate_configured_) { + bitrate_ = max_bitrate_configured_; } - if (*new_bitrate < min_bitrate_configured_) { - WEBRTC_TRACE(kTraceWarning, kTraceRtpRtcp, -1, + if (bitrate_ < min_bitrate_configured_) { + WEBRTC_TRACE(kTraceWarning, + kTraceRtpRtcp, + -1, "The configured min bitrate (%u kbps) is greater than the " "estimated available bandwidth (%u kbps).\n", - min_bitrate_configured_ / 1000, *new_bitrate / 1000); - *new_bitrate = min_bitrate_configured_; + min_bitrate_configured_ / 1000, + bitrate_ / 1000); + bitrate_ = min_bitrate_configured_; } } diff --git a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h index 79b9e2daa5..9ba3a68078 100644 --- a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h +++ b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h @@ -22,39 +22,24 @@ class SendSideBandwidthEstimation { SendSideBandwidthEstimation(); virtual ~SendSideBandwidthEstimation(); - // Call when we receive a RTCP message with TMMBR or REMB - // Return true if new_bitrate is valid. - bool UpdateBandwidthEstimate(const uint32_t bandwidth, - uint32_t* new_bitrate, - uint8_t* fraction_lost, - uint16_t* rtt); + void CurrentEstimate(uint32_t* bitrate, uint8_t* loss, uint32_t* rtt) const; - // Call when we receive a RTCP message with a ReceiveBlock - // Return true if new_bitrate is valid. - bool UpdatePacketLoss(const int number_of_packets, - const uint32_t rtt, - const uint32_t now_ms, - uint8_t* loss, - uint32_t* new_bitrate); + // Call when we receive a RTCP message with TMMBR or REMB. + void UpdateReceiverEstimate(uint32_t bandwidth); - // Return false if no bandwidth estimate is available - bool AvailableBandwidth(uint32_t* bandwidth) const; - void SetSendBitrate(const uint32_t bitrate); - void SetMinMaxBitrate(const uint32_t min_bitrate, const uint32_t max_bitrate); + // Call when we receive a RTCP message with a ReceiveBlock. + void UpdateReceiverBlock(uint8_t fraction_loss, + uint32_t rtt, + int number_of_packets, + uint32_t now_ms); + + void SetSendBitrate(uint32_t bitrate); + void SetMinMaxBitrate(uint32_t min_bitrate, uint32_t max_bitrate); void SetMinBitrate(uint32_t min_bitrate); private: - bool ShapeSimple(const uint8_t loss, const uint32_t rtt, - const uint32_t now_ms, uint32_t* bitrate); - - void CapBitrateToThresholds(uint32_t* bitrate); - - uint32_t CalcTFRCbps(uint16_t rtt, uint8_t loss); - - enum { kBWEIncreaseIntervalMs = 1000 }; - enum { kBWEDecreaseIntervalMs = 300 }; - enum { kLimitNumPackets = 20 }; - enum { kAvgPacketSizeBytes = 1000 }; + void UpdateEstimate(uint32_t now_ms); + void CapBitrateToThresholds(); // incoming filters int accumulate_lost_packets_Q8_; diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index fd619a0ce9..620972b04a 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -1159,7 +1159,6 @@ int ViEEncoder::StopDebugRecording() { void ViEEncoder::SuspendBelowMinBitrate() { vcm_.SuspendBelowMinBitrate(); bitrate_controller_->EnforceMinBitrate(false); - bitrate_controller_->SetBweMinBitrate(10000); } void ViEEncoder::RegisterPreEncodeCallback(