diff --git a/webrtc/modules/congestion_controller/BUILD.gn b/webrtc/modules/congestion_controller/BUILD.gn index f32b7b62f5..ef45297031 100644 --- a/webrtc/modules/congestion_controller/BUILD.gn +++ b/webrtc/modules/congestion_controller/BUILD.gn @@ -10,6 +10,8 @@ import("../../webrtc.gni") rtc_static_library("congestion_controller") { sources = [ + "acknowledge_bitrate_estimator.cc", + "acknowledge_bitrate_estimator.h", "congestion_controller.cc", "delay_based_bwe.cc", "delay_based_bwe.h", diff --git a/webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.cc b/webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.cc new file mode 100644 index 0000000000..9df378c64b --- /dev/null +++ b/webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.cc @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.h" + +#include + +#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" + +namespace webrtc { + +namespace { +constexpr int kInitialRateWindowMs = 500; +constexpr int kRateWindowMs = 150; + +bool IsInSendTimeHistory(const PacketFeedback& packet) { + return packet.send_time_ms >= 0; +} + +} // namespace + +AcknowledgedBitrateEstimator::AcknowledgedBitrateEstimator() + : sum_(0), + current_win_ms_(0), + prev_time_ms_(-1), + bitrate_estimate_(-1.0f), + bitrate_estimate_var_(50.0f) {} + +void AcknowledgedBitrateEstimator::IncomingPacketFeedbackVector( + const std::vector& packet_feedback_vector) { + RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(), + packet_feedback_vector.end(), + PacketFeedbackComparator())); + for (const auto& packet : packet_feedback_vector) { + if (IsInSendTimeHistory(packet)) + Update(packet.arrival_time_ms, packet.payload_size); + } +} + +void AcknowledgedBitrateEstimator::Update(int64_t now_ms, int bytes) { + int rate_window_ms = kRateWindowMs; + // We use a larger window at the beginning to get a more stable sample that + // we can use to initialize the estimate. + if (bitrate_estimate_ < 0.f) + rate_window_ms = kInitialRateWindowMs; + float bitrate_sample = UpdateWindow(now_ms, bytes, rate_window_ms); + if (bitrate_sample < 0.0f) + return; + if (bitrate_estimate_ < 0.0f) { + // This is the very first sample we get. Use it to initialize the estimate. + bitrate_estimate_ = bitrate_sample; + return; + } + // Define the sample uncertainty as a function of how far away it is from the + // current estimate. + float sample_uncertainty = + 10.0f * std::abs(bitrate_estimate_ - bitrate_sample) / bitrate_estimate_; + float sample_var = sample_uncertainty * sample_uncertainty; + // Update a bayesian estimate of the rate, weighting it lower if the sample + // uncertainty is large. + // The bitrate estimate uncertainty is increased with each update to model + // that the bitrate changes over time. + float pred_bitrate_estimate_var = bitrate_estimate_var_ + 5.f; + bitrate_estimate_ = (sample_var * bitrate_estimate_ + + pred_bitrate_estimate_var * bitrate_sample) / + (sample_var + pred_bitrate_estimate_var); + bitrate_estimate_var_ = sample_var * pred_bitrate_estimate_var / + (sample_var + pred_bitrate_estimate_var); +} + +float AcknowledgedBitrateEstimator::UpdateWindow(int64_t now_ms, + int bytes, + int rate_window_ms) { + // Reset if time moves backwards. + if (now_ms < prev_time_ms_) { + prev_time_ms_ = -1; + sum_ = 0; + current_win_ms_ = 0; + } + if (prev_time_ms_ >= 0) { + current_win_ms_ += now_ms - prev_time_ms_; + // Reset if nothing has been received for more than a full window. + if (now_ms - prev_time_ms_ > rate_window_ms) { + sum_ = 0; + current_win_ms_ %= rate_window_ms; + } + } + prev_time_ms_ = now_ms; + float bitrate_sample = -1.0f; + if (current_win_ms_ >= rate_window_ms) { + bitrate_sample = 8.0f * sum_ / static_cast(rate_window_ms); + current_win_ms_ -= rate_window_ms; + sum_ = 0; + } + sum_ += bytes; + return bitrate_sample; +} + +rtc::Optional AcknowledgedBitrateEstimator::bitrate_bps() const { + if (bitrate_estimate_ < 0.f) + return rtc::Optional(); + return rtc::Optional(bitrate_estimate_ * 1000); +} + +} // namespace webrtc diff --git a/webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.h b/webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.h new file mode 100644 index 0000000000..7a9d669a1c --- /dev/null +++ b/webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_CONGESTION_CONTROLLER_ACKNOWLEDGE_BITRATE_ESTIMATOR_H_ +#define WEBRTC_MODULES_CONGESTION_CONTROLLER_ACKNOWLEDGE_BITRATE_ESTIMATOR_H_ + +#include + +#include "webrtc/base/optional.h" + +namespace webrtc { + +struct PacketFeedback; + +// Computes a bayesian estimate of the throughput given acks containing +// the arrival time and payload size. Samples which are far from the current +// estimate or are based on few packets are given a smaller weight, as they +// are considered to be more likely to have been caused by, e.g., delay spikes +// unrelated to congestion. +class AcknowledgedBitrateEstimator { + public: + AcknowledgedBitrateEstimator(); + + void IncomingPacketFeedbackVector( + const std::vector& packet_feedback_vector); + rtc::Optional bitrate_bps() const; + + private: + void Update(int64_t now_ms, int bytes); + float UpdateWindow(int64_t now_ms, int bytes, int rate_window_ms); + + int sum_; + int64_t current_win_ms_; + int64_t prev_time_ms_; + float bitrate_estimate_; + float bitrate_estimate_var_; +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_CONGESTION_CONTROLLER_ACKNOWLEDGE_BITRATE_ESTIMATOR_H_ diff --git a/webrtc/modules/congestion_controller/delay_based_bwe.cc b/webrtc/modules/congestion_controller/delay_based_bwe.cc index fca5143bb1..147f2432b2 100644 --- a/webrtc/modules/congestion_controller/delay_based_bwe.cc +++ b/webrtc/modules/congestion_controller/delay_based_bwe.cc @@ -38,8 +38,6 @@ constexpr double kTimestampToMs = // This ssrc is used to fulfill the current API but will be removed // after the API has been changed. constexpr uint32_t kFixedSsrc = 0; -constexpr int kInitialRateWindowMs = 500; -constexpr int kRateWindowMs = 150; // Parameters for linear least squares fit of regression line to noisy data. constexpr size_t kDefaultTrendlineWindowSize = 20; @@ -55,111 +53,16 @@ bool BweSparseUpdateExperimentIsEnabled() { webrtc::field_trial::FindFullName(kBweSparseUpdateExperiment); return experiment_string == "Enabled"; } - -class PacketFeedbackComparator { - public: - inline bool operator()(const webrtc::PacketFeedback& lhs, - const webrtc::PacketFeedback& rhs) { - if (lhs.arrival_time_ms != rhs.arrival_time_ms) - return lhs.arrival_time_ms < rhs.arrival_time_ms; - if (lhs.send_time_ms != rhs.send_time_ms) - return lhs.send_time_ms < rhs.send_time_ms; - return lhs.sequence_number < rhs.sequence_number; - } -}; - -void SortPacketFeedbackVector(const std::vector& input, - std::vector* output) { - auto pred = [](const webrtc::PacketFeedback& packet_feedback) { - return packet_feedback.arrival_time_ms != - webrtc::PacketFeedback::kNotReceived; - }; - std::copy_if(input.begin(), input.end(), std::back_inserter(*output), pred); - std::sort(output->begin(), output->end(), PacketFeedbackComparator()); -} } // namespace namespace webrtc { -DelayBasedBwe::BitrateEstimator::BitrateEstimator() - : sum_(0), - current_win_ms_(0), - prev_time_ms_(-1), - bitrate_estimate_(-1.0f), - bitrate_estimate_var_(50.0f) {} - -void DelayBasedBwe::BitrateEstimator::Update(int64_t now_ms, int bytes) { - int rate_window_ms = kRateWindowMs; - // We use a larger window at the beginning to get a more stable sample that - // we can use to initialize the estimate. - if (bitrate_estimate_ < 0.f) - rate_window_ms = kInitialRateWindowMs; - float bitrate_sample = UpdateWindow(now_ms, bytes, rate_window_ms); - if (bitrate_sample < 0.0f) - return; - if (bitrate_estimate_ < 0.0f) { - // This is the very first sample we get. Use it to initialize the estimate. - bitrate_estimate_ = bitrate_sample; - return; - } - // Define the sample uncertainty as a function of how far away it is from the - // current estimate. - float sample_uncertainty = - 10.0f * std::abs(bitrate_estimate_ - bitrate_sample) / bitrate_estimate_; - float sample_var = sample_uncertainty * sample_uncertainty; - // Update a bayesian estimate of the rate, weighting it lower if the sample - // uncertainty is large. - // The bitrate estimate uncertainty is increased with each update to model - // that the bitrate changes over time. - float pred_bitrate_estimate_var = bitrate_estimate_var_ + 5.f; - bitrate_estimate_ = (sample_var * bitrate_estimate_ + - pred_bitrate_estimate_var * bitrate_sample) / - (sample_var + pred_bitrate_estimate_var); - bitrate_estimate_var_ = sample_var * pred_bitrate_estimate_var / - (sample_var + pred_bitrate_estimate_var); -} - -float DelayBasedBwe::BitrateEstimator::UpdateWindow(int64_t now_ms, - int bytes, - int rate_window_ms) { - // Reset if time moves backwards. - if (now_ms < prev_time_ms_) { - prev_time_ms_ = -1; - sum_ = 0; - current_win_ms_ = 0; - } - if (prev_time_ms_ >= 0) { - current_win_ms_ += now_ms - prev_time_ms_; - // Reset if nothing has been received for more than a full window. - if (now_ms - prev_time_ms_ > rate_window_ms) { - sum_ = 0; - current_win_ms_ %= rate_window_ms; - } - } - prev_time_ms_ = now_ms; - float bitrate_sample = -1.0f; - if (current_win_ms_ >= rate_window_ms) { - bitrate_sample = 8.0f * sum_ / static_cast(rate_window_ms); - current_win_ms_ -= rate_window_ms; - sum_ = 0; - } - sum_ += bytes; - return bitrate_sample; -} - -rtc::Optional DelayBasedBwe::BitrateEstimator::bitrate_bps() const { - if (bitrate_estimate_ < 0.f) - return rtc::Optional(); - return rtc::Optional(bitrate_estimate_ * 1000); -} - DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock) : event_log_(event_log), clock_(clock), inter_arrival_(), trendline_estimator_(), detector_(), - receiver_incoming_bitrate_(), last_seen_packet_ms_(-1), uma_recorded_(false), probe_bitrate_estimator_(event_log), @@ -177,16 +80,17 @@ DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock) DelayBasedBwe::~DelayBasedBwe() {} DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( - const std::vector& packet_feedback_vector) { + const std::vector& packet_feedback_vector, + rtc::Optional acked_bitrate_bps) { + RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(), + packet_feedback_vector.end(), + PacketFeedbackComparator())); RTC_DCHECK(network_thread_.CalledOnValidThread()); - std::vector sorted_packet_feedback_vector; - SortPacketFeedbackVector(packet_feedback_vector, - &sorted_packet_feedback_vector); // TOOD(holmer): An empty feedback vector here likely means that // all acks were too late and that the send time history had // timed out. We should reduce the rate when this occurs. - if (sorted_packet_feedback_vector.empty()) { + if (packet_feedback_vector.empty()) { LOG(LS_WARNING) << "Very late feedback received."; return DelayBasedBwe::Result(); } @@ -199,7 +103,7 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( } bool overusing = false; bool delayed_feedback = true; - for (const auto& packet_feedback : sorted_packet_feedback_vector) { + for (const auto& packet_feedback : packet_feedback_vector) { if (packet_feedback.send_time_ms < 0) continue; delayed_feedback = false; @@ -213,12 +117,11 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( ++consecutive_delayed_feedbacks_; if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { consecutive_delayed_feedbacks_ = 0; - return OnLongFeedbackDelay( - sorted_packet_feedback_vector.back().arrival_time_ms); + return OnLongFeedbackDelay(packet_feedback_vector.back().arrival_time_ms); } } else { consecutive_delayed_feedbacks_ = 0; - return MaybeUpdateEstimate(overusing); + return MaybeUpdateEstimate(overusing, acked_bitrate_bps); } return Result(); } @@ -243,10 +146,6 @@ DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( void DelayBasedBwe::IncomingPacketFeedback( const PacketFeedback& packet_feedback) { int64_t now_ms = clock_->TimeInMilliseconds(); - - receiver_incoming_bitrate_.Update(packet_feedback.arrival_time_ms, - packet_feedback.payload_size); - Result result; // Reset if the stream has timed out. if (last_seen_packet_ms_ == -1 || now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { @@ -289,12 +188,12 @@ void DelayBasedBwe::IncomingPacketFeedback( } } -DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(bool overusing) { +DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate( + bool overusing, + rtc::Optional acked_bitrate_bps) { Result result; int64_t now_ms = clock_->TimeInMilliseconds(); - rtc::Optional acked_bitrate_bps = - receiver_incoming_bitrate_.bitrate_bps(); rtc::Optional probe_bitrate_bps = probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps(); // Currently overusing the bandwidth. diff --git a/webrtc/modules/congestion_controller/delay_based_bwe.h b/webrtc/modules/congestion_controller/delay_based_bwe.h index eccd73ac4d..c44ea12e1c 100644 --- a/webrtc/modules/congestion_controller/delay_based_bwe.h +++ b/webrtc/modules/congestion_controller/delay_based_bwe.h @@ -48,7 +48,8 @@ class DelayBasedBwe { virtual ~DelayBasedBwe(); Result IncomingPacketFeedbackVector( - const std::vector& packet_feedback_vector); + const std::vector& packet_feedback_vector, + rtc::Optional acked_bitrate_bps); void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms); bool LatestEstimate(std::vector* ssrcs, uint32_t* bitrate_bps) const; @@ -57,30 +58,11 @@ class DelayBasedBwe { int64_t GetExpectedBwePeriodMs() const; private: - // Computes a bayesian estimate of the throughput given acks containing - // the arrival time and payload size. Samples which are far from the current - // estimate or are based on few packets are given a smaller weight, as they - // are considered to be more likely to have been caused by, e.g., delay spikes - // unrelated to congestion. - class BitrateEstimator { - public: - BitrateEstimator(); - void Update(int64_t now_ms, int bytes); - rtc::Optional bitrate_bps() const; - - private: - float UpdateWindow(int64_t now_ms, int bytes, int rate_window_ms); - int sum_; - int64_t current_win_ms_; - int64_t prev_time_ms_; - float bitrate_estimate_; - float bitrate_estimate_var_; - }; - void IncomingPacketFeedback(const PacketFeedback& packet_feedback); Result OnLongFeedbackDelay(int64_t arrival_time_ms); - Result MaybeUpdateEstimate(bool overusing); + Result MaybeUpdateEstimate(bool overusing, + rtc::Optional acked_bitrate_bps); // Updates the current remote rate estimate and returns true if a valid // estimate exists. bool UpdateEstimate(int64_t now_ms, @@ -94,7 +76,6 @@ class DelayBasedBwe { std::unique_ptr inter_arrival_; std::unique_ptr trendline_estimator_; OveruseDetector detector_; - BitrateEstimator receiver_incoming_bitrate_; int64_t last_seen_packet_ms_; bool uma_recorded_; AimdRateControl rate_control_; diff --git a/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc b/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc index dcec0f8000..a368658b7a 100644 --- a/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc +++ b/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc @@ -27,7 +27,8 @@ const PacedPacketInfo kPacingInfo1(1, kNumProbesCluster1, 4000); TEST_F(DelayBasedBweTest, NoCrashEmptyFeedback) { std::vector packet_feedback_vector; - bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector); + bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector, + rtc::Optional()); } TEST_F(DelayBasedBweTest, NoCrashOnlyLostFeedback) { @@ -36,7 +37,8 @@ TEST_F(DelayBasedBweTest, NoCrashOnlyLostFeedback) { PacketFeedback(-1, -1, 0, 1500, PacedPacketInfo())); packet_feedback_vector.push_back( PacketFeedback(-1, -1, 1, 1500, PacedPacketInfo())); - bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector); + bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector, + rtc::Optional()); } TEST_F(DelayBasedBweTest, ProbeDetection) { diff --git a/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.cc b/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.cc index 479ecb457b..62c9f881bc 100644 --- a/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.cc +++ b/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.cc @@ -14,6 +14,7 @@ #include #include "webrtc/base/checks.h" +#include "webrtc/base/ptr_util.h" #include "webrtc/modules/congestion_controller/delay_based_bwe.h" namespace webrtc { @@ -149,6 +150,8 @@ int64_t StreamGenerator::GenerateFrame(std::vector* packets, DelayBasedBweTest::DelayBasedBweTest() : clock_(100000000), + acknowledged_bitrate_estimator_( + rtc::MakeUnique()), bitrate_estimator_(new DelayBasedBwe(nullptr, &clock_)), stream_generator_(new test::StreamGenerator(1e6, // Capacity. clock_.TimeInMicroseconds())), @@ -181,8 +184,10 @@ void DelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms, sequence_number, payload_size, pacing_info); std::vector packets; packets.push_back(packet); + acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets); DelayBasedBwe::Result result = - bitrate_estimator_->IncomingPacketFeedbackVector(packets); + bitrate_estimator_->IncomingPacketFeedbackVector( + packets, acknowledged_bitrate_estimator_->bitrate_bps()); const uint32_t kDummySsrc = 0; if (result.updated) { bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc}, @@ -213,8 +218,11 @@ bool DelayBasedBweTest::GenerateAndProcessFrame(uint32_t ssrc, RTC_CHECK_GE(packet.arrival_time_ms + arrival_time_offset_ms_, 0); packet.arrival_time_ms += arrival_time_offset_ms_; } + + acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets); DelayBasedBwe::Result result = - bitrate_estimator_->IncomingPacketFeedbackVector(packets); + bitrate_estimator_->IncomingPacketFeedbackVector( + packets, acknowledged_bitrate_estimator_->bitrate_bps()); const uint32_t kDummySsrc = 0; if (result.updated) { bitrate_observer_.OnReceiveBitrateChanged({kDummySsrc}, diff --git a/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.h b/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.h index 089391f532..a12bee52b9 100644 --- a/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.h +++ b/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.h @@ -18,6 +18,7 @@ #include #include "webrtc/base/constructormagic.h" +#include "webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.h" #include "webrtc/modules/congestion_controller/delay_based_bwe.h" #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" #include "webrtc/system_wrappers/include/clock.h" @@ -164,6 +165,7 @@ class DelayBasedBweTest : public ::testing::Test { SimulatedClock clock_; // Time at the receiver. test::TestBitrateObserver bitrate_observer_; + std::unique_ptr acknowledged_bitrate_estimator_; std::unique_ptr bitrate_estimator_; std::unique_ptr stream_generator_; int64_t arrival_time_offset_ms_; diff --git a/webrtc/modules/congestion_controller/include/send_side_congestion_controller.h b/webrtc/modules/congestion_controller/include/send_side_congestion_controller.h index fd76ba0cde..4533d46e8e 100644 --- a/webrtc/modules/congestion_controller/include/send_side_congestion_controller.h +++ b/webrtc/modules/congestion_controller/include/send_side_congestion_controller.h @@ -34,6 +34,7 @@ namespace webrtc { class BitrateController; class Clock; +class AcknowledgedBitrateEstimator; class ProbeController; class RateLimiter; class RtcEventLog; @@ -141,6 +142,7 @@ class SendSideCongestionController : public CallStatsObserver, RtcEventLog* const event_log_; const std::unique_ptr pacer_; const std::unique_ptr bitrate_controller_; + std::unique_ptr acknowledged_bitrate_estimator_; const std::unique_ptr probe_controller_; const std::unique_ptr retransmission_rate_limiter_; TransportFeedbackAdapter transport_feedback_adapter_; diff --git a/webrtc/modules/congestion_controller/send_side_congestion_controller.cc b/webrtc/modules/congestion_controller/send_side_congestion_controller.cc index 354ccaaaa5..57e7685f88 100644 --- a/webrtc/modules/congestion_controller/send_side_congestion_controller.cc +++ b/webrtc/modules/congestion_controller/send_side_congestion_controller.cc @@ -16,9 +16,11 @@ #include "webrtc/base/checks.h" #include "webrtc/base/logging.h" +#include "webrtc/base/ptr_util.h" #include "webrtc/base/rate_limiter.h" #include "webrtc/base/socket.h" #include "webrtc/modules/bitrate_controller/include/bitrate_controller.h" +#include "webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.h" #include "webrtc/modules/congestion_controller/probe_controller.h" #include "webrtc/modules/remote_bitrate_estimator/include/bwe_defines.h" @@ -42,6 +44,25 @@ static void ClampBitrates(int* bitrate_bps, *bitrate_bps = std::max(*min_bitrate_bps, *bitrate_bps); } +std::vector ReceivedPacketFeedbackVector( + const std::vector& input) { + std::vector received_packet_feedback_vector; + auto is_received = [](const webrtc::PacketFeedback& packet_feedback) { + return packet_feedback.arrival_time_ms != + webrtc::PacketFeedback::kNotReceived; + }; + std::copy_if(input.begin(), input.end(), + std::back_inserter(received_packet_feedback_vector), + is_received); + return received_packet_feedback_vector; +} + +void SortPacketFeedbackVector( + std::vector* const input) { + RTC_DCHECK(input); + std::sort(input->begin(), input->end(), PacketFeedbackComparator()); +} + } // namespace SendSideCongestionController::SendSideCongestionController( @@ -67,6 +88,8 @@ SendSideCongestionController::SendSideCongestionController( pacer_(std::move(pacer)), bitrate_controller_( BitrateController::CreateBitrateController(clock_, event_log)), + acknowledged_bitrate_estimator_( + rtc::MakeUnique()), probe_controller_(new ProbeController(pacer_.get(), clock_)), retransmission_rate_limiter_( new RateLimiter(clock, kRetransmitWindowSizeMs)), @@ -145,6 +168,7 @@ void SendSideCongestionController::OnNetworkRouteChanged( rtc::CritScope cs(&bwe_lock_); min_bitrate_bps_ = min_bitrate_bps; delay_based_bwe_.reset(new DelayBasedBwe(event_log_, clock_)); + acknowledged_bitrate_estimator_.reset(new AcknowledgedBitrateEstimator()); delay_based_bwe_->SetStartBitrate(bitrate_bps); delay_based_bwe_->SetMinBitrate(min_bitrate_bps); } @@ -251,12 +275,16 @@ void SendSideCongestionController::OnTransportFeedback( const rtcp::TransportFeedback& feedback) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); transport_feedback_adapter_.OnTransportFeedback(feedback); - std::vector feedback_vector = - transport_feedback_adapter_.GetTransportFeedbackVector(); + std::vector feedback_vector = ReceivedPacketFeedbackVector( + transport_feedback_adapter_.GetTransportFeedbackVector()); + SortPacketFeedbackVector(&feedback_vector); + acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector( + feedback_vector); DelayBasedBwe::Result result; { rtc::CritScope cs(&bwe_lock_); - result = delay_based_bwe_->IncomingPacketFeedbackVector(feedback_vector); + result = delay_based_bwe_->IncomingPacketFeedbackVector( + feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps()); } if (result.updated) bitrate_controller_->OnDelayBasedBweResult(result); diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc index 338c4d8e4d..290f0cb125 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.cc @@ -13,6 +13,7 @@ #include #include "webrtc/base/logging.h" +#include "webrtc/base/ptr_util.h" #include "webrtc/modules/congestion_controller/delay_based_bwe.h" #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" @@ -29,6 +30,8 @@ SendSideBweSender::SendSideBweSender(int kbps, BitrateController::CreateBitrateController(clock, observer, &event_log_)), + acknowledged_bitrate_estimator_( + rtc::MakeUnique()), bwe_(new DelayBasedBwe(nullptr, clock)), feedback_observer_(bitrate_controller_->CreateRtcpBandwidthObserver()), clock_(clock), @@ -72,8 +75,10 @@ void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) { bwe_->OnRttUpdate(rtt_ms, rtt_ms); BWE_TEST_LOGGING_PLOT(1, "RTT", clock_->TimeInMilliseconds(), rtt_ms); - DelayBasedBwe::Result result = - bwe_->IncomingPacketFeedbackVector(packet_feedback_vector); + acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector( + packet_feedback_vector); + DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector( + packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate_bps()); if (result.updated) bitrate_controller_->OnDelayBasedBweResult(result); diff --git a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h index 73474eeb19..d2aa8de930 100644 --- a/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h +++ b/webrtc/modules/remote_bitrate_estimator/test/estimators/send_side.h @@ -15,6 +15,7 @@ #include #include "webrtc/logging/rtc_event_log/mock/mock_rtc_event_log.h" +#include "webrtc/modules/congestion_controller/acknowledge_bitrate_estimator.h" #include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h" #include "webrtc/modules/remote_bitrate_estimator/test/bwe.h" @@ -37,6 +38,7 @@ class SendSideBweSender : public BweSender, public RemoteBitrateObserver { protected: std::unique_ptr bitrate_controller_; + std::unique_ptr acknowledged_bitrate_estimator_; std::unique_ptr bwe_; std::unique_ptr feedback_observer_; diff --git a/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h b/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h index 183755eff3..90537c3e30 100644 --- a/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h +++ b/webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h @@ -347,6 +347,17 @@ struct PacketFeedback { PacedPacketInfo pacing_info; }; +class PacketFeedbackComparator { + public: + inline bool operator()(const PacketFeedback& lhs, const PacketFeedback& rhs) { + if (lhs.arrival_time_ms != rhs.arrival_time_ms) + return lhs.arrival_time_ms < rhs.arrival_time_ms; + if (lhs.send_time_ms != rhs.send_time_ms) + return lhs.send_time_ms < rhs.send_time_ms; + return lhs.sequence_number < rhs.sequence_number; + } +}; + class TransportFeedbackObserver { public: TransportFeedbackObserver() {} diff --git a/webrtc/tools/event_log_visualizer/analyzer.cc b/webrtc/tools/event_log_visualizer/analyzer.cc index b5b05dd218..dcff92c9d2 100644 --- a/webrtc/tools/event_log_visualizer/analyzer.cc +++ b/webrtc/tools/event_log_visualizer/analyzer.cc @@ -44,18 +44,6 @@ namespace plotting { namespace { -class PacketFeedbackComparator { - public: - inline bool operator()(const webrtc::PacketFeedback& lhs, - const webrtc::PacketFeedback& rhs) { - if (lhs.arrival_time_ms != rhs.arrival_time_ms) - return lhs.arrival_time_ms < rhs.arrival_time_ms; - if (lhs.send_time_ms != rhs.send_time_ms) - return lhs.send_time_ms < rhs.send_time_ms; - return lhs.sequence_number < rhs.sequence_number; - } -}; - void SortPacketFeedbackVector(std::vector* vec) { auto pred = [](const PacketFeedback& packet_feedback) { return packet_feedback.arrival_time_ms == PacketFeedback::kNotReceived;