1 /*
2 * Copyright (c) 2012 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 // Unit tests for PacketBuffer class.
12
13 #include "modules/audio_coding/neteq/packet_buffer.h"
14
15 #include <memory>
16
17 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
18 #include "api/neteq/tick_timer.h"
19 #include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
20 #include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
21 #include "modules/audio_coding/neteq/packet.h"
22 #include "test/gmock.h"
23 #include "test/gtest.h"
24
25 using ::testing::_;
26 using ::testing::InSequence;
27 using ::testing::MockFunction;
28 using ::testing::Return;
29 using ::testing::StrictMock;
30
31 namespace {
32 class MockEncodedAudioFrame : public webrtc::AudioDecoder::EncodedAudioFrame {
33 public:
34 MOCK_METHOD(size_t, Duration, (), (const, override));
35
36 MOCK_METHOD(bool, IsDtxPacket, (), (const, override));
37
38 MOCK_METHOD(absl::optional<DecodeResult>,
39 Decode,
40 (rtc::ArrayView<int16_t> decoded),
41 (const, override));
42 };
43
44 // Helper class to generate packets. Packets must be deleted by the user.
45 class PacketGenerator {
46 public:
47 PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
~PacketGenerator()48 virtual ~PacketGenerator() {}
49 void Reset(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
50 webrtc::Packet NextPacket(
51 int payload_size_bytes,
52 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame);
53
54 uint16_t seq_no_;
55 uint32_t ts_;
56 uint8_t pt_;
57 int frame_size_;
58 };
59
PacketGenerator(uint16_t seq_no,uint32_t ts,uint8_t pt,int frame_size)60 PacketGenerator::PacketGenerator(uint16_t seq_no,
61 uint32_t ts,
62 uint8_t pt,
63 int frame_size) {
64 Reset(seq_no, ts, pt, frame_size);
65 }
66
Reset(uint16_t seq_no,uint32_t ts,uint8_t pt,int frame_size)67 void PacketGenerator::Reset(uint16_t seq_no,
68 uint32_t ts,
69 uint8_t pt,
70 int frame_size) {
71 seq_no_ = seq_no;
72 ts_ = ts;
73 pt_ = pt;
74 frame_size_ = frame_size;
75 }
76
NextPacket(int payload_size_bytes,std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame)77 webrtc::Packet PacketGenerator::NextPacket(
78 int payload_size_bytes,
79 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame) {
80 webrtc::Packet packet;
81 packet.sequence_number = seq_no_;
82 packet.timestamp = ts_;
83 packet.payload_type = pt_;
84 packet.payload.SetSize(payload_size_bytes);
85 ++seq_no_;
86 ts_ += frame_size_;
87 packet.frame = std::move(audio_frame);
88 return packet;
89 }
90
91 struct PacketsToInsert {
92 uint16_t sequence_number;
93 uint32_t timestamp;
94 uint8_t payload_type;
95 bool primary;
96 // Order of this packet to appear upon extraction, after inserting a series
97 // of packets. A negative number means that it should have been discarded
98 // before extraction.
99 int extract_order;
100 };
101
102 } // namespace
103
104 namespace webrtc {
105
106 // Start of test definitions.
107
TEST(PacketBuffer,CreateAndDestroy)108 TEST(PacketBuffer, CreateAndDestroy) {
109 TickTimer tick_timer;
110 PacketBuffer* buffer = new PacketBuffer(10, &tick_timer); // 10 packets.
111 EXPECT_TRUE(buffer->Empty());
112 delete buffer;
113 }
114
TEST(PacketBuffer,InsertPacket)115 TEST(PacketBuffer, InsertPacket) {
116 TickTimer tick_timer;
117 PacketBuffer buffer(10, &tick_timer); // 10 packets.
118 PacketGenerator gen(17u, 4711u, 0, 10);
119 StrictMock<MockStatisticsCalculator> mock_stats;
120
121 const int payload_len = 100;
122 const Packet packet = gen.NextPacket(payload_len, nullptr);
123 EXPECT_EQ(0, buffer.InsertPacket(packet.Clone(), &mock_stats));
124 uint32_t next_ts;
125 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
126 EXPECT_EQ(4711u, next_ts);
127 EXPECT_FALSE(buffer.Empty());
128 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
129 const Packet* next_packet = buffer.PeekNextPacket();
130 EXPECT_EQ(packet, *next_packet); // Compare contents.
131
132 // Do not explicitly flush buffer or delete packet to test that it is deleted
133 // with the buffer. (Tested with Valgrind or similar tool.)
134 }
135
136 // Test to flush buffer.
TEST(PacketBuffer,FlushBuffer)137 TEST(PacketBuffer, FlushBuffer) {
138 TickTimer tick_timer;
139 PacketBuffer buffer(10, &tick_timer); // 10 packets.
140 PacketGenerator gen(0, 0, 0, 10);
141 const int payload_len = 10;
142 StrictMock<MockStatisticsCalculator> mock_stats;
143
144 // Insert 10 small packets; should be ok.
145 for (int i = 0; i < 10; ++i) {
146 EXPECT_EQ(
147 PacketBuffer::kOK,
148 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
149 }
150 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
151 EXPECT_FALSE(buffer.Empty());
152
153 buffer.Flush();
154 // Buffer should delete the payloads itself.
155 EXPECT_EQ(0u, buffer.NumPacketsInBuffer());
156 EXPECT_TRUE(buffer.Empty());
157 }
158
159 // Test to fill the buffer over the limits, and verify that it flushes.
TEST(PacketBuffer,OverfillBuffer)160 TEST(PacketBuffer, OverfillBuffer) {
161 TickTimer tick_timer;
162 PacketBuffer buffer(10, &tick_timer); // 10 packets.
163 PacketGenerator gen(0, 0, 0, 10);
164 StrictMock<MockStatisticsCalculator> mock_stats;
165
166 // Insert 10 small packets; should be ok.
167 const int payload_len = 10;
168 int i;
169 for (i = 0; i < 10; ++i) {
170 EXPECT_EQ(
171 PacketBuffer::kOK,
172 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
173 }
174 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
175 uint32_t next_ts;
176 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
177 EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
178
179 const Packet packet = gen.NextPacket(payload_len, nullptr);
180 // Insert 11th packet; should flush the buffer and insert it after flushing.
181 EXPECT_EQ(PacketBuffer::kFlushed,
182 buffer.InsertPacket(packet.Clone(), &mock_stats));
183 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
184 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
185 // Expect last inserted packet to be first in line.
186 EXPECT_EQ(packet.timestamp, next_ts);
187
188 // Flush buffer to delete all packets.
189 buffer.Flush();
190 }
191
192 // Test inserting a list of packets.
TEST(PacketBuffer,InsertPacketList)193 TEST(PacketBuffer, InsertPacketList) {
194 TickTimer tick_timer;
195 PacketBuffer buffer(10, &tick_timer); // 10 packets.
196 PacketGenerator gen(0, 0, 0, 10);
197 PacketList list;
198 const int payload_len = 10;
199
200 // Insert 10 small packets.
201 for (int i = 0; i < 10; ++i) {
202 list.push_back(gen.NextPacket(payload_len, nullptr));
203 }
204
205 MockDecoderDatabase decoder_database;
206 auto factory = CreateBuiltinAudioDecoderFactory();
207 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
208 absl::nullopt, factory);
209 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
210 .WillRepeatedly(Return(&info));
211
212 StrictMock<MockStatisticsCalculator> mock_stats;
213
214 absl::optional<uint8_t> current_pt;
215 absl::optional<uint8_t> current_cng_pt;
216 EXPECT_EQ(PacketBuffer::kOK,
217 buffer.InsertPacketList(&list, decoder_database, ¤t_pt,
218 ¤t_cng_pt, &mock_stats));
219 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
220 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
221 EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
222 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
223
224 buffer.Flush(); // Clean up.
225
226 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
227 }
228
229 // Test inserting a list of packets. Last packet is of a different payload type.
230 // Expecting the buffer to flush.
231 // TODO(hlundin): Remove this test when legacy operation is no longer needed.
TEST(PacketBuffer,InsertPacketListChangePayloadType)232 TEST(PacketBuffer, InsertPacketListChangePayloadType) {
233 TickTimer tick_timer;
234 PacketBuffer buffer(10, &tick_timer); // 10 packets.
235 PacketGenerator gen(0, 0, 0, 10);
236 PacketList list;
237 const int payload_len = 10;
238
239 // Insert 10 small packets.
240 for (int i = 0; i < 10; ++i) {
241 list.push_back(gen.NextPacket(payload_len, nullptr));
242 }
243 // Insert 11th packet of another payload type (not CNG).
244 {
245 Packet packet = gen.NextPacket(payload_len, nullptr);
246 packet.payload_type = 1;
247 list.push_back(std::move(packet));
248 }
249
250 MockDecoderDatabase decoder_database;
251 auto factory = CreateBuiltinAudioDecoderFactory();
252 const DecoderDatabase::DecoderInfo info0(SdpAudioFormat("pcmu", 8000, 1),
253 absl::nullopt, factory);
254 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
255 .WillRepeatedly(Return(&info0));
256 const DecoderDatabase::DecoderInfo info1(SdpAudioFormat("pcma", 8000, 1),
257 absl::nullopt, factory);
258 EXPECT_CALL(decoder_database, GetDecoderInfo(1))
259 .WillRepeatedly(Return(&info1));
260
261 StrictMock<MockStatisticsCalculator> mock_stats;
262
263 absl::optional<uint8_t> current_pt;
264 absl::optional<uint8_t> current_cng_pt;
265 EXPECT_EQ(PacketBuffer::kFlushed,
266 buffer.InsertPacketList(&list, decoder_database, ¤t_pt,
267 ¤t_cng_pt, &mock_stats));
268 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
269 EXPECT_EQ(1u, buffer.NumPacketsInBuffer()); // Only the last packet.
270 EXPECT_EQ(1, current_pt); // Current payload type changed to 1.
271 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
272
273 buffer.Flush(); // Clean up.
274
275 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
276 }
277
TEST(PacketBuffer,ExtractOrderRedundancy)278 TEST(PacketBuffer, ExtractOrderRedundancy) {
279 TickTimer tick_timer;
280 PacketBuffer buffer(100, &tick_timer); // 100 packets.
281 const int kPackets = 18;
282 const int kFrameSize = 10;
283 const int kPayloadLength = 10;
284
285 PacketsToInsert packet_facts[kPackets] = {
286 {0xFFFD, 0xFFFFFFD7, 0, true, 0}, {0xFFFE, 0xFFFFFFE1, 0, true, 1},
287 {0xFFFE, 0xFFFFFFD7, 1, false, -1}, {0xFFFF, 0xFFFFFFEB, 0, true, 2},
288 {0xFFFF, 0xFFFFFFE1, 1, false, -1}, {0x0000, 0xFFFFFFF5, 0, true, 3},
289 {0x0000, 0xFFFFFFEB, 1, false, -1}, {0x0001, 0xFFFFFFFF, 0, true, 4},
290 {0x0001, 0xFFFFFFF5, 1, false, -1}, {0x0002, 0x0000000A, 0, true, 5},
291 {0x0002, 0xFFFFFFFF, 1, false, -1}, {0x0003, 0x0000000A, 1, false, -1},
292 {0x0004, 0x0000001E, 0, true, 7}, {0x0004, 0x00000014, 1, false, 6},
293 {0x0005, 0x0000001E, 0, true, -1}, {0x0005, 0x00000014, 1, false, -1},
294 {0x0006, 0x00000028, 0, true, 8}, {0x0006, 0x0000001E, 1, false, -1},
295 };
296
297 const size_t kExpectPacketsInBuffer = 9;
298
299 std::vector<Packet> expect_order(kExpectPacketsInBuffer);
300
301 PacketGenerator gen(0, 0, 0, kFrameSize);
302
303 StrictMock<MockStatisticsCalculator> mock_stats;
304
305 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
306 // check ensures that exactly one call to PacketsDiscarded happens in each
307 // DiscardNextPacket call.
308 InSequence s;
309 MockFunction<void(int check_point_id)> check;
310 for (int i = 0; i < kPackets; ++i) {
311 gen.Reset(packet_facts[i].sequence_number, packet_facts[i].timestamp,
312 packet_facts[i].payload_type, kFrameSize);
313 Packet packet = gen.NextPacket(kPayloadLength, nullptr);
314 packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
315 if (packet_facts[i].extract_order < 0) {
316 if (packet.priority.codec_level > 0) {
317 EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
318 } else {
319 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
320 }
321 }
322 EXPECT_CALL(check, Call(i));
323 EXPECT_EQ(PacketBuffer::kOK,
324 buffer.InsertPacket(packet.Clone(), &mock_stats));
325 if (packet_facts[i].extract_order >= 0) {
326 expect_order[packet_facts[i].extract_order] = std::move(packet);
327 }
328 check.Call(i);
329 }
330
331 EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());
332
333 for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
334 const absl::optional<Packet> packet = buffer.GetNextPacket();
335 EXPECT_EQ(packet, expect_order[i]); // Compare contents.
336 }
337 EXPECT_TRUE(buffer.Empty());
338 }
339
TEST(PacketBuffer,DiscardPackets)340 TEST(PacketBuffer, DiscardPackets) {
341 TickTimer tick_timer;
342 PacketBuffer buffer(100, &tick_timer); // 100 packets.
343 const uint16_t start_seq_no = 17;
344 const uint32_t start_ts = 4711;
345 const uint32_t ts_increment = 10;
346 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
347 PacketList list;
348 const int payload_len = 10;
349 StrictMock<MockStatisticsCalculator> mock_stats;
350
351 constexpr int kTotalPackets = 10;
352 // Insert 10 small packets.
353 for (int i = 0; i < kTotalPackets; ++i) {
354 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats);
355 }
356 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
357
358 uint32_t current_ts = start_ts;
359
360 // Discard them one by one and make sure that the right packets are at the
361 // front of the buffer.
362 constexpr int kDiscardPackets = 5;
363
364 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
365 // check ensures that exactly one call to PacketsDiscarded happens in each
366 // DiscardNextPacket call.
367 InSequence s;
368 MockFunction<void(int check_point_id)> check;
369 for (int i = 0; i < kDiscardPackets; ++i) {
370 uint32_t ts;
371 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
372 EXPECT_EQ(current_ts, ts);
373 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
374 EXPECT_CALL(check, Call(i));
375 EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
376 current_ts += ts_increment;
377 check.Call(i);
378 }
379
380 constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
381 // This will discard all remaining packets but one. The oldest packet is older
382 // than the indicated horizon_samples, and will thus be left in the buffer.
383 constexpr size_t kSkipPackets = 1;
384 EXPECT_CALL(mock_stats, PacketsDiscarded(1))
385 .Times(kRemainingPackets - kSkipPackets);
386 EXPECT_CALL(check, Call(17)); // Arbitrary id number.
387 buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
388 kRemainingPackets * ts_increment, &mock_stats);
389 check.Call(17); // Same arbitrary id number.
390
391 EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
392 uint32_t ts;
393 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
394 EXPECT_EQ(current_ts, ts);
395
396 // Discard all remaining packets.
397 EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
398 buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
399 &mock_stats);
400
401 EXPECT_TRUE(buffer.Empty());
402 }
403
TEST(PacketBuffer,Reordering)404 TEST(PacketBuffer, Reordering) {
405 TickTimer tick_timer;
406 PacketBuffer buffer(100, &tick_timer); // 100 packets.
407 const uint16_t start_seq_no = 17;
408 const uint32_t start_ts = 4711;
409 const uint32_t ts_increment = 10;
410 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
411 const int payload_len = 10;
412
413 // Generate 10 small packets and insert them into a PacketList. Insert every
414 // odd packet to the front, and every even packet to the back, thus creating
415 // a (rather strange) reordering.
416 PacketList list;
417 for (int i = 0; i < 10; ++i) {
418 Packet packet = gen.NextPacket(payload_len, nullptr);
419 if (i % 2) {
420 list.push_front(std::move(packet));
421 } else {
422 list.push_back(std::move(packet));
423 }
424 }
425
426 MockDecoderDatabase decoder_database;
427 auto factory = CreateBuiltinAudioDecoderFactory();
428 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
429 absl::nullopt, factory);
430 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
431 .WillRepeatedly(Return(&info));
432 absl::optional<uint8_t> current_pt;
433 absl::optional<uint8_t> current_cng_pt;
434
435 StrictMock<MockStatisticsCalculator> mock_stats;
436
437 EXPECT_EQ(PacketBuffer::kOK,
438 buffer.InsertPacketList(&list, decoder_database, ¤t_pt,
439 ¤t_cng_pt, &mock_stats));
440 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
441
442 // Extract them and make sure that come out in the right order.
443 uint32_t current_ts = start_ts;
444 for (int i = 0; i < 10; ++i) {
445 const absl::optional<Packet> packet = buffer.GetNextPacket();
446 ASSERT_TRUE(packet);
447 EXPECT_EQ(current_ts, packet->timestamp);
448 current_ts += ts_increment;
449 }
450 EXPECT_TRUE(buffer.Empty());
451
452 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
453 }
454
455 // The test first inserts a packet with narrow-band CNG, then a packet with
456 // wide-band speech. The expected behavior of the packet buffer is to detect a
457 // change in sample rate, even though no speech packet has been inserted before,
458 // and flush out the CNG packet.
TEST(PacketBuffer,CngFirstThenSpeechWithNewSampleRate)459 TEST(PacketBuffer, CngFirstThenSpeechWithNewSampleRate) {
460 TickTimer tick_timer;
461 PacketBuffer buffer(10, &tick_timer); // 10 packets.
462 const uint8_t kCngPt = 13;
463 const int kPayloadLen = 10;
464 const uint8_t kSpeechPt = 100;
465
466 MockDecoderDatabase decoder_database;
467 auto factory = CreateBuiltinAudioDecoderFactory();
468 const DecoderDatabase::DecoderInfo info_cng(SdpAudioFormat("cn", 8000, 1),
469 absl::nullopt, factory);
470 EXPECT_CALL(decoder_database, GetDecoderInfo(kCngPt))
471 .WillRepeatedly(Return(&info_cng));
472 const DecoderDatabase::DecoderInfo info_speech(
473 SdpAudioFormat("l16", 16000, 1), absl::nullopt, factory);
474 EXPECT_CALL(decoder_database, GetDecoderInfo(kSpeechPt))
475 .WillRepeatedly(Return(&info_speech));
476
477 // Insert first packet, which is narrow-band CNG.
478 PacketGenerator gen(0, 0, kCngPt, 10);
479 PacketList list;
480 list.push_back(gen.NextPacket(kPayloadLen, nullptr));
481 absl::optional<uint8_t> current_pt;
482 absl::optional<uint8_t> current_cng_pt;
483
484 StrictMock<MockStatisticsCalculator> mock_stats;
485
486 EXPECT_EQ(PacketBuffer::kOK,
487 buffer.InsertPacketList(&list, decoder_database, ¤t_pt,
488 ¤t_cng_pt, &mock_stats));
489 EXPECT_TRUE(list.empty());
490 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
491 ASSERT_TRUE(buffer.PeekNextPacket());
492 EXPECT_EQ(kCngPt, buffer.PeekNextPacket()->payload_type);
493 EXPECT_EQ(current_pt, absl::nullopt); // Current payload type not set.
494 EXPECT_EQ(kCngPt, current_cng_pt); // CNG payload type set.
495
496 // Insert second packet, which is wide-band speech.
497 {
498 Packet packet = gen.NextPacket(kPayloadLen, nullptr);
499 packet.payload_type = kSpeechPt;
500 list.push_back(std::move(packet));
501 }
502 // Expect the buffer to flush out the CNG packet, since it does not match the
503 // new speech sample rate.
504 EXPECT_EQ(PacketBuffer::kFlushed,
505 buffer.InsertPacketList(&list, decoder_database, ¤t_pt,
506 ¤t_cng_pt, &mock_stats));
507 EXPECT_TRUE(list.empty());
508 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
509 ASSERT_TRUE(buffer.PeekNextPacket());
510 EXPECT_EQ(kSpeechPt, buffer.PeekNextPacket()->payload_type);
511
512 EXPECT_EQ(kSpeechPt, current_pt); // Current payload type set.
513 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type reset.
514
515 buffer.Flush(); // Clean up.
516 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
517 }
518
TEST(PacketBuffer,Failures)519 TEST(PacketBuffer, Failures) {
520 const uint16_t start_seq_no = 17;
521 const uint32_t start_ts = 4711;
522 const uint32_t ts_increment = 10;
523 int payload_len = 100;
524 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
525 TickTimer tick_timer;
526 StrictMock<MockStatisticsCalculator> mock_stats;
527
528 PacketBuffer* buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
529 {
530 Packet packet = gen.NextPacket(payload_len, nullptr);
531 packet.payload.Clear();
532 EXPECT_EQ(PacketBuffer::kInvalidPacket,
533 buffer->InsertPacket(std::move(packet), &mock_stats));
534 }
535 // Buffer should still be empty. Test all empty-checks.
536 uint32_t temp_ts;
537 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->NextTimestamp(&temp_ts));
538 EXPECT_EQ(PacketBuffer::kBufferEmpty,
539 buffer->NextHigherTimestamp(0, &temp_ts));
540 EXPECT_EQ(NULL, buffer->PeekNextPacket());
541 EXPECT_FALSE(buffer->GetNextPacket());
542
543 // Discarding packets will not invoke mock_stats.PacketDiscarded() because the
544 // packet buffer is empty.
545 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket(&mock_stats));
546 buffer->DiscardAllOldPackets(0, &mock_stats);
547
548 // Insert one packet to make the buffer non-empty.
549 EXPECT_EQ(
550 PacketBuffer::kOK,
551 buffer->InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
552 EXPECT_EQ(PacketBuffer::kInvalidPointer, buffer->NextTimestamp(NULL));
553 EXPECT_EQ(PacketBuffer::kInvalidPointer,
554 buffer->NextHigherTimestamp(0, NULL));
555 delete buffer;
556
557 // Insert packet list of three packets, where the second packet has an invalid
558 // payload. Expect first packet to be inserted, and the remaining two to be
559 // discarded.
560 buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
561 PacketList list;
562 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
563 {
564 Packet packet = gen.NextPacket(payload_len, nullptr);
565 packet.payload.Clear(); // Invalid.
566 list.push_back(std::move(packet));
567 }
568 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
569 MockDecoderDatabase decoder_database;
570 auto factory = CreateBuiltinAudioDecoderFactory();
571 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
572 absl::nullopt, factory);
573 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
574 .WillRepeatedly(Return(&info));
575 absl::optional<uint8_t> current_pt;
576 absl::optional<uint8_t> current_cng_pt;
577 EXPECT_EQ(PacketBuffer::kInvalidPacket,
578 buffer->InsertPacketList(&list, decoder_database, ¤t_pt,
579 ¤t_cng_pt, &mock_stats));
580 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
581 EXPECT_EQ(1u, buffer->NumPacketsInBuffer());
582 delete buffer;
583 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
584 }
585
586 // Test packet comparison function.
587 // The function should return true if the first packet "goes before" the second.
TEST(PacketBuffer,ComparePackets)588 TEST(PacketBuffer, ComparePackets) {
589 PacketGenerator gen(0, 0, 0, 10);
590 Packet a(gen.NextPacket(10, nullptr)); // SN = 0, TS = 0.
591 Packet b(gen.NextPacket(10, nullptr)); // SN = 1, TS = 10.
592 EXPECT_FALSE(a == b);
593 EXPECT_TRUE(a != b);
594 EXPECT_TRUE(a < b);
595 EXPECT_FALSE(a > b);
596 EXPECT_TRUE(a <= b);
597 EXPECT_FALSE(a >= b);
598
599 // Testing wrap-around case; 'a' is earlier but has a larger timestamp value.
600 a.timestamp = 0xFFFFFFFF - 10;
601 EXPECT_FALSE(a == b);
602 EXPECT_TRUE(a != b);
603 EXPECT_TRUE(a < b);
604 EXPECT_FALSE(a > b);
605 EXPECT_TRUE(a <= b);
606 EXPECT_FALSE(a >= b);
607
608 // Test equal packets.
609 EXPECT_TRUE(a == a);
610 EXPECT_FALSE(a != a);
611 EXPECT_FALSE(a < a);
612 EXPECT_FALSE(a > a);
613 EXPECT_TRUE(a <= a);
614 EXPECT_TRUE(a >= a);
615
616 // Test equal timestamps but different sequence numbers (0 and 1).
617 a.timestamp = b.timestamp;
618 EXPECT_FALSE(a == b);
619 EXPECT_TRUE(a != b);
620 EXPECT_TRUE(a < b);
621 EXPECT_FALSE(a > b);
622 EXPECT_TRUE(a <= b);
623 EXPECT_FALSE(a >= b);
624
625 // Test equal timestamps but different sequence numbers (32767 and 1).
626 a.sequence_number = 0xFFFF;
627 EXPECT_FALSE(a == b);
628 EXPECT_TRUE(a != b);
629 EXPECT_TRUE(a < b);
630 EXPECT_FALSE(a > b);
631 EXPECT_TRUE(a <= b);
632 EXPECT_FALSE(a >= b);
633
634 // Test equal timestamps and sequence numbers, but differing priorities.
635 a.sequence_number = b.sequence_number;
636 a.priority = {1, 0};
637 b.priority = {0, 0};
638 // a after b
639 EXPECT_FALSE(a == b);
640 EXPECT_TRUE(a != b);
641 EXPECT_FALSE(a < b);
642 EXPECT_TRUE(a > b);
643 EXPECT_FALSE(a <= b);
644 EXPECT_TRUE(a >= b);
645
646 Packet c(gen.NextPacket(0, nullptr)); // SN = 2, TS = 20.
647 Packet d(gen.NextPacket(0, nullptr)); // SN = 3, TS = 20.
648 c.timestamp = b.timestamp;
649 d.timestamp = b.timestamp;
650 c.sequence_number = b.sequence_number;
651 d.sequence_number = b.sequence_number;
652 c.priority = {1, 1};
653 d.priority = {0, 1};
654 // c after d
655 EXPECT_FALSE(c == d);
656 EXPECT_TRUE(c != d);
657 EXPECT_FALSE(c < d);
658 EXPECT_TRUE(c > d);
659 EXPECT_FALSE(c <= d);
660 EXPECT_TRUE(c >= d);
661
662 // c after a
663 EXPECT_FALSE(c == a);
664 EXPECT_TRUE(c != a);
665 EXPECT_FALSE(c < a);
666 EXPECT_TRUE(c > a);
667 EXPECT_FALSE(c <= a);
668 EXPECT_TRUE(c >= a);
669
670 // c after b
671 EXPECT_FALSE(c == b);
672 EXPECT_TRUE(c != b);
673 EXPECT_FALSE(c < b);
674 EXPECT_TRUE(c > b);
675 EXPECT_FALSE(c <= b);
676 EXPECT_TRUE(c >= b);
677
678 // a after d
679 EXPECT_FALSE(a == d);
680 EXPECT_TRUE(a != d);
681 EXPECT_FALSE(a < d);
682 EXPECT_TRUE(a > d);
683 EXPECT_FALSE(a <= d);
684 EXPECT_TRUE(a >= d);
685
686 // d after b
687 EXPECT_FALSE(d == b);
688 EXPECT_TRUE(d != b);
689 EXPECT_FALSE(d < b);
690 EXPECT_TRUE(d > b);
691 EXPECT_FALSE(d <= b);
692 EXPECT_TRUE(d >= b);
693 }
694
TEST(PacketBuffer,GetSpanSamples)695 TEST(PacketBuffer, GetSpanSamples) {
696 constexpr size_t kFrameSizeSamples = 10;
697 constexpr int kPayloadSizeBytes = 1; // Does not matter to this test;
698 constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE; // Close to wrap around.
699 constexpr int kSampleRateHz = 48000;
700 constexpr bool KCountDtxWaitingTime = false;
701 TickTimer tick_timer;
702 PacketBuffer buffer(3, &tick_timer);
703 PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples);
704 StrictMock<MockStatisticsCalculator> mock_stats;
705
706 Packet packet_1 = gen.NextPacket(kPayloadSizeBytes, nullptr);
707
708 std::unique_ptr<MockEncodedAudioFrame> mock_audio_frame =
709 std::make_unique<MockEncodedAudioFrame>();
710 EXPECT_CALL(*mock_audio_frame, Duration())
711 .WillRepeatedly(Return(kFrameSizeSamples));
712 Packet packet_2 =
713 gen.NextPacket(kPayloadSizeBytes, std::move(mock_audio_frame));
714
715 RTC_DCHECK_GT(packet_1.timestamp,
716 packet_2.timestamp); // Tmestamp wrapped around.
717
718 EXPECT_EQ(PacketBuffer::kOK,
719 buffer.InsertPacket(std::move(packet_1), &mock_stats));
720
721 constexpr size_t kLastDecodedSizeSamples = 2;
722 // packet_1 has no access to duration, and relies last decoded duration as
723 // input.
724 EXPECT_EQ(kLastDecodedSizeSamples,
725 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
726 KCountDtxWaitingTime));
727
728 EXPECT_EQ(PacketBuffer::kOK,
729 buffer.InsertPacket(std::move(packet_2), &mock_stats));
730
731 EXPECT_EQ(kFrameSizeSamples * 2,
732 buffer.GetSpanSamples(0, kSampleRateHz, KCountDtxWaitingTime));
733
734 // packet_2 has access to duration, and ignores last decoded duration as
735 // input.
736 EXPECT_EQ(kFrameSizeSamples * 2,
737 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
738 KCountDtxWaitingTime));
739 }
740
741 namespace {
TestIsObsoleteTimestamp(uint32_t limit_timestamp)742 void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
743 // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
744 // half the timestamp range.
745 static const uint32_t kZeroHorizon = 0;
746 static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
747 // Timestamp on the limit is not old.
748 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
749 limit_timestamp, limit_timestamp, kZeroHorizon));
750 // 1 sample behind is old.
751 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
752 limit_timestamp, kZeroHorizon));
753 // 2^31 - 1 samples behind is old.
754 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - k2Pow31Minus1,
755 limit_timestamp, kZeroHorizon));
756 // 1 sample ahead is not old.
757 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
758 limit_timestamp + 1, limit_timestamp, kZeroHorizon));
759 // If |t1-t2|=2^31 and t1>t2, t2 is older than t1 but not the opposite.
760 uint32_t other_timestamp = limit_timestamp + (1 << 31);
761 uint32_t lowest_timestamp = std::min(limit_timestamp, other_timestamp);
762 uint32_t highest_timestamp = std::max(limit_timestamp, other_timestamp);
763 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
764 lowest_timestamp, highest_timestamp, kZeroHorizon));
765 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
766 highest_timestamp, lowest_timestamp, kZeroHorizon));
767
768 // Fixed horizon at 10 samples.
769 static const uint32_t kHorizon = 10;
770 // Timestamp on the limit is not old.
771 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp,
772 limit_timestamp, kHorizon));
773 // 1 sample behind is old.
774 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
775 limit_timestamp, kHorizon));
776 // 9 samples behind is old.
777 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 9,
778 limit_timestamp, kHorizon));
779 // 10 samples behind is not old.
780 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 10,
781 limit_timestamp, kHorizon));
782 // 2^31 - 1 samples behind is not old.
783 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
784 limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
785 // 1 sample ahead is not old.
786 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + 1,
787 limit_timestamp, kHorizon));
788 // 2^31 samples ahead is not old.
789 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + (1 << 31),
790 limit_timestamp, kHorizon));
791 }
792 } // namespace
793
794 // Test the IsObsoleteTimestamp method with different limit timestamps.
TEST(PacketBuffer,IsObsoleteTimestamp)795 TEST(PacketBuffer, IsObsoleteTimestamp) {
796 TestIsObsoleteTimestamp(0);
797 TestIsObsoleteTimestamp(1);
798 TestIsObsoleteTimestamp(0xFFFFFFFF); // -1 in uint32_t.
799 TestIsObsoleteTimestamp(0x80000000); // 2^31.
800 TestIsObsoleteTimestamp(0x80000001); // 2^31 + 1.
801 TestIsObsoleteTimestamp(0x7FFFFFFF); // 2^31 - 1.
802 }
803
804 } // namespace webrtc
805