blob: 688ce8d68dfef198e996f55f9c4dbd0c589bb799 [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
Minyue Li3f2eeb82019-07-03 16:43:29 +020015#include "absl/memory/memory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020016#include "api/audio_codecs/builtin_audio_decoder_factory.h"
17#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
18#include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
19#include "modules/audio_coding/neteq/packet.h"
20#include "modules/audio_coding/neteq/tick_timer.h"
21#include "test/gmock.h"
22#include "test/gtest.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000023
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000024using ::testing::_;
henrik.lundin63d146b2017-07-05 07:03:34 -070025using ::testing::InSequence;
26using ::testing::MockFunction;
Jonas Olssona4d87372019-07-05 19:08:33 +020027using ::testing::Return;
28using ::testing::StrictMock;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000029
Minyue Li3f2eeb82019-07-03 16:43:29 +020030namespace {
31class MockEncodedAudioFrame : public webrtc::AudioDecoder::EncodedAudioFrame {
32 public:
33 MOCK_CONST_METHOD0(Duration, size_t());
34
35 MOCK_CONST_METHOD0(IsDtxPacket, bool());
36
37 MOCK_CONST_METHOD1(
38 Decode,
39 absl::optional<DecodeResult>(rtc::ArrayView<int16_t> decoded));
40};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000041
42// Helper class to generate packets. Packets must be deleted by the user.
43class PacketGenerator {
44 public:
45 PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
46 virtual ~PacketGenerator() {}
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000047 void Reset(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
Minyue Li3f2eeb82019-07-03 16:43:29 +020048 webrtc::Packet NextPacket(
49 int payload_size_bytes,
50 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000051
52 uint16_t seq_no_;
53 uint32_t ts_;
54 uint8_t pt_;
55 int frame_size_;
56};
57
Jonas Olssona4d87372019-07-05 19:08:33 +020058PacketGenerator::PacketGenerator(uint16_t seq_no,
59 uint32_t ts,
60 uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000061 int frame_size) {
62 Reset(seq_no, ts, pt, frame_size);
63}
64
Jonas Olssona4d87372019-07-05 19:08:33 +020065void PacketGenerator::Reset(uint16_t seq_no,
66 uint32_t ts,
67 uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000068 int frame_size) {
69 seq_no_ = seq_no;
70 ts_ = ts;
71 pt_ = pt;
72 frame_size_ = frame_size;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000073}
74
Minyue Li3f2eeb82019-07-03 16:43:29 +020075webrtc::Packet PacketGenerator::NextPacket(
76 int payload_size_bytes,
77 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame) {
78 webrtc::Packet packet;
ossua73f6c92016-10-24 08:25:28 -070079 packet.sequence_number = seq_no_;
80 packet.timestamp = ts_;
81 packet.payload_type = pt_;
82 packet.payload.SetSize(payload_size_bytes);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000083 ++seq_no_;
84 ts_ += frame_size_;
Minyue Li3f2eeb82019-07-03 16:43:29 +020085 packet.frame = std::move(audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000086 return packet;
87}
88
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000089struct PacketsToInsert {
90 uint16_t sequence_number;
91 uint32_t timestamp;
92 uint8_t payload_type;
93 bool primary;
94 // Order of this packet to appear upon extraction, after inserting a series
95 // of packets. A negative number means that it should have been discarded
96 // before extraction.
97 int extract_order;
98};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000099
Minyue Li3f2eeb82019-07-03 16:43:29 +0200100} // namespace
101
102namespace webrtc {
103
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000104// Start of test definitions.
105
106TEST(PacketBuffer, CreateAndDestroy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700107 TickTimer tick_timer;
108 PacketBuffer* buffer = new PacketBuffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000109 EXPECT_TRUE(buffer->Empty());
110 delete buffer;
111}
112
113TEST(PacketBuffer, InsertPacket) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700114 TickTimer tick_timer;
115 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000116 PacketGenerator gen(17u, 4711u, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200117 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000118
119 const int payload_len = 100;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200120 const Packet packet = gen.NextPacket(payload_len, nullptr);
minyue-webrtc12d30842017-07-19 11:44:06 +0200121 EXPECT_EQ(0, buffer.InsertPacket(packet.Clone(), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000122 uint32_t next_ts;
123 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
124 EXPECT_EQ(4711u, next_ts);
125 EXPECT_FALSE(buffer.Empty());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700126 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700127 const Packet* next_packet = buffer.PeekNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700128 EXPECT_EQ(packet, *next_packet); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000129
130 // Do not explicitly flush buffer or delete packet to test that it is deleted
131 // with the buffer. (Tested with Valgrind or similar tool.)
132}
133
134// Test to flush buffer.
135TEST(PacketBuffer, FlushBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700136 TickTimer tick_timer;
137 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000138 PacketGenerator gen(0, 0, 0, 10);
139 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200140 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000141
142 // Insert 10 small packets; should be ok.
143 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200144 EXPECT_EQ(
145 PacketBuffer::kOK,
146 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000147 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700148 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000149 EXPECT_FALSE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000150
151 buffer.Flush();
152 // Buffer should delete the payloads itself.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700153 EXPECT_EQ(0u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000154 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000155}
156
157// Test to fill the buffer over the limits, and verify that it flushes.
158TEST(PacketBuffer, OverfillBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700159 TickTimer tick_timer;
160 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000161 PacketGenerator gen(0, 0, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200162 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000163
164 // Insert 10 small packets; should be ok.
165 const int payload_len = 10;
166 int i;
167 for (i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200168 EXPECT_EQ(
169 PacketBuffer::kOK,
170 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000171 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700172 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000173 uint32_t next_ts;
174 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
175 EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
176
Minyue Li3f2eeb82019-07-03 16:43:29 +0200177 const Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000178 // Insert 11th packet; should flush the buffer and insert it after flushing.
minyue-webrtc12d30842017-07-19 11:44:06 +0200179 EXPECT_EQ(PacketBuffer::kFlushed,
180 buffer.InsertPacket(packet.Clone(), &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700181 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000182 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
183 // Expect last inserted packet to be first in line.
ossua73f6c92016-10-24 08:25:28 -0700184 EXPECT_EQ(packet.timestamp, next_ts);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000185
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +0000186 // Flush buffer to delete all packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000187 buffer.Flush();
188}
189
190// Test inserting a list of packets.
191TEST(PacketBuffer, InsertPacketList) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700192 TickTimer tick_timer;
193 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000194 PacketGenerator gen(0, 0, 0, 10);
195 PacketList list;
196 const int payload_len = 10;
197
198 // Insert 10 small packets.
199 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200200 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000201 }
202
203 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700204 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100205 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200206 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700207 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
208 .WillRepeatedly(Return(&info));
minyue-webrtc12d30842017-07-19 11:44:06 +0200209
210 StrictMock<MockStatisticsCalculator> mock_stats;
211
Danil Chapovalovb6021232018-06-19 13:26:36 +0200212 absl::optional<uint8_t> current_pt;
213 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200214 EXPECT_EQ(PacketBuffer::kOK,
215 buffer.InsertPacketList(&list, decoder_database, &current_pt,
216 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000217 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700218 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
Jonas Olssona4d87372019-07-05 19:08:33 +0200219 EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200220 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000221
222 buffer.Flush(); // Clean up.
223
224 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
225}
226
227// Test inserting a list of packets. Last packet is of a different payload type.
228// Expecting the buffer to flush.
229// TODO(hlundin): Remove this test when legacy operation is no longer needed.
230TEST(PacketBuffer, InsertPacketListChangePayloadType) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700231 TickTimer tick_timer;
232 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000233 PacketGenerator gen(0, 0, 0, 10);
234 PacketList list;
235 const int payload_len = 10;
236
237 // Insert 10 small packets.
238 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200239 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000240 }
241 // Insert 11th packet of another payload type (not CNG).
ossua73f6c92016-10-24 08:25:28 -0700242 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200243 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700244 packet.payload_type = 1;
245 list.push_back(std::move(packet));
246 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000247
248 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700249 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100250 const DecoderDatabase::DecoderInfo info0(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200251 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700252 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
253 .WillRepeatedly(Return(&info0));
Niels Möller72899062019-01-11 09:36:13 +0100254 const DecoderDatabase::DecoderInfo info1(SdpAudioFormat("pcma", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200255 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700256 EXPECT_CALL(decoder_database, GetDecoderInfo(1))
257 .WillRepeatedly(Return(&info1));
minyue-webrtc12d30842017-07-19 11:44:06 +0200258
259 StrictMock<MockStatisticsCalculator> mock_stats;
260
Danil Chapovalovb6021232018-06-19 13:26:36 +0200261 absl::optional<uint8_t> current_pt;
262 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200263 EXPECT_EQ(PacketBuffer::kFlushed,
264 buffer.InsertPacketList(&list, decoder_database, &current_pt,
265 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000266 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700267 EXPECT_EQ(1u, buffer.NumPacketsInBuffer()); // Only the last packet.
Jonas Olssona4d87372019-07-05 19:08:33 +0200268 EXPECT_EQ(1, current_pt); // Current payload type changed to 1.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200269 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000270
271 buffer.Flush(); // Clean up.
272
273 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
274}
275
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000276TEST(PacketBuffer, ExtractOrderRedundancy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700277 TickTimer tick_timer;
278 PacketBuffer buffer(100, &tick_timer); // 100 packets.
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000279 const int kPackets = 18;
280 const int kFrameSize = 10;
281 const int kPayloadLength = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000282
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000283 PacketsToInsert packet_facts[kPackets] = {
Jonas Olssona4d87372019-07-05 19:08:33 +0200284 {0xFFFD, 0xFFFFFFD7, 0, true, 0}, {0xFFFE, 0xFFFFFFE1, 0, true, 1},
285 {0xFFFE, 0xFFFFFFD7, 1, false, -1}, {0xFFFF, 0xFFFFFFEB, 0, true, 2},
286 {0xFFFF, 0xFFFFFFE1, 1, false, -1}, {0x0000, 0xFFFFFFF5, 0, true, 3},
287 {0x0000, 0xFFFFFFEB, 1, false, -1}, {0x0001, 0xFFFFFFFF, 0, true, 4},
288 {0x0001, 0xFFFFFFF5, 1, false, -1}, {0x0002, 0x0000000A, 0, true, 5},
289 {0x0002, 0xFFFFFFFF, 1, false, -1}, {0x0003, 0x0000000A, 1, false, -1},
290 {0x0004, 0x0000001E, 0, true, 7}, {0x0004, 0x00000014, 1, false, 6},
291 {0x0005, 0x0000001E, 0, true, -1}, {0x0005, 0x00000014, 1, false, -1},
292 {0x0006, 0x00000028, 0, true, 8}, {0x0006, 0x0000001E, 1, false, -1},
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000293 };
294
Peter Kastingdce40cf2015-08-24 14:52:23 -0700295 const size_t kExpectPacketsInBuffer = 9;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000296
ossua73f6c92016-10-24 08:25:28 -0700297 std::vector<Packet> expect_order(kExpectPacketsInBuffer);
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000298
299 PacketGenerator gen(0, 0, 0, kFrameSize);
300
minyue-webrtc12d30842017-07-19 11:44:06 +0200301 StrictMock<MockStatisticsCalculator> mock_stats;
302
303 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
304 // check ensures that exactly one call to PacketsDiscarded happens in each
305 // DiscardNextPacket call.
306 InSequence s;
307 MockFunction<void(int check_point_id)> check;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000308 for (int i = 0; i < kPackets; ++i) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200309 gen.Reset(packet_facts[i].sequence_number, packet_facts[i].timestamp,
310 packet_facts[i].payload_type, kFrameSize);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200311 Packet packet = gen.NextPacket(kPayloadLength, nullptr);
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200312 packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
minyue-webrtc12d30842017-07-19 11:44:06 +0200313 if (packet_facts[i].extract_order < 0) {
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200314 if (packet.priority.codec_level > 0) {
315 EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
316 } else {
317 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
318 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200319 }
320 EXPECT_CALL(check, Call(i));
321 EXPECT_EQ(PacketBuffer::kOK,
322 buffer.InsertPacket(packet.Clone(), &mock_stats));
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000323 if (packet_facts[i].extract_order >= 0) {
ossua73f6c92016-10-24 08:25:28 -0700324 expect_order[packet_facts[i].extract_order] = std::move(packet);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000325 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200326 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000327 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000328
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000329 EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000330
Peter Kastingdce40cf2015-08-24 14:52:23 -0700331 for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200332 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700333 EXPECT_EQ(packet, expect_order[i]); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000334 }
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000335 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000336}
337
338TEST(PacketBuffer, DiscardPackets) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700339 TickTimer tick_timer;
340 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000341 const uint16_t start_seq_no = 17;
342 const uint32_t start_ts = 4711;
343 const uint32_t ts_increment = 10;
344 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
345 PacketList list;
346 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200347 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000348
minyue-webrtcfae474c2017-07-05 11:17:40 +0200349 constexpr int kTotalPackets = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000350 // Insert 10 small packets.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200351 for (int i = 0; i < kTotalPackets; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200352 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000353 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700354 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000355
minyue-webrtcfae474c2017-07-05 11:17:40 +0200356 uint32_t current_ts = start_ts;
357
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000358 // Discard them one by one and make sure that the right packets are at the
359 // front of the buffer.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200360 constexpr int kDiscardPackets = 5;
henrik.lundin63d146b2017-07-05 07:03:34 -0700361
362 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
363 // check ensures that exactly one call to PacketsDiscarded happens in each
364 // DiscardNextPacket call.
365 InSequence s;
366 MockFunction<void(int check_point_id)> check;
minyue-webrtcfae474c2017-07-05 11:17:40 +0200367 for (int i = 0; i < kDiscardPackets; ++i) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000368 uint32_t ts;
369 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
370 EXPECT_EQ(current_ts, ts);
henrik.lundin63d146b2017-07-05 07:03:34 -0700371 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
372 EXPECT_CALL(check, Call(i));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200373 EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000374 current_ts += ts_increment;
henrik.lundin63d146b2017-07-05 07:03:34 -0700375 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000376 }
minyue-webrtcfae474c2017-07-05 11:17:40 +0200377
378 constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
henrik.lundin63d146b2017-07-05 07:03:34 -0700379 // This will discard all remaining packets but one. The oldest packet is older
380 // than the indicated horizon_samples, and will thus be left in the buffer.
381 constexpr size_t kSkipPackets = 1;
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200382 EXPECT_CALL(mock_stats, PacketsDiscarded(1))
383 .Times(kRemainingPackets - kSkipPackets);
henrik.lundin63d146b2017-07-05 07:03:34 -0700384 EXPECT_CALL(check, Call(17)); // Arbitrary id number.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200385 buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
386 kRemainingPackets * ts_increment, &mock_stats);
henrik.lundin63d146b2017-07-05 07:03:34 -0700387 check.Call(17); // Same arbitrary id number.
388
389 EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200390 uint32_t ts;
391 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
392 EXPECT_EQ(current_ts, ts);
393
394 // Discard all remaining packets.
henrik.lundin63d146b2017-07-05 07:03:34 -0700395 EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200396 buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
397 &mock_stats);
398
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000399 EXPECT_TRUE(buffer.Empty());
400}
401
402TEST(PacketBuffer, Reordering) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700403 TickTimer tick_timer;
404 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000405 const uint16_t start_seq_no = 17;
406 const uint32_t start_ts = 4711;
407 const uint32_t ts_increment = 10;
408 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
409 const int payload_len = 10;
410
411 // Generate 10 small packets and insert them into a PacketList. Insert every
412 // odd packet to the front, and every even packet to the back, thus creating
413 // a (rather strange) reordering.
414 PacketList list;
415 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200416 Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000417 if (i % 2) {
ossua73f6c92016-10-24 08:25:28 -0700418 list.push_front(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000419 } else {
ossua73f6c92016-10-24 08:25:28 -0700420 list.push_back(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000421 }
422 }
423
424 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700425 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100426 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200427 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700428 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
429 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200430 absl::optional<uint8_t> current_pt;
431 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000432
minyue-webrtc12d30842017-07-19 11:44:06 +0200433 StrictMock<MockStatisticsCalculator> mock_stats;
434
435 EXPECT_EQ(PacketBuffer::kOK,
436 buffer.InsertPacketList(&list, decoder_database, &current_pt,
437 &current_cng_pt, &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700438 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000439
440 // Extract them and make sure that come out in the right order.
441 uint32_t current_ts = start_ts;
442 for (int i = 0; i < 10; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200443 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700444 ASSERT_TRUE(packet);
ossu7a377612016-10-18 04:06:13 -0700445 EXPECT_EQ(current_ts, packet->timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000446 current_ts += ts_increment;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000447 }
448 EXPECT_TRUE(buffer.Empty());
449
450 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
451}
452
henrik.lundin067d8552016-09-01 23:19:05 -0700453// The test first inserts a packet with narrow-band CNG, then a packet with
454// wide-band speech. The expected behavior of the packet buffer is to detect a
455// change in sample rate, even though no speech packet has been inserted before,
456// and flush out the CNG packet.
457TEST(PacketBuffer, CngFirstThenSpeechWithNewSampleRate) {
458 TickTimer tick_timer;
459 PacketBuffer buffer(10, &tick_timer); // 10 packets.
460 const uint8_t kCngPt = 13;
461 const int kPayloadLen = 10;
462 const uint8_t kSpeechPt = 100;
463
464 MockDecoderDatabase decoder_database;
465 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100466 const DecoderDatabase::DecoderInfo info_cng(SdpAudioFormat("cn", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200467 absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700468 EXPECT_CALL(decoder_database, GetDecoderInfo(kCngPt))
469 .WillRepeatedly(Return(&info_cng));
Niels Möller72899062019-01-11 09:36:13 +0100470 const DecoderDatabase::DecoderInfo info_speech(
471 SdpAudioFormat("l16", 16000, 1), absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700472 EXPECT_CALL(decoder_database, GetDecoderInfo(kSpeechPt))
473 .WillRepeatedly(Return(&info_speech));
474
475 // Insert first packet, which is narrow-band CNG.
476 PacketGenerator gen(0, 0, kCngPt, 10);
477 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200478 list.push_back(gen.NextPacket(kPayloadLen, nullptr));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200479 absl::optional<uint8_t> current_pt;
480 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200481
482 StrictMock<MockStatisticsCalculator> mock_stats;
483
henrik.lundin067d8552016-09-01 23:19:05 -0700484 EXPECT_EQ(PacketBuffer::kOK,
485 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200486 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700487 EXPECT_TRUE(list.empty());
488 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700489 ASSERT_TRUE(buffer.PeekNextPacket());
490 EXPECT_EQ(kCngPt, buffer.PeekNextPacket()->payload_type);
Danil Chapovalovb6021232018-06-19 13:26:36 +0200491 EXPECT_EQ(current_pt, absl::nullopt); // Current payload type not set.
Jonas Olssona4d87372019-07-05 19:08:33 +0200492 EXPECT_EQ(kCngPt, current_cng_pt); // CNG payload type set.
henrik.lundin067d8552016-09-01 23:19:05 -0700493
494 // Insert second packet, which is wide-band speech.
ossua73f6c92016-10-24 08:25:28 -0700495 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200496 Packet packet = gen.NextPacket(kPayloadLen, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700497 packet.payload_type = kSpeechPt;
498 list.push_back(std::move(packet));
499 }
henrik.lundin067d8552016-09-01 23:19:05 -0700500 // Expect the buffer to flush out the CNG packet, since it does not match the
501 // new speech sample rate.
502 EXPECT_EQ(PacketBuffer::kFlushed,
503 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200504 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700505 EXPECT_TRUE(list.empty());
506 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700507 ASSERT_TRUE(buffer.PeekNextPacket());
508 EXPECT_EQ(kSpeechPt, buffer.PeekNextPacket()->payload_type);
henrik.lundin067d8552016-09-01 23:19:05 -0700509
Jonas Olssona4d87372019-07-05 19:08:33 +0200510 EXPECT_EQ(kSpeechPt, current_pt); // Current payload type set.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200511 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type reset.
henrik.lundin067d8552016-09-01 23:19:05 -0700512
513 buffer.Flush(); // Clean up.
514 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
515}
516
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000517TEST(PacketBuffer, Failures) {
518 const uint16_t start_seq_no = 17;
519 const uint32_t start_ts = 4711;
520 const uint32_t ts_increment = 10;
521 int payload_len = 100;
522 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
henrik.lundin84f8cd62016-04-26 07:45:16 -0700523 TickTimer tick_timer;
minyue-webrtc12d30842017-07-19 11:44:06 +0200524 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000525
henrik.lundin84f8cd62016-04-26 07:45:16 -0700526 PacketBuffer* buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
ossua73f6c92016-10-24 08:25:28 -0700527 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200528 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700529 packet.payload.Clear();
530 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200531 buffer->InsertPacket(std::move(packet), &mock_stats));
ossua73f6c92016-10-24 08:25:28 -0700532 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000533 // Buffer should still be empty. Test all empty-checks.
534 uint32_t temp_ts;
535 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->NextTimestamp(&temp_ts));
536 EXPECT_EQ(PacketBuffer::kBufferEmpty,
537 buffer->NextHigherTimestamp(0, &temp_ts));
ossu7a377612016-10-18 04:06:13 -0700538 EXPECT_EQ(NULL, buffer->PeekNextPacket());
ossua73f6c92016-10-24 08:25:28 -0700539 EXPECT_FALSE(buffer->GetNextPacket());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200540
minyue-webrtcfae474c2017-07-05 11:17:40 +0200541 // Discarding packets will not invoke mock_stats.PacketDiscarded() because the
542 // packet buffer is empty.
543 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket(&mock_stats));
544 buffer->DiscardAllOldPackets(0, &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000545
546 // Insert one packet to make the buffer non-empty.
Minyue Li3f2eeb82019-07-03 16:43:29 +0200547 EXPECT_EQ(
548 PacketBuffer::kOK,
549 buffer->InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000550 EXPECT_EQ(PacketBuffer::kInvalidPointer, buffer->NextTimestamp(NULL));
551 EXPECT_EQ(PacketBuffer::kInvalidPointer,
552 buffer->NextHigherTimestamp(0, NULL));
553 delete buffer;
554
555 // Insert packet list of three packets, where the second packet has an invalid
556 // payload. Expect first packet to be inserted, and the remaining two to be
557 // discarded.
henrik.lundin84f8cd62016-04-26 07:45:16 -0700558 buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000559 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200560 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
ossua73f6c92016-10-24 08:25:28 -0700561 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200562 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700563 packet.payload.Clear(); // Invalid.
564 list.push_back(std::move(packet));
565 }
Minyue Li3f2eeb82019-07-03 16:43:29 +0200566 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000567 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700568 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100569 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200570 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700571 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
572 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200573 absl::optional<uint8_t> current_pt;
574 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000575 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200576 buffer->InsertPacketList(&list, decoder_database, &current_pt,
577 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000578 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700579 EXPECT_EQ(1u, buffer->NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000580 delete buffer;
581 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
582}
583
584// Test packet comparison function.
585// The function should return true if the first packet "goes before" the second.
586TEST(PacketBuffer, ComparePackets) {
587 PacketGenerator gen(0, 0, 0, 10);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200588 Packet a(gen.NextPacket(10, nullptr)); // SN = 0, TS = 0.
589 Packet b(gen.NextPacket(10, nullptr)); // SN = 1, TS = 10.
ossua73f6c92016-10-24 08:25:28 -0700590 EXPECT_FALSE(a == b);
591 EXPECT_TRUE(a != b);
592 EXPECT_TRUE(a < b);
593 EXPECT_FALSE(a > b);
594 EXPECT_TRUE(a <= b);
595 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000596
597 // Testing wrap-around case; 'a' is earlier but has a larger timestamp value.
ossua73f6c92016-10-24 08:25:28 -0700598 a.timestamp = 0xFFFFFFFF - 10;
599 EXPECT_FALSE(a == b);
600 EXPECT_TRUE(a != b);
601 EXPECT_TRUE(a < b);
602 EXPECT_FALSE(a > b);
603 EXPECT_TRUE(a <= b);
604 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000605
606 // Test equal packets.
ossua73f6c92016-10-24 08:25:28 -0700607 EXPECT_TRUE(a == a);
608 EXPECT_FALSE(a != a);
609 EXPECT_FALSE(a < a);
610 EXPECT_FALSE(a > a);
611 EXPECT_TRUE(a <= a);
612 EXPECT_TRUE(a >= a);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000613
614 // Test equal timestamps but different sequence numbers (0 and 1).
ossua73f6c92016-10-24 08:25:28 -0700615 a.timestamp = b.timestamp;
616 EXPECT_FALSE(a == b);
617 EXPECT_TRUE(a != b);
618 EXPECT_TRUE(a < b);
619 EXPECT_FALSE(a > b);
620 EXPECT_TRUE(a <= b);
621 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000622
623 // Test equal timestamps but different sequence numbers (32767 and 1).
ossua73f6c92016-10-24 08:25:28 -0700624 a.sequence_number = 0xFFFF;
625 EXPECT_FALSE(a == b);
626 EXPECT_TRUE(a != b);
627 EXPECT_TRUE(a < b);
628 EXPECT_FALSE(a > b);
629 EXPECT_TRUE(a <= b);
630 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000631
ossua70695a2016-09-22 02:06:28 -0700632 // Test equal timestamps and sequence numbers, but differing priorities.
ossua73f6c92016-10-24 08:25:28 -0700633 a.sequence_number = b.sequence_number;
634 a.priority = {1, 0};
635 b.priority = {0, 0};
ossua70695a2016-09-22 02:06:28 -0700636 // a after b
ossua73f6c92016-10-24 08:25:28 -0700637 EXPECT_FALSE(a == b);
638 EXPECT_TRUE(a != b);
639 EXPECT_FALSE(a < b);
640 EXPECT_TRUE(a > b);
641 EXPECT_FALSE(a <= b);
642 EXPECT_TRUE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000643
Minyue Li3f2eeb82019-07-03 16:43:29 +0200644 Packet c(gen.NextPacket(0, nullptr)); // SN = 2, TS = 20.
645 Packet d(gen.NextPacket(0, nullptr)); // SN = 3, TS = 20.
ossua73f6c92016-10-24 08:25:28 -0700646 c.timestamp = b.timestamp;
647 d.timestamp = b.timestamp;
648 c.sequence_number = b.sequence_number;
649 d.sequence_number = b.sequence_number;
650 c.priority = {1, 1};
651 d.priority = {0, 1};
ossua70695a2016-09-22 02:06:28 -0700652 // c after d
ossua73f6c92016-10-24 08:25:28 -0700653 EXPECT_FALSE(c == d);
654 EXPECT_TRUE(c != d);
655 EXPECT_FALSE(c < d);
656 EXPECT_TRUE(c > d);
657 EXPECT_FALSE(c <= d);
658 EXPECT_TRUE(c >= d);
ossua70695a2016-09-22 02:06:28 -0700659
660 // c after a
ossua73f6c92016-10-24 08:25:28 -0700661 EXPECT_FALSE(c == a);
662 EXPECT_TRUE(c != a);
663 EXPECT_FALSE(c < a);
664 EXPECT_TRUE(c > a);
665 EXPECT_FALSE(c <= a);
666 EXPECT_TRUE(c >= a);
ossua70695a2016-09-22 02:06:28 -0700667
668 // c after b
ossua73f6c92016-10-24 08:25:28 -0700669 EXPECT_FALSE(c == b);
670 EXPECT_TRUE(c != b);
671 EXPECT_FALSE(c < b);
672 EXPECT_TRUE(c > b);
673 EXPECT_FALSE(c <= b);
674 EXPECT_TRUE(c >= b);
ossua70695a2016-09-22 02:06:28 -0700675
676 // a after d
ossua73f6c92016-10-24 08:25:28 -0700677 EXPECT_FALSE(a == d);
678 EXPECT_TRUE(a != d);
679 EXPECT_FALSE(a < d);
680 EXPECT_TRUE(a > d);
681 EXPECT_FALSE(a <= d);
682 EXPECT_TRUE(a >= d);
ossua70695a2016-09-22 02:06:28 -0700683
684 // d after b
ossua73f6c92016-10-24 08:25:28 -0700685 EXPECT_FALSE(d == b);
686 EXPECT_TRUE(d != b);
687 EXPECT_FALSE(d < b);
688 EXPECT_TRUE(d > b);
689 EXPECT_FALSE(d <= b);
690 EXPECT_TRUE(d >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000691}
692
Minyue Li3f2eeb82019-07-03 16:43:29 +0200693TEST(PacketBuffer, GetSpanSamples) {
694 constexpr size_t kFrameSizeSamples = 10;
695 constexpr int kPayloadSizeBytes = 1; // Does not matter to this test;
696 constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE; // Close to wrap around.
697 constexpr int kSampleRateHz = 48000;
698 constexpr bool KCountDtxWaitingTime = false;
699 TickTimer tick_timer;
700 PacketBuffer buffer(3, &tick_timer);
701 PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples);
702 StrictMock<MockStatisticsCalculator> mock_stats;
703
704 Packet packet_1 = gen.NextPacket(kPayloadSizeBytes, nullptr);
705
706 std::unique_ptr<MockEncodedAudioFrame> mock_audio_frame =
707 absl::make_unique<MockEncodedAudioFrame>();
708 EXPECT_CALL(*mock_audio_frame, Duration())
709 .WillRepeatedly(Return(kFrameSizeSamples));
710 Packet packet_2 =
711 gen.NextPacket(kPayloadSizeBytes, std::move(mock_audio_frame));
712
713 RTC_DCHECK_GT(packet_1.timestamp,
714 packet_2.timestamp); // Tmestamp wrapped around.
715
716 EXPECT_EQ(PacketBuffer::kOK,
717 buffer.InsertPacket(std::move(packet_1), &mock_stats));
718
719 constexpr size_t kLastDecodedSizeSamples = 2;
720 // packet_1 has no access to duration, and relies last decoded duration as
721 // input.
722 EXPECT_EQ(kLastDecodedSizeSamples,
723 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
724 KCountDtxWaitingTime));
725
726 EXPECT_EQ(PacketBuffer::kOK,
727 buffer.InsertPacket(std::move(packet_2), &mock_stats));
728
729 EXPECT_EQ(kFrameSizeSamples * 2,
730 buffer.GetSpanSamples(0, kSampleRateHz, KCountDtxWaitingTime));
731
732 // packet_2 has access to duration, and ignores last decoded duration as
733 // input.
734 EXPECT_EQ(kFrameSizeSamples * 2,
735 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
736 KCountDtxWaitingTime));
737}
738
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000739namespace {
740void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
741 // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
742 // half the timestamp range.
743 static const uint32_t kZeroHorizon = 0;
744 static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
745 // Timestamp on the limit is not old.
746 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
747 limit_timestamp, limit_timestamp, kZeroHorizon));
748 // 1 sample behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200749 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
750 limit_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000751 // 2^31 - 1 samples behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200752 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - k2Pow31Minus1,
753 limit_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000754 // 1 sample ahead is not old.
755 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
756 limit_timestamp + 1, limit_timestamp, kZeroHorizon));
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200757 // If |t1-t2|=2^31 and t1>t2, t2 is older than t1 but not the opposite.
758 uint32_t other_timestamp = limit_timestamp + (1 << 31);
759 uint32_t lowest_timestamp = std::min(limit_timestamp, other_timestamp);
760 uint32_t highest_timestamp = std::max(limit_timestamp, other_timestamp);
761 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
762 lowest_timestamp, highest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000763 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200764 highest_timestamp, lowest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000765
766 // Fixed horizon at 10 samples.
767 static const uint32_t kHorizon = 10;
768 // Timestamp on the limit is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200769 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp,
770 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000771 // 1 sample behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200772 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
773 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000774 // 9 samples behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200775 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 9,
776 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000777 // 10 samples behind is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200778 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 10,
779 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000780 // 2^31 - 1 samples behind is not old.
781 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
782 limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
783 // 1 sample ahead is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200784 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + 1,
785 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000786 // 2^31 samples ahead is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200787 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + (1 << 31),
788 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000789}
790} // namespace
791
792// Test the IsObsoleteTimestamp method with different limit timestamps.
793TEST(PacketBuffer, IsObsoleteTimestamp) {
794 TestIsObsoleteTimestamp(0);
795 TestIsObsoleteTimestamp(1);
796 TestIsObsoleteTimestamp(0xFFFFFFFF); // -1 in uint32_t.
797 TestIsObsoleteTimestamp(0x80000000); // 2^31.
798 TestIsObsoleteTimestamp(0x80000001); // 2^31 + 1.
799 TestIsObsoleteTimestamp(0x7FFFFFFF); // 2^31 - 1.
800}
Minyue Li3f2eeb82019-07-03 16:43:29 +0200801
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000802} // namespace webrtc