blob: 3385f78f1fa084a4d5fe3b848721bc1505524a3a [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 Chapovalov1dac7072019-10-24 12:44:23 +0200447TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
Johannes Kron957c62e2018-10-01 14:53:01 +0200448 uint16_t kFirstSeqNum = 0;
449 uint32_t kTimestampDelta = 100;
450 uint32_t timestamp = 10000;
451 uint16_t seq_num = kFirstSeqNum;
452
453 // Loop until seq_num wraps around.
Philip Eliasson1f850a62019-03-19 12:15:00 +0000454 SeqNumUnwrapper<uint16_t> unwrapper;
Johannes Kron957c62e2018-10-01 14:53:01 +0200455 while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
456 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp);
457 for (int i = 0; i < 5; ++i) {
458 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, 0, nullptr, timestamp);
459 }
460 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, 0, nullptr, timestamp);
461 timestamp += kTimestampDelta;
462 }
463
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200464 // Receive frame with overlapping sequence numbers.
Johannes Kron957c62e2018-10-01 14:53:01 +0200465 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, 0, nullptr, timestamp);
466 for (int i = 0; i < 5; ++i) {
467 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, 0, nullptr, timestamp);
468 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200469 EXPECT_THAT(
470 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, 0, nullptr, timestamp)
471 .frames,
472 SizeIs(1));
Johannes Kron957c62e2018-10-01 14:53:01 +0200473}
474
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100475// If |sps_pps_idr_is_keyframe| is true, we require keyframes to contain
476// SPS/PPS/IDR and the keyframes we create as part of the test do contain
477// SPS/PPS/IDR. If |sps_pps_idr_is_keyframe| is false, we only require and
478// create keyframes containing only IDR.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200479class PacketBufferH264Test : public PacketBufferTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200480 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200481 explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
482 : PacketBufferTest(sps_pps_idr_is_keyframe
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100483 ? "WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/"
484 : ""),
485 sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200486
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200487 PacketBufferInsertResult InsertH264(
488 uint16_t seq_num, // packet sequence number
489 IsKeyFrame keyframe, // is keyframe
490 IsFirst first, // is first packet of frame
491 IsLast last, // is last packet of frame
492 uint32_t timestamp, // rtp timestamp
493 int data_size = 0, // size of data
494 uint8_t* data = nullptr, // data pointer
495 uint32_t width = 0, // width of frame (SPS/IDR)
496 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100497 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100498 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200499 auto& h264_header =
500 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100501 packet.seq_num = seq_num;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200502 packet.timestamp = timestamp;
503 if (keyframe == kKeyFrame) {
504 if (sps_pps_idr_is_keyframe_) {
philipel7d745e52018-08-02 14:03:53 +0200505 h264_header.nalus[0].type = H264::NaluType::kSps;
506 h264_header.nalus[1].type = H264::NaluType::kPps;
507 h264_header.nalus[2].type = H264::NaluType::kIdr;
508 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200509 } else {
philipel7d745e52018-08-02 14:03:53 +0200510 h264_header.nalus[0].type = H264::NaluType::kIdr;
511 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200512 }
513 }
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700514 packet.video_header.width = width;
515 packet.video_header.height = height;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100516 packet.video_header.is_first_packet_in_frame = first == kFirst;
517 packet.video_header.is_last_packet_in_frame = last == kLast;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100518 packet.size_bytes = data_size;
519 packet.data = data;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200520
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200521 return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200522 }
523
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200524 PacketBufferInsertResult InsertH264KeyFrameWithAud(
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700525 uint16_t seq_num, // packet sequence number
526 IsKeyFrame keyframe, // is keyframe
527 IsFirst first, // is first packet of frame
528 IsLast last, // is last packet of frame
529 uint32_t timestamp, // rtp timestamp
530 int data_size = 0, // size of data
531 uint8_t* data = nullptr, // data pointer
532 uint32_t width = 0, // width of frame (SPS/IDR)
533 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100534 PacketBuffer::Packet packet;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700535 packet.video_header.codec = kVideoCodecH264;
536 auto& h264_header =
537 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100538 packet.seq_num = seq_num;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700539 packet.timestamp = timestamp;
540
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200541 // this should be the start of frame.
542 RTC_CHECK(first == kFirst);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700543
544 // Insert a AUD NALU / packet without width/height.
545 h264_header.nalus[0].type = H264::NaluType::kAud;
546 h264_header.nalus_length = 1;
547 packet.video_header.is_first_packet_in_frame = true;
548 packet.video_header.is_last_packet_in_frame = false;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100549 packet.size_bytes = 0;
550 packet.data = nullptr;
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200551 IgnoreResult(packet_buffer_.InsertPacket(&packet));
552 // insert IDR
553 return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp,
554 data_size, data, width, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700555 }
556
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200557 const bool sps_pps_idr_is_keyframe_;
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100558};
559
560// This fixture is used to test the general behaviour of the packet buffer
561// in both configurations.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200562class PacketBufferH264ParameterizedTest
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100563 : public ::testing::WithParamInterface<bool>,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200564 public PacketBufferH264Test {
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100565 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200566 PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200567};
568
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100569INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200570 PacketBufferH264ParameterizedTest,
571 ::testing::Bool());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200572
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200573TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200574 InsertH264(0, kKeyFrame, kFirst, kLast, 0);
575 InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200576 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200577 // Expect no frame because of missing of packet #1
578 EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).frames,
579 IsEmpty());
philipelbc5a4082017-12-06 10:41:08 +0100580}
581
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200582TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
philipel227f8b92017-08-04 06:39:31 -0700583 uint8_t* data_arr[kStartSize];
584 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700585
586 for (uint8_t i = 0; i < kStartSize; ++i) {
587 data_arr[i] = new uint8_t[1];
588 data_arr[i][0] = i;
589 expected[i] = i;
590 }
591
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200592 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700593 for (uint8_t i = 1; i < kStartSize - 1; ++i) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200594 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, 1, data_arr[i]);
philipel227f8b92017-08-04 06:39:31 -0700595 }
philipel227f8b92017-08-04 06:39:31 -0700596
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200597 auto frames = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1, 1,
598 data_arr[kStartSize - 1])
599 .frames;
600 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
601 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
602 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700603}
604
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200605TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
philipel36928452016-11-07 10:42:36 +0100606 uint16_t seq_num = Rand();
philipel41b8ca02016-11-07 15:42:24 +0100607 uint8_t data_data[] = "some plain old data";
608 uint8_t* data = new uint8_t[sizeof(data_data)];
609 memcpy(data, data_data, sizeof(data_data));
philipel36928452016-11-07 10:42:36 +0100610
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100611 PacketBuffer::Packet packet;
philipel7d745e52018-08-02 14:03:53 +0200612 auto& h264_header =
613 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
614 h264_header.nalus_length = 1;
615 h264_header.nalus[0].type = H264::NaluType::kIdr;
616 h264_header.packetization_type = kH264SingleNalu;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100617 packet.seq_num = seq_num;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100618 packet.video_header.codec = kVideoCodecH264;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100619 packet.data = data;
620 packet.size_bytes = sizeof(data_data);
Niels Möllerd5e02f02019-02-20 13:12:21 +0100621 packet.video_header.is_first_packet_in_frame = true;
622 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200623 auto frames = packet_buffer_.InsertPacket(&packet).frames;
philipel36928452016-11-07 10:42:36 +0100624
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200625 ASSERT_THAT(frames, SizeIs(1));
626 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
627 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data_data));
628 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data_data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200629 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
630 ElementsAreArray(data_data));
philipel36928452016-11-07 10:42:36 +0100631}
632
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200633TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700634 uint16_t seq_num = 100;
635 uint8_t data_data[] = "some plain old data";
636 uint8_t* data = new uint8_t[sizeof(data_data)];
637 memcpy(data, data_data, sizeof(data_data));
638 uint32_t width = 640;
639 uint32_t height = 360;
640 uint32_t timestamp = 1000;
641
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200642 auto frames = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp,
643 sizeof(data_data), data, width, height)
644 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700645
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200646 ASSERT_THAT(frames, SizeIs(1));
647 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
648 ElementsAreArray(data_data));
649 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
650 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700651}
652
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200653TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700654 uint16_t seq_num = 100;
655 uint8_t data_data[] = "some plain old data";
656 uint8_t* data = new uint8_t[sizeof(data_data)];
657 memcpy(data, data_data, sizeof(data_data));
658 uint32_t width = 640;
659 uint32_t height = 360;
660 uint32_t timestamp = 1000;
661
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200662 auto frames =
663 InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast, timestamp,
664 sizeof(data_data), data, width, height)
665 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700666
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200667 ASSERT_THAT(StartSeqNums(frames), ElementsAre(seq_num));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700668
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200669 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data_data));
670 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data_data));
671 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
672 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
673 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
674 ElementsAreArray(data_data));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700675}
676
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200677TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
philipelaee3e0e2016-11-01 11:45:34 +0100678 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200679
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200680 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
681 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
682 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
683 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700684
philipel17deeb42016-08-11 15:09:26 +0200685 // Insert frame that fills the whole buffer.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200686 Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
philipel17deeb42016-08-11 15:09:26 +0200687 for (int i = 0; i < kMaxSize - 2; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200688 Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
689 EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
690 StartSeqNumsAre(seq_num + 3));
philipelc707ab72016-04-01 02:01:54 -0700691}
692
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200693TEST_F(PacketBufferTest, Clear) {
philipelaee3e0e2016-11-01 11:45:34 +0100694 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200695
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200696 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
697 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
698 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
699 StartSeqNumsAre(seq_num));
philipelf4139332016-04-20 10:26:34 +0200700
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200701 packet_buffer_.Clear();
philipelf4139332016-04-20 10:26:34 +0200702
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200703 Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
704 Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
705 EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
706 StartSeqNumsAre(seq_num + kStartSize));
philipelc707ab72016-04-01 02:01:54 -0700707}
708
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200709TEST_F(PacketBufferTest, FramesAfterClear) {
philipel20dce342016-11-28 16:14:57 +0100710 Insert(9025, kDeltaFrame, kFirst, kLast);
711 Insert(9024, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200712 packet_buffer_.ClearTo(9025);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200713 EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
714 EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipel20dce342016-11-28 16:14:57 +0100715}
716
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200717TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
philipel8b6995b2019-01-09 12:39:18 +0100718 Insert(0, kKeyFrame, kFirst, kNotLast, 0, nullptr, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200719 EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, 0, nullptr, 1001).frames,
720 IsEmpty());
philipel8b6995b2019-01-09 12:39:18 +0100721}
722
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200723TEST_F(PacketBufferTest, DontLeakPayloadData) {
philipel759e0b72016-11-30 01:32:05 -0800724 // NOTE! Any eventual leak is suppose to be detected by valgrind
725 // or any other similar tool.
726 uint8_t* data1 = new uint8_t[5];
727 uint8_t* data2 = new uint8_t[5];
728 uint8_t* data3 = new uint8_t[5];
729 uint8_t* data4 = new uint8_t[5];
730
731 // Expected to free data1 upon PacketBuffer destruction.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200732 Insert(2, kKeyFrame, kFirst, kNotLast, 5, data1);
philipel759e0b72016-11-30 01:32:05 -0800733
734 // Expect to free data2 upon insertion.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200735 Insert(2, kKeyFrame, kFirst, kNotLast, 5, data2);
philipel759e0b72016-11-30 01:32:05 -0800736
737 // Expect to free data3 upon insertion (old packet).
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200738 packet_buffer_.ClearTo(1);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200739 Insert(1, kKeyFrame, kFirst, kNotLast, 5, data3);
philipel759e0b72016-11-30 01:32:05 -0800740
741 // Expect to free data4 upon insertion (packet buffer is full).
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200742 Insert(2 + kMaxSize, kKeyFrame, kFirst, kNotLast, 5, data4);
philipel759e0b72016-11-30 01:32:05 -0800743}
744
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200745TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
philipelea142f82017-01-11 02:01:56 -0800746 Insert(2, kKeyFrame, kNotFirst, kNotLast);
747 Insert(1, kKeyFrame, kFirst, kLast);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200748 EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).frames, IsEmpty());
philipelea142f82017-01-11 02:01:56 -0800749}
750
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200751TEST_F(PacketBufferTest, PacketTimestamps) {
Danil Chapovalov0040b662018-06-18 10:48:16 +0200752 absl::optional<int64_t> packet_ms;
753 absl::optional<int64_t> packet_keyframe_ms;
philipel3184f8e2017-05-18 08:08:53 -0700754
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200755 packet_ms = packet_buffer_.LastReceivedPacketMs();
756 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700757 EXPECT_FALSE(packet_ms);
758 EXPECT_FALSE(packet_keyframe_ms);
759
760 int64_t keyframe_ms = clock_->TimeInMilliseconds();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200761 Insert(100, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200762 packet_ms = packet_buffer_.LastReceivedPacketMs();
763 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700764 EXPECT_TRUE(packet_ms);
765 EXPECT_TRUE(packet_keyframe_ms);
766 EXPECT_EQ(keyframe_ms, *packet_ms);
767 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
768
769 clock_->AdvanceTimeMilliseconds(100);
770 int64_t delta_ms = clock_->TimeInMilliseconds();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200771 Insert(101, kDeltaFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200772 packet_ms = packet_buffer_.LastReceivedPacketMs();
773 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700774 EXPECT_TRUE(packet_ms);
775 EXPECT_TRUE(packet_keyframe_ms);
776 EXPECT_EQ(delta_ms, *packet_ms);
777 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
778
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200779 packet_buffer_.Clear();
780 packet_ms = packet_buffer_.LastReceivedPacketMs();
781 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700782 EXPECT_FALSE(packet_ms);
783 EXPECT_FALSE(packet_keyframe_ms);
784}
785
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200786TEST_F(PacketBufferTest, IncomingCodecChange) {
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100787 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100788 packet.video_header.is_first_packet_in_frame = true;
789 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100790 packet.size_bytes = 0;
791 packet.data = nullptr;
philipel09133af2018-05-17 14:11:09 +0200792
Niels Möllerd5e02f02019-02-20 13:12:21 +0100793 packet.video_header.codec = kVideoCodecVP8;
794 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200795 packet.timestamp = 1;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100796 packet.seq_num = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200797 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200798 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(1));
philipel09133af2018-05-17 14:11:09 +0200799
Niels Möllerd5e02f02019-02-20 13:12:21 +0100800 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200801 auto& h264_header =
802 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
803 h264_header.nalus_length = 1;
philipel09133af2018-05-17 14:11:09 +0200804 packet.timestamp = 3;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100805 packet.seq_num = 3;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200806 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200807
Niels Möllerd5e02f02019-02-20 13:12:21 +0100808 packet.video_header.codec = kVideoCodecVP8;
809 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200810 packet.timestamp = 2;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100811 packet.seq_num = 2;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200812 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200813 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(2));
philipel09133af2018-05-17 14:11:09 +0200814}
815
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200816TEST_F(PacketBufferTest, TooManyNalusInPacket) {
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100817 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100818 packet.video_header.codec = kVideoCodecH264;
philipel09133af2018-05-17 14:11:09 +0200819 packet.timestamp = 1;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100820 packet.seq_num = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200821 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100822 packet.video_header.is_first_packet_in_frame = true;
823 packet.video_header.is_last_packet_in_frame = true;
philipel7d745e52018-08-02 14:03:53 +0200824 auto& h264_header =
825 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
826 h264_header.nalus_length = kMaxNalusPerPacket;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100827 packet.size_bytes = 0;
828 packet.data = nullptr;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200829 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200830}
831
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200832TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
philipel2c9f9f22017-06-13 02:47:28 -0700833 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
834 for (int i = 1; i < kStartSize - 1; ++i)
835 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200836 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
837 StartSeqNumsAre(0));
philipel2c9f9f22017-06-13 02:47:28 -0700838}
839
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200840TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200841 EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).frames,
842 SizeIs(1));
philipel227f8b92017-08-04 06:39:31 -0700843
844 InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
845 for (int i = 1; i < kStartSize; ++i)
846 InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200847 EXPECT_THAT(
848 InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
849 .frames,
850 IsEmpty());
philipel227f8b92017-08-04 06:39:31 -0700851
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200852 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
853 StartSeqNumsAre(kStartSize - 1, kStartSize));
philipel227f8b92017-08-04 06:39:31 -0700854}
855
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200856TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
philipel2c9f9f22017-06-13 02:47:28 -0700857 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200858 EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
859 StartSeqNumsAre(65534));
philipel2c9f9f22017-06-13 02:47:28 -0700860}
861
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200862TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
philipel2c9f9f22017-06-13 02:47:28 -0700863 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
864 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
865 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
866 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
867
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200868 EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
869 StartSeqNumsAre(kStartSize + 1));
philipel2c9f9f22017-06-13 02:47:28 -0700870}
871
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200872TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200873 EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
874 StartSeqNumsAre(0));
875 EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).frames,
876 IsEmpty());
philipel2c9f9f22017-06-13 02:47:28 -0700877
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200878 EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
philipel2c9f9f22017-06-13 02:47:28 -0700879}
880
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200881class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200882 protected:
883 const uint16_t kSeqNum = 5;
884
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200885 explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
886 : PacketBufferH264Test(sps_pps_idr_is_keyframe) {
Niels Möllerd5e02f02019-02-20 13:12:21 +0100887 packet_.video_header.codec = kVideoCodecH264;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100888 packet_.seq_num = kSeqNum;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200889
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;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200892 }
893
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100894 PacketBuffer::Packet packet_;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200895};
896
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200897class PacketBufferH264IdrIsKeyframeTest
898 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200899 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200900 PacketBufferH264IdrIsKeyframeTest()
901 : PacketBufferH264XIsKeyframeTest(false) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200902};
903
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200904TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200905 auto& h264_header =
906 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
907 h264_header.nalus[0].type = H264::NaluType::kIdr;
908 h264_header.nalus_length = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200909 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
910 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200911}
912
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200913TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200914 auto& h264_header =
915 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
916 h264_header.nalus[0].type = H264::NaluType::kSps;
917 h264_header.nalus[1].type = H264::NaluType::kPps;
918 h264_header.nalus[2].type = H264::NaluType::kIdr;
919 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200920
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200921 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
922 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200923}
924
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200925class PacketBufferH264SpsPpsIdrIsKeyframeTest
926 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200927 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200928 PacketBufferH264SpsPpsIdrIsKeyframeTest()
929 : PacketBufferH264XIsKeyframeTest(true) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200930};
931
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200932TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200933 auto& h264_header =
934 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
935 h264_header.nalus[0].type = H264::NaluType::kIdr;
936 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200937
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200938 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
939 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200940}
941
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200942TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200943 auto& h264_header =
944 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
945 h264_header.nalus[0].type = H264::NaluType::kSps;
946 h264_header.nalus[1].type = H264::NaluType::kPps;
947 h264_header.nalus_length = 2;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200948
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200949 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
950 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200951}
952
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200953TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200954 auto& h264_header =
955 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
956 h264_header.nalus[0].type = H264::NaluType::kSps;
957 h264_header.nalus[1].type = H264::NaluType::kPps;
958 h264_header.nalus[2].type = H264::NaluType::kIdr;
959 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200960
Danil 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 Chapovalovce1ffcd2019-10-22 17:12:42 +0200965} // namespace
philipelc707ab72016-04-01 02:01:54 -0700966} // namespace video_coding
967} // namespace webrtc