diff --git a/webrtc/modules/pacing/paced_sender.cc b/webrtc/modules/pacing/paced_sender.cc index 6a97d025ab..658e13a9d3 100644 --- a/webrtc/modules/pacing/paced_sender.cc +++ b/webrtc/modules/pacing/paced_sender.cc @@ -255,6 +255,7 @@ PacedSender::PacedSender(Clock* clock, PacketSender* packet_sender) media_budget_(new paced_sender::IntervalBudget(0)), padding_budget_(new paced_sender::IntervalBudget(0)), prober_(new BitrateProber()), + probing_send_failure_(false), estimated_bitrate_bps_(0), min_send_bitrate_kbps_(0u), max_padding_bitrate_kbps_(0u), @@ -374,7 +375,7 @@ int64_t PacedSender::TimeUntilNextProcess() { CriticalSectionScoped cs(critsect_.get()); if (prober_->IsProbing()) { int64_t ret = prober_->TimeUntilNextProbe(clock_->TimeInMilliseconds()); - if (ret >= 0) + if (ret > 0 || (ret == 0 && !probing_send_failure_)) return ret; } int64_t elapsed_time_us = clock_->TimeInMicroseconds() - time_last_update_us_; @@ -448,8 +449,11 @@ void PacedSender::Process() { bytes_sent += SendPadding(padding_needed, pacing_info); } } - if (is_probing && bytes_sent > 0) - prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); + if (is_probing) { + probing_send_failure_ = bytes_sent == 0; + if (!probing_send_failure_) + prober_->ProbeSent(clock_->TimeInMilliseconds(), bytes_sent); + } alr_detector_->OnBytesSent(bytes_sent, now_us / 1000); } diff --git a/webrtc/modules/pacing/paced_sender.h b/webrtc/modules/pacing/paced_sender.h index 10d65c006c..196d85afa1 100644 --- a/webrtc/modules/pacing/paced_sender.h +++ b/webrtc/modules/pacing/paced_sender.h @@ -169,6 +169,7 @@ class PacedSender : public Module, public RtpPacketSender { GUARDED_BY(critsect_); std::unique_ptr prober_ GUARDED_BY(critsect_); + bool probing_send_failure_; // Actual configured bitrates (media_budget_ may temporarily be higher in // order to meet pace time constraint). uint32_t estimated_bitrate_bps_ GUARDED_BY(critsect_); diff --git a/webrtc/modules/pacing/paced_sender_unittest.cc b/webrtc/modules/pacing/paced_sender_unittest.cc index cc4769e667..6c5e3df280 100644 --- a/webrtc/modules/pacing/paced_sender_unittest.cc +++ b/webrtc/modules/pacing/paced_sender_unittest.cc @@ -1046,5 +1046,32 @@ TEST_F(PacedSenderTest, ProbeClusterId) { send_bucket_->Process(); } +TEST_F(PacedSenderTest, AvoidBusyLoopOnSendFailure) { + uint32_t ssrc = 12346; + uint16_t sequence_number = 1234; + const size_t kPacketSize = kFirstClusterBps / (8000 / 10); + + send_bucket_->SetSendBitrateLimits(kTargetBitrateBps, kTargetBitrateBps); + send_bucket_->SetProbingEnabled(true); + send_bucket_->InsertPacket(PacedSender::kNormalPriority, ssrc, + sequence_number, clock_.TimeInMilliseconds(), + kPacketSize, false); + + EXPECT_CALL(callback_, TimeToSendPacket(_, _, _, _, _)) + .WillOnce(Return(true)); + send_bucket_->Process(); + EXPECT_EQ(10, send_bucket_->TimeUntilNextProcess()); + clock_.AdvanceTimeMilliseconds(9); + + EXPECT_CALL(callback_, TimeToSendPadding(_, _)) + .Times(2) + .WillRepeatedly(Return(0)); + send_bucket_->Process(); + EXPECT_EQ(1, send_bucket_->TimeUntilNextProcess()); + clock_.AdvanceTimeMilliseconds(1); + send_bucket_->Process(); + EXPECT_EQ(5, send_bucket_->TimeUntilNextProcess()); +} + } // namespace test } // namespace webrtc