Fix problem in PrioritizedPacketQueue when last old RTX packet is purged

Ensure top_active_prio_level_ is set to -1 in MaybeUpdateTopPrioLevel if
last packet is purged.

Bug: webrtc:15740
Change-Id: I81df9ee084de89f79b8ab79db8ce52fe1e20738a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/333883
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41498}
This commit is contained in:
Per K 2024-01-10 09:51:59 +01:00 committed by WebRTC LUCI CQ
parent f81af2f8fd
commit 187ca72ab7
2 changed files with 39 additions and 14 deletions

View File

@ -410,22 +410,24 @@ void PrioritizedPacketQueue::DequeuePacketInternal(QueuedPacket& packet) {
}
void PrioritizedPacketQueue::MaybeUpdateTopPrioLevel() {
if (top_active_prio_level_ == -1 ||
streams_by_prio_[top_active_prio_level_].empty()) {
// No stream queues have packets at this prio level, find top priority
// that is not empty.
if (size_packets_ == 0) {
top_active_prio_level_ = -1;
} else {
for (int i = 0; i < kNumPriorityLevels; ++i) {
PurgeOldPacketsAtPriorityLevel(i, last_update_time_);
if (!streams_by_prio_[i].empty()) {
top_active_prio_level_ = i;
break;
}
}
if (top_active_prio_level_ != -1 &&
!streams_by_prio_[top_active_prio_level_].empty()) {
return;
}
// No stream queues have packets at top_active_prio_level_, find top priority
// that is not empty.
for (int i = 0; i < kNumPriorityLevels; ++i) {
PurgeOldPacketsAtPriorityLevel(i, last_update_time_);
if (!streams_by_prio_[i].empty()) {
top_active_prio_level_ = i;
break;
}
}
if (size_packets_ == 0) {
// There are no packets left to send. Last packet may have been purged. Prio
// will change when a new packet is pushed.
top_active_prio_level_ = -1;
}
}
void PrioritizedPacketQueue::PurgeOldPacketsAtPriorityLevel(int prio_level,

View File

@ -519,6 +519,29 @@ TEST(PrioritizedPacketQueue, DontSendPacketsAfterTttl) {
EXPECT_EQ(queue.SizeInPackets(), 0);
}
TEST(PrioritizedPacketQueue, SendsNewVideoPacketAfterPurgingLastOldRtxPacket) {
Timestamp now = Timestamp::Zero();
PacketQueueTTL ttls;
ttls.video_retransmission = TimeDelta::Millis(400);
PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true,
ttls);
queue.Push(now,
CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/1));
now += ttls.video_retransmission + TimeDelta::Millis(1);
queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/2));
EXPECT_EQ(queue.SizeInPackets(), 2);
// Expect the audio packet to be send and the video retransmission packet to
// be dropped since it is old.
EXPECT_EQ(queue.Pop()->SequenceNumber(), 2);
EXPECT_EQ(queue.SizeInPackets(), 0);
queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3));
EXPECT_EQ(queue.SizeInPackets(), 1);
EXPECT_EQ(queue.Pop()->SequenceNumber(), 3);
EXPECT_EQ(queue.SizeInPackets(), 0);
}
TEST(PrioritizedPacketQueue,
SendsPacketsAfterTttlIfPrioHigherThanPushedPackets) {
Timestamp now = Timestamp::Zero();