diff --git a/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc b/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc index ba8ef7a21d..559179e518 100644 --- a/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc +++ b/webrtc/modules/congestion_controller/delay_based_bwe_unittest.cc @@ -19,9 +19,10 @@ namespace webrtc { namespace { -const PacedPacketInfo kPacingInfo0(0, 5, 2000); -const PacedPacketInfo kPacingInfo1(1, 8, 4000); -constexpr int kNumProbes = 5; +constexpr int kNumProbesCluster0 = 5; +constexpr int kNumProbesCluster1 = 8; +const PacedPacketInfo kPacingInfo0(0, kNumProbesCluster0, 2000); +const PacedPacketInfo kPacingInfo1(1, kNumProbesCluster1, 4000); } // namespace TEST_F(DelayBasedBweTest, ProbeDetection) { @@ -29,7 +30,7 @@ TEST_F(DelayBasedBweTest, ProbeDetection) { uint16_t seq_num = 0; // First burst sent at 8 * 1000 / 10 = 800 kbps. - for (int i = 0; i < kNumProbes; ++i) { + for (int i = 0; i < kNumProbesCluster0; ++i) { clock_.AdvanceTimeMilliseconds(10); now_ms = clock_.TimeInMilliseconds(); IncomingFeedback(now_ms, now_ms, seq_num++, 1000, kPacingInfo0); @@ -37,7 +38,7 @@ TEST_F(DelayBasedBweTest, ProbeDetection) { EXPECT_TRUE(bitrate_observer_.updated()); // Second burst sent at 8 * 1000 / 5 = 1600 kbps. - for (int i = 0; i < kNumProbes; ++i) { + for (int i = 0; i < kNumProbesCluster1; ++i) { clock_.AdvanceTimeMilliseconds(5); now_ms = clock_.TimeInMilliseconds(); IncomingFeedback(now_ms, now_ms, seq_num++, 1000, kPacingInfo1); @@ -52,7 +53,7 @@ TEST_F(DelayBasedBweTest, ProbeDetectionNonPacedPackets) { uint16_t seq_num = 0; // First burst sent at 8 * 1000 / 10 = 800 kbps, but with every other packet // not being paced which could mess things up. - for (int i = 0; i < kNumProbes; ++i) { + for (int i = 0; i < kNumProbesCluster0; ++i) { clock_.AdvanceTimeMilliseconds(5); now_ms = clock_.TimeInMilliseconds(); IncomingFeedback(now_ms, now_ms, seq_num++, 1000, kPacingInfo0); @@ -71,7 +72,7 @@ TEST_F(DelayBasedBweTest, ProbeDetectionFasterArrival) { // First burst sent at 8 * 1000 / 10 = 800 kbps. // Arriving at 8 * 1000 / 5 = 1600 kbps. int64_t send_time_ms = 0; - for (int i = 0; i < kNumProbes; ++i) { + for (int i = 0; i < kNumProbesCluster0; ++i) { clock_.AdvanceTimeMilliseconds(1); send_time_ms += 10; now_ms = clock_.TimeInMilliseconds(); @@ -87,7 +88,7 @@ TEST_F(DelayBasedBweTest, ProbeDetectionSlowerArrival) { // First burst sent at 8 * 1000 / 5 = 1600 kbps. // Arriving at 8 * 1000 / 7 = 1142 kbps. int64_t send_time_ms = 0; - for (int i = 0; i < kNumProbes; ++i) { + for (int i = 0; i < kNumProbesCluster1; ++i) { clock_.AdvanceTimeMilliseconds(7); send_time_ms += 5; now_ms = clock_.TimeInMilliseconds(); @@ -104,7 +105,7 @@ TEST_F(DelayBasedBweTest, ProbeDetectionSlowerArrivalHighBitrate) { // Burst sent at 8 * 1000 / 1 = 8000 kbps. // Arriving at 8 * 1000 / 2 = 4000 kbps. int64_t send_time_ms = 0; - for (int i = 0; i < kNumProbes; ++i) { + for (int i = 0; i < kNumProbesCluster1; ++i) { clock_.AdvanceTimeMilliseconds(2); send_time_ms += 1; now_ms = clock_.TimeInMilliseconds(); 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 50182583f3..c87439e5c7 100644 --- a/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.cc +++ b/webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.cc @@ -264,7 +264,7 @@ void DelayBasedBweTest::InitialBehaviorTestHelper( uint32_t expected_converge_bitrate) { const int kFramerate = 50; // 50 fps to avoid rounding errors. const int kFrameIntervalMs = 1000 / kFramerate; - const PacedPacketInfo kPacingInfo(0, 1, 100); + const PacedPacketInfo kPacingInfo(0, 5, 5000); uint32_t bitrate_bps = 0; int64_t send_time_ms = 0; uint16_t sequence_number = 0; @@ -307,7 +307,7 @@ void DelayBasedBweTest::RateIncreaseReorderingTestHelper( uint32_t expected_bitrate_bps) { const int kFramerate = 50; // 50 fps to avoid rounding errors. const int kFrameIntervalMs = 1000 / kFramerate; - const PacedPacketInfo kPacingInfo(0, 1, 100); + const PacedPacketInfo kPacingInfo(0, 5, 5000); int64_t send_time_ms = 0; uint16_t sequence_number = 0; // Inserting packets for five seconds to get a valid estimate. diff --git a/webrtc/modules/congestion_controller/probe_bitrate_estimator.cc b/webrtc/modules/congestion_controller/probe_bitrate_estimator.cc index 6ce84d26cf..13681115ac 100644 --- a/webrtc/modules/congestion_controller/probe_bitrate_estimator.cc +++ b/webrtc/modules/congestion_controller/probe_bitrate_estimator.cc @@ -16,8 +16,13 @@ #include "webrtc/base/logging.h" namespace { -// The minumum number of probes we need for a valid cluster. -constexpr int kMinNumProbesValidCluster = 4; +// The minumum number of probes we need to receive feedback about in percent +// in order to have a valid estimate. +constexpr int kMinReceivedProbesPercent = 80; + +// The minumum number of bytes we need to receive feedback about in percent +// in order to have a valid estimate. +constexpr int kMinReceivedBytesPercent = 80; // The maximum (receive rate)/(send rate) ratio for a valid estimate. constexpr float kValidRatio = 2.0f; @@ -63,7 +68,14 @@ int ProbeBitrateEstimator::HandleProbeAndEstimateBitrate( cluster->size_total += payload_size_bits; cluster->num_probes += 1; - if (cluster->num_probes < kMinNumProbesValidCluster) + RTC_DCHECK_GT(packet_feedback.pacing_info.probe_cluster_min_probes, 0); + RTC_DCHECK_GT(packet_feedback.pacing_info.probe_cluster_min_bytes, 0); + + int min_probes = packet_feedback.pacing_info.probe_cluster_min_probes * + kMinReceivedProbesPercent / 100; + int min_bytes = packet_feedback.pacing_info.probe_cluster_min_bytes * + kMinReceivedBytesPercent / 100; + if (cluster->num_probes < min_probes || cluster->size_total < min_bytes * 8) return -1; float send_interval_ms = cluster->last_send_ms - cluster->first_send_ms; diff --git a/webrtc/modules/congestion_controller/probe_bitrate_estimator_unittest.cc b/webrtc/modules/congestion_controller/probe_bitrate_estimator_unittest.cc index a96e1d857f..a476bbaf0f 100644 --- a/webrtc/modules/congestion_controller/probe_bitrate_estimator_unittest.cc +++ b/webrtc/modules/congestion_controller/probe_bitrate_estimator_unittest.cc @@ -19,7 +19,11 @@ namespace webrtc { -constexpr int INVALID_BPS = -1; +namespace { +constexpr int kInvalidBitrate = -1; +constexpr int kDefaultMinProbes = 5; +constexpr int kDefaultMinBytes = 5000; +} // anonymous namespace class TestProbeBitrateEstimator : public ::testing::Test { public: @@ -30,15 +34,18 @@ class TestProbeBitrateEstimator : public ::testing::Test { void AddPacketFeedback(int probe_cluster_id, size_t size_bytes, int64_t send_time_ms, - int64_t arrival_time_ms) { + int64_t arrival_time_ms, + int min_probes = kDefaultMinProbes, + int min_bytes = kDefaultMinBytes) { + PacedPacketInfo pacing_info(probe_cluster_id, min_probes, min_bytes); PacketFeedback packet_feedback(arrival_time_ms, send_time_ms, 0, size_bytes, - PacedPacketInfo(probe_cluster_id, -1, -1)); + pacing_info); measured_bps_ = probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); } protected: - int measured_bps_ = INVALID_BPS; + int measured_bps_ = kInvalidBitrate; ProbeBitrateEstimator probe_bitrate_estimator_; }; @@ -51,6 +58,50 @@ TEST_F(TestProbeBitrateEstimator, OneCluster) { EXPECT_NEAR(measured_bps_, 800000, 10); } +TEST_F(TestProbeBitrateEstimator, OneClusterTooFewProbes) { + AddPacketFeedback(0, 2000, 0, 10); + AddPacketFeedback(0, 2000, 10, 20); + AddPacketFeedback(0, 2000, 20, 30); + + EXPECT_EQ(kInvalidBitrate, measured_bps_); +} + +TEST_F(TestProbeBitrateEstimator, OneClusterTooFewBytes) { + const int kMinBytes = 6000; + AddPacketFeedback(0, 800, 0, 10, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 800, 10, 20, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 800, 20, 30, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 800, 30, 40, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 800, 40, 50, kDefaultMinProbes, kMinBytes); + + EXPECT_EQ(kInvalidBitrate, measured_bps_); +} + +TEST_F(TestProbeBitrateEstimator, SmallCluster) { + const int kMinBytes = 1000; + AddPacketFeedback(0, 150, 0, 10, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 150, 10, 20, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 150, 20, 30, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 150, 30, 40, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 150, 40, 50, kDefaultMinProbes, kMinBytes); + AddPacketFeedback(0, 150, 50, 60, kDefaultMinProbes, kMinBytes); + EXPECT_NEAR(measured_bps_, 120000, 10); +} + +TEST_F(TestProbeBitrateEstimator, LargeCluster) { + const int kMinProbes = 30; + const int kMinBytes = 312500; + + int64_t send_time = 0; + int64_t receive_time = 5; + for (int i = 0; i < 25; ++i) { + AddPacketFeedback(0, 12500, send_time, receive_time, kMinProbes, kMinBytes); + ++send_time; + ++receive_time; + } + EXPECT_NEAR(measured_bps_, 100000000, 10); +} + TEST_F(TestProbeBitrateEstimator, FastReceive) { AddPacketFeedback(0, 1000, 0, 15); AddPacketFeedback(0, 1000, 10, 30); @@ -66,7 +117,7 @@ TEST_F(TestProbeBitrateEstimator, TooFastReceive) { AddPacketFeedback(0, 1000, 20, 25); AddPacketFeedback(0, 1000, 40, 27); - EXPECT_EQ(measured_bps_, INVALID_BPS); + EXPECT_EQ(measured_bps_, kInvalidBitrate); } TEST_F(TestProbeBitrateEstimator, SlowReceive) { @@ -84,7 +135,7 @@ TEST_F(TestProbeBitrateEstimator, BurstReceive) { AddPacketFeedback(0, 1000, 20, 50); AddPacketFeedback(0, 1000, 40, 50); - EXPECT_EQ(measured_bps_, INVALID_BPS); + EXPECT_EQ(measured_bps_, kInvalidBitrate); } TEST_F(TestProbeBitrateEstimator, MultipleClusters) { @@ -92,11 +143,9 @@ TEST_F(TestProbeBitrateEstimator, MultipleClusters) { AddPacketFeedback(0, 1000, 10, 20); AddPacketFeedback(0, 1000, 20, 30); AddPacketFeedback(0, 1000, 40, 60); - EXPECT_NEAR(measured_bps_, 480000, 10); AddPacketFeedback(0, 1000, 50, 60); - EXPECT_NEAR(measured_bps_, 640000, 10); AddPacketFeedback(1, 1000, 60, 70); @@ -122,7 +171,7 @@ TEST_F(TestProbeBitrateEstimator, IgnoreOldClusters) { // Coming in 6s later AddPacketFeedback(0, 1000, 40 + 6000, 60 + 6000); - EXPECT_EQ(measured_bps_, INVALID_BPS); + EXPECT_EQ(measured_bps_, kInvalidBitrate); } TEST_F(TestProbeBitrateEstimator, IgnoreSizeLastSendPacket) {