blob: 40e7d5371afaa7692981553a17216672c221564c [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"
Ivo Creusen3ce44a32019-10-31 14:38:11 +010018#include "api/neteq/tick_timer.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
20#include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
21#include "modules/audio_coding/neteq/packet.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#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:
Danil Chapovalov704fb552020-05-18 15:10:15 +020034 MOCK_METHOD(size_t, Duration, (), (const, override));
Minyue Li3f2eeb82019-07-03 16:43:29 +020035
Danil Chapovalov704fb552020-05-18 15:10:15 +020036 MOCK_METHOD(bool, IsDtxPacket, (), (const, override));
Minyue Li3f2eeb82019-07-03 16:43:29 +020037
Danil Chapovalov704fb552020-05-18 15:10:15 +020038 MOCK_METHOD(absl::optional<DecodeResult>,
39 Decode,
40 (rtc::ArrayView<int16_t> decoded),
41 (const, override));
Minyue Li3f2eeb82019-07-03 16:43:29 +020042};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000043
44// Helper class to generate packets. Packets must be deleted by the user.
45class PacketGenerator {
46 public:
47 PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
48 virtual ~PacketGenerator() {}
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000049 void Reset(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
Minyue Li3f2eeb82019-07-03 16:43:29 +020050 webrtc::Packet NextPacket(
51 int payload_size_bytes,
52 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000053
54 uint16_t seq_no_;
55 uint32_t ts_;
56 uint8_t pt_;
57 int frame_size_;
58};
59
Jonas Olssona4d87372019-07-05 19:08:33 +020060PacketGenerator::PacketGenerator(uint16_t seq_no,
61 uint32_t ts,
62 uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000063 int frame_size) {
64 Reset(seq_no, ts, pt, frame_size);
65}
66
Jonas Olssona4d87372019-07-05 19:08:33 +020067void PacketGenerator::Reset(uint16_t seq_no,
68 uint32_t ts,
69 uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000070 int frame_size) {
71 seq_no_ = seq_no;
72 ts_ = ts;
73 pt_ = pt;
74 frame_size_ = frame_size;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000075}
76
Minyue Li3f2eeb82019-07-03 16:43:29 +020077webrtc::Packet PacketGenerator::NextPacket(
78 int payload_size_bytes,
79 std::unique_ptr<webrtc::AudioDecoder::EncodedAudioFrame> audio_frame) {
80 webrtc::Packet packet;
ossua73f6c92016-10-24 08:25:28 -070081 packet.sequence_number = seq_no_;
82 packet.timestamp = ts_;
83 packet.payload_type = pt_;
84 packet.payload.SetSize(payload_size_bytes);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000085 ++seq_no_;
86 ts_ += frame_size_;
Minyue Li3f2eeb82019-07-03 16:43:29 +020087 packet.frame = std::move(audio_frame);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000088 return packet;
89}
90
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000091struct PacketsToInsert {
92 uint16_t sequence_number;
93 uint32_t timestamp;
94 uint8_t payload_type;
95 bool primary;
96 // Order of this packet to appear upon extraction, after inserting a series
97 // of packets. A negative number means that it should have been discarded
98 // before extraction.
99 int extract_order;
100};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000101
Minyue Li3f2eeb82019-07-03 16:43:29 +0200102} // namespace
103
104namespace webrtc {
105
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000106// Start of test definitions.
107
108TEST(PacketBuffer, CreateAndDestroy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700109 TickTimer tick_timer;
110 PacketBuffer* buffer = new PacketBuffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000111 EXPECT_TRUE(buffer->Empty());
112 delete buffer;
113}
114
115TEST(PacketBuffer, InsertPacket) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700116 TickTimer tick_timer;
117 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000118 PacketGenerator gen(17u, 4711u, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200119 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000120
121 const int payload_len = 100;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200122 const Packet packet = gen.NextPacket(payload_len, nullptr);
minyue-webrtc12d30842017-07-19 11:44:06 +0200123 EXPECT_EQ(0, buffer.InsertPacket(packet.Clone(), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000124 uint32_t next_ts;
125 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
126 EXPECT_EQ(4711u, next_ts);
127 EXPECT_FALSE(buffer.Empty());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700128 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700129 const Packet* next_packet = buffer.PeekNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700130 EXPECT_EQ(packet, *next_packet); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000131
132 // Do not explicitly flush buffer or delete packet to test that it is deleted
133 // with the buffer. (Tested with Valgrind or similar tool.)
134}
135
136// Test to flush buffer.
137TEST(PacketBuffer, FlushBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700138 TickTimer tick_timer;
139 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000140 PacketGenerator gen(0, 0, 0, 10);
141 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200142 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000143
144 // Insert 10 small packets; should be ok.
145 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200146 EXPECT_EQ(
147 PacketBuffer::kOK,
148 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000149 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700150 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000151 EXPECT_FALSE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000152
153 buffer.Flush();
154 // Buffer should delete the payloads itself.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700155 EXPECT_EQ(0u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000156 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000157}
158
159// Test to fill the buffer over the limits, and verify that it flushes.
160TEST(PacketBuffer, OverfillBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700161 TickTimer tick_timer;
162 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000163 PacketGenerator gen(0, 0, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200164 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000165
166 // Insert 10 small packets; should be ok.
167 const int payload_len = 10;
168 int i;
169 for (i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200170 EXPECT_EQ(
171 PacketBuffer::kOK,
172 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000173 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700174 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000175 uint32_t next_ts;
176 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
177 EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
178
Minyue Li3f2eeb82019-07-03 16:43:29 +0200179 const Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000180 // Insert 11th packet; should flush the buffer and insert it after flushing.
minyue-webrtc12d30842017-07-19 11:44:06 +0200181 EXPECT_EQ(PacketBuffer::kFlushed,
182 buffer.InsertPacket(packet.Clone(), &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700183 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000184 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
185 // Expect last inserted packet to be first in line.
ossua73f6c92016-10-24 08:25:28 -0700186 EXPECT_EQ(packet.timestamp, next_ts);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000187
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +0000188 // Flush buffer to delete all packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000189 buffer.Flush();
190}
191
192// Test inserting a list of packets.
193TEST(PacketBuffer, InsertPacketList) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700194 TickTimer tick_timer;
195 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000196 PacketGenerator gen(0, 0, 0, 10);
197 PacketList list;
198 const int payload_len = 10;
199
200 // Insert 10 small packets.
201 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200202 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000203 }
204
205 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700206 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100207 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200208 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700209 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
210 .WillRepeatedly(Return(&info));
minyue-webrtc12d30842017-07-19 11:44:06 +0200211
212 StrictMock<MockStatisticsCalculator> mock_stats;
213
Danil Chapovalovb6021232018-06-19 13:26:36 +0200214 absl::optional<uint8_t> current_pt;
215 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200216 EXPECT_EQ(PacketBuffer::kOK,
217 buffer.InsertPacketList(&list, decoder_database, &current_pt,
218 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000219 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700220 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
Jonas Olssona4d87372019-07-05 19:08:33 +0200221 EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200222 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000223
224 buffer.Flush(); // Clean up.
225
226 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
227}
228
229// Test inserting a list of packets. Last packet is of a different payload type.
230// Expecting the buffer to flush.
231// TODO(hlundin): Remove this test when legacy operation is no longer needed.
232TEST(PacketBuffer, InsertPacketListChangePayloadType) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700233 TickTimer tick_timer;
234 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000235 PacketGenerator gen(0, 0, 0, 10);
236 PacketList list;
237 const int payload_len = 10;
238
239 // Insert 10 small packets.
240 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200241 list.push_back(gen.NextPacket(payload_len, nullptr));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000242 }
243 // Insert 11th packet of another payload type (not CNG).
ossua73f6c92016-10-24 08:25:28 -0700244 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200245 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700246 packet.payload_type = 1;
247 list.push_back(std::move(packet));
248 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000249
250 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700251 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100252 const DecoderDatabase::DecoderInfo info0(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200253 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700254 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
255 .WillRepeatedly(Return(&info0));
Niels Möller72899062019-01-11 09:36:13 +0100256 const DecoderDatabase::DecoderInfo info1(SdpAudioFormat("pcma", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200257 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700258 EXPECT_CALL(decoder_database, GetDecoderInfo(1))
259 .WillRepeatedly(Return(&info1));
minyue-webrtc12d30842017-07-19 11:44:06 +0200260
261 StrictMock<MockStatisticsCalculator> mock_stats;
262
Danil Chapovalovb6021232018-06-19 13:26:36 +0200263 absl::optional<uint8_t> current_pt;
264 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200265 EXPECT_EQ(PacketBuffer::kFlushed,
266 buffer.InsertPacketList(&list, decoder_database, &current_pt,
267 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000268 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700269 EXPECT_EQ(1u, buffer.NumPacketsInBuffer()); // Only the last packet.
Jonas Olssona4d87372019-07-05 19:08:33 +0200270 EXPECT_EQ(1, current_pt); // Current payload type changed to 1.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200271 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000272
273 buffer.Flush(); // Clean up.
274
275 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
276}
277
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000278TEST(PacketBuffer, ExtractOrderRedundancy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700279 TickTimer tick_timer;
280 PacketBuffer buffer(100, &tick_timer); // 100 packets.
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000281 const int kPackets = 18;
282 const int kFrameSize = 10;
283 const int kPayloadLength = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000284
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000285 PacketsToInsert packet_facts[kPackets] = {
Jonas Olssona4d87372019-07-05 19:08:33 +0200286 {0xFFFD, 0xFFFFFFD7, 0, true, 0}, {0xFFFE, 0xFFFFFFE1, 0, true, 1},
287 {0xFFFE, 0xFFFFFFD7, 1, false, -1}, {0xFFFF, 0xFFFFFFEB, 0, true, 2},
288 {0xFFFF, 0xFFFFFFE1, 1, false, -1}, {0x0000, 0xFFFFFFF5, 0, true, 3},
289 {0x0000, 0xFFFFFFEB, 1, false, -1}, {0x0001, 0xFFFFFFFF, 0, true, 4},
290 {0x0001, 0xFFFFFFF5, 1, false, -1}, {0x0002, 0x0000000A, 0, true, 5},
291 {0x0002, 0xFFFFFFFF, 1, false, -1}, {0x0003, 0x0000000A, 1, false, -1},
292 {0x0004, 0x0000001E, 0, true, 7}, {0x0004, 0x00000014, 1, false, 6},
293 {0x0005, 0x0000001E, 0, true, -1}, {0x0005, 0x00000014, 1, false, -1},
294 {0x0006, 0x00000028, 0, true, 8}, {0x0006, 0x0000001E, 1, false, -1},
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000295 };
296
Peter Kastingdce40cf2015-08-24 14:52:23 -0700297 const size_t kExpectPacketsInBuffer = 9;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000298
ossua73f6c92016-10-24 08:25:28 -0700299 std::vector<Packet> expect_order(kExpectPacketsInBuffer);
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000300
301 PacketGenerator gen(0, 0, 0, kFrameSize);
302
minyue-webrtc12d30842017-07-19 11:44:06 +0200303 StrictMock<MockStatisticsCalculator> mock_stats;
304
305 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
306 // check ensures that exactly one call to PacketsDiscarded happens in each
307 // DiscardNextPacket call.
308 InSequence s;
309 MockFunction<void(int check_point_id)> check;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000310 for (int i = 0; i < kPackets; ++i) {
Jonas Olssona4d87372019-07-05 19:08:33 +0200311 gen.Reset(packet_facts[i].sequence_number, packet_facts[i].timestamp,
312 packet_facts[i].payload_type, kFrameSize);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200313 Packet packet = gen.NextPacket(kPayloadLength, nullptr);
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200314 packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
minyue-webrtc12d30842017-07-19 11:44:06 +0200315 if (packet_facts[i].extract_order < 0) {
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200316 if (packet.priority.codec_level > 0) {
317 EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
318 } else {
319 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
320 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200321 }
322 EXPECT_CALL(check, Call(i));
323 EXPECT_EQ(PacketBuffer::kOK,
324 buffer.InsertPacket(packet.Clone(), &mock_stats));
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000325 if (packet_facts[i].extract_order >= 0) {
ossua73f6c92016-10-24 08:25:28 -0700326 expect_order[packet_facts[i].extract_order] = std::move(packet);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000327 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200328 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000329 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000330
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000331 EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000332
Peter Kastingdce40cf2015-08-24 14:52:23 -0700333 for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200334 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700335 EXPECT_EQ(packet, expect_order[i]); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000336 }
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000337 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000338}
339
340TEST(PacketBuffer, DiscardPackets) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700341 TickTimer tick_timer;
342 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000343 const uint16_t start_seq_no = 17;
344 const uint32_t start_ts = 4711;
345 const uint32_t ts_increment = 10;
346 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
347 PacketList list;
348 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200349 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000350
minyue-webrtcfae474c2017-07-05 11:17:40 +0200351 constexpr int kTotalPackets = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000352 // Insert 10 small packets.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200353 for (int i = 0; i < kTotalPackets; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200354 buffer.InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000355 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700356 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000357
minyue-webrtcfae474c2017-07-05 11:17:40 +0200358 uint32_t current_ts = start_ts;
359
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000360 // Discard them one by one and make sure that the right packets are at the
361 // front of the buffer.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200362 constexpr int kDiscardPackets = 5;
henrik.lundin63d146b2017-07-05 07:03:34 -0700363
364 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
365 // check ensures that exactly one call to PacketsDiscarded happens in each
366 // DiscardNextPacket call.
367 InSequence s;
368 MockFunction<void(int check_point_id)> check;
minyue-webrtcfae474c2017-07-05 11:17:40 +0200369 for (int i = 0; i < kDiscardPackets; ++i) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000370 uint32_t ts;
371 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
372 EXPECT_EQ(current_ts, ts);
henrik.lundin63d146b2017-07-05 07:03:34 -0700373 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
374 EXPECT_CALL(check, Call(i));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200375 EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000376 current_ts += ts_increment;
henrik.lundin63d146b2017-07-05 07:03:34 -0700377 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000378 }
minyue-webrtcfae474c2017-07-05 11:17:40 +0200379
380 constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
henrik.lundin63d146b2017-07-05 07:03:34 -0700381 // This will discard all remaining packets but one. The oldest packet is older
382 // than the indicated horizon_samples, and will thus be left in the buffer.
383 constexpr size_t kSkipPackets = 1;
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200384 EXPECT_CALL(mock_stats, PacketsDiscarded(1))
385 .Times(kRemainingPackets - kSkipPackets);
henrik.lundin63d146b2017-07-05 07:03:34 -0700386 EXPECT_CALL(check, Call(17)); // Arbitrary id number.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200387 buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
388 kRemainingPackets * ts_increment, &mock_stats);
henrik.lundin63d146b2017-07-05 07:03:34 -0700389 check.Call(17); // Same arbitrary id number.
390
391 EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200392 uint32_t ts;
393 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
394 EXPECT_EQ(current_ts, ts);
395
396 // Discard all remaining packets.
henrik.lundin63d146b2017-07-05 07:03:34 -0700397 EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200398 buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
399 &mock_stats);
400
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000401 EXPECT_TRUE(buffer.Empty());
402}
403
404TEST(PacketBuffer, Reordering) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700405 TickTimer tick_timer;
406 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000407 const uint16_t start_seq_no = 17;
408 const uint32_t start_ts = 4711;
409 const uint32_t ts_increment = 10;
410 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
411 const int payload_len = 10;
412
413 // Generate 10 small packets and insert them into a PacketList. Insert every
414 // odd packet to the front, and every even packet to the back, thus creating
415 // a (rather strange) reordering.
416 PacketList list;
417 for (int i = 0; i < 10; ++i) {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200418 Packet packet = gen.NextPacket(payload_len, nullptr);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000419 if (i % 2) {
ossua73f6c92016-10-24 08:25:28 -0700420 list.push_front(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000421 } else {
ossua73f6c92016-10-24 08:25:28 -0700422 list.push_back(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000423 }
424 }
425
426 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700427 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100428 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200429 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700430 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
431 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200432 absl::optional<uint8_t> current_pt;
433 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000434
minyue-webrtc12d30842017-07-19 11:44:06 +0200435 StrictMock<MockStatisticsCalculator> mock_stats;
436
437 EXPECT_EQ(PacketBuffer::kOK,
438 buffer.InsertPacketList(&list, decoder_database, &current_pt,
439 &current_cng_pt, &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700440 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000441
442 // Extract them and make sure that come out in the right order.
443 uint32_t current_ts = start_ts;
444 for (int i = 0; i < 10; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200445 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700446 ASSERT_TRUE(packet);
ossu7a377612016-10-18 04:06:13 -0700447 EXPECT_EQ(current_ts, packet->timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000448 current_ts += ts_increment;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000449 }
450 EXPECT_TRUE(buffer.Empty());
451
452 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
453}
454
henrik.lundin067d8552016-09-01 23:19:05 -0700455// The test first inserts a packet with narrow-band CNG, then a packet with
456// wide-band speech. The expected behavior of the packet buffer is to detect a
457// change in sample rate, even though no speech packet has been inserted before,
458// and flush out the CNG packet.
459TEST(PacketBuffer, CngFirstThenSpeechWithNewSampleRate) {
460 TickTimer tick_timer;
461 PacketBuffer buffer(10, &tick_timer); // 10 packets.
462 const uint8_t kCngPt = 13;
463 const int kPayloadLen = 10;
464 const uint8_t kSpeechPt = 100;
465
466 MockDecoderDatabase decoder_database;
467 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100468 const DecoderDatabase::DecoderInfo info_cng(SdpAudioFormat("cn", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200469 absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700470 EXPECT_CALL(decoder_database, GetDecoderInfo(kCngPt))
471 .WillRepeatedly(Return(&info_cng));
Niels Möller72899062019-01-11 09:36:13 +0100472 const DecoderDatabase::DecoderInfo info_speech(
473 SdpAudioFormat("l16", 16000, 1), absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700474 EXPECT_CALL(decoder_database, GetDecoderInfo(kSpeechPt))
475 .WillRepeatedly(Return(&info_speech));
476
477 // Insert first packet, which is narrow-band CNG.
478 PacketGenerator gen(0, 0, kCngPt, 10);
479 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200480 list.push_back(gen.NextPacket(kPayloadLen, nullptr));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200481 absl::optional<uint8_t> current_pt;
482 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200483
484 StrictMock<MockStatisticsCalculator> mock_stats;
485
henrik.lundin067d8552016-09-01 23:19:05 -0700486 EXPECT_EQ(PacketBuffer::kOK,
487 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200488 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700489 EXPECT_TRUE(list.empty());
490 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700491 ASSERT_TRUE(buffer.PeekNextPacket());
492 EXPECT_EQ(kCngPt, buffer.PeekNextPacket()->payload_type);
Danil Chapovalovb6021232018-06-19 13:26:36 +0200493 EXPECT_EQ(current_pt, absl::nullopt); // Current payload type not set.
Jonas Olssona4d87372019-07-05 19:08:33 +0200494 EXPECT_EQ(kCngPt, current_cng_pt); // CNG payload type set.
henrik.lundin067d8552016-09-01 23:19:05 -0700495
496 // Insert second packet, which is wide-band speech.
ossua73f6c92016-10-24 08:25:28 -0700497 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200498 Packet packet = gen.NextPacket(kPayloadLen, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700499 packet.payload_type = kSpeechPt;
500 list.push_back(std::move(packet));
501 }
henrik.lundin067d8552016-09-01 23:19:05 -0700502 // Expect the buffer to flush out the CNG packet, since it does not match the
503 // new speech sample rate.
504 EXPECT_EQ(PacketBuffer::kFlushed,
505 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200506 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700507 EXPECT_TRUE(list.empty());
508 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700509 ASSERT_TRUE(buffer.PeekNextPacket());
510 EXPECT_EQ(kSpeechPt, buffer.PeekNextPacket()->payload_type);
henrik.lundin067d8552016-09-01 23:19:05 -0700511
Jonas Olssona4d87372019-07-05 19:08:33 +0200512 EXPECT_EQ(kSpeechPt, current_pt); // Current payload type set.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200513 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type reset.
henrik.lundin067d8552016-09-01 23:19:05 -0700514
515 buffer.Flush(); // Clean up.
516 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
517}
518
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000519TEST(PacketBuffer, Failures) {
520 const uint16_t start_seq_no = 17;
521 const uint32_t start_ts = 4711;
522 const uint32_t ts_increment = 10;
523 int payload_len = 100;
524 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
henrik.lundin84f8cd62016-04-26 07:45:16 -0700525 TickTimer tick_timer;
minyue-webrtc12d30842017-07-19 11:44:06 +0200526 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000527
henrik.lundin84f8cd62016-04-26 07:45:16 -0700528 PacketBuffer* buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
ossua73f6c92016-10-24 08:25:28 -0700529 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200530 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700531 packet.payload.Clear();
532 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200533 buffer->InsertPacket(std::move(packet), &mock_stats));
ossua73f6c92016-10-24 08:25:28 -0700534 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000535 // Buffer should still be empty. Test all empty-checks.
536 uint32_t temp_ts;
537 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->NextTimestamp(&temp_ts));
538 EXPECT_EQ(PacketBuffer::kBufferEmpty,
539 buffer->NextHigherTimestamp(0, &temp_ts));
ossu7a377612016-10-18 04:06:13 -0700540 EXPECT_EQ(NULL, buffer->PeekNextPacket());
ossua73f6c92016-10-24 08:25:28 -0700541 EXPECT_FALSE(buffer->GetNextPacket());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200542
minyue-webrtcfae474c2017-07-05 11:17:40 +0200543 // Discarding packets will not invoke mock_stats.PacketDiscarded() because the
544 // packet buffer is empty.
545 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket(&mock_stats));
546 buffer->DiscardAllOldPackets(0, &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000547
548 // Insert one packet to make the buffer non-empty.
Minyue Li3f2eeb82019-07-03 16:43:29 +0200549 EXPECT_EQ(
550 PacketBuffer::kOK,
551 buffer->InsertPacket(gen.NextPacket(payload_len, nullptr), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000552 EXPECT_EQ(PacketBuffer::kInvalidPointer, buffer->NextTimestamp(NULL));
553 EXPECT_EQ(PacketBuffer::kInvalidPointer,
554 buffer->NextHigherTimestamp(0, NULL));
555 delete buffer;
556
557 // Insert packet list of three packets, where the second packet has an invalid
558 // payload. Expect first packet to be inserted, and the remaining two to be
559 // discarded.
henrik.lundin84f8cd62016-04-26 07:45:16 -0700560 buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000561 PacketList list;
Minyue Li3f2eeb82019-07-03 16:43:29 +0200562 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
ossua73f6c92016-10-24 08:25:28 -0700563 {
Minyue Li3f2eeb82019-07-03 16:43:29 +0200564 Packet packet = gen.NextPacket(payload_len, nullptr);
ossua73f6c92016-10-24 08:25:28 -0700565 packet.payload.Clear(); // Invalid.
566 list.push_back(std::move(packet));
567 }
Minyue Li3f2eeb82019-07-03 16:43:29 +0200568 list.push_back(gen.NextPacket(payload_len, nullptr)); // Valid packet.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000569 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700570 auto factory = CreateBuiltinAudioDecoderFactory();
Niels Möller72899062019-01-11 09:36:13 +0100571 const DecoderDatabase::DecoderInfo info(SdpAudioFormat("pcmu", 8000, 1),
Danil Chapovalovb6021232018-06-19 13:26:36 +0200572 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700573 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
574 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200575 absl::optional<uint8_t> current_pt;
576 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000577 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200578 buffer->InsertPacketList(&list, decoder_database, &current_pt,
579 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000580 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700581 EXPECT_EQ(1u, buffer->NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000582 delete buffer;
583 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
584}
585
586// Test packet comparison function.
587// The function should return true if the first packet "goes before" the second.
588TEST(PacketBuffer, ComparePackets) {
589 PacketGenerator gen(0, 0, 0, 10);
Minyue Li3f2eeb82019-07-03 16:43:29 +0200590 Packet a(gen.NextPacket(10, nullptr)); // SN = 0, TS = 0.
591 Packet b(gen.NextPacket(10, nullptr)); // SN = 1, TS = 10.
ossua73f6c92016-10-24 08:25:28 -0700592 EXPECT_FALSE(a == b);
593 EXPECT_TRUE(a != b);
594 EXPECT_TRUE(a < b);
595 EXPECT_FALSE(a > b);
596 EXPECT_TRUE(a <= b);
597 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000598
599 // Testing wrap-around case; 'a' is earlier but has a larger timestamp value.
ossua73f6c92016-10-24 08:25:28 -0700600 a.timestamp = 0xFFFFFFFF - 10;
601 EXPECT_FALSE(a == b);
602 EXPECT_TRUE(a != b);
603 EXPECT_TRUE(a < b);
604 EXPECT_FALSE(a > b);
605 EXPECT_TRUE(a <= b);
606 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000607
608 // Test equal packets.
ossua73f6c92016-10-24 08:25:28 -0700609 EXPECT_TRUE(a == a);
610 EXPECT_FALSE(a != a);
611 EXPECT_FALSE(a < a);
612 EXPECT_FALSE(a > a);
613 EXPECT_TRUE(a <= a);
614 EXPECT_TRUE(a >= a);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000615
616 // Test equal timestamps but different sequence numbers (0 and 1).
ossua73f6c92016-10-24 08:25:28 -0700617 a.timestamp = b.timestamp;
618 EXPECT_FALSE(a == b);
619 EXPECT_TRUE(a != b);
620 EXPECT_TRUE(a < b);
621 EXPECT_FALSE(a > b);
622 EXPECT_TRUE(a <= b);
623 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000624
625 // Test equal timestamps but different sequence numbers (32767 and 1).
ossua73f6c92016-10-24 08:25:28 -0700626 a.sequence_number = 0xFFFF;
627 EXPECT_FALSE(a == b);
628 EXPECT_TRUE(a != b);
629 EXPECT_TRUE(a < b);
630 EXPECT_FALSE(a > b);
631 EXPECT_TRUE(a <= b);
632 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000633
ossua70695a2016-09-22 02:06:28 -0700634 // Test equal timestamps and sequence numbers, but differing priorities.
ossua73f6c92016-10-24 08:25:28 -0700635 a.sequence_number = b.sequence_number;
636 a.priority = {1, 0};
637 b.priority = {0, 0};
ossua70695a2016-09-22 02:06:28 -0700638 // a after b
ossua73f6c92016-10-24 08:25:28 -0700639 EXPECT_FALSE(a == b);
640 EXPECT_TRUE(a != b);
641 EXPECT_FALSE(a < b);
642 EXPECT_TRUE(a > b);
643 EXPECT_FALSE(a <= b);
644 EXPECT_TRUE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000645
Minyue Li3f2eeb82019-07-03 16:43:29 +0200646 Packet c(gen.NextPacket(0, nullptr)); // SN = 2, TS = 20.
647 Packet d(gen.NextPacket(0, nullptr)); // SN = 3, TS = 20.
ossua73f6c92016-10-24 08:25:28 -0700648 c.timestamp = b.timestamp;
649 d.timestamp = b.timestamp;
650 c.sequence_number = b.sequence_number;
651 d.sequence_number = b.sequence_number;
652 c.priority = {1, 1};
653 d.priority = {0, 1};
ossua70695a2016-09-22 02:06:28 -0700654 // c after d
ossua73f6c92016-10-24 08:25:28 -0700655 EXPECT_FALSE(c == d);
656 EXPECT_TRUE(c != d);
657 EXPECT_FALSE(c < d);
658 EXPECT_TRUE(c > d);
659 EXPECT_FALSE(c <= d);
660 EXPECT_TRUE(c >= d);
ossua70695a2016-09-22 02:06:28 -0700661
662 // c after a
ossua73f6c92016-10-24 08:25:28 -0700663 EXPECT_FALSE(c == a);
664 EXPECT_TRUE(c != a);
665 EXPECT_FALSE(c < a);
666 EXPECT_TRUE(c > a);
667 EXPECT_FALSE(c <= a);
668 EXPECT_TRUE(c >= a);
ossua70695a2016-09-22 02:06:28 -0700669
670 // c after b
ossua73f6c92016-10-24 08:25:28 -0700671 EXPECT_FALSE(c == b);
672 EXPECT_TRUE(c != b);
673 EXPECT_FALSE(c < b);
674 EXPECT_TRUE(c > b);
675 EXPECT_FALSE(c <= b);
676 EXPECT_TRUE(c >= b);
ossua70695a2016-09-22 02:06:28 -0700677
678 // a after d
ossua73f6c92016-10-24 08:25:28 -0700679 EXPECT_FALSE(a == d);
680 EXPECT_TRUE(a != d);
681 EXPECT_FALSE(a < d);
682 EXPECT_TRUE(a > d);
683 EXPECT_FALSE(a <= d);
684 EXPECT_TRUE(a >= d);
ossua70695a2016-09-22 02:06:28 -0700685
686 // d after b
ossua73f6c92016-10-24 08:25:28 -0700687 EXPECT_FALSE(d == b);
688 EXPECT_TRUE(d != b);
689 EXPECT_FALSE(d < b);
690 EXPECT_TRUE(d > b);
691 EXPECT_FALSE(d <= b);
692 EXPECT_TRUE(d >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000693}
694
Minyue Li3f2eeb82019-07-03 16:43:29 +0200695TEST(PacketBuffer, GetSpanSamples) {
696 constexpr size_t kFrameSizeSamples = 10;
697 constexpr int kPayloadSizeBytes = 1; // Does not matter to this test;
698 constexpr uint32_t kStartTimeStamp = 0xFFFFFFFE; // Close to wrap around.
699 constexpr int kSampleRateHz = 48000;
700 constexpr bool KCountDtxWaitingTime = false;
701 TickTimer tick_timer;
702 PacketBuffer buffer(3, &tick_timer);
703 PacketGenerator gen(0, kStartTimeStamp, 0, kFrameSizeSamples);
704 StrictMock<MockStatisticsCalculator> mock_stats;
705
706 Packet packet_1 = gen.NextPacket(kPayloadSizeBytes, nullptr);
707
708 std::unique_ptr<MockEncodedAudioFrame> mock_audio_frame =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200709 std::make_unique<MockEncodedAudioFrame>();
Minyue Li3f2eeb82019-07-03 16:43:29 +0200710 EXPECT_CALL(*mock_audio_frame, Duration())
711 .WillRepeatedly(Return(kFrameSizeSamples));
712 Packet packet_2 =
713 gen.NextPacket(kPayloadSizeBytes, std::move(mock_audio_frame));
714
715 RTC_DCHECK_GT(packet_1.timestamp,
716 packet_2.timestamp); // Tmestamp wrapped around.
717
718 EXPECT_EQ(PacketBuffer::kOK,
719 buffer.InsertPacket(std::move(packet_1), &mock_stats));
720
721 constexpr size_t kLastDecodedSizeSamples = 2;
722 // packet_1 has no access to duration, and relies last decoded duration as
723 // input.
724 EXPECT_EQ(kLastDecodedSizeSamples,
725 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
726 KCountDtxWaitingTime));
727
728 EXPECT_EQ(PacketBuffer::kOK,
729 buffer.InsertPacket(std::move(packet_2), &mock_stats));
730
731 EXPECT_EQ(kFrameSizeSamples * 2,
732 buffer.GetSpanSamples(0, kSampleRateHz, KCountDtxWaitingTime));
733
734 // packet_2 has access to duration, and ignores last decoded duration as
735 // input.
736 EXPECT_EQ(kFrameSizeSamples * 2,
737 buffer.GetSpanSamples(kLastDecodedSizeSamples, kSampleRateHz,
738 KCountDtxWaitingTime));
739}
740
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000741namespace {
742void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
743 // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
744 // half the timestamp range.
745 static const uint32_t kZeroHorizon = 0;
746 static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
747 // Timestamp on the limit is not old.
748 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
749 limit_timestamp, limit_timestamp, kZeroHorizon));
750 // 1 sample behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200751 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
752 limit_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000753 // 2^31 - 1 samples behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200754 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - k2Pow31Minus1,
755 limit_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000756 // 1 sample ahead is not old.
757 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
758 limit_timestamp + 1, limit_timestamp, kZeroHorizon));
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200759 // If |t1-t2|=2^31 and t1>t2, t2 is older than t1 but not the opposite.
760 uint32_t other_timestamp = limit_timestamp + (1 << 31);
761 uint32_t lowest_timestamp = std::min(limit_timestamp, other_timestamp);
762 uint32_t highest_timestamp = std::max(limit_timestamp, other_timestamp);
763 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
764 lowest_timestamp, highest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000765 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200766 highest_timestamp, lowest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000767
768 // Fixed horizon at 10 samples.
769 static const uint32_t kHorizon = 10;
770 // Timestamp on the limit is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200771 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp,
772 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000773 // 1 sample behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200774 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 1,
775 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000776 // 9 samples behind is old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200777 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 9,
778 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000779 // 10 samples behind is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200780 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp - 10,
781 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000782 // 2^31 - 1 samples behind is not old.
783 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
784 limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
785 // 1 sample ahead is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200786 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + 1,
787 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000788 // 2^31 samples ahead is not old.
Jonas Olssona4d87372019-07-05 19:08:33 +0200789 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(limit_timestamp + (1 << 31),
790 limit_timestamp, kHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000791}
792} // namespace
793
794// Test the IsObsoleteTimestamp method with different limit timestamps.
795TEST(PacketBuffer, IsObsoleteTimestamp) {
796 TestIsObsoleteTimestamp(0);
797 TestIsObsoleteTimestamp(1);
798 TestIsObsoleteTimestamp(0xFFFFFFFF); // -1 in uint32_t.
799 TestIsObsoleteTimestamp(0x80000000); // 2^31.
800 TestIsObsoleteTimestamp(0x80000001); // 2^31 + 1.
801 TestIsObsoleteTimestamp(0x7FFFFFFF); // 2^31 - 1.
802}
Minyue Li3f2eeb82019-07-03 16:43:29 +0200803
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000804} // namespace webrtc