diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
commit | d8bbc7858622b6d9c278469aab701ca0b609cddf (patch) | |
tree | eff41dc61d9f714852212739e6b3738b82a2af87 /third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc | |
parent | Releasing progress-linux version 125.0.3-1~progress7.99u1. (diff) | |
download | firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc | 171 |
1 files changed, 161 insertions, 10 deletions
diff --git a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc index 9ed19642c7..76c31036b3 100644 --- a/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc +++ b/third_party/libwebrtc/modules/pacing/prioritized_packet_queue_unittest.cc @@ -10,6 +10,7 @@ #include "modules/pacing/prioritized_packet_queue.h" +#include <memory> #include <utility> #include "api/units/time_delta.h" @@ -26,18 +27,39 @@ constexpr uint32_t kDefaultSsrc = 123; constexpr int kDefaultPayloadSize = 789; std::unique_ptr<RtpPacketToSend> CreatePacket(RtpPacketMediaType type, - uint16_t sequence_number, + uint16_t seq, uint32_t ssrc = kDefaultSsrc, bool is_key_frame = false) { auto packet = std::make_unique<RtpPacketToSend>(/*extensions=*/nullptr); packet->set_packet_type(type); packet->SetSsrc(ssrc); - packet->SetSequenceNumber(sequence_number); + packet->SetSequenceNumber(seq); packet->SetPayloadSize(kDefaultPayloadSize); packet->set_is_key_frame(is_key_frame); return packet; } +std::unique_ptr<RtpPacketToSend> CreateRetransmissionPacket( + RtpPacketMediaType original_type, + uint16_t seq, + uint32_t ssrc = kDefaultSsrc) { + auto packet = std::make_unique<RtpPacketToSend>(/*extensions=*/nullptr); + packet->set_packet_type(original_type); + packet->set_packet_type(RtpPacketMediaType::kRetransmission); + RTC_DCHECK(packet->packet_type() == RtpPacketMediaType::kRetransmission); + if (original_type == RtpPacketMediaType::kVideo) { + RTC_DCHECK(packet->original_packet_type() == + RtpPacketToSend::OriginalType::kVideo); + } else { + RTC_DCHECK(packet->original_packet_type() == + RtpPacketToSend::OriginalType::kAudio); + } + packet->SetSsrc(ssrc); + packet->SetSequenceNumber(seq); + packet->SetPayloadSize(kDefaultPayloadSize); + return packet; +} + } // namespace TEST(PrioritizedPacketQueue, ReturnsPacketsInPrioritizedOrder) { @@ -49,18 +71,42 @@ TEST(PrioritizedPacketQueue, ReturnsPacketsInPrioritizedOrder) { queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); queue.Push(now, CreatePacket(RtpPacketMediaType::kForwardErrorCorrection, /*seq=*/3)); - queue.Push(now, CreatePacket(RtpPacketMediaType::kRetransmission, /*seq=*/4)); - queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/5)); + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/4)); + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/5)); + queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/6)); // Packets should be returned in high to low order. - EXPECT_EQ(queue.Pop()->SequenceNumber(), 5); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 6); + // Audio and video retransmission has same prio, but video was enqueued first. EXPECT_EQ(queue.Pop()->SequenceNumber(), 4); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 5); // Video and FEC prioritized equally - but video was enqueued first. EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); EXPECT_EQ(queue.Pop()->SequenceNumber(), 3); EXPECT_EQ(queue.Pop()->SequenceNumber(), 1); } +TEST(PrioritizedPacketQueue, + PrioritizeAudioRetransmissionBeforeVideoRetransmissionIfConfigured) { + Timestamp now = Timestamp::Zero(); + PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true); + + // Add packets in low to high packet order. + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3)); + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/4)); + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/5)); + queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/6)); + + // Packets should be returned in high to low order. + EXPECT_EQ(queue.Pop()->SequenceNumber(), 6); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 5); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 4); +} + TEST(PrioritizedPacketQueue, ReturnsEqualPrioPacketsInRoundRobinOrder) { Timestamp now = Timestamp::Zero(); PrioritizedPacketQueue queue(now); @@ -251,6 +297,26 @@ TEST(PrioritizedPacketQueue, ReportsLeadingPacketEnqueueTime) { Timestamp::MinusInfinity()); } +TEST(PrioritizedPacketQueue, ReportsLeadingPacketEnqueueTimeForRetransmission) { + PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero(), + /*prioritize_audio_retransmission=*/true); + EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), + Timestamp::PlusInfinity()); + + queue.Push(Timestamp::Millis(10), + CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/1)); + queue.Push(Timestamp::Millis(11), + CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/2)); + EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), + Timestamp::Millis(10)); + queue.Pop(); // Pop audio retransmission since it has higher prio. + EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), + Timestamp::Millis(10)); + queue.Pop(); // Pop video retransmission. + EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), + Timestamp::PlusInfinity()); +} + TEST(PrioritizedPacketQueue, PushAndPopUpdatesSizeInPacketsPerRtpPacketMediaType) { Timestamp now = Timestamp::Zero(); @@ -272,7 +338,7 @@ TEST(PrioritizedPacketQueue, RtpPacketMediaType::kVideo)], 1); - queue.Push(now, CreatePacket(RtpPacketMediaType::kRetransmission, 3)); + queue.Push(now, CreateRetransmissionPacket(RtpPacketMediaType::kVideo, 3)); EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[static_cast<size_t>( RtpPacketMediaType::kRetransmission)], 1); @@ -326,6 +392,8 @@ TEST(PrioritizedPacketQueue, ClearsPackets) { // Remove all of them. queue.RemovePacketsForSsrc(kSsrc); EXPECT_TRUE(queue.Empty()); + queue.RemovePacketsForSsrc(kSsrc); + EXPECT_TRUE(queue.Empty()); } TEST(PrioritizedPacketQueue, ClearPacketsAffectsOnlySpecifiedSsrc) { @@ -338,16 +406,16 @@ TEST(PrioritizedPacketQueue, ClearPacketsAffectsOnlySpecifiedSsrc) { // ensuring they are first in line. queue.Push( now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/1, kRemovingSsrc)); - queue.Push(now, CreatePacket(RtpPacketMediaType::kRetransmission, /*seq=*/2, - kRemovingSsrc)); + queue.Push(now, CreateRetransmissionPacket(RtpPacketMediaType::kVideo, + /*seq=*/2, kRemovingSsrc)); // Add a video packet and a retransmission for the SSRC that will remain. // The retransmission packets now both have pointers to their respective qeues // from the same prio level. queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3, kStayingSsrc)); - queue.Push(now, CreatePacket(RtpPacketMediaType::kRetransmission, /*seq=*/4, - kStayingSsrc)); + queue.Push(now, CreateRetransmissionPacket(RtpPacketMediaType::kVideo, + /*seq=*/4, kStayingSsrc)); EXPECT_EQ(queue.SizeInPackets(), 4); @@ -413,4 +481,87 @@ TEST(PrioritizedPacketQueue, ReportsKeyframePackets) { EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc2)); } +TEST(PrioritizedPacketQueue, PacketsDroppedIfNotPulledWithinTttl) { + Timestamp now = Timestamp::Zero(); + PacketQueueTTL ttls; + ttls.audio_retransmission = TimeDelta::Millis(200); + PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true, + ttls); + + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/1)); + now += ttls.audio_retransmission + TimeDelta::Millis(1); + EXPECT_EQ(queue.SizeInPackets(), 1); + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/2)); + EXPECT_EQ(queue.SizeInPackets(), 1); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); +} + +TEST(PrioritizedPacketQueue, DontSendPacketsAfterTttl) { + Timestamp now = Timestamp::Zero(); + PacketQueueTTL ttls; + ttls.audio_retransmission = TimeDelta::Millis(200); + PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true, + ttls); + + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/1)); + now += ttls.audio_retransmission + TimeDelta::Millis(1); + EXPECT_EQ(queue.SizeInPackets(), 1); + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); + queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/3)); + // Expect the old packet to have been removed since it was not popped in time. + EXPECT_EQ(queue.SizeInPackets(), 3); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 3); + EXPECT_EQ(queue.SizeInPackets(), 1); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); + 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(); + PacketQueueTTL ttls; + ttls.audio_retransmission = TimeDelta::Millis(200); + PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true, + ttls); + + queue.Push(now, + CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/1)); + now += ttls.audio_retransmission + TimeDelta::Millis(1); + EXPECT_EQ(queue.SizeInPackets(), 1); + queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); + + // This test just show that TTL is not enforced strictly. If a new audio + // packet had been queued before a packet was popped, the audio retransmission + // packet would have been dropped. + EXPECT_EQ(queue.SizeInPackets(), 2); + EXPECT_EQ(queue.Pop()->SequenceNumber(), 1); + EXPECT_EQ(queue.SizeInPackets(), 1); +} + } // namespace webrtc |