blob: cc1f1779eaa799059f50a00c3b08698e15a2c44f [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"
Rasmus Brandtedf4ff72017-10-24 10:07:48 +020022#include "test/field_trial.h"
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020023#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020024#include "test/gtest.h"
philipelc707ab72016-04-01 02:01:54 -070025
26namespace webrtc {
27namespace video_coding {
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020028namespace {
philipelc707ab72016-04-01 02:01:54 -070029
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020030using ::testing::ElementsAre;
Danil Chapovalov1dac7072019-10-24 12:44:23 +020031using ::testing::ElementsAreArray;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020032using ::testing::IsEmpty;
Danil Chapovalov1dac7072019-10-24 12:44:23 +020033using ::testing::Matches;
34using ::testing::Pointee;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020035using ::testing::SizeIs;
36
Danil Chapovalov1dac7072019-10-24 12:44:23 +020037constexpr int kStartSize = 16;
38constexpr int kMaxSize = 64;
39
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020040void IgnoreResult(PacketBuffer::InsertResult /*result*/) {}
41
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010042// Validates frame boundaries are valid and returns first sequence_number for
43// each frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +020044std::vector<uint16_t> StartSeqNums(
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010045 rtc::ArrayView<const std::unique_ptr<PacketBuffer::Packet>> packets) {
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020046 std::vector<uint16_t> result;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010047 bool frame_boundary = true;
48 for (const auto& packet : packets) {
49 EXPECT_EQ(frame_boundary, packet->is_first_packet_in_frame());
50 if (packet->is_first_packet_in_frame()) {
51 result.push_back(packet->seq_num);
52 }
53 frame_boundary = packet->is_last_packet_in_frame();
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020054 }
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010055 EXPECT_TRUE(frame_boundary);
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020056 return result;
57}
58
Danil Chapovalov1dac7072019-10-24 12:44:23 +020059MATCHER_P(StartSeqNumsAre, seq_num, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010060 return Matches(ElementsAre(seq_num))(StartSeqNums(arg.packets));
Danil Chapovalov1dac7072019-10-24 12:44:23 +020061}
62
63MATCHER_P2(StartSeqNumsAre, seq_num1, seq_num2, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010064 return Matches(ElementsAre(seq_num1, seq_num2))(StartSeqNums(arg.packets));
Danil Chapovalov1dac7072019-10-24 12:44:23 +020065}
66
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020067MATCHER(KeyFrame, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010068 return arg->is_first_packet_in_frame() &&
69 arg->video_header.frame_type == VideoFrameType::kVideoFrameKey;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020070}
71
72MATCHER(DeltaFrame, "") {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010073 return arg->is_first_packet_in_frame() &&
74 arg->video_header.frame_type == VideoFrameType::kVideoFrameDelta;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020075}
76
Danil Chapovalov1dac7072019-10-24 12:44:23 +020077struct PacketBufferInsertResult : public PacketBuffer::InsertResult {
78 explicit PacketBufferInsertResult(PacketBuffer::InsertResult result)
79 : InsertResult(std::move(result)) {}
80};
81
82void PrintTo(const PacketBufferInsertResult& result, std::ostream* os) {
83 *os << "frames: { ";
Danil Chapovalov810b4ca2020-03-19 13:56:11 +010084 for (const auto& packet : result.packets) {
85 if (packet->is_first_packet_in_frame() &&
86 packet->is_last_packet_in_frame()) {
87 *os << "{sn: " << packet->seq_num << " }";
88 } else if (packet->is_first_packet_in_frame()) {
89 *os << "{sn: [" << packet->seq_num << "-";
90 } else if (packet->is_last_packet_in_frame()) {
91 *os << packet->seq_num << "] }, ";
Danil Chapovalov1dac7072019-10-24 12:44:23 +020092 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +020093 }
94 *os << " }";
95 if (result.buffer_cleared) {
96 *os << ", buffer_cleared";
97 }
98}
99
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200100class PacketBufferTest : public ::testing::Test {
philipelc707ab72016-04-01 02:01:54 -0700101 protected:
philipelce423ce2021-04-12 13:42:03 +0200102 PacketBufferTest() : rand_(0x7732213), packet_buffer_(kStartSize, kMaxSize) {}
philipelc707ab72016-04-01 02:01:54 -0700103
philipel17deeb42016-08-11 15:09:26 +0200104 uint16_t Rand() { return rand_.Rand<uint16_t>(); }
philipelc707ab72016-04-01 02:01:54 -0700105
philipel17deeb42016-08-11 15:09:26 +0200106 enum IsKeyFrame { kKeyFrame, kDeltaFrame };
107 enum IsFirst { kFirst, kNotFirst };
108 enum IsLast { kLast, kNotLast };
philipelc707ab72016-04-01 02:01:54 -0700109
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200110 PacketBufferInsertResult Insert(uint16_t seq_num, // packet sequence number
111 IsKeyFrame keyframe, // is keyframe
112 IsFirst first, // is first packet of frame
113 IsLast last, // is last packet of frame
Danil Chapovalove3c48842019-12-02 15:54:27 +0100114 rtc::ArrayView<const uint8_t> data = {},
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200115 uint32_t timestamp = 123u) { // rtp timestamp
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100116 auto packet = std::make_unique<PacketBuffer::Packet>();
117 packet->video_header.codec = kVideoCodecGeneric;
118 packet->timestamp = timestamp;
119 packet->seq_num = seq_num;
120 packet->video_header.frame_type = keyframe == kKeyFrame
121 ? VideoFrameType::kVideoFrameKey
122 : VideoFrameType::kVideoFrameDelta;
123 packet->video_header.is_first_packet_in_frame = first == kFirst;
124 packet->video_header.is_last_packet_in_frame = last == kLast;
125 packet->video_payload.SetData(data.data(), data.size());
philipelf4139332016-04-20 10:26:34 +0200126
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100127 return PacketBufferInsertResult(
128 packet_buffer_.InsertPacket(std::move(packet)));
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200129 }
130
philipelc707ab72016-04-01 02:01:54 -0700131 Random rand_;
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 Chapovalov810b4ca2020-03-19 13:56:11 +0100137 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, 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 Chapovalov810b4ca2020-03-19 13:56:11 +0100142 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
143 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
144 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).packets, SizeIs(1));
145 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kFirst, kLast).packets, 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 Chapovalov810b4ca2020-03-19 13:56:11 +0100150 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
151 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
152 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).packets,
153 SizeIs(2));
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 Chapovalov810b4ca2020-03-19 13:56:11 +0100169 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
170 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
171 EXPECT_THAT(Insert(101, kKeyFrame, kNotFirst, kLast).packets, SizeIs(2));
philipelaee3e0e2016-11-01 11:45:34 +0100172
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100173 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
174 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
175 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100176
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200177 packet_buffer_.ClearTo(102);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100178 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).packets, IsEmpty());
179 EXPECT_THAT(Insert(103, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
philipel5ceaaae2016-05-24 10:20:47 +0200180}
181
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200182TEST_F(PacketBufferTest, FrameSize) {
philipelaee3e0e2016-11-01 11:45:34 +0100183 const uint16_t seq_num = Rand();
Danil Chapovalove3c48842019-12-02 15:54:27 +0100184 uint8_t data1[5] = {};
185 uint8_t data2[5] = {};
186 uint8_t data3[5] = {};
187 uint8_t data4[5] = {};
philipel5ceaaae2016-05-24 10:20:47 +0200188
Danil Chapovalove3c48842019-12-02 15:54:27 +0100189 Insert(seq_num, kKeyFrame, kFirst, kNotLast, data1);
190 Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast, data2);
191 Insert(seq_num + 2, kKeyFrame, kNotFirst, kNotLast, data3);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100192 auto packets =
193 Insert(seq_num + 3, kKeyFrame, kNotFirst, kLast, data4).packets;
194 // Expect one frame of 4 packets.
195 EXPECT_THAT(StartSeqNums(packets), ElementsAre(seq_num));
196 EXPECT_THAT(packets, SizeIs(4));
philipel5ceaaae2016-05-24 10:20:47 +0200197}
198
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200199TEST_F(PacketBufferTest, ExpandBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100200 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700201
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200202 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Johannes Krona3705562019-08-26 16:37:11 +0200203 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200204 EXPECT_FALSE(
205 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200206
207 // Already inserted kStartSize number of packets, inserting the last packet
208 // should increase the buffer size and also result in an assembled frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200209 EXPECT_FALSE(
210 Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700211}
212
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200213TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100214 const uint16_t seq_num = Rand();
215
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200216 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
philipelaee3e0e2016-11-01 11:45:34 +0100217 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200218 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast);
219 EXPECT_THAT(Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast),
220 StartSeqNumsAre(seq_num));
philipelaee3e0e2016-11-01 11:45:34 +0100221}
222
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200223TEST_F(PacketBufferTest, ExpandBufferOverflow) {
philipelaee3e0e2016-11-01 11:45:34 +0100224 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700225
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200226 EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200227 for (int i = 1; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200228 EXPECT_FALSE(
229 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200230
231 // Already inserted kMaxSize number of packets, inserting the last packet
232 // should overflow the buffer and result in false being returned.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200233 EXPECT_TRUE(
234 Insert(seq_num + kMaxSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700235}
236
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200237TEST_F(PacketBufferTest, OnePacketOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100238 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200239 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
240 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700241}
242
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200243TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100244 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200245
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200246 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
247 StartSeqNumsAre(seq_num));
248 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast),
249 StartSeqNumsAre(seq_num + 1));
philipelc707ab72016-04-01 02:01:54 -0700250}
251
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200252TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100253 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200254
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100255 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200256 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
257 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700258}
259
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200260TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100261 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700262
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100263 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).packets, IsEmpty());
264 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200265 IsEmpty());
266 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast),
267 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700268}
269
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200270TEST_F(PacketBufferTest, Frames) {
philipelaee3e0e2016-11-01 11:45:34 +0100271 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200272
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200273 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
274 StartSeqNumsAre(seq_num));
275 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
276 StartSeqNumsAre(seq_num + 1));
277 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
278 StartSeqNumsAre(seq_num + 2));
279 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
280 StartSeqNumsAre(seq_num + 3));
philipelf4139332016-04-20 10:26:34 +0200281}
282
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200283TEST_F(PacketBufferTest, ClearSinglePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100284 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200285
philipelaee3e0e2016-11-01 11:45:34 +0100286 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200287 Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
philipelaee3e0e2016-11-01 11:45:34 +0100288
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200289 packet_buffer_.ClearTo(seq_num);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200290 EXPECT_FALSE(
291 Insert(seq_num + kMaxSize, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelaee3e0e2016-11-01 11:45:34 +0100292}
293
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200294TEST_F(PacketBufferTest, ClearFullBuffer) {
philipelc5fb4682017-08-02 04:28:57 -0700295 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200296 Insert(i, kDeltaFrame, kFirst, kLast);
philipelc5fb4682017-08-02 04:28:57 -0700297
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200298 packet_buffer_.ClearTo(kMaxSize - 1);
philipelc5fb4682017-08-02 04:28:57 -0700299
300 for (int i = kMaxSize; i < 2 * kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200301 EXPECT_FALSE(Insert(i, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelc5fb4682017-08-02 04:28:57 -0700302}
303
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200304TEST_F(PacketBufferTest, DontClearNewerPacket) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200305 EXPECT_THAT(Insert(0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0));
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200306 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200307 EXPECT_THAT(Insert(2 * kStartSize, kKeyFrame, kFirst, kLast),
308 StartSeqNumsAre(2 * kStartSize));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100309 EXPECT_THAT(Insert(3 * kStartSize + 1, kKeyFrame, kFirst, kNotLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200310 IsEmpty());
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200311 packet_buffer_.ClearTo(2 * kStartSize);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200312 EXPECT_THAT(Insert(3 * kStartSize + 2, kKeyFrame, kNotFirst, kLast),
313 StartSeqNumsAre(3 * kStartSize + 1));
philipelc5fb4682017-08-02 04:28:57 -0700314}
315
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200316TEST_F(PacketBufferTest, OneIncompleteFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100317 const uint16_t seq_num = Rand();
318
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100319 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets,
320 IsEmpty());
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200321 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kNotFirst, kLast),
322 StartSeqNumsAre(seq_num));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100323 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200324 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100325}
326
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200327TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100328 const uint16_t seq_num = Rand();
329
330 for (int i = 1; i < kMaxSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200331 Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100332 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).packets,
333 IsEmpty());
334 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200335 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100336}
337
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200338TEST_F(PacketBufferTest, FramesReordered) {
philipelaee3e0e2016-11-01 11:45:34 +0100339 const uint16_t seq_num = Rand();
340
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200341 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
342 StartSeqNumsAre(seq_num + 1));
343 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
344 StartSeqNumsAre(seq_num));
345 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
346 StartSeqNumsAre(seq_num + 3));
347 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
348 StartSeqNumsAre(seq_num + 2));
philipelf4139332016-04-20 10:26:34 +0200349}
350
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200351TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
Johannes Kron957c62e2018-10-01 14:53:01 +0200352 uint16_t kFirstSeqNum = 0;
353 uint32_t kTimestampDelta = 100;
354 uint32_t timestamp = 10000;
355 uint16_t seq_num = kFirstSeqNum;
356
357 // Loop until seq_num wraps around.
Philip Eliasson1f850a62019-03-19 12:15:00 +0000358 SeqNumUnwrapper<uint16_t> unwrapper;
Johannes Kron957c62e2018-10-01 14:53:01 +0200359 while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100360 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200361 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100362 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200363 }
Danil Chapovalove3c48842019-12-02 15:54:27 +0100364 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200365 timestamp += kTimestampDelta;
366 }
367
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200368 // Receive frame with overlapping sequence numbers.
Danil Chapovalove3c48842019-12-02 15:54:27 +0100369 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200370 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100371 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200372 }
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100373 auto packets =
374 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp).packets;
375 // One frame of 7 packets.
376 EXPECT_THAT(StartSeqNums(packets), SizeIs(1));
377 EXPECT_THAT(packets, SizeIs(7));
Johannes Kron957c62e2018-10-01 14:53:01 +0200378}
379
Artem Titovdcd7fc72021-08-09 13:02:57 +0200380// If `sps_pps_idr_is_keyframe` is true, we require keyframes to contain
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100381// SPS/PPS/IDR and the keyframes we create as part of the test do contain
Artem Titovdcd7fc72021-08-09 13:02:57 +0200382// SPS/PPS/IDR. If `sps_pps_idr_is_keyframe` is false, we only require and
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100383// create keyframes containing only IDR.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200384class PacketBufferH264Test : public PacketBufferTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200385 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200386 explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
Eldar Rello2127aaa2020-08-07 12:08:14 +0300387 : PacketBufferTest(), sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {
388 if (sps_pps_idr_is_keyframe) {
389 packet_buffer_.ForceSpsPpsIdrIsH264Keyframe();
390 }
391 }
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200392
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200393 PacketBufferInsertResult InsertH264(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100394 uint16_t seq_num, // packet sequence number
395 IsKeyFrame keyframe, // is keyframe
396 IsFirst first, // is first packet of frame
397 IsLast last, // is last packet of frame
398 uint32_t timestamp, // rtp timestamp
399 rtc::ArrayView<const uint8_t> data = {},
400 uint32_t width = 0, // width of frame (SPS/IDR)
401 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100402 auto packet = std::make_unique<PacketBuffer::Packet>();
403 packet->video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200404 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100405 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
406 packet->seq_num = seq_num;
407 packet->timestamp = timestamp;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200408 if (keyframe == kKeyFrame) {
409 if (sps_pps_idr_is_keyframe_) {
philipel7d745e52018-08-02 14:03:53 +0200410 h264_header.nalus[0].type = H264::NaluType::kSps;
411 h264_header.nalus[1].type = H264::NaluType::kPps;
412 h264_header.nalus[2].type = H264::NaluType::kIdr;
413 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200414 } else {
philipel7d745e52018-08-02 14:03:53 +0200415 h264_header.nalus[0].type = H264::NaluType::kIdr;
416 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200417 }
418 }
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100419 packet->video_header.width = width;
420 packet->video_header.height = height;
421 packet->video_header.is_first_packet_in_frame = first == kFirst;
422 packet->video_header.is_last_packet_in_frame = last == kLast;
423 packet->video_payload.SetData(data.data(), data.size());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200424
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100425 return PacketBufferInsertResult(
426 packet_buffer_.InsertPacket(std::move(packet)));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200427 }
428
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200429 PacketBufferInsertResult InsertH264KeyFrameWithAud(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100430 uint16_t seq_num, // packet sequence number
431 IsKeyFrame keyframe, // is keyframe
432 IsFirst first, // is first packet of frame
433 IsLast last, // is last packet of frame
434 uint32_t timestamp, // rtp timestamp
435 rtc::ArrayView<const uint8_t> data = {},
436 uint32_t width = 0, // width of frame (SPS/IDR)
437 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100438 auto packet = std::make_unique<PacketBuffer::Packet>();
439 packet->video_header.codec = kVideoCodecH264;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700440 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100441 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
442 packet->seq_num = seq_num;
443 packet->timestamp = timestamp;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700444
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200445 // this should be the start of frame.
446 RTC_CHECK(first == kFirst);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700447
448 // Insert a AUD NALU / packet without width/height.
449 h264_header.nalus[0].type = H264::NaluType::kAud;
450 h264_header.nalus_length = 1;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100451 packet->video_header.is_first_packet_in_frame = true;
452 packet->video_header.is_last_packet_in_frame = false;
453 IgnoreResult(packet_buffer_.InsertPacket(std::move(packet)));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200454 // insert IDR
Danil Chapovalove3c48842019-12-02 15:54:27 +0100455 return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp, data,
456 width, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700457 }
458
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200459 const bool sps_pps_idr_is_keyframe_;
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100460};
461
462// This fixture is used to test the general behaviour of the packet buffer
463// in both configurations.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200464class PacketBufferH264ParameterizedTest
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100465 : public ::testing::WithParamInterface<bool>,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200466 public PacketBufferH264Test {
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100467 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200468 PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200469};
470
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100471INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200472 PacketBufferH264ParameterizedTest,
473 ::testing::Bool());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200474
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200475TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200476 InsertH264(0, kKeyFrame, kFirst, kLast, 0);
477 InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200478 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200479 // Expect no frame because of missing of packet #1
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100480 EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200481 IsEmpty());
philipelbc5a4082017-12-06 10:41:08 +0100482}
483
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200484TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100485 uint8_t data_arr[kStartSize][1];
philipel227f8b92017-08-04 06:39:31 -0700486 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700487
488 for (uint8_t i = 0; i < kStartSize; ++i) {
philipel227f8b92017-08-04 06:39:31 -0700489 data_arr[i][0] = i;
490 expected[i] = i;
491 }
492
Danil Chapovalove3c48842019-12-02 15:54:27 +0100493 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700494 for (uint8_t i = 1; i < kStartSize - 1; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100495 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, data_arr[i]);
philipel227f8b92017-08-04 06:39:31 -0700496 }
philipel227f8b92017-08-04 06:39:31 -0700497
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100498 auto packets = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1,
499 data_arr[kStartSize - 1])
500 .packets;
501 ASSERT_THAT(StartSeqNums(packets), ElementsAre(0));
502 EXPECT_THAT(packets, SizeIs(kStartSize));
503 for (size_t i = 0; i < packets.size(); ++i) {
504 EXPECT_THAT(packets[i]->video_payload, SizeIs(1)) << "Packet #" << i;
505 }
philipel227f8b92017-08-04 06:39:31 -0700506}
507
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200508TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
philipel36928452016-11-07 10:42:36 +0100509 uint16_t seq_num = Rand();
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100510 rtc::CopyOnWriteBuffer data = "some plain old data";
philipel36928452016-11-07 10:42:36 +0100511
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100512 auto packet = std::make_unique<PacketBuffer::Packet>();
philipel7d745e52018-08-02 14:03:53 +0200513 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100514 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200515 h264_header.nalus_length = 1;
516 h264_header.nalus[0].type = H264::NaluType::kIdr;
517 h264_header.packetization_type = kH264SingleNalu;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100518 packet->seq_num = seq_num;
519 packet->video_header.codec = kVideoCodecH264;
520 packet->video_payload = data;
521 packet->video_header.is_first_packet_in_frame = true;
522 packet->video_header.is_last_packet_in_frame = true;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100523 auto frames = packet_buffer_.InsertPacket(std::move(packet)).packets;
philipel36928452016-11-07 10:42:36 +0100524
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200525 ASSERT_THAT(frames, SizeIs(1));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100526 EXPECT_EQ(frames[0]->seq_num, seq_num);
527 EXPECT_EQ(frames[0]->video_payload, data);
philipel36928452016-11-07 10:42:36 +0100528}
529
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200530TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700531 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100532 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700533 uint32_t width = 640;
534 uint32_t height = 360;
535 uint32_t timestamp = 1000;
536
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100537 auto packets = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp, data,
538 width, height)
539 .packets;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700540
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100541 ASSERT_THAT(packets, SizeIs(1));
542 EXPECT_EQ(packets[0]->video_header.width, width);
543 EXPECT_EQ(packets[0]->video_header.height, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700544}
545
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200546TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700547 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100548 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700549 uint32_t width = 640;
550 uint32_t height = 360;
551 uint32_t timestamp = 1000;
552
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100553 auto packets = InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast,
554 timestamp, data, width, height)
555 .packets;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700556
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100557 ASSERT_THAT(StartSeqNums(packets), ElementsAre(seq_num));
558 EXPECT_EQ(packets[0]->video_header.width, width);
559 EXPECT_EQ(packets[0]->video_header.height, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700560}
561
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200562TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
philipelaee3e0e2016-11-01 11:45:34 +0100563 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200564
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200565 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
566 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
567 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
568 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700569
philipel17deeb42016-08-11 15:09:26 +0200570 // Insert frame that fills the whole buffer.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200571 Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
philipel17deeb42016-08-11 15:09:26 +0200572 for (int i = 0; i < kMaxSize - 2; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200573 Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
574 EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
575 StartSeqNumsAre(seq_num + 3));
philipelc707ab72016-04-01 02:01:54 -0700576}
577
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200578TEST_F(PacketBufferTest, Clear) {
philipelaee3e0e2016-11-01 11:45:34 +0100579 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200580
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200581 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
582 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
583 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
584 StartSeqNumsAre(seq_num));
philipelf4139332016-04-20 10:26:34 +0200585
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200586 packet_buffer_.Clear();
philipelf4139332016-04-20 10:26:34 +0200587
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200588 Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
589 Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
590 EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
591 StartSeqNumsAre(seq_num + kStartSize));
philipelc707ab72016-04-01 02:01:54 -0700592}
593
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200594TEST_F(PacketBufferTest, FramesAfterClear) {
philipel20dce342016-11-28 16:14:57 +0100595 Insert(9025, kDeltaFrame, kFirst, kLast);
596 Insert(9024, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200597 packet_buffer_.ClearTo(9025);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100598 EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
599 EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).packets, SizeIs(1));
philipel20dce342016-11-28 16:14:57 +0100600}
601
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200602TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100603 Insert(0, kKeyFrame, kFirst, kNotLast, {}, 1000);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100604 EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, {}, 1001).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200605 IsEmpty());
philipel8b6995b2019-01-09 12:39:18 +0100606}
607
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200608TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
philipelea142f82017-01-11 02:01:56 -0800609 Insert(2, kKeyFrame, kNotFirst, kNotLast);
610 Insert(1, kKeyFrame, kFirst, kLast);
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100611 EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).packets, IsEmpty());
philipelea142f82017-01-11 02:01:56 -0800612}
613
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200614TEST_F(PacketBufferTest, IncomingCodecChange) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100615 auto packet = std::make_unique<PacketBuffer::Packet>();
616 packet->video_header.is_first_packet_in_frame = true;
617 packet->video_header.is_last_packet_in_frame = true;
618 packet->video_header.codec = kVideoCodecVP8;
619 packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
620 packet->timestamp = 1;
621 packet->seq_num = 1;
622 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100623 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
624 SizeIs(1));
philipel09133af2018-05-17 14:11:09 +0200625
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100626 packet = std::make_unique<PacketBuffer::Packet>();
627 packet->video_header.is_first_packet_in_frame = true;
628 packet->video_header.is_last_packet_in_frame = true;
629 packet->video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200630 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100631 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200632 h264_header.nalus_length = 1;
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100633 packet->timestamp = 3;
634 packet->seq_num = 3;
635 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100636 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
637 IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200638
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100639 packet = std::make_unique<PacketBuffer::Packet>();
640 packet->video_header.is_first_packet_in_frame = true;
641 packet->video_header.is_last_packet_in_frame = true;
642 packet->video_header.codec = kVideoCodecVP8;
643 packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
644 packet->timestamp = 2;
645 packet->seq_num = 2;
646 packet->video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100647 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
648 SizeIs(2));
philipel09133af2018-05-17 14:11:09 +0200649}
650
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200651TEST_F(PacketBufferTest, TooManyNalusInPacket) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100652 auto packet = std::make_unique<PacketBuffer::Packet>();
653 packet->video_header.codec = kVideoCodecH264;
654 packet->timestamp = 1;
655 packet->seq_num = 1;
656 packet->video_header.frame_type = VideoFrameType::kVideoFrameKey;
657 packet->video_header.is_first_packet_in_frame = true;
658 packet->video_header.is_last_packet_in_frame = true;
philipel7d745e52018-08-02 14:03:53 +0200659 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100660 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200661 h264_header.nalus_length = kMaxNalusPerPacket;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100662 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
663 IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200664}
665
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200666TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
philipel2c9f9f22017-06-13 02:47:28 -0700667 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
668 for (int i = 1; i < kStartSize - 1; ++i)
669 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200670 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
671 StartSeqNumsAre(0));
philipel2c9f9f22017-06-13 02:47:28 -0700672}
673
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200674TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100675 EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200676 SizeIs(1));
philipel227f8b92017-08-04 06:39:31 -0700677
678 InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
679 for (int i = 1; i < kStartSize; ++i)
680 InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200681 EXPECT_THAT(
682 InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100683 .packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200684 IsEmpty());
philipel227f8b92017-08-04 06:39:31 -0700685
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200686 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
687 StartSeqNumsAre(kStartSize - 1, kStartSize));
philipel227f8b92017-08-04 06:39:31 -0700688}
689
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200690TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
philipel2c9f9f22017-06-13 02:47:28 -0700691 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200692 EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
693 StartSeqNumsAre(65534));
philipel2c9f9f22017-06-13 02:47:28 -0700694}
695
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200696TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
philipel2c9f9f22017-06-13 02:47:28 -0700697 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
698 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
699 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
700 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
701
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200702 EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
703 StartSeqNumsAre(kStartSize + 1));
philipel2c9f9f22017-06-13 02:47:28 -0700704}
705
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200706TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200707 EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
708 StartSeqNumsAre(0));
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100709 EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).packets,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200710 IsEmpty());
philipel2c9f9f22017-06-13 02:47:28 -0700711
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200712 EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
philipel2c9f9f22017-06-13 02:47:28 -0700713}
714
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200715class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200716 protected:
717 const uint16_t kSeqNum = 5;
718
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200719 explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100720 : PacketBufferH264Test(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200721
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100722 std::unique_ptr<PacketBuffer::Packet> CreatePacket() {
723 auto packet = std::make_unique<PacketBuffer::Packet>();
724 packet->video_header.codec = kVideoCodecH264;
725 packet->seq_num = kSeqNum;
726
727 packet->video_header.is_first_packet_in_frame = true;
728 packet->video_header.is_last_packet_in_frame = true;
729 return packet;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200730 }
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200731};
732
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200733class PacketBufferH264IdrIsKeyframeTest
734 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200735 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200736 PacketBufferH264IdrIsKeyframeTest()
737 : PacketBufferH264XIsKeyframeTest(false) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200738};
739
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200740TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100741 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200742 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100743 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200744 h264_header.nalus[0].type = H264::NaluType::kIdr;
745 h264_header.nalus_length = 1;
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100746 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200747 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200748}
749
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200750TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100751 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200752 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100753 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200754 h264_header.nalus[0].type = H264::NaluType::kSps;
755 h264_header.nalus[1].type = H264::NaluType::kPps;
756 h264_header.nalus[2].type = H264::NaluType::kIdr;
757 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200758
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100759 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200760 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200761}
762
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200763class PacketBufferH264SpsPpsIdrIsKeyframeTest
764 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200765 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200766 PacketBufferH264SpsPpsIdrIsKeyframeTest()
767 : PacketBufferH264XIsKeyframeTest(true) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200768};
769
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200770TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100771 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200772 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100773 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200774 h264_header.nalus[0].type = H264::NaluType::kIdr;
775 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200776
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100777 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200778 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200779}
780
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200781TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100782 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200783 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100784 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200785 h264_header.nalus[0].type = H264::NaluType::kSps;
786 h264_header.nalus[1].type = H264::NaluType::kPps;
787 h264_header.nalus_length = 2;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200788
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100789 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200790 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200791}
792
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200793TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100794 auto packet = CreatePacket();
philipel7d745e52018-08-02 14:03:53 +0200795 auto& h264_header =
Danil Chapovalov97ffbef2020-01-24 16:04:35 +0100796 packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
philipel7d745e52018-08-02 14:03:53 +0200797 h264_header.nalus[0].type = H264::NaluType::kSps;
798 h264_header.nalus[1].type = H264::NaluType::kPps;
799 h264_header.nalus[2].type = H264::NaluType::kIdr;
800 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200801
Danil Chapovalov810b4ca2020-03-19 13:56:11 +0100802 EXPECT_THAT(packet_buffer_.InsertPacket(std::move(packet)).packets,
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200803 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200804}
805
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200806} // namespace
philipelc707ab72016-04-01 02:01:54 -0700807} // namespace video_coding
808} // namespace webrtc