blob: ca4222223156d2937060c9bae22000369575d51c [file] [log] [blame]
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "modules/audio_coding/neteq/packet_buffer.h"
Minyue Li3f2eeb82019-07-03 16:43:29 +020014#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "api/audio_codecs/builtin_audio_decoder_factory.h"
16#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
17#include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
18#include "modules/audio_coding/neteq/packet.h"
19#include "modules/audio_coding/neteq/tick_timer.h"
20#include "test/gmock.h"
21#include "test/gtest.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000022
23using ::testing::Return;
minyue-webrtcfae474c2017-07-05 11:17:40 +020024using ::testing::StrictMock;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000025using ::testing::_;
henrik.lundin63d146b2017-07-05 07:03:34 -070026using ::testing::InSequence;
27using ::testing::MockFunction;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000028
Minyue Li3f2eeb82019-07-03 16:43:29 +020029namespace {
30class MockEncodedAudioFrame : public webrtc::AudioDecoder::EncodedAudioFrame {
31 public:
32 MOCK_CONST_METHOD0(Duration, size_t());
33
34 MOCK_CONST_METHOD0(IsDtxPacket, bool());
35
36 MOCK_CONST_METHOD1(
37 Decode,
38 absl::optional<DecodeResult>(rtc::ArrayView<int16_t> decoded));
39};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000040
41// Helper class to generate packets. Packets must be deleted by the user.
42class PacketGenerator {
43 public:
44 PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
45 virtual ~PacketGenerator() {}
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000046 void Reset(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
Minyue Li3f2eeb82019-07-03 16:43:29 +020047 webrtc::Packet NextPacket(
48 int payload_size_bytes,
49 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000050
51 uint16_t seq_no_;
52 uint32_t ts_;
53 uint8_t pt_;
54 int frame_size_;
55};
56
57PacketGenerator::PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000058 int frame_size) {
59 Reset(seq_no, ts, pt, frame_size);
60}
61
62void PacketGenerator::Reset(uint16_t seq_no, uint32_t ts, uint8_t pt,
63 int frame_size) {
64 seq_no_ = seq_no;
65 ts_ = ts;
66 pt_ = pt;
67 frame_size_ = frame_size;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000068}
69
Minyue Li3f2eeb82019-07-03 16:43:29 +020070webrtc::Packet PacketGenerator::NextPacket(
71 int payload_size_bytes,
72 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame) {
73 webrtc::Packet packet;
ossua73f6c92016-10-24 08:25:28 -070074 packet.sequence_number = seq_no_;
75 packet.timestamp = ts_;
76 packet.payload_type = pt_;
77 packet.payload.SetSize(payload_size_bytes);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000078 ++seq_no_;
79 ts_ += frame_size_;
Minyue Li3f2eeb82019-07-03 16:43:29 +020080 packet.frame = std::move(audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000081 return packet;
82}
83
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000084struct PacketsToInsert {
85 uint16_t sequence_number;
86 uint32_t timestamp;
87 uint8_t payload_type;
88 bool primary;
89 // Order of this packet to appear upon extraction, after inserting a series
90 // of packets. A negative number means that it should have been discarded
91 // before extraction.
92 int extract_order;
93};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000094
Minyue Li3f2eeb82019-07-03 16:43:29 +020095} // namespace
96
97namespace webrtc {
98
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000099// Start of test definitions.
100
101TEST(PacketBuffer, CreateAndDestroy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700102 TickTimer tick_timer;
103 PacketBuffer* buffer = new PacketBuffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000104 EXPECT_TRUE(buffer->Empty());
105 delete buffer;
106}
107
108TEST(PacketBuffer, InsertPacket) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700109 TickTimer tick_timer;
110 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000111 PacketGenerator gen(17u, 4711u, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200112 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000113
114 const int payload_len = 100;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200115 const Packet packet = gen.NextPacket(payload_len, nullptr);
minyue-webrtc12d30842017-07-19 11:44:06 +0200116 EXPECT_EQ(0, buffer.InsertPacket(packet.Clone(), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000117 uint32_t next_ts;
118 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
119 EXPECT_EQ(4711u, next_ts);
120 EXPECT_FALSE(buffer.Empty());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700121 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700122 const Packet* next_packet = buffer.PeekNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700123 EXPECT_EQ(packet, *next_packet); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000124
125 // Do not explicitly flush buffer or delete packet to test that it is deleted
126 // with the buffer. (Tested with Valgrind or similar tool.)
127}
128
129// Test to flush buffer.
130TEST(PacketBuffer, FlushBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700131 TickTimer tick_timer;
132 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000133 PacketGenerator gen(0, 0, 0, 10);
134 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200135 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000136
137 // Insert 10 small packets; should be ok.
138 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200139 EXPECT_EQ(
140 PacketBuffer::kOK,
141 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000142 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700143 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000144 EXPECT_FALSE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000145
146 buffer.Flush();
147 // Buffer should delete the payloads itself.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700148 EXPECT_EQ(0u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000149 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000150}
151
152// Test to fill the buffer over the limits, and verify that it flushes.
153TEST(PacketBuffer, OverfillBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700154 TickTimer tick_timer;
155 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000156 PacketGenerator gen(0, 0, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200157 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000158
159 // Insert 10 small packets; should be ok.
160 const int payload_len = 10;
161 int i;
162 for (i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200163 EXPECT_EQ(
164 PacketBuffer::kOK,
165 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000166 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700167 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000168 uint32_t next_ts;
169 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
170 EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
171
Minyue Li3f2eeb82019-07-03 16:43:29 +0200172 const Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000173 // Insert 11th packet; should flush the buffer and insert it after flushing.
minyue-webrtc12d30842017-07-19 11:44:06 +0200174 EXPECT_EQ(PacketBuffer::kFlushed,
175 buffer.InsertPacket(packet.Clone(), &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700176 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000177 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
178 // Expect last inserted packet to be first in line.
ossua73f6c92016-10-24 08:25:28 -0700179 EXPECT_EQ(packet.timestamp, next_ts);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000180
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +0000181 // Flush buffer to delete all packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000182 buffer.Flush();
183}
184
185// Test inserting a list of packets.
186TEST(PacketBuffer, InsertPacketList) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700187 TickTimer tick_timer;
188 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000189 PacketGenerator gen(0, 0, 0, 10);
190 PacketList list;
191 const int payload_len = 10;
192
193 // Insert 10 small packets.
194 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200195 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000196 }
197
198 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700199 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100200 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200201 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700202 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
203 .WillRepeatedly(Return(&info));
minyue-webrtc12d30842017-07-19 11:44:06 +0200204
205 StrictMock<MockStatisticsCalculator> mock_stats;
206
Danil Chapovalovb6021232018-06-19 13:26:36 +0200207 absl::optional<uint8_t> current_pt;
208 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200209 EXPECT_EQ(PacketBuffer::kOK,
210 buffer.InsertPacketList(&list, decoder_database, &current_pt,
211 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000212 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700213 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100214 EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200215 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000216
217 buffer.Flush(); // Clean up.
218
219 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
220}
221
222// Test inserting a list of packets. Last packet is of a different payload type.
223// Expecting the buffer to flush.
224// TODO(hlundin): Remove this test when legacy operation is no longer needed.
225TEST(PacketBuffer, InsertPacketListChangePayloadType) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700226 TickTimer tick_timer;
227 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000228 PacketGenerator gen(0, 0, 0, 10);
229 PacketList list;
230 const int payload_len = 10;
231
232 // Insert 10 small packets.
233 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200234 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000235 }
236 // Insert 11th packet of another payload type (not CNG).
ossua73f6c92016-10-24 08:25:28 -0700237 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200238 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700239 packet.payload_type = 1;
240 list.push_back(std::move(packet));
241 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000242
243 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700244 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100245 const DecoderDatabase::DecoderInfo info0(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200246 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700247 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
248 .WillRepeatedly(Return(&info0));
Niels Möller72899062019-01-11 09:36:13 +0100249 const DecoderDatabase::DecoderInfo info1(SdpAudioFormat("pcma", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200250 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700251 EXPECT_CALL(decoder_database, GetDecoderInfo(1))
252 .WillRepeatedly(Return(&info1));
minyue-webrtc12d30842017-07-19 11:44:06 +0200253
254 StrictMock<MockStatisticsCalculator> mock_stats;
255
Danil Chapovalovb6021232018-06-19 13:26:36 +0200256 absl::optional<uint8_t> current_pt;
257 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200258 EXPECT_EQ(PacketBuffer::kFlushed,
259 buffer.InsertPacketList(&list, decoder_database, &current_pt,
260 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000261 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700262 EXPECT_EQ(1u, buffer.NumPacketsInBuffer()); // Only the last packet.
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100263 EXPECT_EQ(1, current_pt); // Current payload type changed to 1.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200264 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000265
266 buffer.Flush(); // Clean up.
267
268 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
269}
270
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000271TEST(PacketBuffer, ExtractOrderRedundancy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700272 TickTimer tick_timer;
273 PacketBuffer buffer(100, &tick_timer); // 100 packets.
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000274 const int kPackets = 18;
275 const int kFrameSize = 10;
276 const int kPayloadLength = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000277
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000278 PacketsToInsert packet_facts[kPackets] = {
279 {0xFFFD, 0xFFFFFFD7, 0, true, 0},
280 {0xFFFE, 0xFFFFFFE1, 0, true, 1},
281 {0xFFFE, 0xFFFFFFD7, 1, false, -1},
282 {0xFFFF, 0xFFFFFFEB, 0, true, 2},
283 {0xFFFF, 0xFFFFFFE1, 1, false, -1},
284 {0x0000, 0xFFFFFFF5, 0, true, 3},
285 {0x0000, 0xFFFFFFEB, 1, false, -1},
286 {0x0001, 0xFFFFFFFF, 0, true, 4},
287 {0x0001, 0xFFFFFFF5, 1, false, -1},
288 {0x0002, 0x0000000A, 0, true, 5},
289 {0x0002, 0xFFFFFFFF, 1, false, -1},
290 {0x0003, 0x0000000A, 1, false, -1},
291 {0x0004, 0x0000001E, 0, true, 7},
292 {0x0004, 0x00000014, 1, false, 6},
293 {0x0005, 0x0000001E, 0, true, -1},
294 {0x0005, 0x00000014, 1, false, -1},
295 {0x0006, 0x00000028, 0, true, 8},
296 {0x0006, 0x0000001E, 1, false, -1},
297 };
298
Peter Kastingdce40cf2015-08-24 14:52:23 -0700299 const size_t kExpectPacketsInBuffer = 9;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000300
ossua73f6c92016-10-24 08:25:28 -0700301 std::vector<Packet> expect_order(kExpectPacketsInBuffer);
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000302
303 PacketGenerator gen(0, 0, 0, kFrameSize);
304
minyue-webrtc12d30842017-07-19 11:44:06 +0200305 StrictMock<MockStatisticsCalculator> mock_stats;
306
307 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
308 // check ensures that exactly one call to PacketsDiscarded happens in each
309 // DiscardNextPacket call.
310 InSequence s;
311 MockFunction<void(int check_point_id)> check;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000312 for (int i = 0; i < kPackets; ++i) {
313 gen.Reset(packet_facts[i].sequence_number,
314 packet_facts[i].timestamp,
315 packet_facts[i].payload_type,
316 kFrameSize);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200317 Packet packet = gen.NextPacket(kPayloadLength, nullptr);
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200318 packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
minyue-webrtc12d30842017-07-19 11:44:06 +0200319 if (packet_facts[i].extract_order < 0) {
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200320 if (packet.priority.codec_level > 0) {
321 EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
322 } else {
323 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
324 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200325 }
326 EXPECT_CALL(check, Call(i));
327 EXPECT_EQ(PacketBuffer::kOK,
328 buffer.InsertPacket(packet.Clone(), &mock_stats));
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000329 if (packet_facts[i].extract_order >= 0) {
ossua73f6c92016-10-24 08:25:28 -0700330 expect_order[packet_facts[i].extract_order] = std::move(packet);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000331 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200332 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000333 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000334
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000335 EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000336
Peter Kastingdce40cf2015-08-24 14:52:23 -0700337 for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200338 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700339 EXPECT_EQ(packet, expect_order[i]); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000340 }
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000341 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000342}
343
344TEST(PacketBuffer, DiscardPackets) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700345 TickTimer tick_timer;
346 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000347 const uint16_t start_seq_no = 17;
348 const uint32_t start_ts = 4711;
349 const uint32_t ts_increment = 10;
350 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
351 PacketList list;
352 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200353 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000354
minyue-webrtcfae474c2017-07-05 11:17:40 +0200355 constexpr int kTotalPackets = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000356 // Insert 10 small packets.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200357 for (int i = 0; i < kTotalPackets; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200358 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000359 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700360 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000361
minyue-webrtcfae474c2017-07-05 11:17:40 +0200362 uint32_t current_ts = start_ts;
363
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000364 // Discard them one by one and make sure that the right packets are at the
365 // front of the buffer.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200366 constexpr int kDiscardPackets = 5;
henrik.lundin63d146b2017-07-05 07:03:34 -0700367
368 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
369 // check ensures that exactly one call to PacketsDiscarded happens in each
370 // DiscardNextPacket call.
371 InSequence s;
372 MockFunction<void(int check_point_id)> check;
minyue-webrtcfae474c2017-07-05 11:17:40 +0200373 for (int i = 0; i < kDiscardPackets; ++i) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000374 uint32_t ts;
375 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
376 EXPECT_EQ(current_ts, ts);
henrik.lundin63d146b2017-07-05 07:03:34 -0700377 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
378 EXPECT_CALL(check, Call(i));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200379 EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000380 current_ts += ts_increment;
henrik.lundin63d146b2017-07-05 07:03:34 -0700381 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000382 }
minyue-webrtcfae474c2017-07-05 11:17:40 +0200383
384 constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
henrik.lundin63d146b2017-07-05 07:03:34 -0700385 // This will discard all remaining packets but one. The oldest packet is older
386 // than the indicated horizon_samples, and will thus be left in the buffer.
387 constexpr size_t kSkipPackets = 1;
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200388 EXPECT_CALL(mock_stats, PacketsDiscarded(1))
389 .Times(kRemainingPackets - kSkipPackets);
henrik.lundin63d146b2017-07-05 07:03:34 -0700390 EXPECT_CALL(check, Call(17)); // Arbitrary id number.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200391 buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
392 kRemainingPackets * ts_increment, &mock_stats);
henrik.lundin63d146b2017-07-05 07:03:34 -0700393 check.Call(17); // Same arbitrary id number.
394
395 EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200396 uint32_t ts;
397 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
398 EXPECT_EQ(current_ts, ts);
399
400 // Discard all remaining packets.
henrik.lundin63d146b2017-07-05 07:03:34 -0700401 EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200402 buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
403 &mock_stats);
404
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000405 EXPECT_TRUE(buffer.Empty());
406}
407
408TEST(PacketBuffer, Reordering) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700409 TickTimer tick_timer;
410 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000411 const uint16_t start_seq_no = 17;
412 const uint32_t start_ts = 4711;
413 const uint32_t ts_increment = 10;
414 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
415 const int payload_len = 10;
416
417 // Generate 10 small packets and insert them into a PacketList. Insert every
418 // odd packet to the front, and every even packet to the back, thus creating
419 // a (rather strange) reordering.
420 PacketList list;
421 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200422 Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000423 if (i % 2) {
ossua73f6c92016-10-24 08:25:28 -0700424 list.push_front(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000425 } else {
ossua73f6c92016-10-24 08:25:28 -0700426 list.push_back(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000427 }
428 }
429
430 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700431 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100432 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200433 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700434 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
435 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200436 absl::optional<uint8_t> current_pt;
437 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000438
minyue-webrtc12d30842017-07-19 11:44:06 +0200439 StrictMock<MockStatisticsCalculator> mock_stats;
440
441 EXPECT_EQ(PacketBuffer::kOK,
442 buffer.InsertPacketList(&list, decoder_database, &current_pt,
443 &current_cng_pt, &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700444 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000445
446 // Extract them and make sure that come out in the right order.
447 uint32_t current_ts = start_ts;
448 for (int i = 0; i < 10; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200449 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700450 ASSERT_TRUE(packet);
ossu7a377612016-10-18 04:06:13 -0700451 EXPECT_EQ(current_ts, packet->timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000452 current_ts += ts_increment;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000453 }
454 EXPECT_TRUE(buffer.Empty());
455
456 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
457}
458
henrik.lundin067d8552016-09-01 23:19:05 -0700459// The test first inserts a packet with narrow-band CNG, then a packet with
460// wide-band speech. The expected behavior of the packet buffer is to detect a
461// change in sample rate, even though no speech packet has been inserted before,
462// and flush out the CNG packet.
463TEST(PacketBuffer, CngFirstThenSpeechWithNewSampleRate) {
464 TickTimer tick_timer;
465 PacketBuffer buffer(10, &tick_timer); // 10 packets.
466 const uint8_t kCngPt = 13;
467 const int kPayloadLen = 10;
468 const uint8_t kSpeechPt = 100;
469
470 MockDecoderDatabase decoder_database;
471 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100472 const DecoderDatabase::DecoderInfo info_cng(SdpAudioFormat("cn", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200473 absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700474 EXPECT_CALL(decoder_database, GetDecoderInfo(kCngPt))
475 .WillRepeatedly(Return(&info_cng));
Niels Möller72899062019-01-11 09:36:13 +0100476 const DecoderDatabase::DecoderInfo info_speech(
477 SdpAudioFormat("l16", 16000, 1), absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700478 EXPECT_CALL(decoder_database, GetDecoderInfo(kSpeechPt))
479 .WillRepeatedly(Return(&info_speech));
480
481 // Insert first packet, which is narrow-band CNG.
482 PacketGenerator gen(0, 0, kCngPt, 10);
483 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200484 list.push_back(gen.NextPacket(kPayloadLen, nullptr));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200485 absl::optional<uint8_t> current_pt;
486 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200487
488 StrictMock<MockStatisticsCalculator> mock_stats;
489
henrik.lundin067d8552016-09-01 23:19:05 -0700490 EXPECT_EQ(PacketBuffer::kOK,
491 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200492 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700493 EXPECT_TRUE(list.empty());
494 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700495 ASSERT_TRUE(buffer.PeekNextPacket());
496 EXPECT_EQ(kCngPt, buffer.PeekNextPacket()->payload_type);
Danil Chapovalovb6021232018-06-19 13:26:36 +0200497 EXPECT_EQ(current_pt, absl::nullopt); // Current payload type not set.
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100498 EXPECT_EQ(kCngPt, current_cng_pt); // CNG payload type set.
henrik.lundin067d8552016-09-01 23:19:05 -0700499
500 // Insert second packet, which is wide-band speech.
ossua73f6c92016-10-24 08:25:28 -0700501 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200502 Packet packet = gen.NextPacket(kPayloadLen, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700503 packet.payload_type = kSpeechPt;
504 list.push_back(std::move(packet));
505 }
henrik.lundin067d8552016-09-01 23:19:05 -0700506 // Expect the buffer to flush out the CNG packet, since it does not match the
507 // new speech sample rate.
508 EXPECT_EQ(PacketBuffer::kFlushed,
509 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200510 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700511 EXPECT_TRUE(list.empty());
512 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700513 ASSERT_TRUE(buffer.PeekNextPacket());
514 EXPECT_EQ(kSpeechPt, buffer.PeekNextPacket()->payload_type);
henrik.lundin067d8552016-09-01 23:19:05 -0700515
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100516 EXPECT_EQ(kSpeechPt, current_pt); // Current payload type set.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200517 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type reset.
henrik.lundin067d8552016-09-01 23:19:05 -0700518
519 buffer.Flush(); // Clean up.
520 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
521}
522
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000523TEST(PacketBuffer, Failures) {
524 const uint16_t start_seq_no = 17;
525 const uint32_t start_ts = 4711;
526 const uint32_t ts_increment = 10;
527 int payload_len = 100;
528 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
henrik.lundin84f8cd62016-04-26 07:45:16 -0700529 TickTimer tick_timer;
minyue-webrtc12d30842017-07-19 11:44:06 +0200530 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000531
henrik.lundin84f8cd62016-04-26 07:45:16 -0700532 PacketBuffer* buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
ossua73f6c92016-10-24 08:25:28 -0700533 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200534 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700535 packet.payload.Clear();
536 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200537 buffer->InsertPacket(std::move(packet), &mock_stats));
ossua73f6c92016-10-24 08:25:28 -0700538 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000539 // Buffer should still be empty. Test all empty-checks.
540 uint32_t temp_ts;
541 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->NextTimestamp(&temp_ts));
542 EXPECT_EQ(PacketBuffer::kBufferEmpty,
543 buffer->NextHigherTimestamp(0, &temp_ts));
ossu7a377612016-10-18 04:06:13 -0700544 EXPECT_EQ(NULL, buffer->PeekNextPacket());
ossua73f6c92016-10-24 08:25:28 -0700545 EXPECT_FALSE(buffer->GetNextPacket());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200546
minyue-webrtcfae474c2017-07-05 11:17:40 +0200547 // Discarding packets will not invoke mock_stats.PacketDiscarded() because the
548 // packet buffer is empty.
549 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket(&mock_stats));
550 buffer->DiscardAllOldPackets(0, &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000551
552 // Insert one packet to make the buffer non-empty.
Minyue Li3f2eeb82019-07-03 16:43:29 +0200553 EXPECT_EQ(
554 PacketBuffer::kOK,
555 buffer->InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000556 EXPECT_EQ(PacketBuffer::kInvalidPointer, buffer->NextTimestamp(NULL));
557 EXPECT_EQ(PacketBuffer::kInvalidPointer,
558 buffer->NextHigherTimestamp(0, NULL));
559 delete buffer;
560
561 // Insert packet list of three packets, where the second packet has an invalid
562 // payload. Expect first packet to be inserted, and the remaining two to be
563 // discarded.
henrik.lundin84f8cd62016-04-26 07:45:16 -0700564 buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000565 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200566 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
ossua73f6c92016-10-24 08:25:28 -0700567 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200568 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700569 packet.payload.Clear(); // Invalid.
570 list.push_back(std::move(packet));
571 }
Minyue Li3f2eeb82019-07-03 16:43:29 +0200572 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000573 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700574 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100575 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200576 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700577 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
578 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200579 absl::optional<uint8_t> current_pt;
580 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000581 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200582 buffer->InsertPacketList(&list, decoder_database, &current_pt,
583 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000584 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700585 EXPECT_EQ(1u, buffer->NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000586 delete buffer;
587 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
588}
589
590// Test packet comparison function.
591// The function should return true if the first packet "goes before" the second.
592TEST(PacketBuffer, ComparePackets) {
593 PacketGenerator gen(0, 0, 0, 10);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200594 Packet a(gen.NextPacket(10, nullptr)); // SN = 0, TS = 0.
595 Packet b(gen.NextPacket(10, nullptr)); // SN = 1, TS = 10.
ossua73f6c92016-10-24 08:25:28 -0700596 EXPECT_FALSE(a == b);
597 EXPECT_TRUE(a != b);
598 EXPECT_TRUE(a < b);
599 EXPECT_FALSE(a > b);
600 EXPECT_TRUE(a <= b);
601 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000602
603 // Testing wrap-around case; 'a' is earlier but has a larger timestamp value.
ossua73f6c92016-10-24 08:25:28 -0700604 a.timestamp = 0xFFFFFFFF - 10;
605 EXPECT_FALSE(a == b);
606 EXPECT_TRUE(a != b);
607 EXPECT_TRUE(a < b);
608 EXPECT_FALSE(a > b);
609 EXPECT_TRUE(a <= b);
610 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000611
612 // Test equal packets.
ossua73f6c92016-10-24 08:25:28 -0700613 EXPECT_TRUE(a == a);
614 EXPECT_FALSE(a != a);
615 EXPECT_FALSE(a < a);
616 EXPECT_FALSE(a > a);
617 EXPECT_TRUE(a <= a);
618 EXPECT_TRUE(a >= a);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000619
620 // Test equal timestamps but different sequence numbers (0 and 1).
ossua73f6c92016-10-24 08:25:28 -0700621 a.timestamp = b.timestamp;
622 EXPECT_FALSE(a == b);
623 EXPECT_TRUE(a != b);
624 EXPECT_TRUE(a < b);
625 EXPECT_FALSE(a > b);
626 EXPECT_TRUE(a <= b);
627 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000628
629 // Test equal timestamps but different sequence numbers (32767 and 1).
ossua73f6c92016-10-24 08:25:28 -0700630 a.sequence_number = 0xFFFF;
631 EXPECT_FALSE(a == b);
632 EXPECT_TRUE(a != b);
633 EXPECT_TRUE(a < b);
634 EXPECT_FALSE(a > b);
635 EXPECT_TRUE(a <= b);
636 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000637
ossua70695a2016-09-22 02:06:28 -0700638 // Test equal timestamps and sequence numbers, but differing priorities.
ossua73f6c92016-10-24 08:25:28 -0700639 a.sequence_number = b.sequence_number;
640 a.priority = {1, 0};
641 b.priority = {0, 0};
ossua70695a2016-09-22 02:06:28 -0700642 // a after b
ossua73f6c92016-10-24 08:25:28 -0700643 EXPECT_FALSE(a == b);
644 EXPECT_TRUE(a != b);
645 EXPECT_FALSE(a < b);
646 EXPECT_TRUE(a > b);
647 EXPECT_FALSE(a <= b);
648 EXPECT_TRUE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000649
Minyue Li3f2eeb82019-07-03 16:43:29 +0200650 Packet c(gen.NextPacket(0, nullptr)); // SN = 2, TS = 20.
651 Packet d(gen.NextPacket(0, nullptr)); // SN = 3, TS = 20.
ossua73f6c92016-10-24 08:25:28 -0700652 c.timestamp = b.timestamp;
653 d.timestamp = b.timestamp;
654 c.sequence_number = b.sequence_number;
655 d.sequence_number = b.sequence_number;
656 c.priority = {1, 1};
657 d.priority = {0, 1};
ossua70695a2016-09-22 02:06:28 -0700658 // c after d
ossua73f6c92016-10-24 08:25:28 -0700659 EXPECT_FALSE(c == d);
660 EXPECT_TRUE(c != d);
661 EXPECT_FALSE(c < d);
662 EXPECT_TRUE(c > d);
663 EXPECT_FALSE(c <= d);
664 EXPECT_TRUE(c >= d);
ossua70695a2016-09-22 02:06:28 -0700665
666 // c after a
ossua73f6c92016-10-24 08:25:28 -0700667 EXPECT_FALSE(c == a);
668 EXPECT_TRUE(c != a);
669 EXPECT_FALSE(c < a);
670 EXPECT_TRUE(c > a);
671 EXPECT_FALSE(c <= a);
672 EXPECT_TRUE(c >= a);
ossua70695a2016-09-22 02:06:28 -0700673
674 // c after b
ossua73f6c92016-10-24 08:25:28 -0700675 EXPECT_FALSE(c == b);
676 EXPECT_TRUE(c != b);
677 EXPECT_FALSE(c < b);
678 EXPECT_TRUE(c > b);
679 EXPECT_FALSE(c <= b);
680 EXPECT_TRUE(c >= b);
ossua70695a2016-09-22 02:06:28 -0700681
682 // a after d
ossua73f6c92016-10-24 08:25:28 -0700683 EXPECT_FALSE(a == d);
684 EXPECT_TRUE(a != d);
685 EXPECT_FALSE(a < d);
686 EXPECT_TRUE(a > d);
687 EXPECT_FALSE(a <= d);
688 EXPECT_TRUE(a >= d);
ossua70695a2016-09-22 02:06:28 -0700689
690 // d after b
ossua73f6c92016-10-24 08:25:28 -0700691 EXPECT_FALSE(d == b);
692 EXPECT_TRUE(d != b);
693 EXPECT_FALSE(d < b);
694 EXPECT_TRUE(d > b);
695 EXPECT_FALSE(d <= b);
696 EXPECT_TRUE(d >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000697}
698
Minyue Li3f2eeb82019-07-03 16:43:29 +0200699TEST(PacketBuffer, GetSpanSamples) {
700 constexpr size_t kFrameSizeSamples = 10;
701 constexpr int kPayloadSizeBytes = 1; // Does not matter to this test;
702 constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE; // Close to wrap around.
703 constexpr int kSampleRateHz = 48000;
704 constexpr bool KCountDtxWaitingTime = false;
705 TickTimer tick_timer;
706 PacketBuffer buffer(3, &tick_timer);
707 PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples);
708 StrictMock<MockStatisticsCalculator> mock_stats;
709
710 Packet packet_1 = gen.NextPacket(kPayloadSizeBytes, nullptr);
711
712 std::unique_ptr<MockEncodedAudioFrame> mock_audio_frame =
713 absl::make_unique<MockEncodedAudioFrame>();
714 EXPECT_CALL(*mock_audio_frame, Duration())
715 .WillRepeatedly(Return(kFrameSizeSamples));
716 Packet packet_2 =
717 gen.NextPacket(kPayloadSizeBytes, std::move(mock_audio_frame));
718
719 RTC_DCHECK_GT(packet_1.timestamp,
720 packet_2.timestamp); // Tmestamp wrapped around.
721
722 EXPECT_EQ(PacketBuffer::kOK,
723 buffer.InsertPacket(std::move(packet_1), &mock_stats));
724
725 constexpr size_t kLastDecodedSizeSamples = 2;
726 // packet_1 has no access to duration, and relies last decoded duration as
727 // input.
728 EXPECT_EQ(kLastDecodedSizeSamples,
729 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
730 KCountDtxWaitingTime));
731
732 EXPECT_EQ(PacketBuffer::kOK,
733 buffer.InsertPacket(std::move(packet_2), &mock_stats));
734
735 EXPECT_EQ(kFrameSizeSamples * 2,
736 buffer.GetSpanSamples(0, kSampleRateHz, KCountDtxWaitingTime));
737
738 // packet_2 has access to duration, and ignores last decoded duration as
739 // input.
740 EXPECT_EQ(kFrameSizeSamples * 2,
741 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
742 KCountDtxWaitingTime));
743}
744
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000745namespace {
746void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
747 // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
748 // half the timestamp range.
749 static const uint32_t kZeroHorizon = 0;
750 static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
751 // Timestamp on the limit is not old.
752 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
753 limit_timestamp, limit_timestamp, kZeroHorizon));
754 // 1 sample behind is old.
755 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
756 limit_timestamp - 1, limit_timestamp, kZeroHorizon));
757 // 2^31 - 1 samples behind is old.
758 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
759 limit_timestamp - k2Pow31Minus1, limit_timestamp, kZeroHorizon));
760 // 1 sample ahead is not old.
761 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
762 limit_timestamp + 1, limit_timestamp, kZeroHorizon));
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200763 // If |t1-t2|=2^31 and t1>t2, t2 is older than t1 but not the opposite.
764 uint32_t other_timestamp = limit_timestamp + (1 << 31);
765 uint32_t lowest_timestamp = std::min(limit_timestamp, other_timestamp);
766 uint32_t highest_timestamp = std::max(limit_timestamp, other_timestamp);
767 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
768 lowest_timestamp, highest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000769 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200770 highest_timestamp, lowest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000771
772 // Fixed horizon at 10 samples.
773 static const uint32_t kHorizon = 10;
774 // Timestamp on the limit is not old.
775 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
776 limit_timestamp, limit_timestamp, kHorizon));
777 // 1 sample behind is old.
778 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
779 limit_timestamp - 1, limit_timestamp, kHorizon));
780 // 9 samples behind is old.
781 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
782 limit_timestamp - 9, limit_timestamp, kHorizon));
783 // 10 samples behind is not old.
784 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
785 limit_timestamp - 10, limit_timestamp, kHorizon));
786 // 2^31 - 1 samples behind is not old.
787 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
788 limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
789 // 1 sample ahead is not old.
790 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
791 limit_timestamp + 1, limit_timestamp, kHorizon));
792 // 2^31 samples ahead is not old.
793 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
794 limit_timestamp + (1 << 31), limit_timestamp, kHorizon));
795}
796} // namespace
797
798// Test the IsObsoleteTimestamp method with different limit timestamps.
799TEST(PacketBuffer, IsObsoleteTimestamp) {
800 TestIsObsoleteTimestamp(0);
801 TestIsObsoleteTimestamp(1);
802 TestIsObsoleteTimestamp(0xFFFFFFFF); // -1 in uint32_t.
803 TestIsObsoleteTimestamp(0x80000000); // 2^31.
804 TestIsObsoleteTimestamp(0x80000001); // 2^31 + 1.
805 TestIsObsoleteTimestamp(0x7FFFFFFF); // 2^31 - 1.
806}
Minyue Li3f2eeb82019-07-03 16:43:29 +0200807
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000808} // namespace webrtc