• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &current_pt,
218                                     &current_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, &current_pt,
267                                     &current_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, &current_pt,
439                                     &current_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, &current_pt,
488                                     &current_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, &current_pt,
506                                     &current_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, &current_pt,
579                                      &current_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