blob: 7779999fc1648c89124a1ad6e9766299392f9e3e [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 Chapovalov1dac7072019-10-24 12:44:23 +020043std::vector<uint16_t> StartSeqNums(
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020044 rtc::ArrayView<const std::unique_ptr<RtpFrameObject>> frames) {
45 std::vector<uint16_t> result;
46 for (const auto& frame : frames) {
47 result.push_back(frame->first_seq_num());
48 }
49 return result;
50}
51
Danil Chapovalov1dac7072019-10-24 12:44:23 +020052MATCHER_P(StartSeqNumsAre, seq_num, "") {
53 return Matches(ElementsAre(seq_num))(StartSeqNums(arg.frames));
54}
55
56MATCHER_P2(StartSeqNumsAre, seq_num1, seq_num2, "") {
57 return Matches(ElementsAre(seq_num1, seq_num2))(StartSeqNums(arg.frames));
58}
59
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020060MATCHER(KeyFrame, "") {
61 return arg->frame_type() == VideoFrameType::kVideoFrameKey;
62}
63
64MATCHER(DeltaFrame, "") {
65 return arg->frame_type() == VideoFrameType::kVideoFrameDelta;
66}
67
Danil Chapovalov1dac7072019-10-24 12:44:23 +020068struct PacketBufferInsertResult : public PacketBuffer::InsertResult {
69 explicit PacketBufferInsertResult(PacketBuffer::InsertResult result)
70 : InsertResult(std::move(result)) {}
71};
72
73void PrintTo(const PacketBufferInsertResult& result, std::ostream* os) {
74 *os << "frames: { ";
75 for (size_t i = 0; i < result.frames.size(); ++i) {
76 const RtpFrameObject& frame = *result.frames[i];
77 if (i > 0) {
78 *os << ", ";
79 }
80 *os << "{sn: ";
81 if (frame.first_seq_num() == frame.last_seq_num()) {
82 *os << frame.first_seq_num();
83 } else {
84 *os << "[" << frame.first_seq_num() << "-" << frame.last_seq_num() << "]";
85 }
86 *os << "}";
87 }
88 *os << " }";
89 if (result.buffer_cleared) {
90 *os << ", buffer_cleared";
91 }
92}
93
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020094class PacketBufferTest : public ::testing::Test {
philipelc707ab72016-04-01 02:01:54 -070095 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +020096 explicit PacketBufferTest(std::string field_trials = "")
Rasmus Brandt88f080a2017-11-02 14:28:06 +010097 : scoped_field_trials_(field_trials),
98 rand_(0x7732213),
Danil Chapovalove3c48842019-12-02 15:54:27 +010099 clock_(0),
100 packet_buffer_(&clock_, kStartSize, kMaxSize) {}
philipelc707ab72016-04-01 02:01:54 -0700101
philipel17deeb42016-08-11 15:09:26 +0200102 uint16_t Rand() { return rand_.Rand<uint16_t>(); }
philipelc707ab72016-04-01 02:01:54 -0700103
philipel17deeb42016-08-11 15:09:26 +0200104 enum IsKeyFrame { kKeyFrame, kDeltaFrame };
105 enum IsFirst { kFirst, kNotFirst };
106 enum IsLast { kLast, kNotLast };
philipelc707ab72016-04-01 02:01:54 -0700107
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200108 PacketBufferInsertResult Insert(uint16_t seq_num, // packet sequence number
109 IsKeyFrame keyframe, // is keyframe
110 IsFirst first, // is first packet of frame
111 IsLast last, // is last packet of frame
Danil Chapovalove3c48842019-12-02 15:54:27 +0100112 rtc::ArrayView<const uint8_t> data = {},
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200113 uint32_t timestamp = 123u) { // rtp timestamp
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100114 auto packet = std::make_unique<PacketBuffer::Packet>();
115 packet->video_header.codec = kVideoCodecGeneric;
116 packet->timestamp = timestamp;
117 packet->seq_num = seq_num;
118 packet->video_header.frame_type = keyframe == kKeyFrame
119 ? VideoFrameType::kVideoFrameKey
120 : VideoFrameType::kVideoFrameDelta;
121 packet->video_header.is_first_packet_in_frame = first == kFirst;
122 packet->video_header.is_last_packet_in_frame = last == kLast;
123 packet->video_payload.SetData(data.data(), data.size());
philipelf4139332016-04-20 10:26:34 +0200124
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100125 return PacketBufferInsertResult(
126 packet_buffer_.InsertPacket(std::move(packet)));
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200127 }
128
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100129 const test::ScopedFieldTrials scoped_field_trials_;
philipelc707ab72016-04-01 02:01:54 -0700130 Random rand_;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100131 SimulatedClock clock_;
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200132 PacketBuffer packet_buffer_;
philipelc707ab72016-04-01 02:01:54 -0700133};
134
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200135TEST_F(PacketBufferTest, InsertOnePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100136 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200137 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700138}
139
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200140TEST_F(PacketBufferTest, InsertMultiplePackets) {
philipelaee3e0e2016-11-01 11:45:34 +0100141 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200142 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
143 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
144 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
145 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700146}
147
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200148TEST_F(PacketBufferTest, InsertDuplicatePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100149 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200150 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
151 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
152 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).frames,
153 SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100154}
155
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200156TEST_F(PacketBufferTest, SeqNumWrapOneFrame) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200157 Insert(0xFFFF, kKeyFrame, kFirst, kNotLast);
158 EXPECT_THAT(Insert(0x0, kKeyFrame, kNotFirst, kLast),
159 StartSeqNumsAre(0xFFFF));
philipel2c2f34c2017-01-03 05:55:34 -0800160}
161
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200162TEST_F(PacketBufferTest, SeqNumWrapTwoFrames) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200163 EXPECT_THAT(Insert(0xFFFF, kKeyFrame, kFirst, kLast),
164 StartSeqNumsAre(0xFFFF));
165 EXPECT_THAT(Insert(0x0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0x0));
philipelaee3e0e2016-11-01 11:45:34 +0100166}
167
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200168TEST_F(PacketBufferTest, InsertOldPackets) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200169 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
170 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
171 EXPECT_THAT(Insert(101, kKeyFrame, kNotFirst, kLast).frames, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100172
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200173 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
174 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
175 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100176
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200177 packet_buffer_.ClearTo(102);
178 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, IsEmpty());
179 EXPECT_THAT(Insert(103, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700180}
181
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200182TEST_F(PacketBufferTest, NackCount) {
philipelaee3e0e2016-11-01 11:45:34 +0100183 const uint16_t seq_num = Rand();
philipel5ceaaae2016-05-24 10:20:47 +0200184
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100185 auto packet = std::make_unique<PacketBuffer::Packet>();
186 packet->video_header.codec = kVideoCodecGeneric;
187 packet->seq_num = seq_num;
188 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
189 packet->video_header.is_first_packet_in_frame = true;
190 packet->video_header.is_last_packet_in_frame = false;
191 packet->times_nacked = 0;
192 IgnoreResult(packet_buffer_.InsertPacket(std::move(packet)));
philipel5ceaaae2016-05-24 10:20:47 +0200193
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100194 packet = std::make_unique<PacketBuffer::Packet>();
195 packet->seq_num = seq_num + 1;
196 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
197 packet->video_header.is_first_packet_in_frame = false;
198 packet->video_header.is_last_packet_in_frame = false;
199 packet->times_nacked = 1;
200 IgnoreResult(packet_buffer_.InsertPacket(std::move(packet)));
philipel5ceaaae2016-05-24 10:20:47 +0200201
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100202 packet = std::make_unique<PacketBuffer::Packet>();
203 packet->seq_num = seq_num + 2;
204 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
205 packet->video_header.is_first_packet_in_frame = false;
206 packet->video_header.is_last_packet_in_frame = false;
207 packet->times_nacked = 3;
208 IgnoreResult(packet_buffer_.InsertPacket(std::move(packet)));
philipel5ceaaae2016-05-24 10:20:47 +0200209
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100210 packet = std::make_unique<PacketBuffer::Packet>();
211 packet->seq_num = seq_num + 3;
212 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
213 packet->video_header.is_first_packet_in_frame = false;
214 packet->video_header.is_last_packet_in_frame = true;
215 packet->times_nacked = 1;
216 auto frames = packet_buffer_.InsertPacket(std::move(packet)).frames;
philipel5ceaaae2016-05-24 10:20:47 +0200217
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200218 ASSERT_THAT(frames, SizeIs(1));
219 EXPECT_EQ(frames.front()->times_nacked(), 3);
philipel5ceaaae2016-05-24 10:20:47 +0200220}
221
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200222TEST_F(PacketBufferTest, FrameSize) {
philipelaee3e0e2016-11-01 11:45:34 +0100223 const uint16_t seq_num = Rand();
Danil Chapovalove3c48842019-12-02 15:54:27 +0100224 uint8_t data1[5] = {};
225 uint8_t data2[5] = {};
226 uint8_t data3[5] = {};
227 uint8_t data4[5] = {};
philipel5ceaaae2016-05-24 10:20:47 +0200228
Danil Chapovalove3c48842019-12-02 15:54:27 +0100229 Insert(seq_num, kKeyFrame, kFirst, kNotLast, data1);
230 Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast, data2);
231 Insert(seq_num + 2, kKeyFrame, kNotFirst, kNotLast, data3);
232 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kNotFirst, kLast, data4).frames,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200233 ElementsAre(Pointee(SizeIs(20))));
philipel5ceaaae2016-05-24 10:20:47 +0200234}
235
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200236TEST_F(PacketBufferTest, ExpandBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100237 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700238
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200239 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Johannes Krona3705562019-08-26 16:37:11 +0200240 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200241 EXPECT_FALSE(
242 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200243
244 // Already inserted kStartSize number of packets, inserting the last packet
245 // should increase the buffer size and also result in an assembled frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200246 EXPECT_FALSE(
247 Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700248}
249
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200250TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100251 const uint16_t seq_num = Rand();
252
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200253 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
philipelaee3e0e2016-11-01 11:45:34 +0100254 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200255 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast);
256 EXPECT_THAT(Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast),
257 StartSeqNumsAre(seq_num));
philipelaee3e0e2016-11-01 11:45:34 +0100258}
259
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200260TEST_F(PacketBufferTest, ExpandBufferOverflow) {
philipelaee3e0e2016-11-01 11:45:34 +0100261 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700262
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200263 EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200264 for (int i = 1; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200265 EXPECT_FALSE(
266 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200267
268 // Already inserted kMaxSize number of packets, inserting the last packet
269 // should overflow the buffer and result in false being returned.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200270 EXPECT_TRUE(
271 Insert(seq_num + kMaxSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700272}
273
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200274TEST_F(PacketBufferTest, OnePacketOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100275 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200276 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
277 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700278}
279
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200280TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100281 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200282
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200283 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
284 StartSeqNumsAre(seq_num));
285 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast),
286 StartSeqNumsAre(seq_num + 1));
philipelc707ab72016-04-01 02:01:54 -0700287}
288
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200289TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100290 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200291
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200292 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
293 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
294 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700295}
296
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200297TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100298 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700299
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200300 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
301 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).frames,
302 IsEmpty());
303 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast),
304 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700305}
306
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200307TEST_F(PacketBufferTest, Frames) {
philipelaee3e0e2016-11-01 11:45:34 +0100308 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200309
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200310 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
311 StartSeqNumsAre(seq_num));
312 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
313 StartSeqNumsAre(seq_num + 1));
314 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
315 StartSeqNumsAre(seq_num + 2));
316 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
317 StartSeqNumsAre(seq_num + 3));
philipelf4139332016-04-20 10:26:34 +0200318}
319
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200320TEST_F(PacketBufferTest, ClearSinglePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100321 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200322
philipelaee3e0e2016-11-01 11:45:34 +0100323 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200324 Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
philipelaee3e0e2016-11-01 11:45:34 +0100325
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200326 packet_buffer_.ClearTo(seq_num);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200327 EXPECT_FALSE(
328 Insert(seq_num + kMaxSize, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelaee3e0e2016-11-01 11:45:34 +0100329}
330
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200331TEST_F(PacketBufferTest, ClearFullBuffer) {
philipelc5fb4682017-08-02 04:28:57 -0700332 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200333 Insert(i, kDeltaFrame, kFirst, kLast);
philipelc5fb4682017-08-02 04:28:57 -0700334
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200335 packet_buffer_.ClearTo(kMaxSize - 1);
philipelc5fb4682017-08-02 04:28:57 -0700336
337 for (int i = kMaxSize; i < 2 * kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200338 EXPECT_FALSE(Insert(i, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelc5fb4682017-08-02 04:28:57 -0700339}
340
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200341TEST_F(PacketBufferTest, DontClearNewerPacket) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200342 EXPECT_THAT(Insert(0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0));
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200343 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200344 EXPECT_THAT(Insert(2 * kStartSize, kKeyFrame, kFirst, kLast),
345 StartSeqNumsAre(2 * kStartSize));
346 EXPECT_THAT(Insert(3 * kStartSize + 1, kKeyFrame, kFirst, kNotLast).frames,
347 IsEmpty());
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200348 packet_buffer_.ClearTo(2 * kStartSize);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200349 EXPECT_THAT(Insert(3 * kStartSize + 2, kKeyFrame, kNotFirst, kLast),
350 StartSeqNumsAre(3 * kStartSize + 1));
philipelc5fb4682017-08-02 04:28:57 -0700351}
352
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200353TEST_F(PacketBufferTest, OneIncompleteFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100354 const uint16_t seq_num = Rand();
355
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200356 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
357 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kNotFirst, kLast),
358 StartSeqNumsAre(seq_num));
359 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
360 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100361}
362
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200363TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100364 const uint16_t seq_num = Rand();
365
366 for (int i = 1; i < kMaxSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200367 Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
368 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
369 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
370 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100371}
372
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200373TEST_F(PacketBufferTest, FramesReordered) {
philipelaee3e0e2016-11-01 11:45:34 +0100374 const uint16_t seq_num = Rand();
375
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200376 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
377 StartSeqNumsAre(seq_num + 1));
378 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
379 StartSeqNumsAre(seq_num));
380 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
381 StartSeqNumsAre(seq_num + 3));
382 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
383 StartSeqNumsAre(seq_num + 2));
philipelf4139332016-04-20 10:26:34 +0200384}
385
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200386TEST_F(PacketBufferTest, GetBitstream) {
philipelc707ab72016-04-01 02:01:54 -0700387 // "many bitstream, such data" with null termination.
Danil Chapovalove3c48842019-12-02 15:54:27 +0100388 uint8_t many[] = {0x6d, 0x61, 0x6e, 0x79, 0x20};
389 uint8_t bitstream[] = {0x62, 0x69, 0x74, 0x73, 0x74, 0x72,
390 0x65, 0x61, 0x6d, 0x2c, 0x20};
391 uint8_t such[] = {0x73, 0x75, 0x63, 0x68, 0x20};
392 uint8_t data[] = {0x64, 0x61, 0x74, 0x61, 0x0};
philipel41b8ca02016-11-07 15:42:24 +0100393
philipelaee3e0e2016-11-01 11:45:34 +0100394 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700395
Danil Chapovalove3c48842019-12-02 15:54:27 +0100396 Insert(seq_num, kKeyFrame, kFirst, kNotLast, many);
397 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast, bitstream);
398 Insert(seq_num + 2, kDeltaFrame, kNotFirst, kNotLast, such);
399 auto frames = Insert(seq_num + 3, kDeltaFrame, kNotFirst, kLast, data).frames;
philipelf4139332016-04-20 10:26:34 +0200400
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200401 ASSERT_THAT(frames, SizeIs(1));
402 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
403 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
404 ElementsAreArray("many bitstream, such data"));
philipelc707ab72016-04-01 02:01:54 -0700405}
406
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200407TEST_F(PacketBufferTest, GetBitstreamOneFrameOnePacket) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100408 uint8_t bitstream[] = "All the bitstream data for this frame!";
philipel227f8b92017-08-04 06:39:31 -0700409
Danil Chapovalove3c48842019-12-02 15:54:27 +0100410 auto frames = Insert(0, kKeyFrame, kFirst, kLast, bitstream).frames;
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200411 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
412 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100413 ElementsAreArray(bitstream));
philipel227f8b92017-08-04 06:39:31 -0700414}
415
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200416TEST_F(PacketBufferTest, GetBitstreamOneFrameFullBuffer) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100417 uint8_t data_arr[kStartSize][1];
philipel227f8b92017-08-04 06:39:31 -0700418 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700419
420 for (uint8_t i = 0; i < kStartSize; ++i) {
philipel227f8b92017-08-04 06:39:31 -0700421 data_arr[i][0] = i;
422 expected[i] = i;
423 }
424
Danil Chapovalove3c48842019-12-02 15:54:27 +0100425 Insert(0, kKeyFrame, kFirst, kNotLast, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700426 for (uint8_t i = 1; i < kStartSize - 1; ++i)
Danil Chapovalove3c48842019-12-02 15:54:27 +0100427 Insert(i, kKeyFrame, kNotFirst, kNotLast, data_arr[i]);
428 auto frames = Insert(kStartSize - 1, kKeyFrame, kNotFirst, kLast,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200429 data_arr[kStartSize - 1])
430 .frames;
philipel227f8b92017-08-04 06:39:31 -0700431
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200432 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
433 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
434 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700435}
436
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100437TEST_F(PacketBufferTest, GetBitstreamAv1) {
438 const uint8_t data1[] = {0b01'01'0000, 0b0'0100'000, 'm', 'a', 'n', 'y', ' '};
439 const uint8_t data2[] = {0b10'01'0000, 'b', 'i', 't', 's', 0};
440
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100441 auto packet1 = std::make_unique<PacketBuffer::Packet>();
442 packet1->video_header.codec = kVideoCodecAV1;
443 packet1->seq_num = 13;
444 packet1->video_header.is_first_packet_in_frame = true;
445 packet1->video_header.is_last_packet_in_frame = false;
446 packet1->video_payload = data1;
447 auto frames = packet_buffer_.InsertPacket(std::move(packet1)).frames;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100448 EXPECT_THAT(frames, IsEmpty());
449
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100450 auto packet2 = std::make_unique<PacketBuffer::Packet>();
451 packet2->video_header.codec = kVideoCodecAV1;
452 packet2->seq_num = 14;
453 packet2->video_header.is_first_packet_in_frame = false;
454 packet2->video_header.is_last_packet_in_frame = true;
455 packet2->video_payload = data2;
456 frames = packet_buffer_.InsertPacket(std::move(packet2)).frames;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100457
458 ASSERT_THAT(frames, SizeIs(1));
459 EXPECT_EQ(frames[0]->first_seq_num(), 13);
460 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), 2),
461 ElementsAre(0b0'0100'010, 10)); // obu_header and obu_size.
462 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data() + 2, frames[0]->size() - 2),
463 ElementsAreArray("many bits"));
464}
465
466TEST_F(PacketBufferTest, GetBitstreamInvalidAv1) {
467 // Two av1 payloads that can't be combined into proper frame.
468 const uint8_t data1[] = {0b01'01'0000, 0b0'0100'000, 'm', 'a', 'n', 'y', ' '};
469 const uint8_t data2[] = {0b00'01'0000, 'b', 'i', 't', 's', 0};
470
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100471 auto packet1 = std::make_unique<PacketBuffer::Packet>();
472 packet1->video_header.codec = kVideoCodecAV1;
473 packet1->seq_num = 13;
474 packet1->video_header.is_first_packet_in_frame = true;
475 packet1->video_header.is_last_packet_in_frame = false;
476 packet1->video_payload = data1;
477 auto frames = packet_buffer_.InsertPacket(std::move(packet1)).frames;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100478 EXPECT_THAT(frames, IsEmpty());
479
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100480 auto packet2 = std::make_unique<PacketBuffer::Packet>();
481 packet2->video_header.codec = kVideoCodecAV1;
482 packet2->seq_num = 14;
483 packet2->video_header.is_first_packet_in_frame = false;
484 packet2->video_header.is_last_packet_in_frame = true;
485 packet2->video_payload = data2;
486 frames = packet_buffer_.InsertPacket(std::move(packet2)).frames;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100487
488 EXPECT_THAT(frames, IsEmpty());
489}
490
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200491TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
Johannes Kron957c62e2018-10-01 14:53:01 +0200492 uint16_t kFirstSeqNum = 0;
493 uint32_t kTimestampDelta = 100;
494 uint32_t timestamp = 10000;
495 uint16_t seq_num = kFirstSeqNum;
496
497 // Loop until seq_num wraps around.
Philip Eliasson1f850a62019-03-19 12:15:00 +0000498 SeqNumUnwrapper<uint16_t> unwrapper;
Johannes Kron957c62e2018-10-01 14:53:01 +0200499 while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100500 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200501 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100502 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200503 }
Danil Chapovalove3c48842019-12-02 15:54:27 +0100504 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200505 timestamp += kTimestampDelta;
506 }
507
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200508 // Receive frame with overlapping sequence numbers.
Danil Chapovalove3c48842019-12-02 15:54:27 +0100509 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200510 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100511 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200512 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200513 EXPECT_THAT(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100514 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp).frames,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200515 SizeIs(1));
Johannes Kron957c62e2018-10-01 14:53:01 +0200516}
517
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100518// If |sps_pps_idr_is_keyframe| is true, we require keyframes to contain
519// SPS/PPS/IDR and the keyframes we create as part of the test do contain
520// SPS/PPS/IDR. If |sps_pps_idr_is_keyframe| is false, we only require and
521// create keyframes containing only IDR.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200522class PacketBufferH264Test : public PacketBufferTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200523 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200524 explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
525 : PacketBufferTest(sps_pps_idr_is_keyframe
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100526 ? "WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/"
527 : ""),
528 sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200529
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200530 PacketBufferInsertResult InsertH264(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100531 uint16_t seq_num, // packet sequence number
532 IsKeyFrame keyframe, // is keyframe
533 IsFirst first, // is first packet of frame
534 IsLast last, // is last packet of frame
535 uint32_t timestamp, // rtp timestamp
536 rtc::ArrayView<const uint8_t> data = {},
537 uint32_t width = 0, // width of frame (SPS/IDR)
538 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100539 auto packet = std::make_unique<PacketBuffer::Packet>();
540 packet->video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200541 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100542 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
543 packet->seq_num = seq_num;
544 packet->timestamp = timestamp;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200545 if (keyframe == kKeyFrame) {
546 if (sps_pps_idr_is_keyframe_) {
philipel7d745e52018-08-02 14:03:53 +0200547 h264_header.nalus[0].type = H264::NaluType::kSps;
548 h264_header.nalus[1].type = H264::NaluType::kPps;
549 h264_header.nalus[2].type = H264::NaluType::kIdr;
550 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200551 } else {
philipel7d745e52018-08-02 14:03:53 +0200552 h264_header.nalus[0].type = H264::NaluType::kIdr;
553 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200554 }
555 }
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100556 packet->video_header.width = width;
557 packet->video_header.height = height;
558 packet->video_header.is_first_packet_in_frame = first == kFirst;
559 packet->video_header.is_last_packet_in_frame = last == kLast;
560 packet->video_payload.SetData(data.data(), data.size());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200561
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100562 return PacketBufferInsertResult(
563 packet_buffer_.InsertPacket(std::move(packet)));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200564 }
565
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200566 PacketBufferInsertResult InsertH264KeyFrameWithAud(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100567 uint16_t seq_num, // packet sequence number
568 IsKeyFrame keyframe, // is keyframe
569 IsFirst first, // is first packet of frame
570 IsLast last, // is last packet of frame
571 uint32_t timestamp, // rtp timestamp
572 rtc::ArrayView<const uint8_t> data = {},
573 uint32_t width = 0, // width of frame (SPS/IDR)
574 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100575 auto packet = std::make_unique<PacketBuffer::Packet>();
576 packet->video_header.codec = kVideoCodecH264;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700577 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100578 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
579 packet->seq_num = seq_num;
580 packet->timestamp = timestamp;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700581
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200582 // this should be the start of frame.
583 RTC_CHECK(first == kFirst);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700584
585 // Insert a AUD NALU / packet without width/height.
586 h264_header.nalus[0].type = H264::NaluType::kAud;
587 h264_header.nalus_length = 1;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100588 packet->video_header.is_first_packet_in_frame = true;
589 packet->video_header.is_last_packet_in_frame = false;
590 IgnoreResult(packet_buffer_.InsertPacket(std::move(packet)));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200591 // insert IDR
Danil Chapovalove3c48842019-12-02 15:54:27 +0100592 return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp, data,
593 width, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700594 }
595
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200596 const bool sps_pps_idr_is_keyframe_;
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100597};
598
599// This fixture is used to test the general behaviour of the packet buffer
600// in both configurations.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200601class PacketBufferH264ParameterizedTest
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100602 : public ::testing::WithParamInterface<bool>,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200603 public PacketBufferH264Test {
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100604 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200605 PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200606};
607
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100608INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200609 PacketBufferH264ParameterizedTest,
610 ::testing::Bool());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200611
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200612TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200613 InsertH264(0, kKeyFrame, kFirst, kLast, 0);
614 InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200615 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200616 // Expect no frame because of missing of packet #1
617 EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).frames,
618 IsEmpty());
philipelbc5a4082017-12-06 10:41:08 +0100619}
620
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200621TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100622 uint8_t data_arr[kStartSize][1];
philipel227f8b92017-08-04 06:39:31 -0700623 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700624
625 for (uint8_t i = 0; i < kStartSize; ++i) {
philipel227f8b92017-08-04 06:39:31 -0700626 data_arr[i][0] = i;
627 expected[i] = i;
628 }
629
Danil Chapovalove3c48842019-12-02 15:54:27 +0100630 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700631 for (uint8_t i = 1; i < kStartSize - 1; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100632 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, data_arr[i]);
philipel227f8b92017-08-04 06:39:31 -0700633 }
philipel227f8b92017-08-04 06:39:31 -0700634
Danil Chapovalove3c48842019-12-02 15:54:27 +0100635 auto frames = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200636 data_arr[kStartSize - 1])
637 .frames;
638 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
639 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
640 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700641}
642
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200643TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
philipel36928452016-11-07 10:42:36 +0100644 uint16_t seq_num = Rand();
Danil Chapovalove3c48842019-12-02 15:54:27 +0100645 uint8_t data[] = "some plain old data";
philipel36928452016-11-07 10:42:36 +0100646
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100647 auto packet = std::make_unique<PacketBuffer::Packet>();
philipel7d745e52018-08-02 14:03:53 +0200648 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100649 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200650 h264_header.nalus_length = 1;
651 h264_header.nalus[0].type = H264::NaluType::kIdr;
652 h264_header.packetization_type = kH264SingleNalu;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100653 packet->seq_num = seq_num;
654 packet->video_header.codec = kVideoCodecH264;
655 packet->video_payload = data;
656 packet->video_header.is_first_packet_in_frame = true;
657 packet->video_header.is_last_packet_in_frame = true;
658 auto frames = packet_buffer_.InsertPacket(std::move(packet)).frames;
philipel36928452016-11-07 10:42:36 +0100659
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200660 ASSERT_THAT(frames, SizeIs(1));
661 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
Danil Chapovalove3c48842019-12-02 15:54:27 +0100662 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data));
663 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200664 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100665 ElementsAreArray(data));
philipel36928452016-11-07 10:42:36 +0100666}
667
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200668TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700669 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100670 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700671 uint32_t width = 640;
672 uint32_t height = 360;
673 uint32_t timestamp = 1000;
674
Danil Chapovalove3c48842019-12-02 15:54:27 +0100675 auto frames = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp, data,
676 width, height)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200677 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700678
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200679 ASSERT_THAT(frames, SizeIs(1));
680 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100681 ElementsAreArray(data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200682 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
683 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700684}
685
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200686TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700687 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100688 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700689 uint32_t width = 640;
690 uint32_t height = 360;
691 uint32_t timestamp = 1000;
692
Danil Chapovalove3c48842019-12-02 15:54:27 +0100693 auto frames = InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast,
694 timestamp, data, width, height)
695 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700696
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200697 ASSERT_THAT(StartSeqNums(frames), ElementsAre(seq_num));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700698
Danil Chapovalove3c48842019-12-02 15:54:27 +0100699 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data));
700 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200701 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
702 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
703 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100704 ElementsAreArray(data));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700705}
706
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200707TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
philipelaee3e0e2016-11-01 11:45:34 +0100708 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200709
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200710 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
711 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
712 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
713 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700714
philipel17deeb42016-08-11 15:09:26 +0200715 // Insert frame that fills the whole buffer.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200716 Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
philipel17deeb42016-08-11 15:09:26 +0200717 for (int i = 0; i < kMaxSize - 2; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200718 Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
719 EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
720 StartSeqNumsAre(seq_num + 3));
philipelc707ab72016-04-01 02:01:54 -0700721}
722
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200723TEST_F(PacketBufferTest, Clear) {
philipelaee3e0e2016-11-01 11:45:34 +0100724 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200725
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200726 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
727 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
728 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
729 StartSeqNumsAre(seq_num));
philipelf4139332016-04-20 10:26:34 +0200730
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200731 packet_buffer_.Clear();
philipelf4139332016-04-20 10:26:34 +0200732
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200733 Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
734 Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
735 EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
736 StartSeqNumsAre(seq_num + kStartSize));
philipelc707ab72016-04-01 02:01:54 -0700737}
738
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200739TEST_F(PacketBufferTest, FramesAfterClear) {
philipel20dce342016-11-28 16:14:57 +0100740 Insert(9025, kDeltaFrame, kFirst, kLast);
741 Insert(9024, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200742 packet_buffer_.ClearTo(9025);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200743 EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
744 EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipel20dce342016-11-28 16:14:57 +0100745}
746
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200747TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100748 Insert(0, kKeyFrame, kFirst, kNotLast, {}, 1000);
749 EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, {}, 1001).frames,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200750 IsEmpty());
philipel8b6995b2019-01-09 12:39:18 +0100751}
752
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200753TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
philipelea142f82017-01-11 02:01:56 -0800754 Insert(2, kKeyFrame, kNotFirst, kNotLast);
755 Insert(1, kKeyFrame, kFirst, kLast);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200756 EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).frames, IsEmpty());
philipelea142f82017-01-11 02:01:56 -0800757}
758
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200759TEST_F(PacketBufferTest, PacketTimestamps) {
Danil Chapovalov0040b662018-06-18 10:48:16 +0200760 absl::optional<int64_t> packet_ms;
761 absl::optional<int64_t> packet_keyframe_ms;
philipel3184f8e2017-05-18 08:08:53 -0700762
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200763 packet_ms = packet_buffer_.LastReceivedPacketMs();
764 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700765 EXPECT_FALSE(packet_ms);
766 EXPECT_FALSE(packet_keyframe_ms);
767
Danil Chapovalove3c48842019-12-02 15:54:27 +0100768 int64_t keyframe_ms = clock_.TimeInMilliseconds();
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100769 Insert(100, kKeyFrame, kFirst, kLast, {}, /*timestamp=*/1000);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200770 packet_ms = packet_buffer_.LastReceivedPacketMs();
771 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700772 EXPECT_TRUE(packet_ms);
773 EXPECT_TRUE(packet_keyframe_ms);
774 EXPECT_EQ(keyframe_ms, *packet_ms);
775 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
776
Danil Chapovalove3c48842019-12-02 15:54:27 +0100777 clock_.AdvanceTimeMilliseconds(100);
778 int64_t delta_ms = clock_.TimeInMilliseconds();
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100779 Insert(101, kDeltaFrame, kFirst, kLast, {}, /*timestamp=*/2000);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200780 packet_ms = packet_buffer_.LastReceivedPacketMs();
781 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700782 EXPECT_TRUE(packet_ms);
783 EXPECT_TRUE(packet_keyframe_ms);
784 EXPECT_EQ(delta_ms, *packet_ms);
785 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
786
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200787 packet_buffer_.Clear();
788 packet_ms = packet_buffer_.LastReceivedPacketMs();
789 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700790 EXPECT_FALSE(packet_ms);
791 EXPECT_FALSE(packet_keyframe_ms);
792}
793
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100794TEST_F(PacketBufferTest,
795 LastReceivedKeyFrameReturnsReceiveTimeOfALastReceivedPacketOfAKeyFrame) {
796 clock_.AdvanceTimeMilliseconds(100);
797 Insert(/*seq_num=*/100, kKeyFrame, kFirst, kNotLast, {}, /*timestamp=*/1000);
798 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
799 clock_.TimeInMilliseconds());
800
801 clock_.AdvanceTimeMilliseconds(100);
802 Insert(/*seq_num=*/102, kDeltaFrame, kNotFirst, kLast, {},
803 /*timestamp=*/1000);
804 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
805 clock_.TimeInMilliseconds());
806
807 clock_.AdvanceTimeMilliseconds(100);
808 Insert(/*seq_num=*/101, kDeltaFrame, kNotFirst, kNotLast, {},
809 /*timestamp=*/1000);
810 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
811 clock_.TimeInMilliseconds());
812
813 clock_.AdvanceTimeMilliseconds(100);
814 Insert(/*seq_num=*/103, kDeltaFrame, kFirst, kNotLast, {},
815 /*timestamp=*/2000);
816 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
817 clock_.TimeInMilliseconds() - 100);
818}
819
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200820TEST_F(PacketBufferTest, IncomingCodecChange) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100821 auto packet = std::make_unique<PacketBuffer::Packet>();
822 packet->video_header.is_first_packet_in_frame = true;
823 packet->video_header.is_last_packet_in_frame = true;
824 packet->video_header.codec = kVideoCodecVP8;
825 packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
826 packet->timestamp = 1;
827 packet->seq_num = 1;
828 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
829 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames, SizeIs(1));
philipel09133af2018-05-17 14:11:09 +0200830
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100831 packet = std::make_unique<PacketBuffer::Packet>();
832 packet->video_header.is_first_packet_in_frame = true;
833 packet->video_header.is_last_packet_in_frame = true;
834 packet->video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200835 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100836 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200837 h264_header.nalus_length = 1;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100838 packet->timestamp = 3;
839 packet->seq_num = 3;
840 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
841 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200842
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100843 packet = std::make_unique<PacketBuffer::Packet>();
844 packet->video_header.is_first_packet_in_frame = true;
845 packet->video_header.is_last_packet_in_frame = true;
846 packet->video_header.codec = kVideoCodecVP8;
847 packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
848 packet->timestamp = 2;
849 packet->seq_num = 2;
850 packet->video_header.frame_type = VideoFrameType::kVideoFrameDelta;
851 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames, SizeIs(2));
philipel09133af2018-05-17 14:11:09 +0200852}
853
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200854TEST_F(PacketBufferTest, TooManyNalusInPacket) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100855 auto packet = std::make_unique<PacketBuffer::Packet>();
856 packet->video_header.codec = kVideoCodecH264;
857 packet->timestamp = 1;
858 packet->seq_num = 1;
859 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
860 packet->video_header.is_first_packet_in_frame = true;
861 packet->video_header.is_last_packet_in_frame = true;
philipel7d745e52018-08-02 14:03:53 +0200862 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100863 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200864 h264_header.nalus_length = kMaxNalusPerPacket;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100865 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200866}
867
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200868TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
philipel2c9f9f22017-06-13 02:47:28 -0700869 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
870 for (int i = 1; i < kStartSize - 1; ++i)
871 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200872 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
873 StartSeqNumsAre(0));
philipel2c9f9f22017-06-13 02:47:28 -0700874}
875
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200876TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200877 EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).frames,
878 SizeIs(1));
philipel227f8b92017-08-04 06:39:31 -0700879
880 InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
881 for (int i = 1; i < kStartSize; ++i)
882 InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200883 EXPECT_THAT(
884 InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
885 .frames,
886 IsEmpty());
philipel227f8b92017-08-04 06:39:31 -0700887
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200888 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
889 StartSeqNumsAre(kStartSize - 1, kStartSize));
philipel227f8b92017-08-04 06:39:31 -0700890}
891
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200892TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
philipel2c9f9f22017-06-13 02:47:28 -0700893 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200894 EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
895 StartSeqNumsAre(65534));
philipel2c9f9f22017-06-13 02:47:28 -0700896}
897
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200898TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
philipel2c9f9f22017-06-13 02:47:28 -0700899 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
900 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
901 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
902 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
903
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200904 EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
905 StartSeqNumsAre(kStartSize + 1));
philipel2c9f9f22017-06-13 02:47:28 -0700906}
907
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200908TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200909 EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
910 StartSeqNumsAre(0));
911 EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).frames,
912 IsEmpty());
philipel2c9f9f22017-06-13 02:47:28 -0700913
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200914 EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
philipel2c9f9f22017-06-13 02:47:28 -0700915}
916
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200917class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200918 protected:
919 const uint16_t kSeqNum = 5;
920
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200921 explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100922 : PacketBufferH264Test(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200923
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100924 std::unique_ptr<PacketBuffer::Packet> CreatePacket() {
925 auto packet = std::make_unique<PacketBuffer::Packet>();
926 packet->video_header.codec = kVideoCodecH264;
927 packet->seq_num = kSeqNum;
928
929 packet->video_header.is_first_packet_in_frame = true;
930 packet->video_header.is_last_packet_in_frame = true;
931 return packet;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200932 }
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200933};
934
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200935class PacketBufferH264IdrIsKeyframeTest
936 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200937 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200938 PacketBufferH264IdrIsKeyframeTest()
939 : PacketBufferH264XIsKeyframeTest(false) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200940};
941
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200942TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100943 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200944 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100945 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200946 h264_header.nalus[0].type = H264::NaluType::kIdr;
947 h264_header.nalus_length = 1;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100948 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200949 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200950}
951
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200952TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100953 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200954 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100955 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200956 h264_header.nalus[0].type = H264::NaluType::kSps;
957 h264_header.nalus[1].type = H264::NaluType::kPps;
958 h264_header.nalus[2].type = H264::NaluType::kIdr;
959 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200960
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100961 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200962 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200963}
964
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200965class PacketBufferH264SpsPpsIdrIsKeyframeTest
966 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200967 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200968 PacketBufferH264SpsPpsIdrIsKeyframeTest()
969 : PacketBufferH264XIsKeyframeTest(true) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200970};
971
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200972TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100973 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200974 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100975 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200976 h264_header.nalus[0].type = H264::NaluType::kIdr;
977 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200978
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100979 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200980 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200981}
982
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200983TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100984 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200985 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100986 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200987 h264_header.nalus[0].type = H264::NaluType::kSps;
988 h264_header.nalus[1].type = H264::NaluType::kPps;
989 h264_header.nalus_length = 2;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200990
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100991 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200992 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200993}
994
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200995TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100996 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200997 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100998 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200999 h264_header.nalus[0].type = H264::NaluType::kSps;
1000 h264_header.nalus[1].type = H264::NaluType::kPps;
1001 h264_header.nalus[2].type = H264::NaluType::kIdr;
1002 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001003
Danil Chapovalov97ffbef2020-01-24 16:04:35 +01001004 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).frames,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001005 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001006}
1007
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001008} // namespace
philipelc707ab72016-04-01 02:01:54 -07001009} // namespace video_coding
1010} // namespace webrtc