diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
commit | fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch) | |
tree | 4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /third_party/libwebrtc/modules/pacing | |
parent | Releasing progress-linux version 124.0.1-1~progress7.99u1. (diff) | |
download | firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/modules/pacing')
8 files changed, 125 insertions, 145 deletions
diff --git a/third_party/libwebrtc/modules/pacing/interval_budget_gn/moz.build b/third_party/libwebrtc/modules/pacing/interval_budget_gn/moz.build index a528123ae0..8bb44ecf62 100644 --- a/third_party/libwebrtc/modules/pacing/interval_budget_gn/moz.build +++ b/third_party/libwebrtc/modules/pacing/interval_budget_gn/moz.build @@ -188,7 +188,6 @@ if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux": if CONFIG["OS_TARGET"] == "Android" and CONFIG["TARGET_CPU"] == "arm": OS_LIBS += [ - "android_support", "unwind" ] @@ -198,10 +197,6 @@ if CONFIG["OS_TARGET"] == "Android" and CONFIG["TARGET_CPU"] == "x86": "-msse2" ] - OS_LIBS += [ - "android_support" - ] - if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "aarch64": DEFINES["_GNU_SOURCE"] = True diff --git a/third_party/libwebrtc/modules/pacing/pacing_controller.cc b/third_party/libwebrtc/modules/pacing/pacing_controller.cc index 13ff9a2a95..5b81207d56 100644 --- a/third_party/libwebrtc/modules/pacing/pacing_controller.cc +++ b/third_party/libwebrtc/modules/pacing/pacing_controller.cc @@ -73,7 +73,7 @@ PacingController::PacingController(Clock* clock, keyframe_flushing_( IsEnabled(field_trials_, "WebRTC-Pacer-KeyframeFlushing")), transport_overhead_per_packet_(DataSize::Zero()), - send_burst_interval_(TimeDelta::Zero()), + send_burst_interval_(kDefaultBurstInterval), last_timestamp_(clock_->CurrentTime()), paused_(false), media_debt_(DataSize::Zero()), diff --git a/third_party/libwebrtc/modules/pacing/pacing_controller.h b/third_party/libwebrtc/modules/pacing/pacing_controller.h index dd5636ccef..04e0a820f9 100644 --- a/third_party/libwebrtc/modules/pacing/pacing_controller.h +++ b/third_party/libwebrtc/modules/pacing/pacing_controller.h @@ -25,6 +25,7 @@ #include "api/transport/field_trial_based_config.h" #include "api/transport/network_types.h" #include "api/units/data_size.h" +#include "api/units/time_delta.h" #include "modules/pacing/bitrate_prober.h" #include "modules/pacing/interval_budget.h" #include "modules/pacing/prioritized_packet_queue.h" @@ -92,6 +93,10 @@ class PacingController { // the send burst interval. // Ex: max send burst interval = 63Kb / 10Mbit/s = 50ms. static constexpr DataSize kMaxBurstSize = DataSize::Bytes(63 * 1000); + // The pacer is allowed to send enqued packets in bursts and can build up a + // packet "debt" that correspond to approximately the send rate during + // the burst interval. + static constexpr TimeDelta kDefaultBurstInterval = TimeDelta::Millis(40); PacingController(Clock* clock, PacketSender* packet_sender, diff --git a/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc b/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc index ba93d05bb7..9e6ede6dc0 100644 --- a/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc +++ b/third_party/libwebrtc/modules/pacing/pacing_controller_unittest.cc @@ -427,6 +427,7 @@ TEST_F(PacingControllerTest, BudgetAffectsAudioInTrial) { DataRate pacing_rate = DataRate::BitsPerSec(kPacketSize / 3 * 8 * kProcessIntervalsPerSecond); pacer.SetPacingRates(pacing_rate, DataRate::Zero()); + pacer.SetSendBurstInterval(TimeDelta::Zero()); // Video fills budget for following process periods. pacer.EnqueuePacket(video_.BuildNextPacket(kPacketSize)); EXPECT_CALL(callback_, SendPacket).Times(1); @@ -484,7 +485,7 @@ TEST_F(PacingControllerTest, FirstSentPacketTimeIsSet) { EXPECT_EQ(kStartTime, pacer->FirstSentPacketTime()); } -TEST_F(PacingControllerTest, QueueAndPacePackets) { +TEST_F(PacingControllerTest, QueueAndPacePacketsWithZeroBurstPeriod) { const uint32_t kSsrc = 12345; uint16_t sequence_number = 1234; const DataSize kPackeSize = DataSize::Bytes(250); @@ -495,6 +496,7 @@ TEST_F(PacingControllerTest, QueueAndPacePackets) { const size_t kPacketsToSend = (kSendInterval * kTargetRate).bytes() * kPaceMultiplier / kPackeSize.bytes(); auto pacer = std::make_unique<PacingController>(&clock_, &callback_, trials_); + pacer->SetSendBurstInterval(TimeDelta::Zero()); pacer->SetPacingRates(kTargetRate * kPaceMultiplier, DataRate::Zero()); for (size_t i = 0; i < kPacketsToSend; ++i) { @@ -536,30 +538,30 @@ TEST_F(PacingControllerTest, PaceQueuedPackets) { auto pacer = std::make_unique<PacingController>(&clock_, &callback_, trials_); pacer->SetPacingRates(kTargetRate * kPaceMultiplier, DataRate::Zero()); - // Due to the multiplicative factor we can send 5 packets during a send - // interval. (network capacity * multiplier / (8 bits per byte * - // (packet size * #send intervals per second) - const size_t packets_to_send_per_interval = - kTargetRate.bps() * kPaceMultiplier / (8 * kPacketSize * 200); - for (size_t i = 0; i < packets_to_send_per_interval; ++i) { + const size_t packets_to_send_per_burst_interval = + (kTargetRate * kPaceMultiplier * PacingController::kDefaultBurstInterval) + .bytes() / + kPacketSize; + for (size_t i = 0; i < packets_to_send_per_burst_interval; ++i) { SendAndExpectPacket(pacer.get(), RtpPacketMediaType::kVideo, ssrc, sequence_number++, clock_.TimeInMilliseconds(), kPacketSize); } - for (size_t j = 0; j < packets_to_send_per_interval * 10; ++j) { + for (size_t j = 0; j < packets_to_send_per_burst_interval * 10; ++j) { pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kVideo, ssrc, sequence_number++, clock_.TimeInMilliseconds(), kPacketSize)); } - EXPECT_EQ(packets_to_send_per_interval + packets_to_send_per_interval * 10, + EXPECT_EQ(packets_to_send_per_burst_interval + + packets_to_send_per_burst_interval * 10, pacer->QueueSizePackets()); - while (pacer->QueueSizePackets() > packets_to_send_per_interval * 10) { + while (pacer->QueueSizePackets() > packets_to_send_per_burst_interval * 10) { AdvanceTimeUntil(pacer->NextSendTime()); pacer->ProcessPackets(); } - EXPECT_EQ(pacer->QueueSizePackets(), packets_to_send_per_interval * 10); + EXPECT_EQ(pacer->QueueSizePackets(), packets_to_send_per_burst_interval * 10); EXPECT_CALL(callback_, SendPadding).Times(0); EXPECT_CALL(callback_, SendPacket(ssrc, _, _, false, false)) @@ -582,12 +584,12 @@ TEST_F(PacingControllerTest, PaceQueuedPackets) { pacer->ProcessPackets(); // Send some more packet, just show that we can..? - for (size_t i = 0; i < packets_to_send_per_interval; ++i) { + for (size_t i = 0; i < packets_to_send_per_burst_interval; ++i) { SendAndExpectPacket(pacer.get(), RtpPacketMediaType::kVideo, ssrc, sequence_number++, clock_.TimeInMilliseconds(), 250); } - EXPECT_EQ(packets_to_send_per_interval, pacer->QueueSizePackets()); - for (size_t i = 0; i < packets_to_send_per_interval; ++i) { + EXPECT_EQ(packets_to_send_per_burst_interval, pacer->QueueSizePackets()); + for (size_t i = 0; i < packets_to_send_per_burst_interval; ++i) { AdvanceTimeUntil(pacer->NextSendTime()); pacer->ProcessPackets(); } @@ -641,19 +643,23 @@ TEST_F(PacingControllerTest, TEST_F(PacingControllerTest, Padding) { uint32_t ssrc = 12345; uint16_t sequence_number = 1234; - const size_t kPacketSize = 250; + const size_t kPacketSize = 1000; auto pacer = std::make_unique<PacingController>(&clock_, &callback_, trials_); pacer->SetPacingRates(kTargetRate * kPaceMultiplier, kTargetRate); - const size_t kPacketsToSend = 20; + const size_t kPacketsToSend = 30; for (size_t i = 0; i < kPacketsToSend; ++i) { SendAndExpectPacket(pacer.get(), RtpPacketMediaType::kVideo, ssrc, sequence_number++, clock_.TimeInMilliseconds(), kPacketSize); } + + int expected_bursts = + floor(DataSize::Bytes(pacer->QueueSizePackets() * kPacketSize) / + (kPaceMultiplier * kTargetRate) / + PacingController::kDefaultBurstInterval); const TimeDelta expected_pace_time = - DataSize::Bytes(pacer->QueueSizePackets() * kPacketSize) / - (kPaceMultiplier * kTargetRate); + (expected_bursts - 1) * PacingController::kDefaultBurstInterval; EXPECT_CALL(callback_, SendPadding).Times(0); // Only the media packets should be sent. Timestamp start_time = clock_.CurrentTime(); @@ -663,7 +669,7 @@ TEST_F(PacingControllerTest, Padding) { } const TimeDelta actual_pace_time = clock_.CurrentTime() - start_time; EXPECT_LE((actual_pace_time - expected_pace_time).Abs(), - PacingController::kMinSleepTime); + PacingController::kDefaultBurstInterval); // Pacing media happens at 2.5x, but padding was configured with 1.0x // factor. We have to wait until the padding debt is gone before we start @@ -766,8 +772,8 @@ TEST_F(PacingControllerTest, VerifyAverageBitrateVaryingMediaPayload) { media_payload)); media_bytes += media_payload; } - - AdvanceTimeUntil(pacer->NextSendTime()); + AdvanceTimeUntil(std::min(clock_.CurrentTime() + TimeDelta::Millis(20), + pacer->NextSendTime())); pacer->ProcessPackets(); } @@ -805,20 +811,18 @@ TEST_F(PacingControllerTest, Priority) { // Expect all high and normal priority to be sent out first. EXPECT_CALL(callback_, SendPadding).Times(0); + testing::Sequence s; EXPECT_CALL(callback_, SendPacket(ssrc, _, capture_time_ms, _, _)) - .Times(packets_to_send_per_interval + 1); + .Times(packets_to_send_per_interval + 1) + .InSequence(s); + EXPECT_CALL(callback_, SendPacket(ssrc_low_priority, _, + capture_time_ms_low_priority, _, _)) + .InSequence(s); - while (pacer->QueueSizePackets() > 1) { + while (pacer->QueueSizePackets() > 0) { AdvanceTimeUntil(pacer->NextSendTime()); pacer->ProcessPackets(); } - - EXPECT_EQ(1u, pacer->QueueSizePackets()); - - EXPECT_CALL(callback_, SendPacket(ssrc_low_priority, _, - capture_time_ms_low_priority, _, _)); - AdvanceTimeUntil(pacer->NextSendTime()); - pacer->ProcessPackets(); } TEST_F(PacingControllerTest, RetransmissionPriority) { @@ -829,23 +833,22 @@ TEST_F(PacingControllerTest, RetransmissionPriority) { auto pacer = std::make_unique<PacingController>(&clock_, &callback_, trials_); pacer->SetPacingRates(kTargetRate * kPaceMultiplier, DataRate::Zero()); - // Due to the multiplicative factor we can send 5 packets during a send - // interval. (network capacity * multiplier / (8 bits per byte * - // (packet size * #send intervals per second) - const size_t packets_to_send_per_interval = - kTargetRate.bps() * kPaceMultiplier / (8 * 250 * 200); + const size_t packets_to_send_per_burst_interval = + (kTargetRate * kPaceMultiplier * PacingController::kDefaultBurstInterval) + .bytes() / + 250; pacer->ProcessPackets(); EXPECT_EQ(0u, pacer->QueueSizePackets()); // Alternate retransmissions and normal packets. - for (size_t i = 0; i < packets_to_send_per_interval; ++i) { + for (size_t i = 0; i < packets_to_send_per_burst_interval; ++i) { pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kVideo, ssrc, sequence_number++, capture_time_ms, 250)); pacer->EnqueuePacket(BuildPacket(RtpPacketMediaType::kRetransmission, ssrc, sequence_number++, capture_time_ms_retransmission, 250)); } - EXPECT_EQ(2 * packets_to_send_per_interval, pacer->QueueSizePackets()); + EXPECT_EQ(2 * packets_to_send_per_burst_interval, pacer->QueueSizePackets()); // Expect all retransmissions to be sent out first despite having a later // capture time. @@ -853,19 +856,19 @@ TEST_F(PacingControllerTest, RetransmissionPriority) { EXPECT_CALL(callback_, SendPacket(_, _, _, false, _)).Times(0); EXPECT_CALL(callback_, SendPacket(ssrc, _, capture_time_ms_retransmission, true, _)) - .Times(packets_to_send_per_interval); + .Times(packets_to_send_per_burst_interval); - while (pacer->QueueSizePackets() > packets_to_send_per_interval) { + while (pacer->QueueSizePackets() > packets_to_send_per_burst_interval) { AdvanceTimeUntil(pacer->NextSendTime()); pacer->ProcessPackets(); } - EXPECT_EQ(packets_to_send_per_interval, pacer->QueueSizePackets()); + EXPECT_EQ(packets_to_send_per_burst_interval, pacer->QueueSizePackets()); // Expect the remaining (non-retransmission) packets to be sent. EXPECT_CALL(callback_, SendPadding).Times(0); EXPECT_CALL(callback_, SendPacket(_, _, _, true, _)).Times(0); EXPECT_CALL(callback_, SendPacket(ssrc, _, capture_time_ms, false, _)) - .Times(packets_to_send_per_interval); + .Times(packets_to_send_per_burst_interval); while (pacer->QueueSizePackets() > 0) { AdvanceTimeUntil(pacer->NextSendTime()); @@ -890,13 +893,13 @@ TEST_F(PacingControllerTest, HighPrioDoesntAffectBudget) { sequence_number++, capture_time_ms, kPacketSize); } pacer->ProcessPackets(); + EXPECT_EQ(pacer->QueueSizePackets(), 0u); // Low prio packets does affect the budget. - // Due to the multiplicative factor we can send 5 packets during a send - // interval. (network capacity * multiplier / (8 bits per byte * - // (packet size * #send intervals per second) - const size_t kPacketsToSendPerInterval = - kTargetRate.bps() * kPaceMultiplier / (8 * kPacketSize * 200); - for (size_t i = 0; i < kPacketsToSendPerInterval; ++i) { + const size_t kPacketsToSendPerBurstInterval = + (kTargetRate * kPaceMultiplier * PacingController::kDefaultBurstInterval) + .bytes() / + kPacketSize; + for (size_t i = 0; i < kPacketsToSendPerBurstInterval; ++i) { SendAndExpectPacket(pacer.get(), RtpPacketMediaType::kVideo, ssrc, sequence_number++, clock_.TimeInMilliseconds(), kPacketSize); @@ -904,16 +907,16 @@ TEST_F(PacingControllerTest, HighPrioDoesntAffectBudget) { // Send all packets and measure pace time. Timestamp start_time = clock_.CurrentTime(); + EXPECT_EQ(pacer->NextSendTime(), clock_.CurrentTime()); while (pacer->QueueSizePackets() > 0) { AdvanceTimeUntil(pacer->NextSendTime()); pacer->ProcessPackets(); } - // Measure pacing time. Expect only low-prio packets to affect this. + // Measure pacing time. TimeDelta pacing_time = clock_.CurrentTime() - start_time; - TimeDelta expected_pacing_time = - DataSize::Bytes(kPacketsToSendPerInterval * kPacketSize) / - (kTargetRate * kPaceMultiplier); + // All packets sent in one burst since audio packets are not accounted for. + TimeDelta expected_pacing_time = TimeDelta::Zero(); EXPECT_NEAR(pacing_time.us<double>(), expected_pacing_time.us<double>(), PacingController::kMinSleepTime.us<double>()); } @@ -965,6 +968,7 @@ TEST_F(PacingControllerTest, DoesNotAllowOveruseAfterCongestion) { auto now_ms = [this] { return clock_.TimeInMilliseconds(); }; auto pacer = std::make_unique<PacingController>(&clock_, &callback_, trials_); pacer->SetPacingRates(kTargetRate * kPaceMultiplier, DataRate::Zero()); + pacer->SetSendBurstInterval(TimeDelta::Zero()); EXPECT_CALL(callback_, SendPadding).Times(0); // The pacing rate is low enough that the budget should not allow two packets // to be sent in a row. @@ -1853,6 +1857,7 @@ TEST_F(PacingControllerTest, AccountsForAudioEnqueueTime) { // Audio not paced, but still accounted for in budget. pacer->SetAccountForAudioPackets(true); pacer->SetPacingRates(kPacingDataRate, kPaddingDataRate); + pacer->SetSendBurstInterval(TimeDelta::Zero()); // Enqueue two audio packets, advance clock to where one packet // should have drained the buffer already, has they been sent @@ -1898,13 +1903,12 @@ TEST_F(PacingControllerTest, NextSendTimeAccountsForPadding) { EXPECT_EQ(pacer->NextSendTime() - clock_.CurrentTime(), PacingController::kPausedProcessInterval); - // Enqueue a new packet, that can't be sent until previous buffer has - // drained. + // Enqueue a new packet, that can be sent immediately due to default burst + // rate is 40ms. SendAndExpectPacket(pacer.get(), RtpPacketMediaType::kVideo, kSsrc, sequnce_number++, clock_.TimeInMilliseconds(), kPacketSize.bytes()); - EXPECT_EQ(pacer->NextSendTime() - clock_.CurrentTime(), kPacketPacingTime); - clock_.AdvanceTime(kPacketPacingTime); + EXPECT_EQ(pacer->NextSendTime() - clock_.CurrentTime(), TimeDelta::Zero()); pacer->ProcessPackets(); ::testing::Mock::VerifyAndClearExpectations(&callback_); @@ -1916,11 +1920,13 @@ TEST_F(PacingControllerTest, NextSendTimeAccountsForPadding) { // previous debt has cleared. Since padding was disabled before, there // currently is no padding debt. pacer->SetPacingRates(kPacingDataRate, kPacingDataRate / 2); - EXPECT_EQ(pacer->NextSendTime() - clock_.CurrentTime(), kPacketPacingTime); + EXPECT_EQ(pacer->QueueSizePackets(), 0u); + EXPECT_LT(pacer->NextSendTime() - clock_.CurrentTime(), + PacingController::kDefaultBurstInterval); // Advance time, expect padding. EXPECT_CALL(callback_, SendPadding).WillOnce(Return(kPacketSize.bytes())); - clock_.AdvanceTime(kPacketPacingTime); + clock_.AdvanceTime(pacer->NextSendTime() - clock_.CurrentTime()); pacer->ProcessPackets(); ::testing::Mock::VerifyAndClearExpectations(&callback_); @@ -1933,7 +1939,7 @@ TEST_F(PacingControllerTest, NextSendTimeAccountsForPadding) { pacer->EnqueuePacket( BuildPacket(RtpPacketMediaType::kVideo, kSsrc, sequnce_number++, clock_.TimeInMilliseconds(), kPacketSize.bytes())); - EXPECT_EQ(pacer->NextSendTime() - clock_.CurrentTime(), kPacketPacingTime); + EXPECT_EQ(pacer->NextSendTime(), clock_.CurrentTime()); } TEST_F(PacingControllerTest, PaddingTargetAccountsForPaddingRate) { @@ -2011,8 +2017,8 @@ TEST_F(PacingControllerTest, SendsFecPackets) { TEST_F(PacingControllerTest, GapInPacingDoesntAccumulateBudget) { const uint32_t kSsrc = 12345; uint16_t sequence_number = 1234; - const DataSize kPackeSize = DataSize::Bytes(250); - const TimeDelta kPacketSendTime = TimeDelta::Millis(15); + const DataSize kPackeSize = DataSize::Bytes(1000); + const TimeDelta kPacketSendTime = TimeDelta::Millis(25); auto pacer = std::make_unique<PacingController>(&clock_, &callback_, trials_); pacer->SetPacingRates(kPackeSize / kPacketSendTime, @@ -2028,15 +2034,20 @@ TEST_F(PacingControllerTest, GapInPacingDoesntAccumulateBudget) { // Advance time kPacketSendTime past where the media debt should be 0. clock_.AdvanceTime(2 * kPacketSendTime); - // Enqueue two new packets. Expect only one to be sent one ProcessPackets(). + // Enqueue three new packets. Expect only two to be sent one ProcessPackets() + // since the default burst interval is 40ms. + SendAndExpectPacket(pacer.get(), RtpPacketMediaType::kVideo, kSsrc, + sequence_number++, clock_.TimeInMilliseconds(), + kPackeSize.bytes()); + SendAndExpectPacket(pacer.get(), RtpPacketMediaType::kVideo, kSsrc, + sequence_number++, clock_.TimeInMilliseconds(), + kPackeSize.bytes()); + EXPECT_CALL(callback_, SendPacket(kSsrc, sequence_number + 1, _, _, _)) + .Times(0); pacer->EnqueuePacket( BuildPacket(RtpPacketMediaType::kVideo, kSsrc, sequence_number + 1, clock_.TimeInMilliseconds(), kPackeSize.bytes())); - pacer->EnqueuePacket( - BuildPacket(RtpPacketMediaType::kVideo, kSsrc, sequence_number + 2, - clock_.TimeInMilliseconds(), kPackeSize.bytes())); - EXPECT_CALL(callback_, SendPacket(kSsrc, sequence_number + 1, - clock_.TimeInMilliseconds(), false, false)); + pacer->ProcessPackets(); } @@ -2044,6 +2055,7 @@ TEST_F(PacingControllerTest, HandlesSubMicrosecondSendIntervals) { static constexpr DataSize kPacketSize = DataSize::Bytes(1); static constexpr TimeDelta kPacketSendTime = TimeDelta::Micros(1); auto pacer = std::make_unique<PacingController>(&clock_, &callback_, trials_); + pacer->SetSendBurstInterval(TimeDelta::Zero()); // Set pacing rate such that a packet is sent in 0.5us. pacer->SetPacingRates(/*pacing_rate=*/2 * kPacketSize / kPacketSendTime, diff --git a/third_party/libwebrtc/modules/pacing/pacing_gn/moz.build b/third_party/libwebrtc/modules/pacing/pacing_gn/moz.build index 6b7f69865f..353f876c55 100644 --- a/third_party/libwebrtc/modules/pacing/pacing_gn/moz.build +++ b/third_party/libwebrtc/modules/pacing/pacing_gn/moz.build @@ -207,7 +207,6 @@ if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux": if CONFIG["OS_TARGET"] == "Android" and CONFIG["TARGET_CPU"] == "arm": OS_LIBS += [ - "android_support", "unwind" ] @@ -217,10 +216,6 @@ if CONFIG["OS_TARGET"] == "Android" and CONFIG["TARGET_CPU"] == "x86": "-msse2" ] - OS_LIBS += [ - "android_support" - ] - if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "aarch64": DEFINES["_GNU_SOURCE"] = True diff --git a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc index afa36ea88d..f7218e48a1 100644 --- a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc +++ b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.cc @@ -17,35 +17,19 @@ #include "api/task_queue/pending_task_safety_flag.h" #include "api/transport/network_types.h" #include "rtc_base/checks.h" -#include "rtc_base/experiments/field_trial_parser.h" -#include "rtc_base/experiments/field_trial_units.h" #include "rtc_base/trace_event.h" namespace webrtc { -namespace { - -constexpr const char* kBurstyPacerFieldTrial = "WebRTC-BurstyPacer"; - -} // namespace - const int TaskQueuePacedSender::kNoPacketHoldback = -1; -TaskQueuePacedSender::BurstyPacerFlags::BurstyPacerFlags( - const FieldTrialsView& field_trials) - : burst("burst") { - ParseFieldTrial({&burst}, field_trials.Lookup(kBurstyPacerFieldTrial)); -} - TaskQueuePacedSender::TaskQueuePacedSender( Clock* clock, PacingController::PacketSender* packet_sender, const FieldTrialsView& field_trials, TimeDelta max_hold_back_window, - int max_hold_back_window_in_packets, - absl::optional<TimeDelta> burst_interval) + int max_hold_back_window_in_packets) : clock_(clock), - bursty_pacer_flags_(field_trials), max_hold_back_window_(max_hold_back_window), max_hold_back_window_in_packets_(max_hold_back_window_in_packets), pacing_controller_(clock, packet_sender, field_trials), @@ -56,17 +40,6 @@ TaskQueuePacedSender::TaskQueuePacedSender( include_overhead_(false), task_queue_(TaskQueueBase::Current()) { RTC_DCHECK_GE(max_hold_back_window_, PacingController::kMinSleepTime); - // There are multiple field trials that can affect burst. If multiple bursts - // are specified we pick the largest of the values. - absl::optional<TimeDelta> burst = bursty_pacer_flags_.burst.GetOptional(); - // If not overriden by an experiment, the burst is specified by the - // `burst_interval` argument. - if (!burst.has_value()) { - burst = burst_interval; - } - if (burst.has_value()) { - pacing_controller_.SetSendBurstInterval(burst.value()); - } } TaskQueuePacedSender::~TaskQueuePacedSender() { @@ -74,6 +47,11 @@ TaskQueuePacedSender::~TaskQueuePacedSender() { is_shutdown_ = true; } +void TaskQueuePacedSender::SetSendBurstInterval(TimeDelta burst_interval) { + RTC_DCHECK_RUN_ON(task_queue_); + pacing_controller_.SetSendBurstInterval(burst_interval); +} + void TaskQueuePacedSender::EnsureStarted() { RTC_DCHECK_RUN_ON(task_queue_); is_started_ = true; diff --git a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h index fd71be1654..e29acdf878 100644 --- a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h +++ b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender.h @@ -45,23 +45,21 @@ class TaskQueuePacedSender : public RtpPacketPacer, public RtpPacketSender { // processed. Increasing this reduces thread wakeups at the expense of higher // latency. // - // If the `burst_interval` parameter is set, the pacer is allowed to build up - // a packet "debt" that correspond to approximately the send rate during the - // specified interval. This greatly reduced wake ups by not pacing packets - // within the allowed burst budget. - // // The taskqueue used when constructing a TaskQueuePacedSender will also be // used for pacing. - TaskQueuePacedSender( - Clock* clock, - PacingController::PacketSender* packet_sender, - const FieldTrialsView& field_trials, - TimeDelta max_hold_back_window, - int max_hold_back_window_in_packets, - absl::optional<TimeDelta> burst_interval = absl::nullopt); + TaskQueuePacedSender(Clock* clock, + PacingController::PacketSender* packet_sender, + const FieldTrialsView& field_trials, + TimeDelta max_hold_back_window, + int max_hold_back_window_in_packets); ~TaskQueuePacedSender() override; + // The pacer is allowed to send enqued packets in bursts and can build up a + // packet "debt" that correspond to approximately the send rate during + // 'burst_interval'. + void SetSendBurstInterval(TimeDelta burst_interval); + // Ensure that necessary delayed tasks are scheduled. void EnsureStarted(); @@ -145,15 +143,6 @@ class TaskQueuePacedSender : public RtpPacketPacer, public RtpPacketSender { Stats GetStats() const; Clock* const clock_; - struct BurstyPacerFlags { - // Parses `kBurstyPacerFieldTrial`. Example: - // --force-fieldtrials=WebRTC-BurstyPacer/burst:20ms/ - explicit BurstyPacerFlags(const FieldTrialsView& field_trials); - // If set, the pacer is allowed to build up a packet "debt" that correspond - // to approximately the send rate during the specified interval. - FieldTrialOptional<TimeDelta> burst; - }; - const BurstyPacerFlags bursty_pacer_flags_; // The holdback window prevents too frequent delayed MaybeProcessPackets() // calls. These are only applicable if `allow_low_precision` is false. diff --git a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc index 54347493e7..f0a9ad78c2 100644 --- a/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc +++ b/third_party/libwebrtc/modules/pacing/task_queue_paced_sender_unittest.cc @@ -11,6 +11,7 @@ #include "modules/pacing/task_queue_paced_sender.h" #include <algorithm> +#include <any> #include <atomic> #include <list> #include <memory> @@ -24,6 +25,7 @@ #include "api/units/data_rate.h" #include "api/units/data_size.h" #include "api/units/time_delta.h" +#include "modules/pacing/pacing_controller.h" #include "modules/pacing/packet_router.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "test/gmock.h" @@ -33,6 +35,9 @@ using ::testing::_; using ::testing::AtLeast; +using ::testing::AtMost; +using ::testing::Lt; +using ::testing::NiceMock; using ::testing::Return; using ::testing::SaveArg; @@ -167,9 +172,10 @@ TEST(TaskQueuePacedSenderTest, PacesPacketsWithBurst) { TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, PacingController::kMinSleepTime, - TaskQueuePacedSender::kNoPacketHoldback, - // Half a second of bursting. - TimeDelta::Seconds(0.5)); + TaskQueuePacedSender::kNoPacketHoldback); + pacer.SetSendBurstInterval( + // Half a second of bursting. + TimeDelta::Seconds(0.5)); // Insert a number of packets, covering one second. static constexpr size_t kPacketsToSend = 42; @@ -262,7 +268,7 @@ TEST(TaskQueuePacedSenderTest, ReschedulesProcessOnRateChange) { TEST(TaskQueuePacedSenderTest, SendsAudioImmediately) { GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); - MockPacketRouter packet_router; + NiceMock<MockPacketRouter> packet_router; ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, @@ -270,21 +276,16 @@ TEST(TaskQueuePacedSenderTest, SendsAudioImmediately) { TaskQueuePacedSender::kNoPacketHoldback); const DataRate kPacingDataRate = DataRate::KilobitsPerSec(125); - const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize); - const TimeDelta kPacketPacingTime = kPacketSize / kPacingDataRate; pacer.SetPacingRates(kPacingDataRate, DataRate::Zero()); pacer.EnsureStarted(); - // Add some initial video packets, only one should be sent. - EXPECT_CALL(packet_router, SendPacket); + // Add some initial video packets. Not all should be sent immediately. + EXPECT_CALL(packet_router, SendPacket).Times(AtMost(9)); pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10)); time_controller.AdvanceTime(TimeDelta::Zero()); ::testing::Mock::VerifyAndClearExpectations(&packet_router); - // Advance time, but still before next packet should be sent. - time_controller.AdvanceTime(kPacketPacingTime / 2); - // Insert an audio packet, it should be sent immediately. EXPECT_CALL(packet_router, SendPacket); pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kAudio, 1)); @@ -295,12 +296,13 @@ TEST(TaskQueuePacedSenderTest, SendsAudioImmediately) { TEST(TaskQueuePacedSenderTest, SleepsDuringCoalscingWindow) { const TimeDelta kCoalescingWindow = TimeDelta::Millis(5); GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); - MockPacketRouter packet_router; + NiceMock<MockPacketRouter> packet_router; ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, kCoalescingWindow, TaskQueuePacedSender::kNoPacketHoldback); + pacer.SetSendBurstInterval(TimeDelta::Zero()); // Set rates so one packet adds one ms of buffer level. const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize); @@ -310,9 +312,9 @@ TEST(TaskQueuePacedSenderTest, SleepsDuringCoalscingWindow) { pacer.SetPacingRates(kPacingDataRate, DataRate::Zero()); pacer.EnsureStarted(); - // Add 10 packets. The first should be sent immediately since the buffers - // are clear. - EXPECT_CALL(packet_router, SendPacket); + // Add 10 packets. The first burst should be sent immediately since the + // buffers are clear. + EXPECT_CALL(packet_router, SendPacket).Times(AtMost(9)); pacer.EnqueuePackets(GeneratePackets(RtpPacketMediaType::kVideo, 10)); time_controller.AdvanceTime(TimeDelta::Zero()); ::testing::Mock::VerifyAndClearExpectations(&packet_router); @@ -370,11 +372,12 @@ TEST(TaskQueuePacedSenderTest, SchedulesProbeAtSentTime) { ScopedKeyValueConfig trials( "WebRTC-Bwe-ProbingBehavior/min_probe_delta:1ms/"); GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); - MockPacketRouter packet_router; + NiceMock<MockPacketRouter> packet_router; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, PacingController::kMinSleepTime, TaskQueuePacedSender::kNoPacketHoldback); + pacer.SetSendBurstInterval(TimeDelta::Zero()); // Set rates so one packet adds 4ms of buffer level. const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize); @@ -504,11 +507,12 @@ TEST(TaskQueuePacedSenderTest, PacketBasedCoalescing) { const int kPacketBasedHoldback = 5; GlobalSimulatedTimeController time_controller(Timestamp::Millis(1234)); - MockPacketRouter packet_router; + NiceMock<MockPacketRouter> packet_router; ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, kFixedCoalescingWindow, kPacketBasedHoldback); + pacer.SetSendBurstInterval(TimeDelta::Zero()); // Set rates so one packet adds one ms of buffer level. const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize); @@ -559,6 +563,7 @@ TEST(TaskQueuePacedSenderTest, FixedHoldBackHasPriorityOverPackets) { TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, kFixedCoalescingWindow, kPacketBasedHoldback); + pacer.SetSendBurstInterval(TimeDelta::Zero()); // Set rates so one packet adds one ms of buffer level. const DataSize kPacketSize = DataSize::Bytes(kDefaultPacketSize); @@ -691,7 +696,7 @@ TEST(TaskQueuePacedSenderTest, PostedPacketsNotSendFromRemovePacketsForSsrc) { TEST(TaskQueuePacedSenderTest, Stats) { static constexpr Timestamp kStartTime = Timestamp::Millis(1234); GlobalSimulatedTimeController time_controller(kStartTime); - MockPacketRouter packet_router; + NiceMock<MockPacketRouter> packet_router; ScopedKeyValueConfig trials; TaskQueuePacedSender pacer(time_controller.GetClock(), &packet_router, trials, @@ -708,7 +713,8 @@ TEST(TaskQueuePacedSenderTest, Stats) { // Allowed `QueueSizeData` and `ExpectedQueueTime` deviation. static constexpr size_t kAllowedPacketsDeviation = 1; static constexpr DataSize kAllowedQueueSizeDeviation = - DataSize::Bytes(kDefaultPacketSize * kAllowedPacketsDeviation); + DataSize::Bytes(kDefaultPacketSize * kAllowedPacketsDeviation) + + kPacingRate * PacingController::kDefaultBurstInterval; static constexpr TimeDelta kAllowedQueueTimeDeviation = kAllowedQueueSizeDeviation / kPacingRate; |