blob: b1468537b33f02d1ff751767eb073be467c3074d [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),
philipelb4d31082016-07-11 08:46:29 -070099 clock_(new SimulatedClock(0)),
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200100 packet_buffer_(clock_.get(), 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
112 int data_size = 0, // size of data
113 uint8_t* data = nullptr, // data pointer
114 uint32_t timestamp = 123u) { // rtp timestamp
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100115 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100116 packet.video_header.codec = kVideoCodecGeneric;
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100117 packet.timestamp = timestamp;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100118 packet.seq_num = seq_num;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200119 packet.video_header.frame_type = keyframe == kKeyFrame
120 ? VideoFrameType::kVideoFrameKey
121 : VideoFrameType::kVideoFrameDelta;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100122 packet.video_header.is_first_packet_in_frame = first == kFirst;
123 packet.video_header.is_last_packet_in_frame = last == kLast;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100124 packet.size_bytes = data_size;
125 packet.data = data;
philipelf4139332016-04-20 10:26:34 +0200126
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200127 return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200128 }
129
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100130 const test::ScopedFieldTrials scoped_field_trials_;
philipelc707ab72016-04-01 02:01:54 -0700131 Random rand_;
philipel3184f8e2017-05-18 08:08:53 -0700132 std::unique_ptr<SimulatedClock> clock_;
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200133 PacketBuffer packet_buffer_;
philipelc707ab72016-04-01 02:01:54 -0700134};
135
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200136TEST_F(PacketBufferTest, InsertOnePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100137 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200138 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700139}
140
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200141TEST_F(PacketBufferTest, InsertMultiplePackets) {
philipelaee3e0e2016-11-01 11:45:34 +0100142 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200143 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
144 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
145 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
146 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700147}
148
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200149TEST_F(PacketBufferTest, InsertDuplicatePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100150 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200151 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
152 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
153 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).frames,
154 SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100155}
156
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200157TEST_F(PacketBufferTest, SeqNumWrapOneFrame) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200158 Insert(0xFFFF, kKeyFrame, kFirst, kNotLast);
159 EXPECT_THAT(Insert(0x0, kKeyFrame, kNotFirst, kLast),
160 StartSeqNumsAre(0xFFFF));
philipel2c2f34c2017-01-03 05:55:34 -0800161}
162
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200163TEST_F(PacketBufferTest, SeqNumWrapTwoFrames) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200164 EXPECT_THAT(Insert(0xFFFF, kKeyFrame, kFirst, kLast),
165 StartSeqNumsAre(0xFFFF));
166 EXPECT_THAT(Insert(0x0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0x0));
philipelaee3e0e2016-11-01 11:45:34 +0100167}
168
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200169TEST_F(PacketBufferTest, InsertOldPackets) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200170 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
171 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
172 EXPECT_THAT(Insert(101, kKeyFrame, kNotFirst, kLast).frames, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100173
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200174 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
175 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
176 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100177
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200178 packet_buffer_.ClearTo(102);
179 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, IsEmpty());
180 EXPECT_THAT(Insert(103, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700181}
182
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200183TEST_F(PacketBufferTest, NackCount) {
philipelaee3e0e2016-11-01 11:45:34 +0100184 const uint16_t seq_num = Rand();
philipel5ceaaae2016-05-24 10:20:47 +0200185
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100186 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100187 packet.video_header.codec = kVideoCodecGeneric;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100188 packet.seq_num = seq_num;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200189 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100190 packet.video_header.is_first_packet_in_frame = true;
191 packet.video_header.is_last_packet_in_frame = false;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100192 packet.times_nacked = 0;
philipel5ceaaae2016-05-24 10:20:47 +0200193
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200194 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200195
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100196 packet.seq_num++;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100197 packet.video_header.is_first_packet_in_frame = false;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100198 packet.times_nacked = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200199 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200200
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100201 packet.seq_num++;
202 packet.times_nacked = 3;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200203 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200204
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100205 packet.seq_num++;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100206 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100207 packet.times_nacked = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200208 auto frames = packet_buffer_.InsertPacket(&packet).frames;
philipel5ceaaae2016-05-24 10:20:47 +0200209
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200210 ASSERT_THAT(frames, SizeIs(1));
211 EXPECT_EQ(frames.front()->times_nacked(), 3);
philipel5ceaaae2016-05-24 10:20:47 +0200212}
213
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200214TEST_F(PacketBufferTest, FrameSize) {
philipelaee3e0e2016-11-01 11:45:34 +0100215 const uint16_t seq_num = Rand();
philipel41b8ca02016-11-07 15:42:24 +0100216 uint8_t* data1 = new uint8_t[5]();
217 uint8_t* data2 = new uint8_t[5]();
218 uint8_t* data3 = new uint8_t[5]();
219 uint8_t* data4 = new uint8_t[5]();
philipel5ceaaae2016-05-24 10:20:47 +0200220
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200221 Insert(seq_num, kKeyFrame, kFirst, kNotLast, 5, data1);
222 Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast, 5, data2);
223 Insert(seq_num + 2, kKeyFrame, kNotFirst, kNotLast, 5, data3);
224 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kNotFirst, kLast, 5, data4).frames,
225 ElementsAre(Pointee(SizeIs(20))));
philipel5ceaaae2016-05-24 10:20:47 +0200226}
227
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200228TEST_F(PacketBufferTest, ExpandBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100229 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700230
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200231 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Johannes Krona3705562019-08-26 16:37:11 +0200232 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200233 EXPECT_FALSE(
234 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200235
236 // Already inserted kStartSize number of packets, inserting the last packet
237 // should increase the buffer size and also result in an assembled frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200238 EXPECT_FALSE(
239 Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700240}
241
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200242TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100243 const uint16_t seq_num = Rand();
244
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200245 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
philipelaee3e0e2016-11-01 11:45:34 +0100246 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200247 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast);
248 EXPECT_THAT(Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast),
249 StartSeqNumsAre(seq_num));
philipelaee3e0e2016-11-01 11:45:34 +0100250}
251
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200252TEST_F(PacketBufferTest, ExpandBufferOverflow) {
philipelaee3e0e2016-11-01 11:45:34 +0100253 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700254
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200255 EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200256 for (int i = 1; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200257 EXPECT_FALSE(
258 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200259
260 // Already inserted kMaxSize number of packets, inserting the last packet
261 // should overflow the buffer and result in false being returned.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200262 EXPECT_TRUE(
263 Insert(seq_num + kMaxSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700264}
265
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200266TEST_F(PacketBufferTest, OnePacketOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100267 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200268 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
269 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700270}
271
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200272TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100273 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200274
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200275 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
276 StartSeqNumsAre(seq_num));
277 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast),
278 StartSeqNumsAre(seq_num + 1));
philipelc707ab72016-04-01 02:01:54 -0700279}
280
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200281TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100282 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200283
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200284 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
285 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
286 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700287}
288
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200289TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100290 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700291
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200292 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
293 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).frames,
294 IsEmpty());
295 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast),
296 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700297}
298
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200299TEST_F(PacketBufferTest, Frames) {
philipelaee3e0e2016-11-01 11:45:34 +0100300 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200301
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200302 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
303 StartSeqNumsAre(seq_num));
304 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
305 StartSeqNumsAre(seq_num + 1));
306 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
307 StartSeqNumsAre(seq_num + 2));
308 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
309 StartSeqNumsAre(seq_num + 3));
philipelf4139332016-04-20 10:26:34 +0200310}
311
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200312TEST_F(PacketBufferTest, ClearSinglePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100313 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200314
philipelaee3e0e2016-11-01 11:45:34 +0100315 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200316 Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
philipelaee3e0e2016-11-01 11:45:34 +0100317
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200318 packet_buffer_.ClearTo(seq_num);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200319 EXPECT_FALSE(
320 Insert(seq_num + kMaxSize, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelaee3e0e2016-11-01 11:45:34 +0100321}
322
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200323TEST_F(PacketBufferTest, ClearFullBuffer) {
philipelc5fb4682017-08-02 04:28:57 -0700324 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200325 Insert(i, kDeltaFrame, kFirst, kLast);
philipelc5fb4682017-08-02 04:28:57 -0700326
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200327 packet_buffer_.ClearTo(kMaxSize - 1);
philipelc5fb4682017-08-02 04:28:57 -0700328
329 for (int i = kMaxSize; i < 2 * kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200330 EXPECT_FALSE(Insert(i, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelc5fb4682017-08-02 04:28:57 -0700331}
332
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200333TEST_F(PacketBufferTest, DontClearNewerPacket) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200334 EXPECT_THAT(Insert(0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0));
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200335 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200336 EXPECT_THAT(Insert(2 * kStartSize, kKeyFrame, kFirst, kLast),
337 StartSeqNumsAre(2 * kStartSize));
338 EXPECT_THAT(Insert(3 * kStartSize + 1, kKeyFrame, kFirst, kNotLast).frames,
339 IsEmpty());
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200340 packet_buffer_.ClearTo(2 * kStartSize);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200341 EXPECT_THAT(Insert(3 * kStartSize + 2, kKeyFrame, kNotFirst, kLast),
342 StartSeqNumsAre(3 * kStartSize + 1));
philipelc5fb4682017-08-02 04:28:57 -0700343}
344
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200345TEST_F(PacketBufferTest, OneIncompleteFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100346 const uint16_t seq_num = Rand();
347
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200348 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
349 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kNotFirst, kLast),
350 StartSeqNumsAre(seq_num));
351 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
352 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100353}
354
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200355TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100356 const uint16_t seq_num = Rand();
357
358 for (int i = 1; i < kMaxSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200359 Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
360 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
361 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
362 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100363}
364
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200365TEST_F(PacketBufferTest, FramesReordered) {
philipelaee3e0e2016-11-01 11:45:34 +0100366 const uint16_t seq_num = Rand();
367
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200368 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
369 StartSeqNumsAre(seq_num + 1));
370 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
371 StartSeqNumsAre(seq_num));
372 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
373 StartSeqNumsAre(seq_num + 3));
374 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
375 StartSeqNumsAre(seq_num + 2));
philipelf4139332016-04-20 10:26:34 +0200376}
377
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200378TEST_F(PacketBufferTest, GetBitstream) {
philipelc707ab72016-04-01 02:01:54 -0700379 // "many bitstream, such data" with null termination.
philipel41b8ca02016-11-07 15:42:24 +0100380 uint8_t many_data[] = {0x6d, 0x61, 0x6e, 0x79, 0x20};
381 uint8_t bitstream_data[] = {0x62, 0x69, 0x74, 0x73, 0x74, 0x72,
382 0x65, 0x61, 0x6d, 0x2c, 0x20};
383 uint8_t such_data[] = {0x73, 0x75, 0x63, 0x68, 0x20};
384 uint8_t data_data[] = {0x64, 0x61, 0x74, 0x61, 0x0};
385
386 uint8_t* many = new uint8_t[sizeof(many_data)];
387 uint8_t* bitstream = new uint8_t[sizeof(bitstream_data)];
388 uint8_t* such = new uint8_t[sizeof(such_data)];
389 uint8_t* data = new uint8_t[sizeof(data_data)];
390
391 memcpy(many, many_data, sizeof(many_data));
392 memcpy(bitstream, bitstream_data, sizeof(bitstream_data));
393 memcpy(such, such_data, sizeof(such_data));
394 memcpy(data, data_data, sizeof(data_data));
395
philipelaee3e0e2016-11-01 11:45:34 +0100396 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700397
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200398 Insert(seq_num, kKeyFrame, kFirst, kNotLast, sizeof(many_data), many);
399 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast, sizeof(bitstream_data),
400 bitstream);
401 Insert(seq_num + 2, kDeltaFrame, kNotFirst, kNotLast, sizeof(such_data),
402 such);
403 auto frames = Insert(seq_num + 3, kDeltaFrame, kNotFirst, kLast,
404 sizeof(data_data), data)
405 .frames;
philipelf4139332016-04-20 10:26:34 +0200406
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200407 ASSERT_THAT(frames, SizeIs(1));
408 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
409 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
410 ElementsAreArray("many bitstream, such data"));
philipelc707ab72016-04-01 02:01:54 -0700411}
412
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200413TEST_F(PacketBufferTest, GetBitstreamOneFrameOnePacket) {
philipel227f8b92017-08-04 06:39:31 -0700414 uint8_t bitstream_data[] = "All the bitstream data for this frame!";
philipel227f8b92017-08-04 06:39:31 -0700415 uint8_t* data = new uint8_t[sizeof(bitstream_data)];
416 memcpy(data, bitstream_data, sizeof(bitstream_data));
417
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200418 auto frames =
419 Insert(0, kKeyFrame, kFirst, kLast, sizeof(bitstream_data), data).frames;
420 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
421 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
422 ElementsAreArray(bitstream_data));
philipel227f8b92017-08-04 06:39:31 -0700423}
424
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200425TEST_F(PacketBufferTest, GetBitstreamOneFrameFullBuffer) {
philipel227f8b92017-08-04 06:39:31 -0700426 uint8_t* data_arr[kStartSize];
427 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700428
429 for (uint8_t i = 0; i < kStartSize; ++i) {
430 data_arr[i] = new uint8_t[1];
431 data_arr[i][0] = i;
432 expected[i] = i;
433 }
434
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200435 Insert(0, kKeyFrame, kFirst, kNotLast, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700436 for (uint8_t i = 1; i < kStartSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200437 Insert(i, kKeyFrame, kNotFirst, kNotLast, 1, data_arr[i]);
438 auto frames = Insert(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1,
439 data_arr[kStartSize - 1])
440 .frames;
philipel227f8b92017-08-04 06:39:31 -0700441
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200442 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
443 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
444 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700445}
446
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100447TEST_F(PacketBufferTest, GetBitstreamAv1) {
448 const uint8_t data1[] = {0b01'01'0000, 0b0'0100'000, 'm', 'a', 'n', 'y', ' '};
449 const uint8_t data2[] = {0b10'01'0000, 'b', 'i', 't', 's', 0};
450
451 uint8_t* new_data1 = new uint8_t[sizeof(data1)];
452 memcpy(new_data1, data1, sizeof(data1));
453 uint8_t* new_data2 = new uint8_t[sizeof(data2)];
454 memcpy(new_data2, data2, sizeof(data2));
455
456 PacketBuffer::Packet packet1;
457 packet1.video_header.codec = kVideoCodecAV1;
458 packet1.seq_num = 13;
459 packet1.video_header.is_first_packet_in_frame = true;
460 packet1.video_header.is_last_packet_in_frame = false;
461 packet1.size_bytes = sizeof(data1);
462 packet1.data = new_data1;
463 auto frames = packet_buffer_.InsertPacket(&packet1).frames;
464 EXPECT_THAT(frames, IsEmpty());
465
466 PacketBuffer::Packet packet2;
467 packet2.video_header.codec = kVideoCodecAV1;
468 packet2.seq_num = 14;
469 packet2.video_header.is_first_packet_in_frame = false;
470 packet2.video_header.is_last_packet_in_frame = true;
471 packet2.size_bytes = sizeof(data2);
472 packet2.data = new_data2;
473 frames = packet_buffer_.InsertPacket(&packet2).frames;
474
475 ASSERT_THAT(frames, SizeIs(1));
476 EXPECT_EQ(frames[0]->first_seq_num(), 13);
477 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), 2),
478 ElementsAre(0b0'0100'010, 10)); // obu_header and obu_size.
479 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data() + 2, frames[0]->size() - 2),
480 ElementsAreArray("many bits"));
481}
482
483TEST_F(PacketBufferTest, GetBitstreamInvalidAv1) {
484 // Two av1 payloads that can't be combined into proper frame.
485 const uint8_t data1[] = {0b01'01'0000, 0b0'0100'000, 'm', 'a', 'n', 'y', ' '};
486 const uint8_t data2[] = {0b00'01'0000, 'b', 'i', 't', 's', 0};
487
488 uint8_t* new_data1 = new uint8_t[sizeof(data1)];
489 memcpy(new_data1, data1, sizeof(data1));
490 uint8_t* new_data2 = new uint8_t[sizeof(data2)];
491 memcpy(new_data2, data2, sizeof(data2));
492
493 PacketBuffer::Packet packet1;
494 packet1.video_header.codec = kVideoCodecAV1;
495 packet1.seq_num = 13;
496 packet1.video_header.is_first_packet_in_frame = true;
497 packet1.video_header.is_last_packet_in_frame = false;
498 packet1.size_bytes = sizeof(data1);
499 packet1.data = new_data1;
500 auto frames = packet_buffer_.InsertPacket(&packet1).frames;
501 EXPECT_THAT(frames, IsEmpty());
502
503 PacketBuffer::Packet packet2;
504 packet2.video_header.codec = kVideoCodecAV1;
505 packet2.seq_num = 14;
506 packet2.video_header.is_first_packet_in_frame = false;
507 packet2.video_header.is_last_packet_in_frame = true;
508 packet2.size_bytes = sizeof(data2);
509 packet2.data = new_data2;
510 frames = packet_buffer_.InsertPacket(&packet2).frames;
511
512 EXPECT_THAT(frames, IsEmpty());
513}
514
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200515TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
Johannes Kron957c62e2018-10-01 14:53:01 +0200516 uint16_t kFirstSeqNum = 0;
517 uint32_t kTimestampDelta = 100;
518 uint32_t timestamp = 10000;
519 uint16_t seq_num = kFirstSeqNum;
520
521 // Loop until seq_num wraps around.
Philip Eliasson1f850a62019-03-19 12:15:00 +0000522 SeqNumUnwrapper<uint16_t> unwrapper;
Johannes Kron957c62e2018-10-01 14:53:01 +0200523 while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
524 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp);
525 for (int i = 0; i < 5; ++i) {
526 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, 0, nullptr, timestamp);
527 }
528 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, 0, nullptr, timestamp);
529 timestamp += kTimestampDelta;
530 }
531
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200532 // Receive frame with overlapping sequence numbers.
Johannes Kron957c62e2018-10-01 14:53:01 +0200533 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp);
534 for (int i = 0; i < 5; ++i) {
535 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, 0, nullptr, timestamp);
536 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200537 EXPECT_THAT(
538 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, 0, nullptr, timestamp)
539 .frames,
540 SizeIs(1));
Johannes Kron957c62e2018-10-01 14:53:01 +0200541}
542
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100543// If |sps_pps_idr_is_keyframe| is true, we require keyframes to contain
544// SPS/PPS/IDR and the keyframes we create as part of the test do contain
545// SPS/PPS/IDR. If |sps_pps_idr_is_keyframe| is false, we only require and
546// create keyframes containing only IDR.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200547class PacketBufferH264Test : public PacketBufferTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200548 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200549 explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
550 : PacketBufferTest(sps_pps_idr_is_keyframe
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100551 ? "WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/"
552 : ""),
553 sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200554
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200555 PacketBufferInsertResult InsertH264(
556 uint16_t seq_num, // packet sequence number
557 IsKeyFrame keyframe, // is keyframe
558 IsFirst first, // is first packet of frame
559 IsLast last, // is last packet of frame
560 uint32_t timestamp, // rtp timestamp
561 int data_size = 0, // size of data
562 uint8_t* data = nullptr, // data pointer
563 uint32_t width = 0, // width of frame (SPS/IDR)
564 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100565 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100566 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200567 auto& h264_header =
568 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100569 packet.seq_num = seq_num;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200570 packet.timestamp = timestamp;
571 if (keyframe == kKeyFrame) {
572 if (sps_pps_idr_is_keyframe_) {
philipel7d745e52018-08-02 14:03:53 +0200573 h264_header.nalus[0].type = H264::NaluType::kSps;
574 h264_header.nalus[1].type = H264::NaluType::kPps;
575 h264_header.nalus[2].type = H264::NaluType::kIdr;
576 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200577 } else {
philipel7d745e52018-08-02 14:03:53 +0200578 h264_header.nalus[0].type = H264::NaluType::kIdr;
579 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200580 }
581 }
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700582 packet.video_header.width = width;
583 packet.video_header.height = height;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100584 packet.video_header.is_first_packet_in_frame = first == kFirst;
585 packet.video_header.is_last_packet_in_frame = last == kLast;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100586 packet.size_bytes = data_size;
587 packet.data = data;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200588
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200589 return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200590 }
591
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200592 PacketBufferInsertResult InsertH264KeyFrameWithAud(
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700593 uint16_t seq_num, // packet sequence number
594 IsKeyFrame keyframe, // is keyframe
595 IsFirst first, // is first packet of frame
596 IsLast last, // is last packet of frame
597 uint32_t timestamp, // rtp timestamp
598 int data_size = 0, // size of data
599 uint8_t* data = nullptr, // data pointer
600 uint32_t width = 0, // width of frame (SPS/IDR)
601 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100602 PacketBuffer::Packet packet;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700603 packet.video_header.codec = kVideoCodecH264;
604 auto& h264_header =
605 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100606 packet.seq_num = seq_num;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700607 packet.timestamp = timestamp;
608
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200609 // this should be the start of frame.
610 RTC_CHECK(first == kFirst);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700611
612 // Insert a AUD NALU / packet without width/height.
613 h264_header.nalus[0].type = H264::NaluType::kAud;
614 h264_header.nalus_length = 1;
615 packet.video_header.is_first_packet_in_frame = true;
616 packet.video_header.is_last_packet_in_frame = false;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100617 packet.size_bytes = 0;
618 packet.data = nullptr;
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200619 IgnoreResult(packet_buffer_.InsertPacket(&packet));
620 // insert IDR
621 return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp,
622 data_size, data, width, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700623 }
624
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200625 const bool sps_pps_idr_is_keyframe_;
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100626};
627
628// This fixture is used to test the general behaviour of the packet buffer
629// in both configurations.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200630class PacketBufferH264ParameterizedTest
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100631 : public ::testing::WithParamInterface<bool>,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200632 public PacketBufferH264Test {
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100633 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200634 PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200635};
636
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100637INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200638 PacketBufferH264ParameterizedTest,
639 ::testing::Bool());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200640
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200641TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200642 InsertH264(0, kKeyFrame, kFirst, kLast, 0);
643 InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200644 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200645 // Expect no frame because of missing of packet #1
646 EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).frames,
647 IsEmpty());
philipelbc5a4082017-12-06 10:41:08 +0100648}
649
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200650TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
philipel227f8b92017-08-04 06:39:31 -0700651 uint8_t* data_arr[kStartSize];
652 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700653
654 for (uint8_t i = 0; i < kStartSize; ++i) {
655 data_arr[i] = new uint8_t[1];
656 data_arr[i][0] = i;
657 expected[i] = i;
658 }
659
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200660 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700661 for (uint8_t i = 1; i < kStartSize - 1; ++i) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200662 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, 1, data_arr[i]);
philipel227f8b92017-08-04 06:39:31 -0700663 }
philipel227f8b92017-08-04 06:39:31 -0700664
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200665 auto frames = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1, 1,
666 data_arr[kStartSize - 1])
667 .frames;
668 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
669 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
670 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700671}
672
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200673TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
philipel36928452016-11-07 10:42:36 +0100674 uint16_t seq_num = Rand();
philipel41b8ca02016-11-07 15:42:24 +0100675 uint8_t data_data[] = "some plain old data";
676 uint8_t* data = new uint8_t[sizeof(data_data)];
677 memcpy(data, data_data, sizeof(data_data));
philipel36928452016-11-07 10:42:36 +0100678
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100679 PacketBuffer::Packet packet;
philipel7d745e52018-08-02 14:03:53 +0200680 auto& h264_header =
681 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
682 h264_header.nalus_length = 1;
683 h264_header.nalus[0].type = H264::NaluType::kIdr;
684 h264_header.packetization_type = kH264SingleNalu;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100685 packet.seq_num = seq_num;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100686 packet.video_header.codec = kVideoCodecH264;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100687 packet.data = data;
688 packet.size_bytes = sizeof(data_data);
Niels Möllerd5e02f02019-02-20 13:12:21 +0100689 packet.video_header.is_first_packet_in_frame = true;
690 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200691 auto frames = packet_buffer_.InsertPacket(&packet).frames;
philipel36928452016-11-07 10:42:36 +0100692
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200693 ASSERT_THAT(frames, SizeIs(1));
694 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
695 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data_data));
696 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data_data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200697 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
698 ElementsAreArray(data_data));
philipel36928452016-11-07 10:42:36 +0100699}
700
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200701TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700702 uint16_t seq_num = 100;
703 uint8_t data_data[] = "some plain old data";
704 uint8_t* data = new uint8_t[sizeof(data_data)];
705 memcpy(data, data_data, sizeof(data_data));
706 uint32_t width = 640;
707 uint32_t height = 360;
708 uint32_t timestamp = 1000;
709
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200710 auto frames = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp,
711 sizeof(data_data), data, width, height)
712 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700713
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200714 ASSERT_THAT(frames, SizeIs(1));
715 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
716 ElementsAreArray(data_data));
717 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
718 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700719}
720
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200721TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700722 uint16_t seq_num = 100;
723 uint8_t data_data[] = "some plain old data";
724 uint8_t* data = new uint8_t[sizeof(data_data)];
725 memcpy(data, data_data, sizeof(data_data));
726 uint32_t width = 640;
727 uint32_t height = 360;
728 uint32_t timestamp = 1000;
729
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200730 auto frames =
731 InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast, timestamp,
732 sizeof(data_data), data, width, height)
733 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700734
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200735 ASSERT_THAT(StartSeqNums(frames), ElementsAre(seq_num));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700736
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200737 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data_data));
738 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data_data));
739 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
740 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
741 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
742 ElementsAreArray(data_data));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700743}
744
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200745TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
philipelaee3e0e2016-11-01 11:45:34 +0100746 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200747
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200748 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
749 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
750 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
751 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700752
philipel17deeb42016-08-11 15:09:26 +0200753 // Insert frame that fills the whole buffer.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200754 Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
philipel17deeb42016-08-11 15:09:26 +0200755 for (int i = 0; i < kMaxSize - 2; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200756 Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
757 EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
758 StartSeqNumsAre(seq_num + 3));
philipelc707ab72016-04-01 02:01:54 -0700759}
760
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200761TEST_F(PacketBufferTest, Clear) {
philipelaee3e0e2016-11-01 11:45:34 +0100762 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200763
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200764 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
765 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
766 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
767 StartSeqNumsAre(seq_num));
philipelf4139332016-04-20 10:26:34 +0200768
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200769 packet_buffer_.Clear();
philipelf4139332016-04-20 10:26:34 +0200770
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200771 Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
772 Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
773 EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
774 StartSeqNumsAre(seq_num + kStartSize));
philipelc707ab72016-04-01 02:01:54 -0700775}
776
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200777TEST_F(PacketBufferTest, FramesAfterClear) {
philipel20dce342016-11-28 16:14:57 +0100778 Insert(9025, kDeltaFrame, kFirst, kLast);
779 Insert(9024, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200780 packet_buffer_.ClearTo(9025);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200781 EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
782 EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipel20dce342016-11-28 16:14:57 +0100783}
784
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200785TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
philipel8b6995b2019-01-09 12:39:18 +0100786 Insert(0, kKeyFrame, kFirst, kNotLast, 0, nullptr, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200787 EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, 0, nullptr, 1001).frames,
788 IsEmpty());
philipel8b6995b2019-01-09 12:39:18 +0100789}
790
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200791TEST_F(PacketBufferTest, DontLeakPayloadData) {
philipel759e0b72016-11-30 01:32:05 -0800792 // NOTE! Any eventual leak is suppose to be detected by valgrind
793 // or any other similar tool.
794 uint8_t* data1 = new uint8_t[5];
795 uint8_t* data2 = new uint8_t[5];
796 uint8_t* data3 = new uint8_t[5];
797 uint8_t* data4 = new uint8_t[5];
798
799 // Expected to free data1 upon PacketBuffer destruction.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200800 Insert(2, kKeyFrame, kFirst, kNotLast, 5, data1);
philipel759e0b72016-11-30 01:32:05 -0800801
802 // Expect to free data2 upon insertion.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200803 Insert(2, kKeyFrame, kFirst, kNotLast, 5, data2);
philipel759e0b72016-11-30 01:32:05 -0800804
805 // Expect to free data3 upon insertion (old packet).
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200806 packet_buffer_.ClearTo(1);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200807 Insert(1, kKeyFrame, kFirst, kNotLast, 5, data3);
philipel759e0b72016-11-30 01:32:05 -0800808
809 // Expect to free data4 upon insertion (packet buffer is full).
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200810 Insert(2 + kMaxSize, kKeyFrame, kFirst, kNotLast, 5, data4);
philipel759e0b72016-11-30 01:32:05 -0800811}
812
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200813TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
philipelea142f82017-01-11 02:01:56 -0800814 Insert(2, kKeyFrame, kNotFirst, kNotLast);
815 Insert(1, kKeyFrame, kFirst, kLast);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200816 EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).frames, IsEmpty());
philipelea142f82017-01-11 02:01:56 -0800817}
818
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200819TEST_F(PacketBufferTest, PacketTimestamps) {
Danil Chapovalov0040b662018-06-18 10:48:16 +0200820 absl::optional<int64_t> packet_ms;
821 absl::optional<int64_t> packet_keyframe_ms;
philipel3184f8e2017-05-18 08:08:53 -0700822
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200823 packet_ms = packet_buffer_.LastReceivedPacketMs();
824 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700825 EXPECT_FALSE(packet_ms);
826 EXPECT_FALSE(packet_keyframe_ms);
827
828 int64_t keyframe_ms = clock_->TimeInMilliseconds();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200829 Insert(100, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200830 packet_ms = packet_buffer_.LastReceivedPacketMs();
831 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700832 EXPECT_TRUE(packet_ms);
833 EXPECT_TRUE(packet_keyframe_ms);
834 EXPECT_EQ(keyframe_ms, *packet_ms);
835 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
836
837 clock_->AdvanceTimeMilliseconds(100);
838 int64_t delta_ms = clock_->TimeInMilliseconds();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200839 Insert(101, kDeltaFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200840 packet_ms = packet_buffer_.LastReceivedPacketMs();
841 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700842 EXPECT_TRUE(packet_ms);
843 EXPECT_TRUE(packet_keyframe_ms);
844 EXPECT_EQ(delta_ms, *packet_ms);
845 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
846
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200847 packet_buffer_.Clear();
848 packet_ms = packet_buffer_.LastReceivedPacketMs();
849 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700850 EXPECT_FALSE(packet_ms);
851 EXPECT_FALSE(packet_keyframe_ms);
852}
853
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200854TEST_F(PacketBufferTest, IncomingCodecChange) {
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100855 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100856 packet.video_header.is_first_packet_in_frame = true;
857 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100858 packet.size_bytes = 0;
859 packet.data = nullptr;
philipel09133af2018-05-17 14:11:09 +0200860
Niels Möllerd5e02f02019-02-20 13:12:21 +0100861 packet.video_header.codec = kVideoCodecVP8;
862 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200863 packet.timestamp = 1;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100864 packet.seq_num = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200865 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200866 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(1));
philipel09133af2018-05-17 14:11:09 +0200867
Niels Möllerd5e02f02019-02-20 13:12:21 +0100868 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200869 auto& h264_header =
870 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
871 h264_header.nalus_length = 1;
philipel09133af2018-05-17 14:11:09 +0200872 packet.timestamp = 3;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100873 packet.seq_num = 3;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200874 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200875
Niels Möllerd5e02f02019-02-20 13:12:21 +0100876 packet.video_header.codec = kVideoCodecVP8;
877 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200878 packet.timestamp = 2;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100879 packet.seq_num = 2;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200880 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200881 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(2));
philipel09133af2018-05-17 14:11:09 +0200882}
883
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200884TEST_F(PacketBufferTest, TooManyNalusInPacket) {
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100885 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100886 packet.video_header.codec = kVideoCodecH264;
philipel09133af2018-05-17 14:11:09 +0200887 packet.timestamp = 1;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100888 packet.seq_num = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200889 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100890 packet.video_header.is_first_packet_in_frame = true;
891 packet.video_header.is_last_packet_in_frame = true;
philipel7d745e52018-08-02 14:03:53 +0200892 auto& h264_header =
893 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
894 h264_header.nalus_length = kMaxNalusPerPacket;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100895 packet.size_bytes = 0;
896 packet.data = nullptr;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200897 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200898}
899
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200900TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
philipel2c9f9f22017-06-13 02:47:28 -0700901 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
902 for (int i = 1; i < kStartSize - 1; ++i)
903 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200904 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
905 StartSeqNumsAre(0));
philipel2c9f9f22017-06-13 02:47:28 -0700906}
907
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200908TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200909 EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).frames,
910 SizeIs(1));
philipel227f8b92017-08-04 06:39:31 -0700911
912 InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
913 for (int i = 1; i < kStartSize; ++i)
914 InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200915 EXPECT_THAT(
916 InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
917 .frames,
918 IsEmpty());
philipel227f8b92017-08-04 06:39:31 -0700919
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200920 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
921 StartSeqNumsAre(kStartSize - 1, kStartSize));
philipel227f8b92017-08-04 06:39:31 -0700922}
923
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200924TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
philipel2c9f9f22017-06-13 02:47:28 -0700925 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200926 EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
927 StartSeqNumsAre(65534));
philipel2c9f9f22017-06-13 02:47:28 -0700928}
929
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200930TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
philipel2c9f9f22017-06-13 02:47:28 -0700931 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
932 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
933 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
934 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
935
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200936 EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
937 StartSeqNumsAre(kStartSize + 1));
philipel2c9f9f22017-06-13 02:47:28 -0700938}
939
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200940TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200941 EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
942 StartSeqNumsAre(0));
943 EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).frames,
944 IsEmpty());
philipel2c9f9f22017-06-13 02:47:28 -0700945
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200946 EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
philipel2c9f9f22017-06-13 02:47:28 -0700947}
948
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200949class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200950 protected:
951 const uint16_t kSeqNum = 5;
952
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200953 explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
954 : PacketBufferH264Test(sps_pps_idr_is_keyframe) {
Niels Möllerd5e02f02019-02-20 13:12:21 +0100955 packet_.video_header.codec = kVideoCodecH264;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100956 packet_.seq_num = kSeqNum;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200957
Niels Möllerd5e02f02019-02-20 13:12:21 +0100958 packet_.video_header.is_first_packet_in_frame = true;
959 packet_.video_header.is_last_packet_in_frame = true;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200960 }
961
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100962 PacketBuffer::Packet packet_;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200963};
964
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200965class PacketBufferH264IdrIsKeyframeTest
966 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200967 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200968 PacketBufferH264IdrIsKeyframeTest()
969 : PacketBufferH264XIsKeyframeTest(false) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200970};
971
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200972TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200973 auto& h264_header =
974 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
975 h264_header.nalus[0].type = H264::NaluType::kIdr;
976 h264_header.nalus_length = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200977 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
978 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200979}
980
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200981TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200982 auto& h264_header =
983 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
984 h264_header.nalus[0].type = H264::NaluType::kSps;
985 h264_header.nalus[1].type = H264::NaluType::kPps;
986 h264_header.nalus[2].type = H264::NaluType::kIdr;
987 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200988
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200989 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
990 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200991}
992
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200993class PacketBufferH264SpsPpsIdrIsKeyframeTest
994 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200995 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200996 PacketBufferH264SpsPpsIdrIsKeyframeTest()
997 : PacketBufferH264XIsKeyframeTest(true) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200998};
999
Danil Chapovalov05269ec2019-10-17 19:06:46 +02001000TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +02001001 auto& h264_header =
1002 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
1003 h264_header.nalus[0].type = H264::NaluType::kIdr;
1004 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001005
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001006 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
1007 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001008}
1009
Danil Chapovalov05269ec2019-10-17 19:06:46 +02001010TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +02001011 auto& h264_header =
1012 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
1013 h264_header.nalus[0].type = H264::NaluType::kSps;
1014 h264_header.nalus[1].type = H264::NaluType::kPps;
1015 h264_header.nalus_length = 2;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001016
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001017 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
1018 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001019}
1020
Danil Chapovalov05269ec2019-10-17 19:06:46 +02001021TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +02001022 auto& h264_header =
1023 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
1024 h264_header.nalus[0].type = H264::NaluType::kSps;
1025 h264_header.nalus[1].type = H264::NaluType::kPps;
1026 h264_header.nalus[2].type = H264::NaluType::kIdr;
1027 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001028
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001029 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
1030 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001031}
1032
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001033} // namespace
philipelc707ab72016-04-01 02:01:54 -07001034} // namespace video_coding
1035} // namespace webrtc