blob: cb40d7da32dc232c2216a5815e4c1f8fa55d05ac [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"
14#include "api/audio_codecs/builtin_audio_decoder_factory.h"
15#include "modules/audio_coding/neteq/mock/mock_decoder_database.h"
16#include "modules/audio_coding/neteq/mock/mock_statistics_calculator.h"
17#include "modules/audio_coding/neteq/packet.h"
18#include "modules/audio_coding/neteq/tick_timer.h"
19#include "test/gmock.h"
20#include "test/gtest.h"
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000021
22using ::testing::Return;
minyue-webrtcfae474c2017-07-05 11:17:40 +020023using ::testing::StrictMock;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000024using ::testing::_;
henrik.lundin63d146b2017-07-05 07:03:34 -070025using ::testing::InSequence;
26using ::testing::MockFunction;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000027
28namespace webrtc {
29
30// Helper class to generate packets. Packets must be deleted by the user.
31class PacketGenerator {
32 public:
33 PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
34 virtual ~PacketGenerator() {}
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000035 void Reset(uint16_t seq_no, uint32_t ts, uint8_t pt, int frame_size);
ossua73f6c92016-10-24 08:25:28 -070036 Packet NextPacket(int payload_size_bytes);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000037
38 uint16_t seq_no_;
39 uint32_t ts_;
40 uint8_t pt_;
41 int frame_size_;
42};
43
44PacketGenerator::PacketGenerator(uint16_t seq_no, uint32_t ts, uint8_t pt,
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000045 int frame_size) {
46 Reset(seq_no, ts, pt, frame_size);
47}
48
49void PacketGenerator::Reset(uint16_t seq_no, uint32_t ts, uint8_t pt,
50 int frame_size) {
51 seq_no_ = seq_no;
52 ts_ = ts;
53 pt_ = pt;
54 frame_size_ = frame_size;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000055}
56
ossua73f6c92016-10-24 08:25:28 -070057Packet PacketGenerator::NextPacket(int payload_size_bytes) {
58 Packet packet;
59 packet.sequence_number = seq_no_;
60 packet.timestamp = ts_;
61 packet.payload_type = pt_;
62 packet.payload.SetSize(payload_size_bytes);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000063 ++seq_no_;
64 ts_ += frame_size_;
65 return packet;
66}
67
minyue@webrtc.orgc8039072014-10-09 10:49:54 +000068struct PacketsToInsert {
69 uint16_t sequence_number;
70 uint32_t timestamp;
71 uint8_t payload_type;
72 bool primary;
73 // Order of this packet to appear upon extraction, after inserting a series
74 // of packets. A negative number means that it should have been discarded
75 // before extraction.
76 int extract_order;
77};
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000078
79// Start of test definitions.
80
81TEST(PacketBuffer, CreateAndDestroy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -070082 TickTimer tick_timer;
83 PacketBuffer* buffer = new PacketBuffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000084 EXPECT_TRUE(buffer->Empty());
85 delete buffer;
86}
87
88TEST(PacketBuffer, InsertPacket) {
henrik.lundin84f8cd62016-04-26 07:45:16 -070089 TickTimer tick_timer;
90 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000091 PacketGenerator gen(17u, 4711u, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +020092 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000093
94 const int payload_len = 100;
ossua73f6c92016-10-24 08:25:28 -070095 const Packet packet = gen.NextPacket(payload_len);
minyue-webrtc12d30842017-07-19 11:44:06 +020096 EXPECT_EQ(0, buffer.InsertPacket(packet.Clone(), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +000097 uint32_t next_ts;
98 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
99 EXPECT_EQ(4711u, next_ts);
100 EXPECT_FALSE(buffer.Empty());
Peter Kastingdce40cf2015-08-24 14:52:23 -0700101 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700102 const Packet* next_packet = buffer.PeekNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700103 EXPECT_EQ(packet, *next_packet); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000104
105 // Do not explicitly flush buffer or delete packet to test that it is deleted
106 // with the buffer. (Tested with Valgrind or similar tool.)
107}
108
109// Test to flush buffer.
110TEST(PacketBuffer, FlushBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700111 TickTimer tick_timer;
112 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000113 PacketGenerator gen(0, 0, 0, 10);
114 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200115 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000116
117 // Insert 10 small packets; should be ok.
118 for (int i = 0; i < 10; ++i) {
ossua73f6c92016-10-24 08:25:28 -0700119 EXPECT_EQ(PacketBuffer::kOK,
minyue-webrtc12d30842017-07-19 11:44:06 +0200120 buffer.InsertPacket(gen.NextPacket(payload_len), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000121 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700122 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000123 EXPECT_FALSE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000124
125 buffer.Flush();
126 // Buffer should delete the payloads itself.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700127 EXPECT_EQ(0u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000128 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000129}
130
131// Test to fill the buffer over the limits, and verify that it flushes.
132TEST(PacketBuffer, OverfillBuffer) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700133 TickTimer tick_timer;
134 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000135 PacketGenerator gen(0, 0, 0, 10);
minyue-webrtc12d30842017-07-19 11:44:06 +0200136 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000137
138 // Insert 10 small packets; should be ok.
139 const int payload_len = 10;
140 int i;
141 for (i = 0; i < 10; ++i) {
ossua73f6c92016-10-24 08:25:28 -0700142 EXPECT_EQ(PacketBuffer::kOK,
minyue-webrtc12d30842017-07-19 11:44:06 +0200143 buffer.InsertPacket(gen.NextPacket(payload_len), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000144 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700145 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000146 uint32_t next_ts;
147 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
148 EXPECT_EQ(0u, next_ts); // Expect first inserted packet to be first in line.
149
ossua73f6c92016-10-24 08:25:28 -0700150 const Packet packet = gen.NextPacket(payload_len);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000151 // Insert 11th packet; should flush the buffer and insert it after flushing.
minyue-webrtc12d30842017-07-19 11:44:06 +0200152 EXPECT_EQ(PacketBuffer::kFlushed,
153 buffer.InsertPacket(packet.Clone(), &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700154 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000155 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&next_ts));
156 // Expect last inserted packet to be first in line.
ossua73f6c92016-10-24 08:25:28 -0700157 EXPECT_EQ(packet.timestamp, next_ts);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000158
henrik.lundin@webrtc.org116ed1d2014-04-28 08:20:04 +0000159 // Flush buffer to delete all packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000160 buffer.Flush();
161}
162
163// Test inserting a list of packets.
164TEST(PacketBuffer, InsertPacketList) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700165 TickTimer tick_timer;
166 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000167 PacketGenerator gen(0, 0, 0, 10);
168 PacketList list;
169 const int payload_len = 10;
170
171 // Insert 10 small packets.
172 for (int i = 0; i < 10; ++i) {
ossua73f6c92016-10-24 08:25:28 -0700173 list.push_back(gen.NextPacket(payload_len));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000174 }
175
176 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700177 auto factory = CreateBuiltinAudioDecoderFactory();
Karl Wiberg08126342018-03-20 19:18:55 +0100178 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200179 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700180 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
181 .WillRepeatedly(Return(&info));
minyue-webrtc12d30842017-07-19 11:44:06 +0200182
183 StrictMock<MockStatisticsCalculator> mock_stats;
184
Danil Chapovalovb6021232018-06-19 13:26:36 +0200185 absl::optional<uint8_t> current_pt;
186 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200187 EXPECT_EQ(PacketBuffer::kOK,
188 buffer.InsertPacketList(&list, decoder_database, &current_pt,
189 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000190 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700191 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100192 EXPECT_EQ(0, current_pt); // Current payload type changed to 0.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200193 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000194
195 buffer.Flush(); // Clean up.
196
197 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
198}
199
200// Test inserting a list of packets. Last packet is of a different payload type.
201// Expecting the buffer to flush.
202// TODO(hlundin): Remove this test when legacy operation is no longer needed.
203TEST(PacketBuffer, InsertPacketListChangePayloadType) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700204 TickTimer tick_timer;
205 PacketBuffer buffer(10, &tick_timer); // 10 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000206 PacketGenerator gen(0, 0, 0, 10);
207 PacketList list;
208 const int payload_len = 10;
209
210 // Insert 10 small packets.
211 for (int i = 0; i < 10; ++i) {
ossua73f6c92016-10-24 08:25:28 -0700212 list.push_back(gen.NextPacket(payload_len));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000213 }
214 // Insert 11th packet of another payload type (not CNG).
ossua73f6c92016-10-24 08:25:28 -0700215 {
216 Packet packet = gen.NextPacket(payload_len);
217 packet.payload_type = 1;
218 list.push_back(std::move(packet));
219 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000220
221 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700222 auto factory = CreateBuiltinAudioDecoderFactory();
Karl Wiberg08126342018-03-20 19:18:55 +0100223 const DecoderDatabase::DecoderInfo info0(NetEqDecoder::kDecoderPCMu,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200224 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700225 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
226 .WillRepeatedly(Return(&info0));
Karl Wiberg08126342018-03-20 19:18:55 +0100227 const DecoderDatabase::DecoderInfo info1(NetEqDecoder::kDecoderPCMa,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200228 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700229 EXPECT_CALL(decoder_database, GetDecoderInfo(1))
230 .WillRepeatedly(Return(&info1));
minyue-webrtc12d30842017-07-19 11:44:06 +0200231
232 StrictMock<MockStatisticsCalculator> mock_stats;
233
Danil Chapovalovb6021232018-06-19 13:26:36 +0200234 absl::optional<uint8_t> current_pt;
235 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200236 EXPECT_EQ(PacketBuffer::kFlushed,
237 buffer.InsertPacketList(&list, decoder_database, &current_pt,
238 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000239 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700240 EXPECT_EQ(1u, buffer.NumPacketsInBuffer()); // Only the last packet.
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100241 EXPECT_EQ(1, current_pt); // Current payload type changed to 1.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200242 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type not changed.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000243
244 buffer.Flush(); // Clean up.
245
246 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
247}
248
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000249TEST(PacketBuffer, ExtractOrderRedundancy) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700250 TickTimer tick_timer;
251 PacketBuffer buffer(100, &tick_timer); // 100 packets.
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000252 const int kPackets = 18;
253 const int kFrameSize = 10;
254 const int kPayloadLength = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000255
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000256 PacketsToInsert packet_facts[kPackets] = {
257 {0xFFFD, 0xFFFFFFD7, 0, true, 0},
258 {0xFFFE, 0xFFFFFFE1, 0, true, 1},
259 {0xFFFE, 0xFFFFFFD7, 1, false, -1},
260 {0xFFFF, 0xFFFFFFEB, 0, true, 2},
261 {0xFFFF, 0xFFFFFFE1, 1, false, -1},
262 {0x0000, 0xFFFFFFF5, 0, true, 3},
263 {0x0000, 0xFFFFFFEB, 1, false, -1},
264 {0x0001, 0xFFFFFFFF, 0, true, 4},
265 {0x0001, 0xFFFFFFF5, 1, false, -1},
266 {0x0002, 0x0000000A, 0, true, 5},
267 {0x0002, 0xFFFFFFFF, 1, false, -1},
268 {0x0003, 0x0000000A, 1, false, -1},
269 {0x0004, 0x0000001E, 0, true, 7},
270 {0x0004, 0x00000014, 1, false, 6},
271 {0x0005, 0x0000001E, 0, true, -1},
272 {0x0005, 0x00000014, 1, false, -1},
273 {0x0006, 0x00000028, 0, true, 8},
274 {0x0006, 0x0000001E, 1, false, -1},
275 };
276
Peter Kastingdce40cf2015-08-24 14:52:23 -0700277 const size_t kExpectPacketsInBuffer = 9;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000278
ossua73f6c92016-10-24 08:25:28 -0700279 std::vector<Packet> expect_order(kExpectPacketsInBuffer);
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000280
281 PacketGenerator gen(0, 0, 0, kFrameSize);
282
minyue-webrtc12d30842017-07-19 11:44:06 +0200283 StrictMock<MockStatisticsCalculator> mock_stats;
284
285 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
286 // check ensures that exactly one call to PacketsDiscarded happens in each
287 // DiscardNextPacket call.
288 InSequence s;
289 MockFunction<void(int check_point_id)> check;
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000290 for (int i = 0; i < kPackets; ++i) {
291 gen.Reset(packet_facts[i].sequence_number,
292 packet_facts[i].timestamp,
293 packet_facts[i].payload_type,
294 kFrameSize);
ossua73f6c92016-10-24 08:25:28 -0700295 Packet packet = gen.NextPacket(kPayloadLength);
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200296 packet.priority.codec_level = packet_facts[i].primary ? 0 : 1;
minyue-webrtc12d30842017-07-19 11:44:06 +0200297 if (packet_facts[i].extract_order < 0) {
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200298 if (packet.priority.codec_level > 0) {
299 EXPECT_CALL(mock_stats, SecondaryPacketsDiscarded(1));
300 } else {
301 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
302 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200303 }
304 EXPECT_CALL(check, Call(i));
305 EXPECT_EQ(PacketBuffer::kOK,
306 buffer.InsertPacket(packet.Clone(), &mock_stats));
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000307 if (packet_facts[i].extract_order >= 0) {
ossua73f6c92016-10-24 08:25:28 -0700308 expect_order[packet_facts[i].extract_order] = std::move(packet);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000309 }
minyue-webrtc12d30842017-07-19 11:44:06 +0200310 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000311 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000312
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000313 EXPECT_EQ(kExpectPacketsInBuffer, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000314
Peter Kastingdce40cf2015-08-24 14:52:23 -0700315 for (size_t i = 0; i < kExpectPacketsInBuffer; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200316 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700317 EXPECT_EQ(packet, expect_order[i]); // Compare contents.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000318 }
minyue@webrtc.orgc8039072014-10-09 10:49:54 +0000319 EXPECT_TRUE(buffer.Empty());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000320}
321
322TEST(PacketBuffer, DiscardPackets) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700323 TickTimer tick_timer;
324 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000325 const uint16_t start_seq_no = 17;
326 const uint32_t start_ts = 4711;
327 const uint32_t ts_increment = 10;
328 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
329 PacketList list;
330 const int payload_len = 10;
minyue-webrtc12d30842017-07-19 11:44:06 +0200331 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000332
minyue-webrtcfae474c2017-07-05 11:17:40 +0200333 constexpr int kTotalPackets = 10;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000334 // Insert 10 small packets.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200335 for (int i = 0; i < kTotalPackets; ++i) {
minyue-webrtc12d30842017-07-19 11:44:06 +0200336 buffer.InsertPacket(gen.NextPacket(payload_len), &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000337 }
Peter Kastingdce40cf2015-08-24 14:52:23 -0700338 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000339
minyue-webrtcfae474c2017-07-05 11:17:40 +0200340 uint32_t current_ts = start_ts;
341
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000342 // Discard them one by one and make sure that the right packets are at the
343 // front of the buffer.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200344 constexpr int kDiscardPackets = 5;
henrik.lundin63d146b2017-07-05 07:03:34 -0700345
346 // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
347 // check ensures that exactly one call to PacketsDiscarded happens in each
348 // DiscardNextPacket call.
349 InSequence s;
350 MockFunction<void(int check_point_id)> check;
minyue-webrtcfae474c2017-07-05 11:17:40 +0200351 for (int i = 0; i < kDiscardPackets; ++i) {
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000352 uint32_t ts;
353 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
354 EXPECT_EQ(current_ts, ts);
henrik.lundin63d146b2017-07-05 07:03:34 -0700355 EXPECT_CALL(mock_stats, PacketsDiscarded(1));
356 EXPECT_CALL(check, Call(i));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200357 EXPECT_EQ(PacketBuffer::kOK, buffer.DiscardNextPacket(&mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000358 current_ts += ts_increment;
henrik.lundin63d146b2017-07-05 07:03:34 -0700359 check.Call(i);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000360 }
minyue-webrtcfae474c2017-07-05 11:17:40 +0200361
362 constexpr int kRemainingPackets = kTotalPackets - kDiscardPackets;
henrik.lundin63d146b2017-07-05 07:03:34 -0700363 // This will discard all remaining packets but one. The oldest packet is older
364 // than the indicated horizon_samples, and will thus be left in the buffer.
365 constexpr size_t kSkipPackets = 1;
minyue-webrtc0c3ca752017-08-23 15:59:38 +0200366 EXPECT_CALL(mock_stats, PacketsDiscarded(1))
367 .Times(kRemainingPackets - kSkipPackets);
henrik.lundin63d146b2017-07-05 07:03:34 -0700368 EXPECT_CALL(check, Call(17)); // Arbitrary id number.
minyue-webrtcfae474c2017-07-05 11:17:40 +0200369 buffer.DiscardOldPackets(start_ts + kTotalPackets * ts_increment,
370 kRemainingPackets * ts_increment, &mock_stats);
henrik.lundin63d146b2017-07-05 07:03:34 -0700371 check.Call(17); // Same arbitrary id number.
372
373 EXPECT_EQ(kSkipPackets, buffer.NumPacketsInBuffer());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200374 uint32_t ts;
375 EXPECT_EQ(PacketBuffer::kOK, buffer.NextTimestamp(&ts));
376 EXPECT_EQ(current_ts, ts);
377
378 // Discard all remaining packets.
henrik.lundin63d146b2017-07-05 07:03:34 -0700379 EXPECT_CALL(mock_stats, PacketsDiscarded(kSkipPackets));
minyue-webrtcfae474c2017-07-05 11:17:40 +0200380 buffer.DiscardAllOldPackets(start_ts + kTotalPackets * ts_increment,
381 &mock_stats);
382
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000383 EXPECT_TRUE(buffer.Empty());
384}
385
386TEST(PacketBuffer, Reordering) {
henrik.lundin84f8cd62016-04-26 07:45:16 -0700387 TickTimer tick_timer;
388 PacketBuffer buffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000389 const uint16_t start_seq_no = 17;
390 const uint32_t start_ts = 4711;
391 const uint32_t ts_increment = 10;
392 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
393 const int payload_len = 10;
394
395 // Generate 10 small packets and insert them into a PacketList. Insert every
396 // odd packet to the front, and every even packet to the back, thus creating
397 // a (rather strange) reordering.
398 PacketList list;
399 for (int i = 0; i < 10; ++i) {
ossua73f6c92016-10-24 08:25:28 -0700400 Packet packet = gen.NextPacket(payload_len);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000401 if (i % 2) {
ossua73f6c92016-10-24 08:25:28 -0700402 list.push_front(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000403 } else {
ossua73f6c92016-10-24 08:25:28 -0700404 list.push_back(std::move(packet));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000405 }
406 }
407
408 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700409 auto factory = CreateBuiltinAudioDecoderFactory();
Karl Wiberg08126342018-03-20 19:18:55 +0100410 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200411 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700412 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
413 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200414 absl::optional<uint8_t> current_pt;
415 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000416
minyue-webrtc12d30842017-07-19 11:44:06 +0200417 StrictMock<MockStatisticsCalculator> mock_stats;
418
419 EXPECT_EQ(PacketBuffer::kOK,
420 buffer.InsertPacketList(&list, decoder_database, &current_pt,
421 &current_cng_pt, &mock_stats));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700422 EXPECT_EQ(10u, buffer.NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000423
424 // Extract them and make sure that come out in the right order.
425 uint32_t current_ts = start_ts;
426 for (int i = 0; i < 10; ++i) {
Danil Chapovalovb6021232018-06-19 13:26:36 +0200427 const absl::optional<Packet> packet = buffer.GetNextPacket();
ossua73f6c92016-10-24 08:25:28 -0700428 ASSERT_TRUE(packet);
ossu7a377612016-10-18 04:06:13 -0700429 EXPECT_EQ(current_ts, packet->timestamp);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000430 current_ts += ts_increment;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000431 }
432 EXPECT_TRUE(buffer.Empty());
433
434 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
435}
436
henrik.lundin067d8552016-09-01 23:19:05 -0700437// The test first inserts a packet with narrow-band CNG, then a packet with
438// wide-band speech. The expected behavior of the packet buffer is to detect a
439// change in sample rate, even though no speech packet has been inserted before,
440// and flush out the CNG packet.
441TEST(PacketBuffer, CngFirstThenSpeechWithNewSampleRate) {
442 TickTimer tick_timer;
443 PacketBuffer buffer(10, &tick_timer); // 10 packets.
444 const uint8_t kCngPt = 13;
445 const int kPayloadLen = 10;
446 const uint8_t kSpeechPt = 100;
447
448 MockDecoderDatabase decoder_database;
449 auto factory = CreateBuiltinAudioDecoderFactory();
ossuf1b08da2016-09-23 02:19:43 -0700450 const DecoderDatabase::DecoderInfo info_cng(NetEqDecoder::kDecoderCNGnb,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200451 absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700452 EXPECT_CALL(decoder_database, GetDecoderInfo(kCngPt))
453 .WillRepeatedly(Return(&info_cng));
454 const DecoderDatabase::DecoderInfo info_speech(NetEqDecoder::kDecoderPCM16Bwb,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200455 absl::nullopt, factory);
henrik.lundin067d8552016-09-01 23:19:05 -0700456 EXPECT_CALL(decoder_database, GetDecoderInfo(kSpeechPt))
457 .WillRepeatedly(Return(&info_speech));
458
459 // Insert first packet, which is narrow-band CNG.
460 PacketGenerator gen(0, 0, kCngPt, 10);
461 PacketList list;
462 list.push_back(gen.NextPacket(kPayloadLen));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200463 absl::optional<uint8_t> current_pt;
464 absl::optional<uint8_t> current_cng_pt;
minyue-webrtc12d30842017-07-19 11:44:06 +0200465
466 StrictMock<MockStatisticsCalculator> mock_stats;
467
henrik.lundin067d8552016-09-01 23:19:05 -0700468 EXPECT_EQ(PacketBuffer::kOK,
469 buffer.InsertPacketList(&list, decoder_database, &current_pt,
minyue-webrtc12d30842017-07-19 11:44:06 +0200470 &current_cng_pt, &mock_stats));
henrik.lundin067d8552016-09-01 23:19:05 -0700471 EXPECT_TRUE(list.empty());
472 EXPECT_EQ(1u, buffer.NumPacketsInBuffer());
ossu7a377612016-10-18 04:06:13 -0700473 ASSERT_TRUE(buffer.PeekNextPacket());
474 EXPECT_EQ(kCngPt, buffer.PeekNextPacket()->payload_type);
Danil Chapovalovb6021232018-06-19 13:26:36 +0200475 EXPECT_EQ(current_pt, absl::nullopt); // Current payload type not set.
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100476 EXPECT_EQ(kCngPt, current_cng_pt); // CNG payload type set.
henrik.lundin067d8552016-09-01 23:19:05 -0700477
478 // Insert second packet, which is wide-band speech.
ossua73f6c92016-10-24 08:25:28 -0700479 {
480 Packet packet = gen.NextPacket(kPayloadLen);
481 packet.payload_type = kSpeechPt;
482 list.push_back(std::move(packet));
483 }
henrik.lundin067d8552016-09-01 23:19:05 -0700484 // Expect the buffer to flush out the CNG packet, since it does not match the
485 // new speech sample rate.
486 EXPECT_EQ(PacketBuffer::kFlushed,
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(kSpeechPt, buffer.PeekNextPacket()->payload_type);
henrik.lundin067d8552016-09-01 23:19:05 -0700493
Oskar Sundbom12ab00b2017-11-16 15:31:38 +0100494 EXPECT_EQ(kSpeechPt, current_pt); // Current payload type set.
Danil Chapovalovb6021232018-06-19 13:26:36 +0200495 EXPECT_EQ(absl::nullopt, current_cng_pt); // CNG payload type reset.
henrik.lundin067d8552016-09-01 23:19:05 -0700496
497 buffer.Flush(); // Clean up.
498 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
499}
500
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000501TEST(PacketBuffer, Failures) {
502 const uint16_t start_seq_no = 17;
503 const uint32_t start_ts = 4711;
504 const uint32_t ts_increment = 10;
505 int payload_len = 100;
506 PacketGenerator gen(start_seq_no, start_ts, 0, ts_increment);
henrik.lundin84f8cd62016-04-26 07:45:16 -0700507 TickTimer tick_timer;
minyue-webrtc12d30842017-07-19 11:44:06 +0200508 StrictMock<MockStatisticsCalculator> mock_stats;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000509
henrik.lundin84f8cd62016-04-26 07:45:16 -0700510 PacketBuffer* buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
ossua73f6c92016-10-24 08:25:28 -0700511 {
512 Packet packet = gen.NextPacket(payload_len);
513 packet.payload.Clear();
514 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200515 buffer->InsertPacket(std::move(packet), &mock_stats));
ossua73f6c92016-10-24 08:25:28 -0700516 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000517 // Buffer should still be empty. Test all empty-checks.
518 uint32_t temp_ts;
519 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->NextTimestamp(&temp_ts));
520 EXPECT_EQ(PacketBuffer::kBufferEmpty,
521 buffer->NextHigherTimestamp(0, &temp_ts));
ossu7a377612016-10-18 04:06:13 -0700522 EXPECT_EQ(NULL, buffer->PeekNextPacket());
ossua73f6c92016-10-24 08:25:28 -0700523 EXPECT_FALSE(buffer->GetNextPacket());
minyue-webrtcfae474c2017-07-05 11:17:40 +0200524
minyue-webrtcfae474c2017-07-05 11:17:40 +0200525 // Discarding packets will not invoke mock_stats.PacketDiscarded() because the
526 // packet buffer is empty.
527 EXPECT_EQ(PacketBuffer::kBufferEmpty, buffer->DiscardNextPacket(&mock_stats));
528 buffer->DiscardAllOldPackets(0, &mock_stats);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000529
530 // Insert one packet to make the buffer non-empty.
ossua73f6c92016-10-24 08:25:28 -0700531 EXPECT_EQ(PacketBuffer::kOK,
minyue-webrtc12d30842017-07-19 11:44:06 +0200532 buffer->InsertPacket(gen.NextPacket(payload_len), &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000533 EXPECT_EQ(PacketBuffer::kInvalidPointer, buffer->NextTimestamp(NULL));
534 EXPECT_EQ(PacketBuffer::kInvalidPointer,
535 buffer->NextHigherTimestamp(0, NULL));
536 delete buffer;
537
538 // Insert packet list of three packets, where the second packet has an invalid
539 // payload. Expect first packet to be inserted, and the remaining two to be
540 // discarded.
henrik.lundin84f8cd62016-04-26 07:45:16 -0700541 buffer = new PacketBuffer(100, &tick_timer); // 100 packets.
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000542 PacketList list;
543 list.push_back(gen.NextPacket(payload_len)); // Valid packet.
ossua73f6c92016-10-24 08:25:28 -0700544 {
545 Packet packet = gen.NextPacket(payload_len);
546 packet.payload.Clear(); // Invalid.
547 list.push_back(std::move(packet));
548 }
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000549 list.push_back(gen.NextPacket(payload_len)); // Valid packet.
550 MockDecoderDatabase decoder_database;
henrik.lundinebd9fd72016-08-31 13:03:36 -0700551 auto factory = CreateBuiltinAudioDecoderFactory();
Karl Wiberg08126342018-03-20 19:18:55 +0100552 const DecoderDatabase::DecoderInfo info(NetEqDecoder::kDecoderPCMu,
Danil Chapovalovb6021232018-06-19 13:26:36 +0200553 absl::nullopt, factory);
henrik.lundinebd9fd72016-08-31 13:03:36 -0700554 EXPECT_CALL(decoder_database, GetDecoderInfo(0))
555 .WillRepeatedly(Return(&info));
Danil Chapovalovb6021232018-06-19 13:26:36 +0200556 absl::optional<uint8_t> current_pt;
557 absl::optional<uint8_t> current_cng_pt;
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000558 EXPECT_EQ(PacketBuffer::kInvalidPacket,
minyue-webrtc12d30842017-07-19 11:44:06 +0200559 buffer->InsertPacketList(&list, decoder_database, &current_pt,
560 &current_cng_pt, &mock_stats));
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000561 EXPECT_TRUE(list.empty()); // The PacketBuffer should have depleted the list.
Peter Kastingdce40cf2015-08-24 14:52:23 -0700562 EXPECT_EQ(1u, buffer->NumPacketsInBuffer());
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000563 delete buffer;
564 EXPECT_CALL(decoder_database, Die()); // Called when object is deleted.
565}
566
567// Test packet comparison function.
568// The function should return true if the first packet "goes before" the second.
569TEST(PacketBuffer, ComparePackets) {
570 PacketGenerator gen(0, 0, 0, 10);
ossua73f6c92016-10-24 08:25:28 -0700571 Packet a(gen.NextPacket(10)); // SN = 0, TS = 0.
572 Packet b(gen.NextPacket(10)); // SN = 1, TS = 10.
573 EXPECT_FALSE(a == b);
574 EXPECT_TRUE(a != b);
575 EXPECT_TRUE(a < b);
576 EXPECT_FALSE(a > b);
577 EXPECT_TRUE(a <= b);
578 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000579
580 // Testing wrap-around case; 'a' is earlier but has a larger timestamp value.
ossua73f6c92016-10-24 08:25:28 -0700581 a.timestamp = 0xFFFFFFFF - 10;
582 EXPECT_FALSE(a == b);
583 EXPECT_TRUE(a != b);
584 EXPECT_TRUE(a < b);
585 EXPECT_FALSE(a > b);
586 EXPECT_TRUE(a <= b);
587 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000588
589 // Test equal packets.
ossua73f6c92016-10-24 08:25:28 -0700590 EXPECT_TRUE(a == a);
591 EXPECT_FALSE(a != a);
592 EXPECT_FALSE(a < a);
593 EXPECT_FALSE(a > a);
594 EXPECT_TRUE(a <= a);
595 EXPECT_TRUE(a >= a);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000596
597 // Test equal timestamps but different sequence numbers (0 and 1).
ossua73f6c92016-10-24 08:25:28 -0700598 a.timestamp = b.timestamp;
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 timestamps but different sequence numbers (32767 and 1).
ossua73f6c92016-10-24 08:25:28 -0700607 a.sequence_number = 0xFFFF;
608 EXPECT_FALSE(a == b);
609 EXPECT_TRUE(a != b);
610 EXPECT_TRUE(a < b);
611 EXPECT_FALSE(a > b);
612 EXPECT_TRUE(a <= b);
613 EXPECT_FALSE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000614
ossua70695a2016-09-22 02:06:28 -0700615 // Test equal timestamps and sequence numbers, but differing priorities.
ossua73f6c92016-10-24 08:25:28 -0700616 a.sequence_number = b.sequence_number;
617 a.priority = {1, 0};
618 b.priority = {0, 0};
ossua70695a2016-09-22 02:06:28 -0700619 // a after b
ossua73f6c92016-10-24 08:25:28 -0700620 EXPECT_FALSE(a == b);
621 EXPECT_TRUE(a != b);
622 EXPECT_FALSE(a < b);
623 EXPECT_TRUE(a > b);
624 EXPECT_FALSE(a <= b);
625 EXPECT_TRUE(a >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000626
ossua73f6c92016-10-24 08:25:28 -0700627 Packet c(gen.NextPacket(0)); // SN = 2, TS = 20.
628 Packet d(gen.NextPacket(0)); // SN = 3, TS = 20.
629 c.timestamp = b.timestamp;
630 d.timestamp = b.timestamp;
631 c.sequence_number = b.sequence_number;
632 d.sequence_number = b.sequence_number;
633 c.priority = {1, 1};
634 d.priority = {0, 1};
ossua70695a2016-09-22 02:06:28 -0700635 // c after d
ossua73f6c92016-10-24 08:25:28 -0700636 EXPECT_FALSE(c == d);
637 EXPECT_TRUE(c != d);
638 EXPECT_FALSE(c < d);
639 EXPECT_TRUE(c > d);
640 EXPECT_FALSE(c <= d);
641 EXPECT_TRUE(c >= d);
ossua70695a2016-09-22 02:06:28 -0700642
643 // c after a
ossua73f6c92016-10-24 08:25:28 -0700644 EXPECT_FALSE(c == a);
645 EXPECT_TRUE(c != a);
646 EXPECT_FALSE(c < a);
647 EXPECT_TRUE(c > a);
648 EXPECT_FALSE(c <= a);
649 EXPECT_TRUE(c >= a);
ossua70695a2016-09-22 02:06:28 -0700650
651 // c after b
ossua73f6c92016-10-24 08:25:28 -0700652 EXPECT_FALSE(c == b);
653 EXPECT_TRUE(c != b);
654 EXPECT_FALSE(c < b);
655 EXPECT_TRUE(c > b);
656 EXPECT_FALSE(c <= b);
657 EXPECT_TRUE(c >= b);
ossua70695a2016-09-22 02:06:28 -0700658
659 // a after d
ossua73f6c92016-10-24 08:25:28 -0700660 EXPECT_FALSE(a == d);
661 EXPECT_TRUE(a != d);
662 EXPECT_FALSE(a < d);
663 EXPECT_TRUE(a > d);
664 EXPECT_FALSE(a <= d);
665 EXPECT_TRUE(a >= d);
ossua70695a2016-09-22 02:06:28 -0700666
667 // d after b
ossua73f6c92016-10-24 08:25:28 -0700668 EXPECT_FALSE(d == b);
669 EXPECT_TRUE(d != b);
670 EXPECT_FALSE(d < b);
671 EXPECT_TRUE(d > b);
672 EXPECT_FALSE(d <= b);
673 EXPECT_TRUE(d >= b);
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000674}
675
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000676namespace {
677void TestIsObsoleteTimestamp(uint32_t limit_timestamp) {
678 // Check with zero horizon, which implies that the horizon is at 2^31, i.e.,
679 // half the timestamp range.
680 static const uint32_t kZeroHorizon = 0;
681 static const uint32_t k2Pow31Minus1 = 0x7FFFFFFF;
682 // Timestamp on the limit is not old.
683 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
684 limit_timestamp, limit_timestamp, kZeroHorizon));
685 // 1 sample behind is old.
686 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
687 limit_timestamp - 1, limit_timestamp, kZeroHorizon));
688 // 2^31 - 1 samples behind is old.
689 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
690 limit_timestamp - k2Pow31Minus1, limit_timestamp, kZeroHorizon));
691 // 1 sample ahead is not old.
692 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
693 limit_timestamp + 1, limit_timestamp, kZeroHorizon));
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200694 // If |t1-t2|=2^31 and t1>t2, t2 is older than t1 but not the opposite.
695 uint32_t other_timestamp = limit_timestamp + (1 << 31);
696 uint32_t lowest_timestamp = std::min(limit_timestamp, other_timestamp);
697 uint32_t highest_timestamp = std::max(limit_timestamp, other_timestamp);
698 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
699 lowest_timestamp, highest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000700 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
Cesar Magalhaesf69f1fb2015-05-30 17:49:18 +0200701 highest_timestamp, lowest_timestamp, kZeroHorizon));
henrik.lundin@webrtc.org52b42cb2014-11-04 14:03:58 +0000702
703 // Fixed horizon at 10 samples.
704 static const uint32_t kHorizon = 10;
705 // Timestamp on the limit is not old.
706 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
707 limit_timestamp, limit_timestamp, kHorizon));
708 // 1 sample behind is old.
709 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
710 limit_timestamp - 1, limit_timestamp, kHorizon));
711 // 9 samples behind is old.
712 EXPECT_TRUE(PacketBuffer::IsObsoleteTimestamp(
713 limit_timestamp - 9, limit_timestamp, kHorizon));
714 // 10 samples behind is not old.
715 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
716 limit_timestamp - 10, limit_timestamp, kHorizon));
717 // 2^31 - 1 samples behind is not old.
718 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
719 limit_timestamp - k2Pow31Minus1, limit_timestamp, kHorizon));
720 // 1 sample ahead is not old.
721 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
722 limit_timestamp + 1, limit_timestamp, kHorizon));
723 // 2^31 samples ahead is not old.
724 EXPECT_FALSE(PacketBuffer::IsObsoleteTimestamp(
725 limit_timestamp + (1 << 31), limit_timestamp, kHorizon));
726}
727} // namespace
728
729// Test the IsObsoleteTimestamp method with different limit timestamps.
730TEST(PacketBuffer, IsObsoleteTimestamp) {
731 TestIsObsoleteTimestamp(0);
732 TestIsObsoleteTimestamp(1);
733 TestIsObsoleteTimestamp(0xFFFFFFFF); // -1 in uint32_t.
734 TestIsObsoleteTimestamp(0x80000000); // 2^31.
735 TestIsObsoleteTimestamp(0x80000001); // 2^31 + 1.
736 TestIsObsoleteTimestamp(0x7FFFFFFF); // 2^31 - 1.
737}
henrik.lundin@webrtc.orgd94659d2013-01-29 12:09:21 +0000738} // namespace webrtc