blob: 0b638bfbe9e0e0ddfa4c323eab91db145c6ae4f1 [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"
Jonas Olssona4d87372019-07-05 19:08:33 +020014
Mirko Bonadei317a1f02019-09-17 17:06:18 +020015#include <memory>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/audio_codecs/builtin_audio_decoder_factory.h"
18#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
19#include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
20#include "modules/audio_coding/neteq/packet.h"
21#include "modules/audio_coding/neteq/tick_timer.h"
22#include "test/gmock.h"
23#include "test/gtest.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000024
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000025using ::testing::_;
henrik.lundin63d146b2017-07-05 07:03:34 -070026using ::testing::InSequence;
27using ::testing::MockFunction;
Jonas Olssona4d87372019-07-05 19:08:33 +020028using ::testing::Return;
29using ::testing::StrictMock;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000030
Minyue Li3f2eeb82019-07-03 16:43:29 +020031namespace {
32class MockEncodedAudioFrame : public webrtc::AudioDecoder::EncodedAudioFrame {
33 public:
34 MOCK_CONST_METHOD0(Duration, size_t());
35
36 MOCK_CONST_METHOD0(IsDtxPacket, bool());
37
38 MOCK_CONST_METHOD1(
39 Decode,
40 absl::optional<DecodeResult>(rtc::ArrayView<int16_t> decoded));
41};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000042
43// Helper class to generate packets. Packets must be deleted by the user.
44class PacketGenerator {
45 public:
46 PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
47 virtual ~PacketGenerator() {}
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000048 void Reset(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
Minyue Li3f2eeb82019-07-03 16:43:29 +020049 webrtc::Packet NextPacket(
50 int payload_size_bytes,
51 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000052
53 uint16_t seq_no_;
54 uint32_t ts_;
55 uint8_t pt_;
56 int frame_size_;
57};
58
Jonas Olssona4d87372019-07-05 19:08:33 +020059PacketGenerator::PacketGenerator(uint16_t seq_no,
60 uint32_t ts,
61 uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000062 int frame_size) {
63 Reset(seq_no, ts, pt, frame_size);
64}
65
Jonas Olssona4d87372019-07-05 19:08:33 +020066void PacketGenerator::Reset(uint16_t seq_no,
67 uint32_t ts,
68 uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000069 int frame_size) {
70 seq_no_ = seq_no;
71 ts_ = ts;
72 pt_ = pt;
73 frame_size_ = frame_size;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000074}
75
Minyue Li3f2eeb82019-07-03 16:43:29 +020076webrtc::Packet PacketGenerator::NextPacket(
77 int payload_size_bytes,
78 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame) {
79 webrtc::Packet packet;
ossua73f6c92016-10-24 08:25:28 -070080 packet.sequence_number = seq_no_;
81 packet.timestamp = ts_;
82 packet.payload_type = pt_;
83 packet.payload.SetSize(payload_size_bytes);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000084 ++seq_no_;
85 ts_ += frame_size_;
Minyue Li3f2eeb82019-07-03 16:43:29 +020086 packet.frame = std::move(audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000087 return packet;
88}
89
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000090struct PacketsToInsert {
91 uint16_t sequence_number;
92 uint32_t timestamp;
93 uint8_t payload_type;
94 bool primary;
95 // Order of this packet to appear upon extraction, after inserting a series
96 // of packets. A negative number means that it should have been discarded
97 // before extraction.
98 int extract_order;
99};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000100
Minyue Li3f2eeb82019-07-03 16:43:29 +0200101} // namespace
102
103namespace webrtc {
104
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000105// Start of test definitions.
106
107TEST(PacketBuffer, CreateAndDestroy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700108 TickTimer tick_timer;
109 PacketBuffer* buffer = new PacketBuffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000110 EXPECT_TRUE(buffer->Empty());
111 delete buffer;
112}
113
114TEST(PacketBuffer, InsertPacket) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700115 TickTimer tick_timer;
116 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000117 PacketGenerator gen(17u, 4711u, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200118 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000119
120 const int payload_len = 100;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200121 const Packet packet = gen.NextPacket(payload_len, nullptr);
minyue-webrtc12d30842017-07-19 11:44:06 +0200122 EXPECT_EQ(0, buffer.InsertPacket(packet.Clone(), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000123 uint32_t next_ts;
124 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
125 EXPECT_EQ(4711u, next_ts);
126 EXPECT_FALSE(buffer.Empty());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700127 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700128 const Packet* next_packet = buffer.PeekNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700129 EXPECT_EQ(packet, *next_packet); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000130
131 // Do not explicitly flush buffer or delete packet to test that it is deleted
132 // with the buffer. (Tested with Valgrind or similar tool.)
133}
134
135// Test to flush buffer.
136TEST(PacketBuffer, FlushBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700137 TickTimer tick_timer;
138 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000139 PacketGenerator gen(0, 0, 0, 10);
140 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200141 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000142
143 // Insert 10 small packets; should be ok.
144 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200145 EXPECT_EQ(
146 PacketBuffer::kOK,
147 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000148 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700149 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000150 EXPECT_FALSE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000151
152 buffer.Flush();
153 // Buffer should delete the payloads itself.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700154 EXPECT_EQ(0u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000155 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000156}
157
158// Test to fill the buffer over the limits, and verify that it flushes.
159TEST(PacketBuffer, OverfillBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700160 TickTimer tick_timer;
161 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000162 PacketGenerator gen(0, 0, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200163 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000164
165 // Insert 10 small packets; should be ok.
166 const int payload_len = 10;
167 int i;
168 for (i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200169 EXPECT_EQ(
170 PacketBuffer::kOK,
171 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000172 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700173 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000174 uint32_t next_ts;
175 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
176 EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
177
Minyue Li3f2eeb82019-07-03 16:43:29 +0200178 const Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000179 // Insert 11th packet; should flush the buffer and insert it after flushing.
minyue-webrtc12d30842017-07-19 11:44:06 +0200180 EXPECT_EQ(PacketBuffer::kFlushed,
181 buffer.InsertPacket(packet.Clone(), &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700182 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000183 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
184 // Expect last inserted packet to be first in line.
ossua73f6c92016-10-24 08:25:28 -0700185 EXPECT_EQ(packet.timestamp, next_ts);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000186
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +0000187 // Flush buffer to delete all packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000188 buffer.Flush();
189}
190
191// Test inserting a list of packets.
192TEST(PacketBuffer, InsertPacketList) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700193 TickTimer tick_timer;
194 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000195 PacketGenerator gen(0, 0, 0, 10);
196 PacketList list;
197 const int payload_len = 10;
198
199 // Insert 10 small packets.
200 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200201 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000202 }
203
204 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700205 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100206 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200207 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700208 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
209 .WillRepeatedly(Return(&info));
minyue-webrtc12d30842017-07-19 11:44:06 +0200210
211 StrictMock<MockStatisticsCalculator> mock_stats;
212
Danil Chapovalovb6021232018-06-19 13:26:36 +0200213 absl::optional<uint8_t> current_pt;
214 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200215 EXPECT_EQ(PacketBuffer::kOK,
216 buffer.InsertPacketList(&list, decoder_database, &current_pt,
217 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000218 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700219 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
Jonas Olssona4d87372019-07-05 19:08:33 +0200220 EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200221 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000222
223 buffer.Flush(); // Clean up.
224
225 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
226}
227
228// Test inserting a list of packets. Last packet is of a different payload type.
229// Expecting the buffer to flush.
230// TODO(hlundin): Remove this test when legacy operation is no longer needed.
231TEST(PacketBuffer, InsertPacketListChangePayloadType) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700232 TickTimer tick_timer;
233 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000234 PacketGenerator gen(0, 0, 0, 10);
235 PacketList list;
236 const int payload_len = 10;
237
238 // Insert 10 small packets.
239 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200240 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000241 }
242 // Insert 11th packet of another payload type (not CNG).
ossua73f6c92016-10-24 08:25:28 -0700243 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200244 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700245 packet.payload_type = 1;
246 list.push_back(std::move(packet));
247 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000248
249 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700250 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100251 const DecoderDatabase::DecoderInfo info0(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200252 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700253 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
254 .WillRepeatedly(Return(&info0));
Niels Möller72899062019-01-11 09:36:13 +0100255 const DecoderDatabase::DecoderInfo info1(SdpAudioFormat("pcma", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200256 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700257 EXPECT_CALL(decoder_database, GetDecoderInfo(1))
258 .WillRepeatedly(Return(&info1));
minyue-webrtc12d30842017-07-19 11:44:06 +0200259
260 StrictMock<MockStatisticsCalculator> mock_stats;
261
Danil Chapovalovb6021232018-06-19 13:26:36 +0200262 absl::optional<uint8_t> current_pt;
263 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200264 EXPECT_EQ(PacketBuffer::kFlushed,
265 buffer.InsertPacketList(&list, decoder_database, &current_pt,
266 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000267 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700268 EXPECT_EQ(1u, buffer.NumPacketsInBuffer()); // Only the last packet.
Jonas Olssona4d87372019-07-05 19:08:33 +0200269 EXPECT_EQ(1, current_pt); // Current payload type changed to 1.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200270 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000271
272 buffer.Flush(); // Clean up.
273
274 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
275}
276
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000277TEST(PacketBuffer, ExtractOrderRedundancy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700278 TickTimer tick_timer;
279 PacketBuffer buffer(100, &tick_timer); // 100 packets.
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000280 const int kPackets = 18;
281 const int kFrameSize = 10;
282 const int kPayloadLength = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000283
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000284 PacketsToInsert packet_facts[kPackets] = {
Jonas Olssona4d87372019-07-05 19:08:33 +0200285 {0xFFFD, 0xFFFFFFD7, 0, true, 0}, {0xFFFE, 0xFFFFFFE1, 0, true, 1},
286 {0xFFFE, 0xFFFFFFD7, 1, false, -1}, {0xFFFF, 0xFFFFFFEB, 0, true, 2},
287 {0xFFFF, 0xFFFFFFE1, 1, false, -1}, {0x0000, 0xFFFFFFF5, 0, true, 3},
288 {0x0000, 0xFFFFFFEB, 1, false, -1}, {0x0001, 0xFFFFFFFF, 0, true, 4},
289 {0x0001, 0xFFFFFFF5, 1, false, -1}, {0x0002, 0x0000000A, 0, true, 5},
290 {0x0002, 0xFFFFFFFF, 1, false, -1}, {0x0003, 0x0000000A, 1, false, -1},
291 {0x0004, 0x0000001E, 0, true, 7}, {0x0004, 0x00000014, 1, false, 6},
292 {0x0005, 0x0000001E, 0, true, -1}, {0x0005, 0x00000014, 1, false, -1},
293 {0x0006, 0x00000028, 0, true, 8}, {0x0006, 0x0000001E, 1, false, -1},
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000294 };
295
Peter Kastingdce40cf2015-08-24 14:52:23 -0700296 const size_t kExpectPacketsInBuffer = 9;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000297
ossua73f6c92016-10-24 08:25:28 -0700298 std::vector<Packet> expect_order(kExpectPacketsInBuffer);
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000299
300 PacketGenerator gen(0, 0, 0, kFrameSize);
301
minyue-webrtc12d30842017-07-19 11:44:06 +0200302 StrictMock<MockStatisticsCalculator> mock_stats;
303
304 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
305 // check ensures that exactly one call to PacketsDiscarded happens in each
306 // DiscardNextPacket call.
307 InSequence s;
308 MockFunction<void(int check_point_id)> check;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000309 for (int i = 0; i < kPackets; ++i) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200310 gen.Reset(packet_facts[i].sequence_number, packet_facts[i].timestamp,
311 packet_facts[i].payload_type, kFrameSize);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200312 Packet packet = gen.NextPacket(kPayloadLength, nullptr);
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200313 packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
minyue-webrtc12d30842017-07-19 11:44:06 +0200314 if (packet_facts[i].extract_order < 0) {
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200315 if (packet.priority.codec_level > 0) {
316 EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
317 } else {
318 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
319 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200320 }
321 EXPECT_CALL(check, Call(i));
322 EXPECT_EQ(PacketBuffer::kOK,
323 buffer.InsertPacket(packet.Clone(), &mock_stats));
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000324 if (packet_facts[i].extract_order >= 0) {
ossua73f6c92016-10-24 08:25:28 -0700325 expect_order[packet_facts[i].extract_order] = std::move(packet);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000326 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200327 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000328 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000329
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000330 EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000331
Peter Kastingdce40cf2015-08-24 14:52:23 -0700332 for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200333 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700334 EXPECT_EQ(packet, expect_order[i]); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000335 }
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000336 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000337}
338
339TEST(PacketBuffer, DiscardPackets) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700340 TickTimer tick_timer;
341 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000342 const uint16_t start_seq_no = 17;
343 const uint32_t start_ts = 4711;
344 const uint32_t ts_increment = 10;
345 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
346 PacketList list;
347 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200348 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000349
minyue-webrtcfae474c2017-07-05 11:17:40 +0200350 constexpr int kTotalPackets = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000351 // Insert 10 small packets.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200352 for (int i = 0; i < kTotalPackets; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200353 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000354 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700355 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000356
minyue-webrtcfae474c2017-07-05 11:17:40 +0200357 uint32_t current_ts = start_ts;
358
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000359 // Discard them one by one and make sure that the right packets are at the
360 // front of the buffer.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200361 constexpr int kDiscardPackets = 5;
henrik.lundin63d146b2017-07-05 07:03:34 -0700362
363 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
364 // check ensures that exactly one call to PacketsDiscarded happens in each
365 // DiscardNextPacket call.
366 InSequence s;
367 MockFunction<void(int check_point_id)> check;
minyue-webrtcfae474c2017-07-05 11:17:40 +0200368 for (int i = 0; i < kDiscardPackets; ++i) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000369 uint32_t ts;
370 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
371 EXPECT_EQ(current_ts, ts);
henrik.lundin63d146b2017-07-05 07:03:34 -0700372 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
373 EXPECT_CALL(check, Call(i));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200374 EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000375 current_ts += ts_increment;
henrik.lundin63d146b2017-07-05 07:03:34 -0700376 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000377 }
minyue-webrtcfae474c2017-07-05 11:17:40 +0200378
379 constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
henrik.lundin63d146b2017-07-05 07:03:34 -0700380 // This will discard all remaining packets but one. The oldest packet is older
381 // than the indicated horizon_samples, and will thus be left in the buffer.
382 constexpr size_t kSkipPackets = 1;
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200383 EXPECT_CALL(mock_stats, PacketsDiscarded(1))
384 .Times(kRemainingPackets - kSkipPackets);
henrik.lundin63d146b2017-07-05 07:03:34 -0700385 EXPECT_CALL(check, Call(17)); // Arbitrary id number.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200386 buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
387 kRemainingPackets * ts_increment, &mock_stats);
henrik.lundin63d146b2017-07-05 07:03:34 -0700388 check.Call(17); // Same arbitrary id number.
389
390 EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200391 uint32_t ts;
392 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
393 EXPECT_EQ(current_ts, ts);
394
395 // Discard all remaining packets.
henrik.lundin63d146b2017-07-05 07:03:34 -0700396 EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200397 buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
398 &mock_stats);
399
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000400 EXPECT_TRUE(buffer.Empty());
401}
402
403TEST(PacketBuffer, Reordering) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700404 TickTimer tick_timer;
405 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000406 const uint16_t start_seq_no = 17;
407 const uint32_t start_ts = 4711;
408 const uint32_t ts_increment = 10;
409 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
410 const int payload_len = 10;
411
412 // Generate 10 small packets and insert them into a PacketList. Insert every
413 // odd packet to the front, and every even packet to the back, thus creating
414 // a (rather strange) reordering.
415 PacketList list;
416 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200417 Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000418 if (i % 2) {
ossua73f6c92016-10-24 08:25:28 -0700419 list.push_front(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000420 } else {
ossua73f6c92016-10-24 08:25:28 -0700421 list.push_back(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000422 }
423 }
424
425 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700426 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100427 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200428 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700429 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
430 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200431 absl::optional<uint8_t> current_pt;
432 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000433
minyue-webrtc12d30842017-07-19 11:44:06 +0200434 StrictMock<MockStatisticsCalculator> mock_stats;
435
436 EXPECT_EQ(PacketBuffer::kOK,
437 buffer.InsertPacketList(&list, decoder_database, &current_pt,
438 &current_cng_pt, &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700439 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000440
441 // Extract them and make sure that come out in the right order.
442 uint32_t current_ts = start_ts;
443 for (int i = 0; i < 10; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200444 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700445 ASSERT_TRUE(packet);
ossu7a377612016-10-18 04:06:13 -0700446 EXPECT_EQ(current_ts, packet->timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000447 current_ts += ts_increment;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000448 }
449 EXPECT_TRUE(buffer.Empty());
450
451 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
452}
453
henrik.lundin067d8552016-09-01 23:19:05 -0700454// The test first inserts a packet with narrow-band CNG, then a packet with
455// wide-band speech. The expected behavior of the packet buffer is to detect a
456// change in sample rate, even though no speech packet has been inserted before,
457// and flush out the CNG packet.
458TEST(PacketBuffer, CngFirstThenSpeechWithNewSampleRate) {
459 TickTimer tick_timer;
460 PacketBuffer buffer(10, &tick_timer); // 10 packets.
461 const uint8_t kCngPt = 13;
462 const int kPayloadLen = 10;
463 const uint8_t kSpeechPt = 100;
464
465 MockDecoderDatabase decoder_database;
466 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100467 const DecoderDatabase::DecoderInfo info_cng(SdpAudioFormat("cn", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200468 absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700469 EXPECT_CALL(decoder_database, GetDecoderInfo(kCngPt))
470 .WillRepeatedly(Return(&info_cng));
Niels Möller72899062019-01-11 09:36:13 +0100471 const DecoderDatabase::DecoderInfo info_speech(
472 SdpAudioFormat("l16", 16000, 1), absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700473 EXPECT_CALL(decoder_database, GetDecoderInfo(kSpeechPt))
474 .WillRepeatedly(Return(&info_speech));
475
476 // Insert first packet, which is narrow-band CNG.
477 PacketGenerator gen(0, 0, kCngPt, 10);
478 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200479 list.push_back(gen.NextPacket(kPayloadLen, nullptr));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200480 absl::optional<uint8_t> current_pt;
481 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200482
483 StrictMock<MockStatisticsCalculator> mock_stats;
484
henrik.lundin067d8552016-09-01 23:19:05 -0700485 EXPECT_EQ(PacketBuffer::kOK,
486 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200487 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700488 EXPECT_TRUE(list.empty());
489 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700490 ASSERT_TRUE(buffer.PeekNextPacket());
491 EXPECT_EQ(kCngPt, buffer.PeekNextPacket()->payload_type);
Danil Chapovalovb6021232018-06-19 13:26:36 +0200492 EXPECT_EQ(current_pt, absl::nullopt); // Current payload type not set.
Jonas Olssona4d87372019-07-05 19:08:33 +0200493 EXPECT_EQ(kCngPt, current_cng_pt); // CNG payload type set.
henrik.lundin067d8552016-09-01 23:19:05 -0700494
495 // Insert second packet, which is wide-band speech.
ossua73f6c92016-10-24 08:25:28 -0700496 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200497 Packet packet = gen.NextPacket(kPayloadLen, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700498 packet.payload_type = kSpeechPt;
499 list.push_back(std::move(packet));
500 }
henrik.lundin067d8552016-09-01 23:19:05 -0700501 // Expect the buffer to flush out the CNG packet, since it does not match the
502 // new speech sample rate.
503 EXPECT_EQ(PacketBuffer::kFlushed,
504 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200505 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700506 EXPECT_TRUE(list.empty());
507 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700508 ASSERT_TRUE(buffer.PeekNextPacket());
509 EXPECT_EQ(kSpeechPt, buffer.PeekNextPacket()->payload_type);
henrik.lundin067d8552016-09-01 23:19:05 -0700510
Jonas Olssona4d87372019-07-05 19:08:33 +0200511 EXPECT_EQ(kSpeechPt, current_pt); // Current payload type set.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200512 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type reset.
henrik.lundin067d8552016-09-01 23:19:05 -0700513
514 buffer.Flush(); // Clean up.
515 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
516}
517
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000518TEST(PacketBuffer, Failures) {
519 const uint16_t start_seq_no = 17;
520 const uint32_t start_ts = 4711;
521 const uint32_t ts_increment = 10;
522 int payload_len = 100;
523 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
henrik.lundin84f8cd62016-04-26 07:45:16 -0700524 TickTimer tick_timer;
minyue-webrtc12d30842017-07-19 11:44:06 +0200525 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000526
henrik.lundin84f8cd62016-04-26 07:45:16 -0700527 PacketBuffer* buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
ossua73f6c92016-10-24 08:25:28 -0700528 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200529 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700530 packet.payload.Clear();
531 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200532 buffer->InsertPacket(std::move(packet), &mock_stats));
ossua73f6c92016-10-24 08:25:28 -0700533 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000534 // Buffer should still be empty. Test all empty-checks.
535 uint32_t temp_ts;
536 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->NextTimestamp(&temp_ts));
537 EXPECT_EQ(PacketBuffer::kBufferEmpty,
538 buffer->NextHigherTimestamp(0, &temp_ts));
ossu7a377612016-10-18 04:06:13 -0700539 EXPECT_EQ(NULL, buffer->PeekNextPacket());
ossua73f6c92016-10-24 08:25:28 -0700540 EXPECT_FALSE(buffer->GetNextPacket());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200541
minyue-webrtcfae474c2017-07-05 11:17:40 +0200542 // Discarding packets will not invoke mock_stats.PacketDiscarded() because the
543 // packet buffer is empty.
544 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket(&mock_stats));
545 buffer->DiscardAllOldPackets(0, &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000546
547 // Insert one packet to make the buffer non-empty.
Minyue Li3f2eeb82019-07-03 16:43:29 +0200548 EXPECT_EQ(
549 PacketBuffer::kOK,
550 buffer->InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000551 EXPECT_EQ(PacketBuffer::kInvalidPointer, buffer->NextTimestamp(NULL));
552 EXPECT_EQ(PacketBuffer::kInvalidPointer,
553 buffer->NextHigherTimestamp(0, NULL));
554 delete buffer;
555
556 // Insert packet list of three packets, where the second packet has an invalid
557 // payload. Expect first packet to be inserted, and the remaining two to be
558 // discarded.
henrik.lundin84f8cd62016-04-26 07:45:16 -0700559 buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000560 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200561 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
ossua73f6c92016-10-24 08:25:28 -0700562 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200563 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700564 packet.payload.Clear(); // Invalid.
565 list.push_back(std::move(packet));
566 }
Minyue Li3f2eeb82019-07-03 16:43:29 +0200567 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000568 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700569 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100570 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200571 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700572 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
573 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200574 absl::optional<uint8_t> current_pt;
575 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000576 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200577 buffer->InsertPacketList(&list, decoder_database, &current_pt,
578 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000579 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700580 EXPECT_EQ(1u, buffer->NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000581 delete buffer;
582 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
583}
584
585// Test packet comparison function.
586// The function should return true if the first packet "goes before" the second.
587TEST(PacketBuffer, ComparePackets) {
588 PacketGenerator gen(0, 0, 0, 10);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200589 Packet a(gen.NextPacket(10, nullptr)); // SN = 0, TS = 0.
590 Packet b(gen.NextPacket(10, nullptr)); // SN = 1, TS = 10.
ossua73f6c92016-10-24 08:25:28 -0700591 EXPECT_FALSE(a == b);
592 EXPECT_TRUE(a != b);
593 EXPECT_TRUE(a < b);
594 EXPECT_FALSE(a > b);
595 EXPECT_TRUE(a <= b);
596 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000597
598 // Testing wrap-around case; 'a' is earlier but has a larger timestamp value.
ossua73f6c92016-10-24 08:25:28 -0700599 a.timestamp = 0xFFFFFFFF - 10;
600 EXPECT_FALSE(a == b);
601 EXPECT_TRUE(a != b);
602 EXPECT_TRUE(a < b);
603 EXPECT_FALSE(a > b);
604 EXPECT_TRUE(a <= b);
605 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000606
607 // Test equal packets.
ossua73f6c92016-10-24 08:25:28 -0700608 EXPECT_TRUE(a == a);
609 EXPECT_FALSE(a != a);
610 EXPECT_FALSE(a < a);
611 EXPECT_FALSE(a > a);
612 EXPECT_TRUE(a <= a);
613 EXPECT_TRUE(a >= a);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000614
615 // Test equal timestamps but different sequence numbers (0 and 1).
ossua73f6c92016-10-24 08:25:28 -0700616 a.timestamp = b.timestamp;
617 EXPECT_FALSE(a == b);
618 EXPECT_TRUE(a != b);
619 EXPECT_TRUE(a < b);
620 EXPECT_FALSE(a > b);
621 EXPECT_TRUE(a <= b);
622 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000623
624 // Test equal timestamps but different sequence numbers (32767 and 1).
ossua73f6c92016-10-24 08:25:28 -0700625 a.sequence_number = 0xFFFF;
626 EXPECT_FALSE(a == b);
627 EXPECT_TRUE(a != b);
628 EXPECT_TRUE(a < b);
629 EXPECT_FALSE(a > b);
630 EXPECT_TRUE(a <= b);
631 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000632
ossua70695a2016-09-22 02:06:28 -0700633 // Test equal timestamps and sequence numbers, but differing priorities.
ossua73f6c92016-10-24 08:25:28 -0700634 a.sequence_number = b.sequence_number;
635 a.priority = {1, 0};
636 b.priority = {0, 0};
ossua70695a2016-09-22 02:06:28 -0700637 // a after b
ossua73f6c92016-10-24 08:25:28 -0700638 EXPECT_FALSE(a == b);
639 EXPECT_TRUE(a != b);
640 EXPECT_FALSE(a < b);
641 EXPECT_TRUE(a > b);
642 EXPECT_FALSE(a <= b);
643 EXPECT_TRUE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000644
Minyue Li3f2eeb82019-07-03 16:43:29 +0200645 Packet c(gen.NextPacket(0, nullptr)); // SN = 2, TS = 20.
646 Packet d(gen.NextPacket(0, nullptr)); // SN = 3, TS = 20.
ossua73f6c92016-10-24 08:25:28 -0700647 c.timestamp = b.timestamp;
648 d.timestamp = b.timestamp;
649 c.sequence_number = b.sequence_number;
650 d.sequence_number = b.sequence_number;
651 c.priority = {1, 1};
652 d.priority = {0, 1};
ossua70695a2016-09-22 02:06:28 -0700653 // c after d
ossua73f6c92016-10-24 08:25:28 -0700654 EXPECT_FALSE(c == d);
655 EXPECT_TRUE(c != d);
656 EXPECT_FALSE(c < d);
657 EXPECT_TRUE(c > d);
658 EXPECT_FALSE(c <= d);
659 EXPECT_TRUE(c >= d);
ossua70695a2016-09-22 02:06:28 -0700660
661 // c after a
ossua73f6c92016-10-24 08:25:28 -0700662 EXPECT_FALSE(c == a);
663 EXPECT_TRUE(c != a);
664 EXPECT_FALSE(c < a);
665 EXPECT_TRUE(c > a);
666 EXPECT_FALSE(c <= a);
667 EXPECT_TRUE(c >= a);
ossua70695a2016-09-22 02:06:28 -0700668
669 // c after b
ossua73f6c92016-10-24 08:25:28 -0700670 EXPECT_FALSE(c == b);
671 EXPECT_TRUE(c != b);
672 EXPECT_FALSE(c < b);
673 EXPECT_TRUE(c > b);
674 EXPECT_FALSE(c <= b);
675 EXPECT_TRUE(c >= b);
ossua70695a2016-09-22 02:06:28 -0700676
677 // a after d
ossua73f6c92016-10-24 08:25:28 -0700678 EXPECT_FALSE(a == d);
679 EXPECT_TRUE(a != d);
680 EXPECT_FALSE(a < d);
681 EXPECT_TRUE(a > d);
682 EXPECT_FALSE(a <= d);
683 EXPECT_TRUE(a >= d);
ossua70695a2016-09-22 02:06:28 -0700684
685 // d after b
ossua73f6c92016-10-24 08:25:28 -0700686 EXPECT_FALSE(d == b);
687 EXPECT_TRUE(d != b);
688 EXPECT_FALSE(d < b);
689 EXPECT_TRUE(d > b);
690 EXPECT_FALSE(d <= b);
691 EXPECT_TRUE(d >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000692}
693
Minyue Li3f2eeb82019-07-03 16:43:29 +0200694TEST(PacketBuffer, GetSpanSamples) {
695 constexpr size_t kFrameSizeSamples = 10;
696 constexpr int kPayloadSizeBytes = 1; // Does not matter to this test;
697 constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE; // Close to wrap around.
698 constexpr int kSampleRateHz = 48000;
699 constexpr bool KCountDtxWaitingTime = false;
700 TickTimer tick_timer;
701 PacketBuffer buffer(3, &tick_timer);
702 PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples);
703 StrictMock<MockStatisticsCalculator> mock_stats;
704
705 Packet packet_1 = gen.NextPacket(kPayloadSizeBytes, nullptr);
706
707 std::unique_ptr<MockEncodedAudioFrame> mock_audio_frame =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200708 std::make_unique<MockEncodedAudioFrame>();
Minyue Li3f2eeb82019-07-03 16:43:29 +0200709 EXPECT_CALL(*mock_audio_frame, Duration())
710 .WillRepeatedly(Return(kFrameSizeSamples));
711 Packet packet_2 =
712 gen.NextPacket(kPayloadSizeBytes, std::move(mock_audio_frame));
713
714 RTC_DCHECK_GT(packet_1.timestamp,
715 packet_2.timestamp); // Tmestamp wrapped around.
716
717 EXPECT_EQ(PacketBuffer::kOK,
718 buffer.InsertPacket(std::move(packet_1), &mock_stats));
719
720 constexpr size_t kLastDecodedSizeSamples = 2;
721 // packet_1 has no access to duration, and relies last decoded duration as
722 // input.
723 EXPECT_EQ(kLastDecodedSizeSamples,
724 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
725 KCountDtxWaitingTime));
726
727 EXPECT_EQ(PacketBuffer::kOK,
728 buffer.InsertPacket(std::move(packet_2), &mock_stats));
729
730 EXPECT_EQ(kFrameSizeSamples * 2,
731 buffer.GetSpanSamples(0, kSampleRateHz, KCountDtxWaitingTime));
732
733 // packet_2 has access to duration, and ignores last decoded duration as
734 // input.
735 EXPECT_EQ(kFrameSizeSamples * 2,
736 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
737 KCountDtxWaitingTime));
738}
739
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000740namespace {
741void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
742 // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
743 // half the timestamp range.
744 static const uint32_t kZeroHorizon = 0;
745 static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
746 // Timestamp on the limit is not old.
747 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
748 limit_timestamp, limit_timestamp, kZeroHorizon));
749 // 1 sample behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200750 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
751 limit_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000752 // 2^31 - 1 samples behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200753 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - k2Pow31Minus1,
754 limit_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000755 // 1 sample ahead is not old.
756 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
757 limit_timestamp + 1, limit_timestamp, kZeroHorizon));
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200758 // If |t1-t2|=2^31 and t1>t2, t2 is older than t1 but not the opposite.
759 uint32_t other_timestamp = limit_timestamp + (1 << 31);
760 uint32_t lowest_timestamp = std::min(limit_timestamp, other_timestamp);
761 uint32_t highest_timestamp = std::max(limit_timestamp, other_timestamp);
762 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
763 lowest_timestamp, highest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000764 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200765 highest_timestamp, lowest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000766
767 // Fixed horizon at 10 samples.
768 static const uint32_t kHorizon = 10;
769 // Timestamp on the limit is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200770 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp,
771 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000772 // 1 sample behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200773 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
774 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000775 // 9 samples behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200776 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 9,
777 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000778 // 10 samples behind is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200779 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 10,
780 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000781 // 2^31 - 1 samples behind is not old.
782 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
783 limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
784 // 1 sample ahead is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200785 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + 1,
786 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000787 // 2^31 samples ahead is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200788 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + (1 << 31),
789 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000790}
791} // namespace
792
793// Test the IsObsoleteTimestamp method with different limit timestamps.
794TEST(PacketBuffer, IsObsoleteTimestamp) {
795 TestIsObsoleteTimestamp(0);
796 TestIsObsoleteTimestamp(1);
797 TestIsObsoleteTimestamp(0xFFFFFFFF); // -1 in uint32_t.
798 TestIsObsoleteTimestamp(0x80000000); // 2^31.
799 TestIsObsoleteTimestamp(0x80000001); // 2^31 + 1.
800 TestIsObsoleteTimestamp(0x7FFFFFFF); // 2^31 - 1.
801}
Minyue Li3f2eeb82019-07-03 16:43:29 +0200802
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000803} // namespace webrtc