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