prioritized_packet_queue_unittest.cc (22991B)
1 /* 2 * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/pacing/prioritized_packet_queue.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <memory> 16 #include <utility> 17 18 #include "api/units/data_size.h" 19 #include "api/units/time_delta.h" 20 #include "api/units/timestamp.h" 21 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 22 #include "modules/rtp_rtcp/source/rtp_packet_to_send.h" 23 #include "rtc_base/checks.h" 24 #include "test/gtest.h" 25 26 namespace webrtc { 27 namespace { 28 29 constexpr uint32_t kDefaultSsrc = 123; 30 constexpr int kDefaultPayloadSize = 789; 31 32 std::unique_ptr<RtpPacketToSend> CreatePacket(RtpPacketMediaType type, 33 uint16_t seq, 34 uint32_t ssrc = kDefaultSsrc, 35 bool is_key_frame = false) { 36 auto packet = std::make_unique<RtpPacketToSend>(/*extensions=*/nullptr); 37 packet->set_packet_type(type); 38 packet->SetSsrc(ssrc); 39 packet->SetSequenceNumber(seq); 40 packet->SetPayloadSize(kDefaultPayloadSize); 41 packet->set_is_key_frame(is_key_frame); 42 return packet; 43 } 44 45 std::unique_ptr<RtpPacketToSend> CreateRetransmissionPacket( 46 RtpPacketMediaType original_type, 47 uint16_t seq, 48 uint32_t ssrc = kDefaultSsrc) { 49 auto packet = std::make_unique<RtpPacketToSend>(/*extensions=*/nullptr); 50 packet->set_packet_type(original_type); 51 packet->set_packet_type(RtpPacketMediaType::kRetransmission); 52 RTC_DCHECK(packet->packet_type() == RtpPacketMediaType::kRetransmission); 53 if (original_type == RtpPacketMediaType::kVideo) { 54 RTC_DCHECK(packet->original_packet_type() == 55 RtpPacketToSend::OriginalType::kVideo); 56 } else { 57 RTC_DCHECK(packet->original_packet_type() == 58 RtpPacketToSend::OriginalType::kAudio); 59 } 60 packet->SetSsrc(ssrc); 61 packet->SetSequenceNumber(seq); 62 packet->SetPayloadSize(kDefaultPayloadSize); 63 return packet; 64 } 65 66 } // namespace 67 68 TEST(PrioritizedPacketQueue, ReturnsPacketsInPrioritizedOrder) { 69 Timestamp now = Timestamp::Zero(); 70 PrioritizedPacketQueue queue(now); 71 72 // Add packets in low to high packet order. 73 queue.Push(now, CreatePacket(RtpPacketMediaType::kPadding, /*seq=*/1)); 74 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); 75 queue.Push(now, CreatePacket(RtpPacketMediaType::kForwardErrorCorrection, 76 /*seq=*/3)); 77 queue.Push(now, 78 CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/4)); 79 queue.Push(now, 80 CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/5)); 81 queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/6)); 82 83 // Packets should be returned in high to low order. 84 EXPECT_EQ(queue.Pop()->SequenceNumber(), 6); 85 // Audio and video retransmission has same prio, but video was enqueued first. 86 EXPECT_EQ(queue.Pop()->SequenceNumber(), 4); 87 EXPECT_EQ(queue.Pop()->SequenceNumber(), 5); 88 // Video and FEC prioritized equally - but video was enqueued first. 89 EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); 90 EXPECT_EQ(queue.Pop()->SequenceNumber(), 3); 91 EXPECT_EQ(queue.Pop()->SequenceNumber(), 1); 92 } 93 94 TEST(PrioritizedPacketQueue, 95 PrioritizeAudioRetransmissionBeforeVideoRetransmissionIfConfigured) { 96 Timestamp now = Timestamp::Zero(); 97 PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true); 98 99 // Add packets in low to high packet order. 100 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3)); 101 queue.Push(now, 102 CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/4)); 103 queue.Push(now, 104 CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/5)); 105 queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/6)); 106 107 // Packets should be returned in high to low order. 108 EXPECT_EQ(queue.Pop()->SequenceNumber(), 6); 109 EXPECT_EQ(queue.Pop()->SequenceNumber(), 5); 110 EXPECT_EQ(queue.Pop()->SequenceNumber(), 4); 111 } 112 113 TEST(PrioritizedPacketQueue, ReturnsEqualPrioPacketsInRoundRobinOrder) { 114 Timestamp now = Timestamp::Zero(); 115 PrioritizedPacketQueue queue(now); 116 117 // Insert video packets (prioritized equally), simulating a simulcast-type use 118 // case. 119 queue.Push(now, 120 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/1, /*ssrc=*/100)); 121 122 queue.Push(now, 123 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2, /*ssrc=*/101)); 124 queue.Push(now, 125 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3, /*ssrc=*/101)); 126 127 queue.Push(now, 128 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/4, /*ssrc=*/102)); 129 queue.Push(now, 130 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/5, /*ssrc=*/102)); 131 queue.Push(now, 132 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/6, /*ssrc=*/102)); 133 queue.Push(now, 134 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/7, /*ssrc=*/102)); 135 136 // First packet from each SSRC. 137 EXPECT_EQ(queue.Pop()->SequenceNumber(), 1); 138 EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); 139 EXPECT_EQ(queue.Pop()->SequenceNumber(), 4); 140 141 // Second packets from streams that have packets left. 142 EXPECT_EQ(queue.Pop()->SequenceNumber(), 3); 143 EXPECT_EQ(queue.Pop()->SequenceNumber(), 5); 144 145 // Only packets from last stream remaining. 146 EXPECT_EQ(queue.Pop()->SequenceNumber(), 6); 147 EXPECT_EQ(queue.Pop()->SequenceNumber(), 7); 148 } 149 150 TEST(PrioritizedPacketQueue, ReportsSizeInPackets) { 151 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero()); 152 EXPECT_EQ(queue.SizeInPackets(), 0); 153 154 queue.Push(/*enqueue_time=*/Timestamp::Zero(), 155 CreatePacket(RtpPacketMediaType::kVideo, 156 /*seq_no=*/1)); 157 EXPECT_EQ(queue.SizeInPackets(), 1); 158 159 queue.Pop(); 160 EXPECT_EQ(queue.SizeInPackets(), 0); 161 } 162 163 TEST(PrioritizedPacketQueue, ReportsPayloadSize) { 164 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero()); 165 EXPECT_EQ(queue.SizeInPayloadBytes(), DataSize::Zero()); 166 167 queue.Push(/*enqueue_time=*/Timestamp::Zero(), 168 CreatePacket(RtpPacketMediaType::kVideo, 169 /*seq_no=*/1)); 170 EXPECT_EQ(queue.SizeInPayloadBytes(), DataSize::Bytes(kDefaultPayloadSize)); 171 172 queue.Pop(); 173 EXPECT_EQ(queue.SizeInPayloadBytes(), DataSize::Zero()); 174 } 175 176 TEST(PrioritizedPacketQueue, ReportsPaddingSize) { 177 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero()); 178 EXPECT_EQ(queue.SizeInPayloadBytes(), DataSize::Zero()); 179 static constexpr DataSize kPaddingSize = DataSize::Bytes(190); 180 181 auto packet = std::make_unique<RtpPacketToSend>(/*extensions=*/nullptr); 182 packet->set_packet_type(RtpPacketMediaType::kPadding); 183 packet->SetSsrc(kDefaultSsrc); 184 packet->SetSequenceNumber(/*seq=*/1); 185 packet->SetPadding(kPaddingSize.bytes()); 186 queue.Push(/*enqueue_time=*/Timestamp::Zero(), std::move(packet)); 187 EXPECT_EQ(queue.SizeInPayloadBytes(), kPaddingSize); 188 189 queue.Pop(); 190 EXPECT_EQ(queue.SizeInPayloadBytes(), DataSize::Zero()); 191 } 192 193 TEST(PrioritizedPacketQueue, ReportsOldestEnqueueTime) { 194 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero()); 195 EXPECT_EQ(queue.OldestEnqueueTime(), Timestamp::MinusInfinity()); 196 197 // Add three packets, with the middle packet having higher prio. 198 queue.Push(Timestamp::Millis(10), 199 CreatePacket(RtpPacketMediaType::kPadding, /*seq=*/1)); 200 queue.Push(Timestamp::Millis(20), 201 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); 202 queue.Push(Timestamp::Millis(30), 203 CreatePacket(RtpPacketMediaType::kPadding, /*seq=*/3)); 204 EXPECT_EQ(queue.OldestEnqueueTime(), Timestamp::Millis(10)); 205 206 queue.Pop(); // Pop packet with enqueue time 20. 207 EXPECT_EQ(queue.OldestEnqueueTime(), Timestamp::Millis(10)); 208 209 queue.Pop(); // Pop packet with enqueue time 10. 210 EXPECT_EQ(queue.OldestEnqueueTime(), Timestamp::Millis(30)); 211 212 queue.Pop(); // Pop packet with enqueue time 30, queue empty again. 213 EXPECT_EQ(queue.OldestEnqueueTime(), Timestamp::MinusInfinity()); 214 } 215 216 TEST(PrioritizedPacketQueue, ReportsAverageQueueTime) { 217 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero()); 218 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Zero()); 219 220 // Add three packets, with the middle packet having higher prio. 221 queue.Push(Timestamp::Millis(10), 222 CreatePacket(RtpPacketMediaType::kPadding, /*seq=*/1)); 223 queue.Push(Timestamp::Millis(20), 224 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); 225 queue.Push(Timestamp::Millis(30), 226 CreatePacket(RtpPacketMediaType::kPadding, /*seq=*/3)); 227 228 queue.UpdateAverageQueueTime(Timestamp::Millis(40)); 229 // Packets have waited 30, 20, 10 ms -> average = 20ms. 230 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Millis(20)); 231 232 queue.Pop(); // Pop packet with enqueue time 20. 233 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Millis(20)); 234 235 queue.Pop(); // Pop packet with enqueue time 10. 236 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Millis(10)); 237 238 queue.Pop(); // Pop packet with enqueue time 30, queue empty again. 239 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Zero()); 240 } 241 242 TEST(PrioritizedPacketQueue, SubtractsPusedTimeFromAverageQueueTime) { 243 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero()); 244 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Zero()); 245 246 // Add a packet and then enable paused state. 247 queue.Push(Timestamp::Millis(100), 248 CreatePacket(RtpPacketMediaType::kPadding, /*seq=*/1)); 249 queue.SetPauseState(true, Timestamp::Millis(600)); 250 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Millis(500)); 251 252 // Enqueue a packet 500ms into the paused state. Queue time of 253 // original packet is still seen as 500ms and new one has 0ms giving 254 // an average of 250ms. 255 queue.Push(Timestamp::Millis(1100), 256 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); 257 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Millis(250)); 258 259 // Unpause some time later, queue time still unchanged. 260 queue.SetPauseState(false, Timestamp::Millis(1600)); 261 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Millis(250)); 262 263 // Update queue time 500ms after pause state ended. 264 queue.UpdateAverageQueueTime(Timestamp::Millis(2100)); 265 EXPECT_EQ(queue.AverageQueueTime(), TimeDelta::Millis(750)); 266 } 267 268 TEST(PrioritizedPacketQueue, ReportsLeadingPacketEnqueueTime) { 269 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero()); 270 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kAudio), 271 Timestamp::MinusInfinity()); 272 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kVideo), 273 Timestamp::MinusInfinity()); 274 275 queue.Push(Timestamp::Millis(10), 276 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/1)); 277 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kAudio), 278 Timestamp::MinusInfinity()); 279 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kVideo), 280 Timestamp::Millis(10)); 281 282 queue.Push(Timestamp::Millis(20), 283 CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/2)); 284 285 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kAudio), 286 Timestamp::Millis(20)); 287 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kVideo), 288 Timestamp::Millis(10)); 289 290 queue.Pop(); // Pop audio packet. 291 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kAudio), 292 Timestamp::MinusInfinity()); 293 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kVideo), 294 Timestamp::Millis(10)); 295 296 queue.Pop(); // Pop video packet. 297 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kAudio), 298 Timestamp::MinusInfinity()); 299 EXPECT_EQ(queue.LeadingPacketEnqueueTime(RtpPacketMediaType::kVideo), 300 Timestamp::MinusInfinity()); 301 } 302 303 TEST(PrioritizedPacketQueue, ReportsLeadingPacketEnqueueTimeForRetransmission) { 304 PrioritizedPacketQueue queue(/*creation_time=*/Timestamp::Zero(), 305 /*prioritize_audio_retransmission=*/true); 306 EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), 307 Timestamp::PlusInfinity()); 308 309 queue.Push(Timestamp::Millis(10), 310 CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/1)); 311 queue.Push(Timestamp::Millis(11), 312 CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/2)); 313 EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), 314 Timestamp::Millis(10)); 315 queue.Pop(); // Pop audio retransmission since it has higher prio. 316 EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), 317 Timestamp::Millis(10)); 318 queue.Pop(); // Pop video retransmission. 319 EXPECT_EQ(queue.LeadingPacketEnqueueTimeForRetransmission(), 320 Timestamp::PlusInfinity()); 321 } 322 323 TEST(PrioritizedPacketQueue, 324 PushAndPopUpdatesSizeInPacketsPerRtpPacketMediaType) { 325 Timestamp now = Timestamp::Zero(); 326 PrioritizedPacketQueue queue(now); 327 328 // Initially all sizes are zero. 329 for (size_t i = 0; i < kNumMediaTypes; ++i) { 330 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[i], 0); 331 } 332 333 // Push packets. 334 queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, 1)); 335 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[static_cast<size_t>( 336 RtpPacketMediaType::kAudio)], 337 1); 338 339 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, 2)); 340 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[static_cast<size_t>( 341 RtpPacketMediaType::kVideo)], 342 1); 343 344 queue.Push(now, CreateRetransmissionPacket(RtpPacketMediaType::kVideo, 3)); 345 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[static_cast<size_t>( 346 RtpPacketMediaType::kRetransmission)], 347 1); 348 349 queue.Push(now, CreatePacket(RtpPacketMediaType::kForwardErrorCorrection, 4)); 350 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[static_cast<size_t>( 351 RtpPacketMediaType::kForwardErrorCorrection)], 352 1); 353 354 queue.Push(now, CreatePacket(RtpPacketMediaType::kPadding, 5)); 355 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[static_cast<size_t>( 356 RtpPacketMediaType::kPadding)], 357 1); 358 359 // Now all sizes are 1. 360 for (size_t i = 0; i < kNumMediaTypes; ++i) { 361 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[i], 1); 362 } 363 364 // Popping happens in a priority order based on media type. This test does not 365 // assert what this order is, only that the counter for the popped packet's 366 // media type is decremented. 367 for (size_t i = 0; i < kNumMediaTypes; ++i) { 368 auto popped_packet = queue.Pop(); 369 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[static_cast<size_t>( 370 popped_packet->packet_type().value())], 371 0); 372 } 373 374 // We've popped all packets, so all sizes are zero. 375 for (size_t i = 0; i < kNumMediaTypes; ++i) { 376 EXPECT_EQ(queue.SizeInPacketsPerRtpPacketMediaType()[i], 0); 377 } 378 } 379 380 TEST(PrioritizedPacketQueue, ClearsPackets) { 381 Timestamp now = Timestamp::Zero(); 382 PrioritizedPacketQueue queue(now); 383 const uint32_t kSsrc = 1; 384 385 // Add two packets of each type, all using the same SSRC. 386 int sequence_number = 0; 387 for (size_t i = 0; i < kNumMediaTypes; ++i) { 388 queue.Push(now, CreatePacket(static_cast<RtpPacketMediaType>(i), 389 sequence_number++, kSsrc)); 390 queue.Push(now, CreatePacket(static_cast<RtpPacketMediaType>(i), 391 sequence_number++, kSsrc)); 392 } 393 EXPECT_EQ(queue.SizeInPackets(), 2 * int{kNumMediaTypes}); 394 395 // Remove all of them. 396 queue.RemovePacketsForSsrc(kSsrc); 397 EXPECT_TRUE(queue.Empty()); 398 queue.RemovePacketsForSsrc(kSsrc); 399 EXPECT_TRUE(queue.Empty()); 400 } 401 402 TEST(PrioritizedPacketQueue, ClearPacketsAffectsOnlySpecifiedSsrc) { 403 Timestamp now = Timestamp::Zero(); 404 PrioritizedPacketQueue queue(now); 405 const uint32_t kRemovingSsrc = 1; 406 const uint32_t kStayingSsrc = 2; 407 408 // Add an audio packet and a retransmission for the SSRC we will remove, 409 // ensuring they are first in line. 410 queue.Push( 411 now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/1, kRemovingSsrc)); 412 queue.Push(now, CreateRetransmissionPacket(RtpPacketMediaType::kVideo, 413 /*seq=*/2, kRemovingSsrc)); 414 415 // Add a video packet and a retransmission for the SSRC that will remain. 416 // The retransmission packets now both have pointers to their respective qeues 417 // from the same prio level. 418 queue.Push(now, 419 CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3, kStayingSsrc)); 420 queue.Push(now, CreateRetransmissionPacket(RtpPacketMediaType::kVideo, 421 /*seq=*/4, kStayingSsrc)); 422 423 EXPECT_EQ(queue.SizeInPackets(), 4); 424 425 // Clear the first two packets. 426 queue.RemovePacketsForSsrc(kRemovingSsrc); 427 EXPECT_EQ(queue.SizeInPackets(), 2); 428 429 // We should get the single remaining retransmission first, then the video 430 // packet. 431 EXPECT_EQ(queue.Pop()->SequenceNumber(), 4); 432 EXPECT_EQ(queue.Pop()->SequenceNumber(), 3); 433 EXPECT_TRUE(queue.Empty()); 434 } 435 436 TEST(PrioritizedPacketQueue, ReportsKeyframePackets) { 437 Timestamp now = Timestamp::Zero(); 438 PrioritizedPacketQueue queue(now); 439 const uint32_t kVideoSsrc1 = 1234; 440 const uint32_t kVideoSsrc2 = 2345; 441 442 EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc1)); 443 EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc2)); 444 445 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/1, 446 kVideoSsrc1, /*is_key_frame=*/true)); 447 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/11, 448 kVideoSsrc2, /*is_key_frame=*/false)); 449 450 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); 451 EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc2)); 452 453 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2, 454 kVideoSsrc1, /*is_key_frame=*/true)); 455 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/12, 456 kVideoSsrc2, /*is_key_frame=*/true)); 457 458 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); 459 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); 460 461 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3, 462 kVideoSsrc1, /*is_key_frame=*/false)); 463 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/13, 464 kVideoSsrc2, /*is_key_frame=*/true)); 465 466 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); 467 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); 468 469 EXPECT_EQ(queue.Pop()->SequenceNumber(), 1); 470 EXPECT_EQ(queue.Pop()->SequenceNumber(), 11); 471 472 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc1)); 473 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); 474 475 EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); 476 EXPECT_EQ(queue.Pop()->SequenceNumber(), 12); 477 478 EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc1)); 479 EXPECT_TRUE(queue.HasKeyframePackets(kVideoSsrc2)); 480 481 queue.RemovePacketsForSsrc(kVideoSsrc2); 482 483 EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc1)); 484 EXPECT_FALSE(queue.HasKeyframePackets(kVideoSsrc2)); 485 } 486 487 TEST(PrioritizedPacketQueue, PacketsDroppedIfNotPulledWithinTttl) { 488 Timestamp now = Timestamp::Zero(); 489 PacketQueueTTL ttls; 490 ttls.audio_retransmission = TimeDelta::Millis(200); 491 PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true, 492 ttls); 493 494 queue.Push(now, 495 CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/1)); 496 now += ttls.audio_retransmission + TimeDelta::Millis(1); 497 EXPECT_EQ(queue.SizeInPackets(), 1); 498 queue.Push(now, 499 CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/2)); 500 EXPECT_EQ(queue.SizeInPackets(), 1); 501 EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); 502 } 503 504 TEST(PrioritizedPacketQueue, DontSendPacketsAfterTttl) { 505 Timestamp now = Timestamp::Zero(); 506 PacketQueueTTL ttls; 507 ttls.audio_retransmission = TimeDelta::Millis(200); 508 PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true, 509 ttls); 510 511 queue.Push(now, 512 CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/1)); 513 now += ttls.audio_retransmission + TimeDelta::Millis(1); 514 EXPECT_EQ(queue.SizeInPackets(), 1); 515 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); 516 queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/3)); 517 // Expect the old packet to have been removed since it was not popped in time. 518 EXPECT_EQ(queue.SizeInPackets(), 3); 519 EXPECT_EQ(queue.Pop()->SequenceNumber(), 3); 520 EXPECT_EQ(queue.SizeInPackets(), 1); 521 EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); 522 EXPECT_EQ(queue.SizeInPackets(), 0); 523 } 524 525 TEST(PrioritizedPacketQueue, SendsNewVideoPacketAfterPurgingLastOldRtxPacket) { 526 Timestamp now = Timestamp::Zero(); 527 PacketQueueTTL ttls; 528 ttls.video_retransmission = TimeDelta::Millis(400); 529 PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true, 530 ttls); 531 532 queue.Push(now, 533 CreateRetransmissionPacket(RtpPacketMediaType::kVideo, /*seq=*/1)); 534 now += ttls.video_retransmission + TimeDelta::Millis(1); 535 queue.Push(now, CreatePacket(RtpPacketMediaType::kAudio, /*seq=*/2)); 536 EXPECT_EQ(queue.SizeInPackets(), 2); 537 // Expect the audio packet to be send and the video retransmission packet to 538 // be dropped since it is old. 539 EXPECT_EQ(queue.Pop()->SequenceNumber(), 2); 540 EXPECT_EQ(queue.SizeInPackets(), 0); 541 542 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/3)); 543 EXPECT_EQ(queue.SizeInPackets(), 1); 544 EXPECT_EQ(queue.Pop()->SequenceNumber(), 3); 545 EXPECT_EQ(queue.SizeInPackets(), 0); 546 } 547 548 TEST(PrioritizedPacketQueue, 549 SendsPacketsAfterTttlIfPrioHigherThanPushedPackets) { 550 Timestamp now = Timestamp::Zero(); 551 PacketQueueTTL ttls; 552 ttls.audio_retransmission = TimeDelta::Millis(200); 553 PrioritizedPacketQueue queue(now, /*prioritize_audio_retransmission=*/true, 554 ttls); 555 556 queue.Push(now, 557 CreateRetransmissionPacket(RtpPacketMediaType::kAudio, /*seq=*/1)); 558 now += ttls.audio_retransmission + TimeDelta::Millis(1); 559 EXPECT_EQ(queue.SizeInPackets(), 1); 560 queue.Push(now, CreatePacket(RtpPacketMediaType::kVideo, /*seq=*/2)); 561 562 // This test just show that TTL is not enforced strictly. If a new audio 563 // packet had been queued before a packet was popped, the audio retransmission 564 // packet would have been dropped. 565 EXPECT_EQ(queue.SizeInPackets(), 2); 566 EXPECT_EQ(queue.Pop()->SequenceNumber(), 1); 567 EXPECT_EQ(queue.SizeInPackets(), 1); 568 } 569 570 } // namespace webrtc