blob: a01b480398761f41fa069c79f0ad3349187c34c6 [file] [log] [blame]
philipelc707ab72016-04-01 02:01:54 -07001/*
2 * Copyright (c) 2016 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 */
Danil Chapovalov05269ec2019-10-17 19:06:46 +020010#include "modules/video_coding/packet_buffer.h"
philipelc707ab72016-04-01 02:01:54 -070011
12#include <cstring>
Danil Chapovalov05269ec2019-10-17 19:06:46 +020013#include <limits>
Danil Chapovalov1dac7072019-10-24 12:44:23 +020014#include <ostream>
Danil Chapovalov05269ec2019-10-17 19:06:46 +020015#include <string>
philipela1059872016-05-09 11:41:48 +020016#include <utility>
philipelc707ab72016-04-01 02:01:54 -070017
Danil Chapovalov1dac7072019-10-24 12:44:23 +020018#include "api/array_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "common_video/h264/h264_common.h"
20#include "modules/video_coding/frame_object.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/random.h"
22#include "system_wrappers/include/clock.h"
Rasmus Brandtedf4ff72017-10-24 10:07:48 +020023#include "test/field_trial.h"
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020024#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "test/gtest.h"
philipelc707ab72016-04-01 02:01:54 -070026
27namespace webrtc {
28namespace video_coding {
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020029namespace {
philipelc707ab72016-04-01 02:01:54 -070030
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020031using ::testing::ElementsAre;
Danil Chapovalov1dac7072019-10-24 12:44:23 +020032using ::testing::ElementsAreArray;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020033using ::testing::IsEmpty;
Danil Chapovalov1dac7072019-10-24 12:44:23 +020034using ::testing::Matches;
35using ::testing::Pointee;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020036using ::testing::SizeIs;
37
Danil Chapovalov1dac7072019-10-24 12:44:23 +020038constexpr int kStartSize = 16;
39constexpr int kMaxSize = 64;
40
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020041void IgnoreResult(PacketBuffer::InsertResult /*result*/) {}
42
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010043// Validates frame boundaries are valid and returns first sequence_number for
44// each frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +020045std::vector<uint16_t> StartSeqNums(
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010046 rtc::ArrayView<const std::unique_ptr<PacketBuffer::Packet>> packets) {
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020047 std::vector<uint16_t> result;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010048 bool frame_boundary = true;
49 for (const auto& packet : packets) {
50 EXPECT_EQ(frame_boundary, packet->is_first_packet_in_frame());
51 if (packet->is_first_packet_in_frame()) {
52 result.push_back(packet->seq_num);
53 }
54 frame_boundary = packet->is_last_packet_in_frame();
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020055 }
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010056 EXPECT_TRUE(frame_boundary);
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020057 return result;
58}
59
Danil Chapovalov1dac7072019-10-24 12:44:23 +020060MATCHER_P(StartSeqNumsAre, seq_num, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010061 return Matches(ElementsAre(seq_num))(StartSeqNums(arg.packets));
Danil Chapovalov1dac7072019-10-24 12:44:23 +020062}
63
64MATCHER_P2(StartSeqNumsAre, seq_num1, seq_num2, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010065 return Matches(ElementsAre(seq_num1, seq_num2))(StartSeqNums(arg.packets));
Danil Chapovalov1dac7072019-10-24 12:44:23 +020066}
67
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020068MATCHER(KeyFrame, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010069 return arg->is_first_packet_in_frame() &&
70 arg->video_header.frame_type == VideoFrameType::kVideoFrameKey;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020071}
72
73MATCHER(DeltaFrame, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010074 return arg->is_first_packet_in_frame() &&
75 arg->video_header.frame_type == VideoFrameType::kVideoFrameDelta;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020076}
77
Danil Chapovalov1dac7072019-10-24 12:44:23 +020078struct PacketBufferInsertResult : public PacketBuffer::InsertResult {
79 explicit PacketBufferInsertResult(PacketBuffer::InsertResult result)
80 : InsertResult(std::move(result)) {}
81};
82
83void PrintTo(const PacketBufferInsertResult& result, std::ostream* os) {
84 *os << "frames: { ";
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010085 for (const auto& packet : result.packets) {
86 if (packet->is_first_packet_in_frame() &&
87 packet->is_last_packet_in_frame()) {
88 *os << "{sn: " << packet->seq_num << " }";
89 } else if (packet->is_first_packet_in_frame()) {
90 *os << "{sn: [" << packet->seq_num << "-";
91 } else if (packet->is_last_packet_in_frame()) {
92 *os << packet->seq_num << "] }, ";
Danil Chapovalov1dac7072019-10-24 12:44:23 +020093 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +020094 }
95 *os << " }";
96 if (result.buffer_cleared) {
97 *os << ", buffer_cleared";
98 }
99}
100
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200101class PacketBufferTest : public ::testing::Test {
philipelc707ab72016-04-01 02:01:54 -0700102 protected:
Eldar Rello2127aaa2020-08-07 12:08:14 +0300103 PacketBufferTest()
104 : rand_(0x7732213),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100105 clock_(0),
106 packet_buffer_(&clock_, kStartSize, kMaxSize) {}
philipelc707ab72016-04-01 02:01:54 -0700107
philipel17deeb42016-08-11 15:09:26 +0200108 uint16_t Rand() { return rand_.Rand<uint16_t>(); }
philipelc707ab72016-04-01 02:01:54 -0700109
philipel17deeb42016-08-11 15:09:26 +0200110 enum IsKeyFrame { kKeyFrame, kDeltaFrame };
111 enum IsFirst { kFirst, kNotFirst };
112 enum IsLast { kLast, kNotLast };
philipelc707ab72016-04-01 02:01:54 -0700113
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200114 PacketBufferInsertResult Insert(uint16_t seq_num, // packet sequence number
115 IsKeyFrame keyframe, // is keyframe
116 IsFirst first, // is first packet of frame
117 IsLast last, // is last packet of frame
Danil Chapovalove3c48842019-12-02 15:54:27 +0100118 rtc::ArrayView<const uint8_t> data = {},
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200119 uint32_t timestamp = 123u) { // rtp timestamp
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100120 auto packet = std::make_unique<PacketBuffer::Packet>();
121 packet->video_header.codec = kVideoCodecGeneric;
122 packet->timestamp = timestamp;
123 packet->seq_num = seq_num;
124 packet->video_header.frame_type = keyframe == kKeyFrame
125 ? VideoFrameType::kVideoFrameKey
126 : VideoFrameType::kVideoFrameDelta;
127 packet->video_header.is_first_packet_in_frame = first == kFirst;
128 packet->video_header.is_last_packet_in_frame = last == kLast;
129 packet->video_payload.SetData(data.data(), data.size());
philipelf4139332016-04-20 10:26:34 +0200130
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100131 return PacketBufferInsertResult(
132 packet_buffer_.InsertPacket(std::move(packet)));
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200133 }
134
philipelc707ab72016-04-01 02:01:54 -0700135 Random rand_;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100136 SimulatedClock clock_;
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200137 PacketBuffer packet_buffer_;
philipelc707ab72016-04-01 02:01:54 -0700138};
139
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200140TEST_F(PacketBufferTest, InsertOnePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100141 const uint16_t seq_num = Rand();
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100142 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700143}
144
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200145TEST_F(PacketBufferTest, InsertMultiplePackets) {
philipelaee3e0e2016-11-01 11:45:34 +0100146 const uint16_t seq_num = Rand();
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100147 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
148 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
149 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
150 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700151}
152
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200153TEST_F(PacketBufferTest, InsertDuplicatePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100154 const uint16_t seq_num = Rand();
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100155 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
156 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
157 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).packets,
158 SizeIs(2));
philipelaee3e0e2016-11-01 11:45:34 +0100159}
160
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200161TEST_F(PacketBufferTest, SeqNumWrapOneFrame) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200162 Insert(0xFFFF, kKeyFrame, kFirst, kNotLast);
163 EXPECT_THAT(Insert(0x0, kKeyFrame, kNotFirst, kLast),
164 StartSeqNumsAre(0xFFFF));
philipel2c2f34c2017-01-03 05:55:34 -0800165}
166
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200167TEST_F(PacketBufferTest, SeqNumWrapTwoFrames) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200168 EXPECT_THAT(Insert(0xFFFF, kKeyFrame, kFirst, kLast),
169 StartSeqNumsAre(0xFFFF));
170 EXPECT_THAT(Insert(0x0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0x0));
philipelaee3e0e2016-11-01 11:45:34 +0100171}
172
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200173TEST_F(PacketBufferTest, InsertOldPackets) {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100174 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
175 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
176 EXPECT_THAT(Insert(101, kKeyFrame, kNotFirst, kLast).packets, SizeIs(2));
philipelaee3e0e2016-11-01 11:45:34 +0100177
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100178 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
179 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
180 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100181
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200182 packet_buffer_.ClearTo(102);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100183 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, IsEmpty());
184 EXPECT_THAT(Insert(103, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
philipel5ceaaae2016-05-24 10:20:47 +0200185}
186
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200187TEST_F(PacketBufferTest, FrameSize) {
philipelaee3e0e2016-11-01 11:45:34 +0100188 const uint16_t seq_num = Rand();
Danil Chapovalove3c48842019-12-02 15:54:27 +0100189 uint8_t data1[5] = {};
190 uint8_t data2[5] = {};
191 uint8_t data3[5] = {};
192 uint8_t data4[5] = {};
philipel5ceaaae2016-05-24 10:20:47 +0200193
Danil Chapovalove3c48842019-12-02 15:54:27 +0100194 Insert(seq_num, kKeyFrame, kFirst, kNotLast, data1);
195 Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast, data2);
196 Insert(seq_num + 2, kKeyFrame, kNotFirst, kNotLast, data3);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100197 auto packets =
198 Insert(seq_num + 3, kKeyFrame, kNotFirst, kLast, data4).packets;
199 // Expect one frame of 4 packets.
200 EXPECT_THAT(StartSeqNums(packets), ElementsAre(seq_num));
201 EXPECT_THAT(packets, SizeIs(4));
philipel5ceaaae2016-05-24 10:20:47 +0200202}
203
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200204TEST_F(PacketBufferTest, ExpandBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100205 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700206
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200207 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Johannes Krona3705562019-08-26 16:37:11 +0200208 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200209 EXPECT_FALSE(
210 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200211
212 // Already inserted kStartSize number of packets, inserting the last packet
213 // should increase the buffer size and also result in an assembled frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200214 EXPECT_FALSE(
215 Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700216}
217
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200218TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100219 const uint16_t seq_num = Rand();
220
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200221 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
philipelaee3e0e2016-11-01 11:45:34 +0100222 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200223 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast);
224 EXPECT_THAT(Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast),
225 StartSeqNumsAre(seq_num));
philipelaee3e0e2016-11-01 11:45:34 +0100226}
227
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200228TEST_F(PacketBufferTest, ExpandBufferOverflow) {
philipelaee3e0e2016-11-01 11:45:34 +0100229 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700230
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200231 EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200232 for (int i = 1; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200233 EXPECT_FALSE(
234 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200235
236 // Already inserted kMaxSize number of packets, inserting the last packet
237 // should overflow the buffer and result in false being returned.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200238 EXPECT_TRUE(
239 Insert(seq_num + kMaxSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700240}
241
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200242TEST_F(PacketBufferTest, OnePacketOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100243 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200244 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
245 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700246}
247
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200248TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100249 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200250
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200251 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
252 StartSeqNumsAre(seq_num));
253 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast),
254 StartSeqNumsAre(seq_num + 1));
philipelc707ab72016-04-01 02:01:54 -0700255}
256
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200257TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100258 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200259
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100260 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200261 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
262 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700263}
264
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200265TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100266 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700267
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100268 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
269 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200270 IsEmpty());
271 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast),
272 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700273}
274
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200275TEST_F(PacketBufferTest, Frames) {
philipelaee3e0e2016-11-01 11:45:34 +0100276 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200277
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200278 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
279 StartSeqNumsAre(seq_num));
280 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
281 StartSeqNumsAre(seq_num + 1));
282 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
283 StartSeqNumsAre(seq_num + 2));
284 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
285 StartSeqNumsAre(seq_num + 3));
philipelf4139332016-04-20 10:26:34 +0200286}
287
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200288TEST_F(PacketBufferTest, ClearSinglePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100289 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200290
philipelaee3e0e2016-11-01 11:45:34 +0100291 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200292 Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
philipelaee3e0e2016-11-01 11:45:34 +0100293
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200294 packet_buffer_.ClearTo(seq_num);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200295 EXPECT_FALSE(
296 Insert(seq_num + kMaxSize, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelaee3e0e2016-11-01 11:45:34 +0100297}
298
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200299TEST_F(PacketBufferTest, ClearFullBuffer) {
philipelc5fb4682017-08-02 04:28:57 -0700300 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200301 Insert(i, kDeltaFrame, kFirst, kLast);
philipelc5fb4682017-08-02 04:28:57 -0700302
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200303 packet_buffer_.ClearTo(kMaxSize - 1);
philipelc5fb4682017-08-02 04:28:57 -0700304
305 for (int i = kMaxSize; i < 2 * kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200306 EXPECT_FALSE(Insert(i, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelc5fb4682017-08-02 04:28:57 -0700307}
308
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200309TEST_F(PacketBufferTest, DontClearNewerPacket) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200310 EXPECT_THAT(Insert(0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0));
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200311 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200312 EXPECT_THAT(Insert(2 * kStartSize, kKeyFrame, kFirst, kLast),
313 StartSeqNumsAre(2 * kStartSize));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100314 EXPECT_THAT(Insert(3 * kStartSize + 1, kKeyFrame, kFirst, kNotLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200315 IsEmpty());
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200316 packet_buffer_.ClearTo(2 * kStartSize);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200317 EXPECT_THAT(Insert(3 * kStartSize + 2, kKeyFrame, kNotFirst, kLast),
318 StartSeqNumsAre(3 * kStartSize + 1));
philipelc5fb4682017-08-02 04:28:57 -0700319}
320
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200321TEST_F(PacketBufferTest, OneIncompleteFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100322 const uint16_t seq_num = Rand();
323
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100324 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets,
325 IsEmpty());
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200326 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kNotFirst, kLast),
327 StartSeqNumsAre(seq_num));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100328 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200329 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100330}
331
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200332TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100333 const uint16_t seq_num = Rand();
334
335 for (int i = 1; i < kMaxSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200336 Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100337 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets,
338 IsEmpty());
339 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200340 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100341}
342
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200343TEST_F(PacketBufferTest, FramesReordered) {
philipelaee3e0e2016-11-01 11:45:34 +0100344 const uint16_t seq_num = Rand();
345
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200346 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
347 StartSeqNumsAre(seq_num + 1));
348 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
349 StartSeqNumsAre(seq_num));
350 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
351 StartSeqNumsAre(seq_num + 3));
352 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
353 StartSeqNumsAre(seq_num + 2));
philipelf4139332016-04-20 10:26:34 +0200354}
355
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200356TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
Johannes Kron957c62e2018-10-01 14:53:01 +0200357 uint16_t kFirstSeqNum = 0;
358 uint32_t kTimestampDelta = 100;
359 uint32_t timestamp = 10000;
360 uint16_t seq_num = kFirstSeqNum;
361
362 // Loop until seq_num wraps around.
Philip Eliasson1f850a62019-03-19 12:15:00 +0000363 SeqNumUnwrapper<uint16_t> unwrapper;
Johannes Kron957c62e2018-10-01 14:53:01 +0200364 while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100365 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200366 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100367 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200368 }
Danil Chapovalove3c48842019-12-02 15:54:27 +0100369 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200370 timestamp += kTimestampDelta;
371 }
372
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200373 // Receive frame with overlapping sequence numbers.
Danil Chapovalove3c48842019-12-02 15:54:27 +0100374 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200375 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100376 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200377 }
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100378 auto packets =
379 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp).packets;
380 // One frame of 7 packets.
381 EXPECT_THAT(StartSeqNums(packets), SizeIs(1));
382 EXPECT_THAT(packets, SizeIs(7));
Johannes Kron957c62e2018-10-01 14:53:01 +0200383}
384
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100385// If |sps_pps_idr_is_keyframe| is true, we require keyframes to contain
386// SPS/PPS/IDR and the keyframes we create as part of the test do contain
387// SPS/PPS/IDR. If |sps_pps_idr_is_keyframe| is false, we only require and
388// create keyframes containing only IDR.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200389class PacketBufferH264Test : public PacketBufferTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200390 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200391 explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
Eldar Rello2127aaa2020-08-07 12:08:14 +0300392 : PacketBufferTest(), sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {
393 if (sps_pps_idr_is_keyframe) {
394 packet_buffer_.ForceSpsPpsIdrIsH264Keyframe();
395 }
396 }
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200397
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200398 PacketBufferInsertResult InsertH264(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100399 uint16_t seq_num, // packet sequence number
400 IsKeyFrame keyframe, // is keyframe
401 IsFirst first, // is first packet of frame
402 IsLast last, // is last packet of frame
403 uint32_t timestamp, // rtp timestamp
404 rtc::ArrayView<const uint8_t> data = {},
405 uint32_t width = 0, // width of frame (SPS/IDR)
406 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100407 auto packet = std::make_unique<PacketBuffer::Packet>();
408 packet->video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200409 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100410 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
411 packet->seq_num = seq_num;
412 packet->timestamp = timestamp;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200413 if (keyframe == kKeyFrame) {
414 if (sps_pps_idr_is_keyframe_) {
philipel7d745e52018-08-02 14:03:53 +0200415 h264_header.nalus[0].type = H264::NaluType::kSps;
416 h264_header.nalus[1].type = H264::NaluType::kPps;
417 h264_header.nalus[2].type = H264::NaluType::kIdr;
418 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200419 } else {
philipel7d745e52018-08-02 14:03:53 +0200420 h264_header.nalus[0].type = H264::NaluType::kIdr;
421 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200422 }
423 }
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100424 packet->video_header.width = width;
425 packet->video_header.height = height;
426 packet->video_header.is_first_packet_in_frame = first == kFirst;
427 packet->video_header.is_last_packet_in_frame = last == kLast;
428 packet->video_payload.SetData(data.data(), data.size());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200429
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100430 return PacketBufferInsertResult(
431 packet_buffer_.InsertPacket(std::move(packet)));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200432 }
433
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200434 PacketBufferInsertResult InsertH264KeyFrameWithAud(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100435 uint16_t seq_num, // packet sequence number
436 IsKeyFrame keyframe, // is keyframe
437 IsFirst first, // is first packet of frame
438 IsLast last, // is last packet of frame
439 uint32_t timestamp, // rtp timestamp
440 rtc::ArrayView<const uint8_t> data = {},
441 uint32_t width = 0, // width of frame (SPS/IDR)
442 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100443 auto packet = std::make_unique<PacketBuffer::Packet>();
444 packet->video_header.codec = kVideoCodecH264;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700445 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100446 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
447 packet->seq_num = seq_num;
448 packet->timestamp = timestamp;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700449
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200450 // this should be the start of frame.
451 RTC_CHECK(first == kFirst);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700452
453 // Insert a AUD NALU / packet without width/height.
454 h264_header.nalus[0].type = H264::NaluType::kAud;
455 h264_header.nalus_length = 1;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100456 packet->video_header.is_first_packet_in_frame = true;
457 packet->video_header.is_last_packet_in_frame = false;
458 IgnoreResult(packet_buffer_.InsertPacket(std::move(packet)));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200459 // insert IDR
Danil Chapovalove3c48842019-12-02 15:54:27 +0100460 return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp, data,
461 width, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700462 }
463
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200464 const bool sps_pps_idr_is_keyframe_;
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100465};
466
467// This fixture is used to test the general behaviour of the packet buffer
468// in both configurations.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200469class PacketBufferH264ParameterizedTest
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100470 : public ::testing::WithParamInterface<bool>,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200471 public PacketBufferH264Test {
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100472 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200473 PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200474};
475
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100476INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200477 PacketBufferH264ParameterizedTest,
478 ::testing::Bool());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200479
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200480TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200481 InsertH264(0, kKeyFrame, kFirst, kLast, 0);
482 InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200483 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200484 // Expect no frame because of missing of packet #1
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100485 EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200486 IsEmpty());
philipelbc5a4082017-12-06 10:41:08 +0100487}
488
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200489TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100490 uint8_t data_arr[kStartSize][1];
philipel227f8b92017-08-04 06:39:31 -0700491 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700492
493 for (uint8_t i = 0; i < kStartSize; ++i) {
philipel227f8b92017-08-04 06:39:31 -0700494 data_arr[i][0] = i;
495 expected[i] = i;
496 }
497
Danil Chapovalove3c48842019-12-02 15:54:27 +0100498 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700499 for (uint8_t i = 1; i < kStartSize - 1; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100500 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, data_arr[i]);
philipel227f8b92017-08-04 06:39:31 -0700501 }
philipel227f8b92017-08-04 06:39:31 -0700502
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100503 auto packets = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1,
504 data_arr[kStartSize - 1])
505 .packets;
506 ASSERT_THAT(StartSeqNums(packets), ElementsAre(0));
507 EXPECT_THAT(packets, SizeIs(kStartSize));
508 for (size_t i = 0; i < packets.size(); ++i) {
509 EXPECT_THAT(packets[i]->video_payload, SizeIs(1)) << "Packet #" << i;
510 }
philipel227f8b92017-08-04 06:39:31 -0700511}
512
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200513TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
philipel36928452016-11-07 10:42:36 +0100514 uint16_t seq_num = Rand();
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100515 rtc::CopyOnWriteBuffer data = "some plain old data";
philipel36928452016-11-07 10:42:36 +0100516
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100517 auto packet = std::make_unique<PacketBuffer::Packet>();
philipel7d745e52018-08-02 14:03:53 +0200518 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100519 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200520 h264_header.nalus_length = 1;
521 h264_header.nalus[0].type = H264::NaluType::kIdr;
522 h264_header.packetization_type = kH264SingleNalu;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100523 packet->seq_num = seq_num;
524 packet->video_header.codec = kVideoCodecH264;
525 packet->video_payload = data;
526 packet->video_header.is_first_packet_in_frame = true;
527 packet->video_header.is_last_packet_in_frame = true;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100528 auto frames = packet_buffer_.InsertPacket(std::move(packet)).packets;
philipel36928452016-11-07 10:42:36 +0100529
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200530 ASSERT_THAT(frames, SizeIs(1));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100531 EXPECT_EQ(frames[0]->seq_num, seq_num);
532 EXPECT_EQ(frames[0]->video_payload, data);
philipel36928452016-11-07 10:42:36 +0100533}
534
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200535TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700536 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100537 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700538 uint32_t width = 640;
539 uint32_t height = 360;
540 uint32_t timestamp = 1000;
541
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100542 auto packets = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp, data,
543 width, height)
544 .packets;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700545
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100546 ASSERT_THAT(packets, SizeIs(1));
547 EXPECT_EQ(packets[0]->video_header.width, width);
548 EXPECT_EQ(packets[0]->video_header.height, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700549}
550
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200551TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700552 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100553 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700554 uint32_t width = 640;
555 uint32_t height = 360;
556 uint32_t timestamp = 1000;
557
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100558 auto packets = InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast,
559 timestamp, data, width, height)
560 .packets;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700561
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100562 ASSERT_THAT(StartSeqNums(packets), ElementsAre(seq_num));
563 EXPECT_EQ(packets[0]->video_header.width, width);
564 EXPECT_EQ(packets[0]->video_header.height, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700565}
566
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200567TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
philipelaee3e0e2016-11-01 11:45:34 +0100568 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200569
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200570 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
571 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
572 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
573 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700574
philipel17deeb42016-08-11 15:09:26 +0200575 // Insert frame that fills the whole buffer.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200576 Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
philipel17deeb42016-08-11 15:09:26 +0200577 for (int i = 0; i < kMaxSize - 2; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200578 Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
579 EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
580 StartSeqNumsAre(seq_num + 3));
philipelc707ab72016-04-01 02:01:54 -0700581}
582
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200583TEST_F(PacketBufferTest, Clear) {
philipelaee3e0e2016-11-01 11:45:34 +0100584 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200585
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200586 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
587 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
588 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
589 StartSeqNumsAre(seq_num));
philipelf4139332016-04-20 10:26:34 +0200590
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200591 packet_buffer_.Clear();
philipelf4139332016-04-20 10:26:34 +0200592
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200593 Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
594 Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
595 EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
596 StartSeqNumsAre(seq_num + kStartSize));
philipelc707ab72016-04-01 02:01:54 -0700597}
598
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200599TEST_F(PacketBufferTest, FramesAfterClear) {
philipel20dce342016-11-28 16:14:57 +0100600 Insert(9025, kDeltaFrame, kFirst, kLast);
601 Insert(9024, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200602 packet_buffer_.ClearTo(9025);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100603 EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
604 EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
philipel20dce342016-11-28 16:14:57 +0100605}
606
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200607TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100608 Insert(0, kKeyFrame, kFirst, kNotLast, {}, 1000);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100609 EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, {}, 1001).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200610 IsEmpty());
philipel8b6995b2019-01-09 12:39:18 +0100611}
612
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200613TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
philipelea142f82017-01-11 02:01:56 -0800614 Insert(2, kKeyFrame, kNotFirst, kNotLast);
615 Insert(1, kKeyFrame, kFirst, kLast);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100616 EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).packets, IsEmpty());
philipelea142f82017-01-11 02:01:56 -0800617}
618
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200619TEST_F(PacketBufferTest, PacketTimestamps) {
Danil Chapovalov0040b662018-06-18 10:48:16 +0200620 absl::optional<int64_t> packet_ms;
621 absl::optional<int64_t> packet_keyframe_ms;
philipel3184f8e2017-05-18 08:08:53 -0700622
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200623 packet_ms = packet_buffer_.LastReceivedPacketMs();
624 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700625 EXPECT_FALSE(packet_ms);
626 EXPECT_FALSE(packet_keyframe_ms);
627
Danil Chapovalove3c48842019-12-02 15:54:27 +0100628 int64_t keyframe_ms = clock_.TimeInMilliseconds();
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100629 Insert(100, kKeyFrame, kFirst, kLast, {}, /*timestamp=*/1000);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200630 packet_ms = packet_buffer_.LastReceivedPacketMs();
631 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700632 EXPECT_TRUE(packet_ms);
633 EXPECT_TRUE(packet_keyframe_ms);
634 EXPECT_EQ(keyframe_ms, *packet_ms);
635 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
636
Danil Chapovalove3c48842019-12-02 15:54:27 +0100637 clock_.AdvanceTimeMilliseconds(100);
638 int64_t delta_ms = clock_.TimeInMilliseconds();
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100639 Insert(101, kDeltaFrame, kFirst, kLast, {}, /*timestamp=*/2000);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200640 packet_ms = packet_buffer_.LastReceivedPacketMs();
641 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700642 EXPECT_TRUE(packet_ms);
643 EXPECT_TRUE(packet_keyframe_ms);
644 EXPECT_EQ(delta_ms, *packet_ms);
645 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
646
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200647 packet_buffer_.Clear();
648 packet_ms = packet_buffer_.LastReceivedPacketMs();
649 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700650 EXPECT_FALSE(packet_ms);
651 EXPECT_FALSE(packet_keyframe_ms);
652}
653
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100654TEST_F(PacketBufferTest,
655 LastReceivedKeyFrameReturnsReceiveTimeOfALastReceivedPacketOfAKeyFrame) {
656 clock_.AdvanceTimeMilliseconds(100);
657 Insert(/*seq_num=*/100, kKeyFrame, kFirst, kNotLast, {}, /*timestamp=*/1000);
658 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
659 clock_.TimeInMilliseconds());
660
661 clock_.AdvanceTimeMilliseconds(100);
662 Insert(/*seq_num=*/102, kDeltaFrame, kNotFirst, kLast, {},
663 /*timestamp=*/1000);
664 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
665 clock_.TimeInMilliseconds());
666
667 clock_.AdvanceTimeMilliseconds(100);
668 Insert(/*seq_num=*/101, kDeltaFrame, kNotFirst, kNotLast, {},
669 /*timestamp=*/1000);
670 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
671 clock_.TimeInMilliseconds());
672
673 clock_.AdvanceTimeMilliseconds(100);
674 Insert(/*seq_num=*/103, kDeltaFrame, kFirst, kNotLast, {},
675 /*timestamp=*/2000);
676 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
677 clock_.TimeInMilliseconds() - 100);
678}
679
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200680TEST_F(PacketBufferTest, IncomingCodecChange) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100681 auto packet = std::make_unique<PacketBuffer::Packet>();
682 packet->video_header.is_first_packet_in_frame = true;
683 packet->video_header.is_last_packet_in_frame = true;
684 packet->video_header.codec = kVideoCodecVP8;
685 packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
686 packet->timestamp = 1;
687 packet->seq_num = 1;
688 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100689 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
690 SizeIs(1));
philipel09133af2018-05-17 14:11:09 +0200691
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100692 packet = std::make_unique<PacketBuffer::Packet>();
693 packet->video_header.is_first_packet_in_frame = true;
694 packet->video_header.is_last_packet_in_frame = true;
695 packet->video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200696 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100697 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200698 h264_header.nalus_length = 1;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100699 packet->timestamp = 3;
700 packet->seq_num = 3;
701 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100702 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
703 IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200704
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100705 packet = std::make_unique<PacketBuffer::Packet>();
706 packet->video_header.is_first_packet_in_frame = true;
707 packet->video_header.is_last_packet_in_frame = true;
708 packet->video_header.codec = kVideoCodecVP8;
709 packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
710 packet->timestamp = 2;
711 packet->seq_num = 2;
712 packet->video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100713 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
714 SizeIs(2));
philipel09133af2018-05-17 14:11:09 +0200715}
716
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200717TEST_F(PacketBufferTest, TooManyNalusInPacket) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100718 auto packet = std::make_unique<PacketBuffer::Packet>();
719 packet->video_header.codec = kVideoCodecH264;
720 packet->timestamp = 1;
721 packet->seq_num = 1;
722 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
723 packet->video_header.is_first_packet_in_frame = true;
724 packet->video_header.is_last_packet_in_frame = true;
philipel7d745e52018-08-02 14:03:53 +0200725 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100726 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200727 h264_header.nalus_length = kMaxNalusPerPacket;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100728 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
729 IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200730}
731
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200732TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
philipel2c9f9f22017-06-13 02:47:28 -0700733 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
734 for (int i = 1; i < kStartSize - 1; ++i)
735 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200736 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
737 StartSeqNumsAre(0));
philipel2c9f9f22017-06-13 02:47:28 -0700738}
739
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200740TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100741 EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200742 SizeIs(1));
philipel227f8b92017-08-04 06:39:31 -0700743
744 InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
745 for (int i = 1; i < kStartSize; ++i)
746 InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200747 EXPECT_THAT(
748 InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100749 .packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200750 IsEmpty());
philipel227f8b92017-08-04 06:39:31 -0700751
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200752 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
753 StartSeqNumsAre(kStartSize - 1, kStartSize));
philipel227f8b92017-08-04 06:39:31 -0700754}
755
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200756TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
philipel2c9f9f22017-06-13 02:47:28 -0700757 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200758 EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
759 StartSeqNumsAre(65534));
philipel2c9f9f22017-06-13 02:47:28 -0700760}
761
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200762TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
philipel2c9f9f22017-06-13 02:47:28 -0700763 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
764 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
765 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
766 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
767
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200768 EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
769 StartSeqNumsAre(kStartSize + 1));
philipel2c9f9f22017-06-13 02:47:28 -0700770}
771
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200772TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200773 EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
774 StartSeqNumsAre(0));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100775 EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200776 IsEmpty());
philipel2c9f9f22017-06-13 02:47:28 -0700777
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200778 EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
philipel2c9f9f22017-06-13 02:47:28 -0700779}
780
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200781class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200782 protected:
783 const uint16_t kSeqNum = 5;
784
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200785 explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100786 : PacketBufferH264Test(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200787
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100788 std::unique_ptr<PacketBuffer::Packet> CreatePacket() {
789 auto packet = std::make_unique<PacketBuffer::Packet>();
790 packet->video_header.codec = kVideoCodecH264;
791 packet->seq_num = kSeqNum;
792
793 packet->video_header.is_first_packet_in_frame = true;
794 packet->video_header.is_last_packet_in_frame = true;
795 return packet;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200796 }
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200797};
798
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200799class PacketBufferH264IdrIsKeyframeTest
800 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200801 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200802 PacketBufferH264IdrIsKeyframeTest()
803 : PacketBufferH264XIsKeyframeTest(false) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200804};
805
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200806TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100807 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200808 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100809 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200810 h264_header.nalus[0].type = H264::NaluType::kIdr;
811 h264_header.nalus_length = 1;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100812 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200813 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200814}
815
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200816TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100817 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200818 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100819 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200820 h264_header.nalus[0].type = H264::NaluType::kSps;
821 h264_header.nalus[1].type = H264::NaluType::kPps;
822 h264_header.nalus[2].type = H264::NaluType::kIdr;
823 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200824
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100825 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200826 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200827}
828
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200829class PacketBufferH264SpsPpsIdrIsKeyframeTest
830 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200831 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200832 PacketBufferH264SpsPpsIdrIsKeyframeTest()
833 : PacketBufferH264XIsKeyframeTest(true) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200834};
835
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200836TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100837 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200838 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100839 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200840 h264_header.nalus[0].type = H264::NaluType::kIdr;
841 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200842
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100843 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200844 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200845}
846
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200847TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100848 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200849 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100850 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200851 h264_header.nalus[0].type = H264::NaluType::kSps;
852 h264_header.nalus[1].type = H264::NaluType::kPps;
853 h264_header.nalus_length = 2;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200854
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100855 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200856 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200857}
858
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200859TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100860 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200861 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100862 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200863 h264_header.nalus[0].type = H264::NaluType::kSps;
864 h264_header.nalus[1].type = H264::NaluType::kPps;
865 h264_header.nalus[2].type = H264::NaluType::kIdr;
866 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200867
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100868 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200869 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200870}
871
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200872} // namespace
philipelc707ab72016-04-01 02:01:54 -0700873} // namespace video_coding
874} // namespace webrtc