blob: 9da432cb3cd9d76d5159fb0822855b92e4e95012 [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
philipelf4139332016-04-20 10:26:34 +0200115 VCMPacket 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;
philipelf4139332016-04-20 10:26:34 +0200118 packet.seqNum = 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;
philipelf4139332016-04-20 10:26:34 +0200124 packet.sizeBytes = data_size;
125 packet.dataPtr = data;
126
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
186 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100187 packet.video_header.codec = kVideoCodecGeneric;
philipel5ceaaae2016-05-24 10:20:47 +0200188 packet.seqNum = 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;
philipel5ceaaae2016-05-24 10:20:47 +0200192 packet.timesNacked = 0;
193
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200194 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200195
196 packet.seqNum++;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100197 packet.video_header.is_first_packet_in_frame = false;
philipel5ceaaae2016-05-24 10:20:47 +0200198 packet.timesNacked = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200199 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200200
201 packet.seqNum++;
202 packet.timesNacked = 3;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200203 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200204
205 packet.seqNum++;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100206 packet.video_header.is_last_packet_in_frame = true;
philipel5ceaaae2016-05-24 10:20:47 +0200207 packet.timesNacked = 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, CountsUniqueFrames) {
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100229 const uint16_t seq_num = Rand();
230
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200231 ASSERT_EQ(packet_buffer_.GetUniqueFramesSeen(), 0);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100232
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200233 Insert(seq_num, kKeyFrame, kFirst, kNotLast, 0, nullptr, 100);
234 ASSERT_EQ(packet_buffer_.GetUniqueFramesSeen(), 1);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100235 // Still the same frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200236 Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast, 0, nullptr, 100);
237 ASSERT_EQ(packet_buffer_.GetUniqueFramesSeen(), 1);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100238
239 // Second frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200240 Insert(seq_num + 2, kKeyFrame, kFirst, kNotLast, 0, nullptr, 200);
241 ASSERT_EQ(packet_buffer_.GetUniqueFramesSeen(), 2);
242 Insert(seq_num + 3, kKeyFrame, kNotFirst, kLast, 0, nullptr, 200);
243 ASSERT_EQ(packet_buffer_.GetUniqueFramesSeen(), 2);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100244
245 // Old packet.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200246 Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast, 0, nullptr, 100);
247 ASSERT_EQ(packet_buffer_.GetUniqueFramesSeen(), 2);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100248
249 // Missing middle packet.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200250 Insert(seq_num + 4, kKeyFrame, kFirst, kNotLast, 0, nullptr, 300);
251 Insert(seq_num + 6, kKeyFrame, kNotFirst, kLast, 0, nullptr, 300);
252 ASSERT_EQ(packet_buffer_.GetUniqueFramesSeen(), 3);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100253}
254
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200255TEST_F(PacketBufferTest, HasHistoryOfUniqueFrames) {
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100256 const int kNumFrames = 1500;
257 const int kRequiredHistoryLength = 1000;
258 const uint16_t seq_num = Rand();
259 const uint32_t timestamp = 0xFFFFFFF0; // Large enough to cause wrap-around.
260
261 for (int i = 0; i < kNumFrames; ++i) {
Johannes Kronbd3f3052019-08-01 15:45:54 +0200262 Insert(seq_num + i, kKeyFrame, kFirst, kNotLast, 0, nullptr,
263 timestamp + 10 * i);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100264 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200265 EXPECT_EQ(packet_buffer_.GetUniqueFramesSeen(), kNumFrames);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100266
267 // Old packets within history should not affect number of seen unique frames.
268 for (int i = kNumFrames - kRequiredHistoryLength; i < kNumFrames; ++i) {
Johannes Kronbd3f3052019-08-01 15:45:54 +0200269 Insert(seq_num + i, kKeyFrame, kFirst, kNotLast, 0, nullptr,
270 timestamp + 10 * i);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100271 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200272 EXPECT_EQ(packet_buffer_.GetUniqueFramesSeen(), kNumFrames);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100273
274 // Very old packets should be treated as unique.
Johannes Kronbd3f3052019-08-01 15:45:54 +0200275 Insert(seq_num, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200276 EXPECT_EQ(packet_buffer_.GetUniqueFramesSeen(), kNumFrames + 1);
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100277}
278
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200279TEST_F(PacketBufferTest, ExpandBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100280 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700281
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200282 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Johannes Krona3705562019-08-26 16:37:11 +0200283 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200284 EXPECT_FALSE(
285 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200286
287 // Already inserted kStartSize number of packets, inserting the last packet
288 // should increase the buffer size and also result in an assembled frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200289 EXPECT_FALSE(
290 Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700291}
292
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200293TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100294 const uint16_t seq_num = Rand();
295
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200296 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
philipelaee3e0e2016-11-01 11:45:34 +0100297 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200298 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast);
299 EXPECT_THAT(Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast),
300 StartSeqNumsAre(seq_num));
philipelaee3e0e2016-11-01 11:45:34 +0100301}
302
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200303TEST_F(PacketBufferTest, ExpandBufferOverflow) {
philipelaee3e0e2016-11-01 11:45:34 +0100304 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700305
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200306 EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200307 for (int i = 1; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200308 EXPECT_FALSE(
309 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200310
311 // Already inserted kMaxSize number of packets, inserting the last packet
312 // should overflow the buffer and result in false being returned.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200313 EXPECT_TRUE(
314 Insert(seq_num + kMaxSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700315}
316
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200317TEST_F(PacketBufferTest, OnePacketOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100318 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200319 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
320 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700321}
322
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200323TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100324 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200325
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200326 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
327 StartSeqNumsAre(seq_num));
328 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast),
329 StartSeqNumsAre(seq_num + 1));
philipelc707ab72016-04-01 02:01:54 -0700330}
331
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200332TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100333 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200334
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200335 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
336 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
337 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700338}
339
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200340TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100341 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700342
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200343 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
344 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).frames,
345 IsEmpty());
346 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast),
347 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700348}
349
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200350TEST_F(PacketBufferTest, Frames) {
philipelaee3e0e2016-11-01 11:45:34 +0100351 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200352
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200353 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
354 StartSeqNumsAre(seq_num));
355 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
356 StartSeqNumsAre(seq_num + 1));
357 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
358 StartSeqNumsAre(seq_num + 2));
359 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
360 StartSeqNumsAre(seq_num + 3));
philipelf4139332016-04-20 10:26:34 +0200361}
362
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200363TEST_F(PacketBufferTest, ClearSinglePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100364 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200365
philipelaee3e0e2016-11-01 11:45:34 +0100366 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200367 Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
philipelaee3e0e2016-11-01 11:45:34 +0100368
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200369 packet_buffer_.ClearTo(seq_num);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200370 EXPECT_FALSE(
371 Insert(seq_num + kMaxSize, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelaee3e0e2016-11-01 11:45:34 +0100372}
373
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200374TEST_F(PacketBufferTest, ClearFullBuffer) {
philipelc5fb4682017-08-02 04:28:57 -0700375 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200376 Insert(i, kDeltaFrame, kFirst, kLast);
philipelc5fb4682017-08-02 04:28:57 -0700377
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200378 packet_buffer_.ClearTo(kMaxSize - 1);
philipelc5fb4682017-08-02 04:28:57 -0700379
380 for (int i = kMaxSize; i < 2 * kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200381 EXPECT_FALSE(Insert(i, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelc5fb4682017-08-02 04:28:57 -0700382}
383
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200384TEST_F(PacketBufferTest, DontClearNewerPacket) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200385 EXPECT_THAT(Insert(0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0));
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200386 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200387 EXPECT_THAT(Insert(2 * kStartSize, kKeyFrame, kFirst, kLast),
388 StartSeqNumsAre(2 * kStartSize));
389 EXPECT_THAT(Insert(3 * kStartSize + 1, kKeyFrame, kFirst, kNotLast).frames,
390 IsEmpty());
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200391 packet_buffer_.ClearTo(2 * kStartSize);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200392 EXPECT_THAT(Insert(3 * kStartSize + 2, kKeyFrame, kNotFirst, kLast),
393 StartSeqNumsAre(3 * kStartSize + 1));
philipelc5fb4682017-08-02 04:28:57 -0700394}
395
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200396TEST_F(PacketBufferTest, OneIncompleteFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100397 const uint16_t seq_num = Rand();
398
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200399 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
400 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kNotFirst, kLast),
401 StartSeqNumsAre(seq_num));
402 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
403 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100404}
405
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200406TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100407 const uint16_t seq_num = Rand();
408
409 for (int i = 1; i < kMaxSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200410 Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
411 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
412 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
413 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100414}
415
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200416TEST_F(PacketBufferTest, FramesReordered) {
philipelaee3e0e2016-11-01 11:45:34 +0100417 const uint16_t seq_num = Rand();
418
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200419 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
420 StartSeqNumsAre(seq_num + 1));
421 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
422 StartSeqNumsAre(seq_num));
423 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
424 StartSeqNumsAre(seq_num + 3));
425 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
426 StartSeqNumsAre(seq_num + 2));
philipelf4139332016-04-20 10:26:34 +0200427}
428
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200429TEST_F(PacketBufferTest, GetBitstream) {
philipelc707ab72016-04-01 02:01:54 -0700430 // "many bitstream, such data" with null termination.
philipel41b8ca02016-11-07 15:42:24 +0100431 uint8_t many_data[] = {0x6d, 0x61, 0x6e, 0x79, 0x20};
432 uint8_t bitstream_data[] = {0x62, 0x69, 0x74, 0x73, 0x74, 0x72,
433 0x65, 0x61, 0x6d, 0x2c, 0x20};
434 uint8_t such_data[] = {0x73, 0x75, 0x63, 0x68, 0x20};
435 uint8_t data_data[] = {0x64, 0x61, 0x74, 0x61, 0x0};
436
437 uint8_t* many = new uint8_t[sizeof(many_data)];
438 uint8_t* bitstream = new uint8_t[sizeof(bitstream_data)];
439 uint8_t* such = new uint8_t[sizeof(such_data)];
440 uint8_t* data = new uint8_t[sizeof(data_data)];
441
442 memcpy(many, many_data, sizeof(many_data));
443 memcpy(bitstream, bitstream_data, sizeof(bitstream_data));
444 memcpy(such, such_data, sizeof(such_data));
445 memcpy(data, data_data, sizeof(data_data));
446
philipelaee3e0e2016-11-01 11:45:34 +0100447 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700448
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200449 Insert(seq_num, kKeyFrame, kFirst, kNotLast, sizeof(many_data), many);
450 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast, sizeof(bitstream_data),
451 bitstream);
452 Insert(seq_num + 2, kDeltaFrame, kNotFirst, kNotLast, sizeof(such_data),
453 such);
454 auto frames = Insert(seq_num + 3, kDeltaFrame, kNotFirst, kLast,
455 sizeof(data_data), data)
456 .frames;
philipelf4139332016-04-20 10:26:34 +0200457
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200458 ASSERT_THAT(frames, SizeIs(1));
459 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
460 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
461 ElementsAreArray("many bitstream, such data"));
philipelc707ab72016-04-01 02:01:54 -0700462}
463
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200464TEST_F(PacketBufferTest, GetBitstreamOneFrameOnePacket) {
philipel227f8b92017-08-04 06:39:31 -0700465 uint8_t bitstream_data[] = "All the bitstream data for this frame!";
philipel227f8b92017-08-04 06:39:31 -0700466 uint8_t* data = new uint8_t[sizeof(bitstream_data)];
467 memcpy(data, bitstream_data, sizeof(bitstream_data));
468
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200469 auto frames =
470 Insert(0, kKeyFrame, kFirst, kLast, sizeof(bitstream_data), data).frames;
471 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
472 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
473 ElementsAreArray(bitstream_data));
philipel227f8b92017-08-04 06:39:31 -0700474}
475
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200476TEST_F(PacketBufferTest, GetBitstreamOneFrameFullBuffer) {
philipel227f8b92017-08-04 06:39:31 -0700477 uint8_t* data_arr[kStartSize];
478 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700479
480 for (uint8_t i = 0; i < kStartSize; ++i) {
481 data_arr[i] = new uint8_t[1];
482 data_arr[i][0] = i;
483 expected[i] = i;
484 }
485
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200486 Insert(0, kKeyFrame, kFirst, kNotLast, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700487 for (uint8_t i = 1; i < kStartSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200488 Insert(i, kKeyFrame, kNotFirst, kNotLast, 1, data_arr[i]);
489 auto frames = Insert(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1,
490 data_arr[kStartSize - 1])
491 .frames;
philipel227f8b92017-08-04 06:39:31 -0700492
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200493 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
494 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
495 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700496}
497
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200498TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
Johannes Kron957c62e2018-10-01 14:53:01 +0200499 uint16_t kFirstSeqNum = 0;
500 uint32_t kTimestampDelta = 100;
501 uint32_t timestamp = 10000;
502 uint16_t seq_num = kFirstSeqNum;
503
504 // Loop until seq_num wraps around.
Philip Eliasson1f850a62019-03-19 12:15:00 +0000505 SeqNumUnwrapper<uint16_t> unwrapper;
Johannes Kron957c62e2018-10-01 14:53:01 +0200506 while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
507 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp);
508 for (int i = 0; i < 5; ++i) {
509 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, 0, nullptr, timestamp);
510 }
511 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, 0, nullptr, timestamp);
512 timestamp += kTimestampDelta;
513 }
514
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200515 // Receive frame with overlapping sequence numbers.
Johannes Kron957c62e2018-10-01 14:53:01 +0200516 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp);
517 for (int i = 0; i < 5; ++i) {
518 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, 0, nullptr, timestamp);
519 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200520 EXPECT_THAT(
521 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, 0, nullptr, timestamp)
522 .frames,
523 SizeIs(1));
Johannes Kron957c62e2018-10-01 14:53:01 +0200524}
525
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100526// If |sps_pps_idr_is_keyframe| is true, we require keyframes to contain
527// SPS/PPS/IDR and the keyframes we create as part of the test do contain
528// SPS/PPS/IDR. If |sps_pps_idr_is_keyframe| is false, we only require and
529// create keyframes containing only IDR.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200530class PacketBufferH264Test : public PacketBufferTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200531 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200532 explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
533 : PacketBufferTest(sps_pps_idr_is_keyframe
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100534 ? "WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/"
535 : ""),
536 sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200537
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200538 PacketBufferInsertResult InsertH264(
539 uint16_t seq_num, // packet sequence number
540 IsKeyFrame keyframe, // is keyframe
541 IsFirst first, // is first packet of frame
542 IsLast last, // is last packet of frame
543 uint32_t timestamp, // rtp timestamp
544 int data_size = 0, // size of data
545 uint8_t* data = nullptr, // data pointer
546 uint32_t width = 0, // width of frame (SPS/IDR)
547 uint32_t height = 0) { // height of frame (SPS/IDR)
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200548 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100549 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200550 auto& h264_header =
551 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200552 packet.seqNum = seq_num;
553 packet.timestamp = timestamp;
554 if (keyframe == kKeyFrame) {
555 if (sps_pps_idr_is_keyframe_) {
philipel7d745e52018-08-02 14:03:53 +0200556 h264_header.nalus[0].type = H264::NaluType::kSps;
557 h264_header.nalus[1].type = H264::NaluType::kPps;
558 h264_header.nalus[2].type = H264::NaluType::kIdr;
559 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200560 } else {
philipel7d745e52018-08-02 14:03:53 +0200561 h264_header.nalus[0].type = H264::NaluType::kIdr;
562 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200563 }
564 }
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700565 packet.video_header.width = width;
566 packet.video_header.height = height;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100567 packet.video_header.is_first_packet_in_frame = first == kFirst;
568 packet.video_header.is_last_packet_in_frame = last == kLast;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200569 packet.sizeBytes = data_size;
570 packet.dataPtr = data;
571
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200572 return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200573 }
574
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200575 PacketBufferInsertResult InsertH264KeyFrameWithAud(
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700576 uint16_t seq_num, // packet sequence number
577 IsKeyFrame keyframe, // is keyframe
578 IsFirst first, // is first packet of frame
579 IsLast last, // is last packet of frame
580 uint32_t timestamp, // rtp timestamp
581 int data_size = 0, // size of data
582 uint8_t* data = nullptr, // data pointer
583 uint32_t width = 0, // width of frame (SPS/IDR)
584 uint32_t height = 0) { // height of frame (SPS/IDR)
585 VCMPacket packet;
586 packet.video_header.codec = kVideoCodecH264;
587 auto& h264_header =
588 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
589 packet.seqNum = seq_num;
590 packet.timestamp = timestamp;
591
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200592 // this should be the start of frame.
593 RTC_CHECK(first == kFirst);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700594
595 // Insert a AUD NALU / packet without width/height.
596 h264_header.nalus[0].type = H264::NaluType::kAud;
597 h264_header.nalus_length = 1;
598 packet.video_header.is_first_packet_in_frame = true;
599 packet.video_header.is_last_packet_in_frame = false;
600 packet.sizeBytes = 0;
601 packet.dataPtr = nullptr;
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200602 IgnoreResult(packet_buffer_.InsertPacket(&packet));
603 // insert IDR
604 return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp,
605 data_size, data, width, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700606 }
607
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200608 const bool sps_pps_idr_is_keyframe_;
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100609};
610
611// This fixture is used to test the general behaviour of the packet buffer
612// in both configurations.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200613class PacketBufferH264ParameterizedTest
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100614 : public ::testing::WithParamInterface<bool>,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200615 public PacketBufferH264Test {
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100616 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200617 PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200618};
619
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100620INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200621 PacketBufferH264ParameterizedTest,
622 ::testing::Bool());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200623
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200624TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200625 InsertH264(0, kKeyFrame, kFirst, kLast, 0);
626 InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200627 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200628 // Expect no frame because of missing of packet #1
629 EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).frames,
630 IsEmpty());
philipelbc5a4082017-12-06 10:41:08 +0100631}
632
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200633TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
philipel227f8b92017-08-04 06:39:31 -0700634 uint8_t* data_arr[kStartSize];
635 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700636
637 for (uint8_t i = 0; i < kStartSize; ++i) {
638 data_arr[i] = new uint8_t[1];
639 data_arr[i][0] = i;
640 expected[i] = i;
641 }
642
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200643 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700644 for (uint8_t i = 1; i < kStartSize - 1; ++i) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200645 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, 1, data_arr[i]);
philipel227f8b92017-08-04 06:39:31 -0700646 }
philipel227f8b92017-08-04 06:39:31 -0700647
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200648 auto frames = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1, 1,
649 data_arr[kStartSize - 1])
650 .frames;
651 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
652 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
653 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700654}
655
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200656TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
philipel36928452016-11-07 10:42:36 +0100657 uint16_t seq_num = Rand();
philipel41b8ca02016-11-07 15:42:24 +0100658 uint8_t data_data[] = "some plain old data";
659 uint8_t* data = new uint8_t[sizeof(data_data)];
660 memcpy(data, data_data, sizeof(data_data));
philipel36928452016-11-07 10:42:36 +0100661
philipel36928452016-11-07 10:42:36 +0100662 VCMPacket packet;
philipel7d745e52018-08-02 14:03:53 +0200663 auto& h264_header =
664 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
665 h264_header.nalus_length = 1;
666 h264_header.nalus[0].type = H264::NaluType::kIdr;
667 h264_header.packetization_type = kH264SingleNalu;
philipel36928452016-11-07 10:42:36 +0100668 packet.seqNum = seq_num;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100669 packet.video_header.codec = kVideoCodecH264;
philipel36928452016-11-07 10:42:36 +0100670 packet.insertStartCode = true;
philipel36928452016-11-07 10:42:36 +0100671 packet.dataPtr = data;
philipel41b8ca02016-11-07 15:42:24 +0100672 packet.sizeBytes = sizeof(data_data);
Niels Möllerd5e02f02019-02-20 13:12:21 +0100673 packet.video_header.is_first_packet_in_frame = true;
674 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200675 auto frames = packet_buffer_.InsertPacket(&packet).frames;
philipel36928452016-11-07 10:42:36 +0100676
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200677 ASSERT_THAT(frames, SizeIs(1));
678 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
679 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data_data));
680 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data_data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200681 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
682 ElementsAreArray(data_data));
philipel36928452016-11-07 10:42:36 +0100683}
684
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200685TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700686 uint16_t seq_num = 100;
687 uint8_t data_data[] = "some plain old data";
688 uint8_t* data = new uint8_t[sizeof(data_data)];
689 memcpy(data, data_data, sizeof(data_data));
690 uint32_t width = 640;
691 uint32_t height = 360;
692 uint32_t timestamp = 1000;
693
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200694 auto frames = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp,
695 sizeof(data_data), data, width, height)
696 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700697
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200698 ASSERT_THAT(frames, SizeIs(1));
699 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
700 ElementsAreArray(data_data));
701 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
702 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700703}
704
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200705TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700706 uint16_t seq_num = 100;
707 uint8_t data_data[] = "some plain old data";
708 uint8_t* data = new uint8_t[sizeof(data_data)];
709 memcpy(data, data_data, sizeof(data_data));
710 uint32_t width = 640;
711 uint32_t height = 360;
712 uint32_t timestamp = 1000;
713
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200714 auto frames =
715 InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast, timestamp,
716 sizeof(data_data), data, width, height)
717 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700718
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200719 ASSERT_THAT(StartSeqNums(frames), ElementsAre(seq_num));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700720
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200721 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data_data));
722 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data_data));
723 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
724 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
725 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
726 ElementsAreArray(data_data));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700727}
728
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200729TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
philipelaee3e0e2016-11-01 11:45:34 +0100730 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200731
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200732 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
733 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
734 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
735 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700736
philipel17deeb42016-08-11 15:09:26 +0200737 // Insert frame that fills the whole buffer.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200738 Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
philipel17deeb42016-08-11 15:09:26 +0200739 for (int i = 0; i < kMaxSize - 2; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200740 Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
741 EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
742 StartSeqNumsAre(seq_num + 3));
philipelc707ab72016-04-01 02:01:54 -0700743}
744
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200745TEST_F(PacketBufferTest, Clear) {
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));
philipelf4139332016-04-20 10:26:34 +0200752
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200753 packet_buffer_.Clear();
philipelf4139332016-04-20 10:26:34 +0200754
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200755 Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
756 Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
757 EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
758 StartSeqNumsAre(seq_num + kStartSize));
philipelc707ab72016-04-01 02:01:54 -0700759}
760
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200761TEST_F(PacketBufferTest, FramesAfterClear) {
philipel20dce342016-11-28 16:14:57 +0100762 Insert(9025, kDeltaFrame, kFirst, kLast);
763 Insert(9024, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200764 packet_buffer_.ClearTo(9025);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200765 EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
766 EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipel20dce342016-11-28 16:14:57 +0100767}
768
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200769TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
philipel8b6995b2019-01-09 12:39:18 +0100770 Insert(0, kKeyFrame, kFirst, kNotLast, 0, nullptr, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200771 EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, 0, nullptr, 1001).frames,
772 IsEmpty());
philipel8b6995b2019-01-09 12:39:18 +0100773}
774
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200775TEST_F(PacketBufferTest, DontLeakPayloadData) {
philipel759e0b72016-11-30 01:32:05 -0800776 // NOTE! Any eventual leak is suppose to be detected by valgrind
777 // or any other similar tool.
778 uint8_t* data1 = new uint8_t[5];
779 uint8_t* data2 = new uint8_t[5];
780 uint8_t* data3 = new uint8_t[5];
781 uint8_t* data4 = new uint8_t[5];
782
783 // Expected to free data1 upon PacketBuffer destruction.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200784 Insert(2, kKeyFrame, kFirst, kNotLast, 5, data1);
philipel759e0b72016-11-30 01:32:05 -0800785
786 // Expect to free data2 upon insertion.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200787 Insert(2, kKeyFrame, kFirst, kNotLast, 5, data2);
philipel759e0b72016-11-30 01:32:05 -0800788
789 // Expect to free data3 upon insertion (old packet).
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200790 packet_buffer_.ClearTo(1);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200791 Insert(1, kKeyFrame, kFirst, kNotLast, 5, data3);
philipel759e0b72016-11-30 01:32:05 -0800792
793 // Expect to free data4 upon insertion (packet buffer is full).
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200794 Insert(2 + kMaxSize, kKeyFrame, kFirst, kNotLast, 5, data4);
philipel759e0b72016-11-30 01:32:05 -0800795}
796
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200797TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
philipelea142f82017-01-11 02:01:56 -0800798 Insert(2, kKeyFrame, kNotFirst, kNotLast);
799 Insert(1, kKeyFrame, kFirst, kLast);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200800 EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).frames, IsEmpty());
philipelea142f82017-01-11 02:01:56 -0800801}
802
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200803TEST_F(PacketBufferTest, PacketTimestamps) {
Danil Chapovalov0040b662018-06-18 10:48:16 +0200804 absl::optional<int64_t> packet_ms;
805 absl::optional<int64_t> packet_keyframe_ms;
philipel3184f8e2017-05-18 08:08:53 -0700806
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200807 packet_ms = packet_buffer_.LastReceivedPacketMs();
808 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700809 EXPECT_FALSE(packet_ms);
810 EXPECT_FALSE(packet_keyframe_ms);
811
812 int64_t keyframe_ms = clock_->TimeInMilliseconds();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200813 Insert(100, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200814 packet_ms = packet_buffer_.LastReceivedPacketMs();
815 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700816 EXPECT_TRUE(packet_ms);
817 EXPECT_TRUE(packet_keyframe_ms);
818 EXPECT_EQ(keyframe_ms, *packet_ms);
819 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
820
821 clock_->AdvanceTimeMilliseconds(100);
822 int64_t delta_ms = clock_->TimeInMilliseconds();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200823 Insert(101, kDeltaFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200824 packet_ms = packet_buffer_.LastReceivedPacketMs();
825 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700826 EXPECT_TRUE(packet_ms);
827 EXPECT_TRUE(packet_keyframe_ms);
828 EXPECT_EQ(delta_ms, *packet_ms);
829 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
830
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200831 packet_buffer_.Clear();
832 packet_ms = packet_buffer_.LastReceivedPacketMs();
833 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700834 EXPECT_FALSE(packet_ms);
835 EXPECT_FALSE(packet_keyframe_ms);
836}
837
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200838TEST_F(PacketBufferTest, IncomingCodecChange) {
philipel09133af2018-05-17 14:11:09 +0200839 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100840 packet.video_header.is_first_packet_in_frame = true;
841 packet.video_header.is_last_packet_in_frame = true;
philipel09133af2018-05-17 14:11:09 +0200842 packet.sizeBytes = 0;
843 packet.dataPtr = nullptr;
844
Niels Möllerd5e02f02019-02-20 13:12:21 +0100845 packet.video_header.codec = kVideoCodecVP8;
846 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200847 packet.timestamp = 1;
848 packet.seqNum = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200849 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200850 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(1));
philipel09133af2018-05-17 14:11:09 +0200851
Niels Möllerd5e02f02019-02-20 13:12:21 +0100852 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200853 auto& h264_header =
854 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
855 h264_header.nalus_length = 1;
philipel09133af2018-05-17 14:11:09 +0200856 packet.timestamp = 3;
857 packet.seqNum = 3;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200858 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200859
Niels Möllerd5e02f02019-02-20 13:12:21 +0100860 packet.video_header.codec = kVideoCodecVP8;
861 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200862 packet.timestamp = 2;
863 packet.seqNum = 2;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200864 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200865 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(2));
philipel09133af2018-05-17 14:11:09 +0200866}
867
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200868TEST_F(PacketBufferTest, TooManyNalusInPacket) {
philipel09133af2018-05-17 14:11:09 +0200869 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100870 packet.video_header.codec = kVideoCodecH264;
philipel09133af2018-05-17 14:11:09 +0200871 packet.timestamp = 1;
872 packet.seqNum = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200873 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100874 packet.video_header.is_first_packet_in_frame = true;
875 packet.video_header.is_last_packet_in_frame = true;
philipel7d745e52018-08-02 14:03:53 +0200876 auto& h264_header =
877 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
878 h264_header.nalus_length = kMaxNalusPerPacket;
philipel09133af2018-05-17 14:11:09 +0200879 packet.sizeBytes = 0;
880 packet.dataPtr = nullptr;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200881 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200882}
883
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200884TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
philipel2c9f9f22017-06-13 02:47:28 -0700885 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
886 for (int i = 1; i < kStartSize - 1; ++i)
887 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200888 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
889 StartSeqNumsAre(0));
philipel2c9f9f22017-06-13 02:47:28 -0700890}
891
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200892TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200893 EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).frames,
894 SizeIs(1));
philipel227f8b92017-08-04 06:39:31 -0700895
896 InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
897 for (int i = 1; i < kStartSize; ++i)
898 InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200899 EXPECT_THAT(
900 InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
901 .frames,
902 IsEmpty());
philipel227f8b92017-08-04 06:39:31 -0700903
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200904 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
905 StartSeqNumsAre(kStartSize - 1, kStartSize));
philipel227f8b92017-08-04 06:39:31 -0700906}
907
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200908TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
philipel2c9f9f22017-06-13 02:47:28 -0700909 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200910 EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
911 StartSeqNumsAre(65534));
philipel2c9f9f22017-06-13 02:47:28 -0700912}
913
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200914TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
philipel2c9f9f22017-06-13 02:47:28 -0700915 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
916 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
917 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
918 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
919
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200920 EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
921 StartSeqNumsAre(kStartSize + 1));
philipel2c9f9f22017-06-13 02:47:28 -0700922}
923
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200924TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200925 EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
926 StartSeqNumsAre(0));
927 EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).frames,
928 IsEmpty());
philipel2c9f9f22017-06-13 02:47:28 -0700929
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200930 EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
philipel2c9f9f22017-06-13 02:47:28 -0700931}
932
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200933class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200934 protected:
935 const uint16_t kSeqNum = 5;
936
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200937 explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
938 : PacketBufferH264Test(sps_pps_idr_is_keyframe) {
Niels Möllerd5e02f02019-02-20 13:12:21 +0100939 packet_.video_header.codec = kVideoCodecH264;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200940 packet_.seqNum = kSeqNum;
941
Niels Möllerd5e02f02019-02-20 13:12:21 +0100942 packet_.video_header.is_first_packet_in_frame = true;
943 packet_.video_header.is_last_packet_in_frame = true;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200944 }
945
946 VCMPacket packet_;
947};
948
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200949class PacketBufferH264IdrIsKeyframeTest
950 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200951 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200952 PacketBufferH264IdrIsKeyframeTest()
953 : PacketBufferH264XIsKeyframeTest(false) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200954};
955
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200956TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200957 auto& h264_header =
958 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
959 h264_header.nalus[0].type = H264::NaluType::kIdr;
960 h264_header.nalus_length = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200961 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
962 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200963}
964
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200965TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200966 auto& h264_header =
967 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
968 h264_header.nalus[0].type = H264::NaluType::kSps;
969 h264_header.nalus[1].type = H264::NaluType::kPps;
970 h264_header.nalus[2].type = H264::NaluType::kIdr;
971 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200972
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200973 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
974 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200975}
976
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200977class PacketBufferH264SpsPpsIdrIsKeyframeTest
978 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200979 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200980 PacketBufferH264SpsPpsIdrIsKeyframeTest()
981 : PacketBufferH264XIsKeyframeTest(true) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200982};
983
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200984TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200985 auto& h264_header =
986 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
987 h264_header.nalus[0].type = H264::NaluType::kIdr;
988 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200989
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200990 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
991 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200992}
993
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200994TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200995 auto& h264_header =
996 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
997 h264_header.nalus[0].type = H264::NaluType::kSps;
998 h264_header.nalus[1].type = H264::NaluType::kPps;
999 h264_header.nalus_length = 2;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001000
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001001 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
1002 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001003}
1004
Danil Chapovalov05269ec2019-10-17 19:06:46 +02001005TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +02001006 auto& h264_header =
1007 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
1008 h264_header.nalus[0].type = H264::NaluType::kSps;
1009 h264_header.nalus[1].type = H264::NaluType::kPps;
1010 h264_header.nalus[2].type = H264::NaluType::kIdr;
1011 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001012
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001013 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
1014 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +02001015}
1016
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +02001017} // namespace
philipelc707ab72016-04-01 02:01:54 -07001018} // namespace video_coding
1019} // namespace webrtc