Non-zero pacing debt should result in non-zero process time delta.

Bug: webrtc:11340
Change-Id: Ib5567ef03d324b44fd1c0f3f8265870acb710cc9
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/259764
Reviewed-by: Emil Lundmark <lndmrk@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36616}
This commit is contained in:
Erik Språng 2022-04-22 12:18:17 +02:00 committed by WebRTC LUCI CQ
parent 1729642b72
commit b844dd8465
2 changed files with 55 additions and 0 deletions

View file

@ -366,6 +366,13 @@ Timestamp PacingController::NextSendTime() const {
RTC_DCHECK_GT(media_rate_, DataRate::Zero()); RTC_DCHECK_GT(media_rate_, DataRate::Zero());
TimeDelta drain_time = TimeDelta drain_time =
std::max(media_debt_ / media_rate_, padding_debt_ / padding_rate_); std::max(media_debt_ / media_rate_, padding_debt_ / padding_rate_);
if (drain_time.IsZero() &&
(!media_debt_.IsZero() || !padding_debt_.IsZero())) {
// We have a non-zero debt, but drain time is smaller than tick size of
// TimeDelta, round it up to the smallest possible non-zero delta.
drain_time = TimeDelta::Micros(1);
}
next_send_time = last_process_time_ + drain_time; next_send_time = last_process_time_ + drain_time;
} else { } else {
// Nothing to do. // Nothing to do.

View file

@ -2114,6 +2114,54 @@ TEST_P(PacingControllerTest, GapInPacingDoesntAccumulateBudget) {
pacer_->ProcessPackets(); pacer_->ProcessPackets();
} }
TEST_P(PacingControllerTest, HandlesSubMicrosecondSendIntervals) {
if (PeriodicProcess()) {
GTEST_SKIP() << "This test checks behavior when not using interval budget.";
}
static constexpr DataSize kPacketSize = DataSize::Bytes(1);
static constexpr TimeDelta kPacketSendTime = TimeDelta::Micros(1);
// Set pacing rate such that a packet is sent in 0.5us.
pacer_->SetPacingRates(/*pacing_rate=*/2 * kPacketSize / kPacketSendTime,
/*padding_rate=*/DataRate::Zero());
// Enqueue three packets, the first two should be sent immediately - the third
// should cause a non-zero delta to the next process time.
EXPECT_CALL(callback_, SendPacket).Times(2);
for (int i = 0; i < 3; ++i) {
Send(RtpPacketMediaType::kVideo, /*ssrc=*/12345, /*sequence_number=*/i,
clock_.TimeInMilliseconds(), kPacketSize.bytes());
}
pacer_->ProcessPackets();
EXPECT_GT(pacer_->NextSendTime(), clock_.CurrentTime());
}
TEST_P(PacingControllerTest, HandlesSubMicrosecondPaddingInterval) {
if (PeriodicProcess()) {
GTEST_SKIP() << "This test checks behavior when not using interval budget.";
}
static constexpr DataSize kPacketSize = DataSize::Bytes(1);
static constexpr TimeDelta kPacketSendTime = TimeDelta::Micros(1);
// Set both pacing and padding rates to 1 byte per 0.5us.
pacer_->SetPacingRates(/*pacing_rate=*/2 * kPacketSize / kPacketSendTime,
/*padding_rate=*/2 * kPacketSize / kPacketSendTime);
// Enqueue and send one packet.
EXPECT_CALL(callback_, SendPacket);
Send(RtpPacketMediaType::kVideo, /*ssrc=*/12345, /*sequence_number=*/1234,
clock_.TimeInMilliseconds(), kPacketSize.bytes());
pacer_->ProcessPackets();
// The padding debt is now 1 byte, and the pacing time for that is lower than
// the precision of a TimeStamp tick. Make sure the pacer still indicates a
// non-zero sleep time is needed until the next process.
EXPECT_GT(pacer_->NextSendTime(), clock_.CurrentTime());
}
INSTANTIATE_TEST_SUITE_P( INSTANTIATE_TEST_SUITE_P(
WithAndWithoutIntervalBudget, WithAndWithoutIntervalBudget,
PacingControllerTest, PacingControllerTest,