blob: 0936bf8ab0043f1ddaeae30e30be7a6e7747203f [file] [log] [blame]
philipelc707ab72016-04-01 02:01:54 -07001/*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
Danil Chapovalov05269ec2019-10-17 19:06:46 +020010#include "modules/video_coding/packet_buffer.h"
philipelc707ab72016-04-01 02:01:54 -070011
12#include <cstring>
Danil Chapovalov05269ec2019-10-17 19:06:46 +020013#include <limits>
Danil Chapovalov1dac7072019-10-24 12:44:23 +020014#include <ostream>
Danil Chapovalov05269ec2019-10-17 19:06:46 +020015#include <string>
philipela1059872016-05-09 11:41:48 +020016#include <utility>
philipelc707ab72016-04-01 02:01:54 -070017
Danil Chapovalov1dac7072019-10-24 12:44:23 +020018#include "api/array_view.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "common_video/h264/h264_common.h"
20#include "modules/video_coding/frame_object.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/random.h"
22#include "system_wrappers/include/clock.h"
Rasmus Brandtedf4ff72017-10-24 10:07:48 +020023#include "test/field_trial.h"
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020024#include "test/gmock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020025#include "test/gtest.h"
philipelc707ab72016-04-01 02:01:54 -070026
27namespace webrtc {
28namespace video_coding {
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020029namespace {
philipelc707ab72016-04-01 02:01:54 -070030
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020031using ::testing::ElementsAre;
Danil Chapovalov1dac7072019-10-24 12:44:23 +020032using ::testing::ElementsAreArray;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020033using ::testing::IsEmpty;
Danil Chapovalov1dac7072019-10-24 12:44:23 +020034using ::testing::Matches;
35using ::testing::Pointee;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020036using ::testing::SizeIs;
37
Danil Chapovalov1dac7072019-10-24 12:44:23 +020038constexpr int kStartSize = 16;
39constexpr int kMaxSize = 64;
40
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020041void IgnoreResult(PacketBuffer::InsertResult /*result*/) {}
42
Danil Chapovalov1dac7072019-10-24 12:44:23 +020043std::vector<uint16_t> StartSeqNums(
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020044 rtc::ArrayView<const std::unique_ptr<RtpFrameObject>> frames) {
45 std::vector<uint16_t> result;
46 for (const auto& frame : frames) {
47 result.push_back(frame->first_seq_num());
48 }
49 return result;
50}
51
Danil Chapovalov1dac7072019-10-24 12:44:23 +020052MATCHER_P(StartSeqNumsAre, seq_num, "") {
53 return Matches(ElementsAre(seq_num))(StartSeqNums(arg.frames));
54}
55
56MATCHER_P2(StartSeqNumsAre, seq_num1, seq_num2, "") {
57 return Matches(ElementsAre(seq_num1, seq_num2))(StartSeqNums(arg.frames));
58}
59
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020060MATCHER(KeyFrame, "") {
61 return arg->frame_type() == VideoFrameType::kVideoFrameKey;
62}
63
64MATCHER(DeltaFrame, "") {
65 return arg->frame_type() == VideoFrameType::kVideoFrameDelta;
66}
67
Danil Chapovalov1dac7072019-10-24 12:44:23 +020068struct PacketBufferInsertResult : public PacketBuffer::InsertResult {
69 explicit PacketBufferInsertResult(PacketBuffer::InsertResult result)
70 : InsertResult(std::move(result)) {}
71};
72
73void PrintTo(const PacketBufferInsertResult& result, std::ostream* os) {
74 *os << "frames: { ";
75 for (size_t i = 0; i < result.frames.size(); ++i) {
76 const RtpFrameObject& frame = *result.frames[i];
77 if (i > 0) {
78 *os << ", ";
79 }
80 *os << "{sn: ";
81 if (frame.first_seq_num() == frame.last_seq_num()) {
82 *os << frame.first_seq_num();
83 } else {
84 *os << "[" << frame.first_seq_num() << "-" << frame.last_seq_num() << "]";
85 }
86 *os << "}";
87 }
88 *os << " }";
89 if (result.buffer_cleared) {
90 *os << ", buffer_cleared";
91 }
92}
93
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +020094class PacketBufferTest : public ::testing::Test {
philipelc707ab72016-04-01 02:01:54 -070095 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +020096 explicit PacketBufferTest(std::string field_trials = "")
Rasmus Brandt88f080a2017-11-02 14:28:06 +010097 : scoped_field_trials_(field_trials),
98 rand_(0x7732213),
Danil Chapovalove3c48842019-12-02 15:54:27 +010099 clock_(0),
100 packet_buffer_(&clock_, kStartSize, kMaxSize) {}
philipelc707ab72016-04-01 02:01:54 -0700101
philipel17deeb42016-08-11 15:09:26 +0200102 uint16_t Rand() { return rand_.Rand<uint16_t>(); }
philipelc707ab72016-04-01 02:01:54 -0700103
philipel17deeb42016-08-11 15:09:26 +0200104 enum IsKeyFrame { kKeyFrame, kDeltaFrame };
105 enum IsFirst { kFirst, kNotFirst };
106 enum IsLast { kLast, kNotLast };
philipelc707ab72016-04-01 02:01:54 -0700107
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200108 PacketBufferInsertResult Insert(uint16_t seq_num, // packet sequence number
109 IsKeyFrame keyframe, // is keyframe
110 IsFirst first, // is first packet of frame
111 IsLast last, // is last packet of frame
Danil Chapovalove3c48842019-12-02 15:54:27 +0100112 rtc::ArrayView<const uint8_t> data = {},
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200113 uint32_t timestamp = 123u) { // rtp timestamp
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100114 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100115 packet.video_header.codec = kVideoCodecGeneric;
Ilya Nikolaevskiyd397a0d2018-02-21 15:57:09 +0100116 packet.timestamp = timestamp;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100117 packet.seq_num = seq_num;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200118 packet.video_header.frame_type = keyframe == kKeyFrame
119 ? VideoFrameType::kVideoFrameKey
120 : VideoFrameType::kVideoFrameDelta;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100121 packet.video_header.is_first_packet_in_frame = first == kFirst;
122 packet.video_header.is_last_packet_in_frame = last == kLast;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100123 packet.video_payload.SetData(data.data(), data.size());
philipelf4139332016-04-20 10:26:34 +0200124
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200125 return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200126 }
127
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100128 const test::ScopedFieldTrials scoped_field_trials_;
philipelc707ab72016-04-01 02:01:54 -0700129 Random rand_;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100130 SimulatedClock clock_;
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200131 PacketBuffer packet_buffer_;
philipelc707ab72016-04-01 02:01:54 -0700132};
133
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200134TEST_F(PacketBufferTest, InsertOnePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100135 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200136 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700137}
138
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200139TEST_F(PacketBufferTest, InsertMultiplePackets) {
philipelaee3e0e2016-11-01 11:45:34 +0100140 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200141 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
142 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
143 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
144 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700145}
146
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200147TEST_F(PacketBufferTest, InsertDuplicatePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100148 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200149 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
150 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
151 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast).frames,
152 SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100153}
154
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200155TEST_F(PacketBufferTest, SeqNumWrapOneFrame) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200156 Insert(0xFFFF, kKeyFrame, kFirst, kNotLast);
157 EXPECT_THAT(Insert(0x0, kKeyFrame, kNotFirst, kLast),
158 StartSeqNumsAre(0xFFFF));
philipel2c2f34c2017-01-03 05:55:34 -0800159}
160
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200161TEST_F(PacketBufferTest, SeqNumWrapTwoFrames) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200162 EXPECT_THAT(Insert(0xFFFF, kKeyFrame, kFirst, kLast),
163 StartSeqNumsAre(0xFFFF));
164 EXPECT_THAT(Insert(0x0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0x0));
philipelaee3e0e2016-11-01 11:45:34 +0100165}
166
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200167TEST_F(PacketBufferTest, InsertOldPackets) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200168 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
169 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
170 EXPECT_THAT(Insert(101, kKeyFrame, kNotFirst, kLast).frames, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100171
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200172 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
173 EXPECT_THAT(Insert(100, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
174 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipelaee3e0e2016-11-01 11:45:34 +0100175
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200176 packet_buffer_.ClearTo(102);
177 EXPECT_THAT(Insert(102, kDeltaFrame, kFirst, kLast).frames, IsEmpty());
178 EXPECT_THAT(Insert(103, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipelc707ab72016-04-01 02:01:54 -0700179}
180
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200181TEST_F(PacketBufferTest, NackCount) {
philipelaee3e0e2016-11-01 11:45:34 +0100182 const uint16_t seq_num = Rand();
philipel5ceaaae2016-05-24 10:20:47 +0200183
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100184 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100185 packet.video_header.codec = kVideoCodecGeneric;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100186 packet.seq_num = seq_num;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200187 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100188 packet.video_header.is_first_packet_in_frame = true;
189 packet.video_header.is_last_packet_in_frame = false;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100190 packet.times_nacked = 0;
philipel5ceaaae2016-05-24 10:20:47 +0200191
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200192 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200193
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100194 packet.seq_num++;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100195 packet.video_header.is_first_packet_in_frame = false;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100196 packet.times_nacked = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200197 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200198
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100199 packet.seq_num++;
200 packet.times_nacked = 3;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200201 IgnoreResult(packet_buffer_.InsertPacket(&packet));
philipel5ceaaae2016-05-24 10:20:47 +0200202
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100203 packet.seq_num++;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100204 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100205 packet.times_nacked = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200206 auto frames = packet_buffer_.InsertPacket(&packet).frames;
philipel5ceaaae2016-05-24 10:20:47 +0200207
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200208 ASSERT_THAT(frames, SizeIs(1));
209 EXPECT_EQ(frames.front()->times_nacked(), 3);
philipel5ceaaae2016-05-24 10:20:47 +0200210}
211
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200212TEST_F(PacketBufferTest, FrameSize) {
philipelaee3e0e2016-11-01 11:45:34 +0100213 const uint16_t seq_num = Rand();
Danil Chapovalove3c48842019-12-02 15:54:27 +0100214 uint8_t data1[5] = {};
215 uint8_t data2[5] = {};
216 uint8_t data3[5] = {};
217 uint8_t data4[5] = {};
philipel5ceaaae2016-05-24 10:20:47 +0200218
Danil Chapovalove3c48842019-12-02 15:54:27 +0100219 Insert(seq_num, kKeyFrame, kFirst, kNotLast, data1);
220 Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast, data2);
221 Insert(seq_num + 2, kKeyFrame, kNotFirst, kNotLast, data3);
222 EXPECT_THAT(Insert(seq_num + 3, kKeyFrame, kNotFirst, kLast, data4).frames,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200223 ElementsAre(Pointee(SizeIs(20))));
philipel5ceaaae2016-05-24 10:20:47 +0200224}
225
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200226TEST_F(PacketBufferTest, ExpandBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100227 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700228
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200229 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
Johannes Krona3705562019-08-26 16:37:11 +0200230 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200231 EXPECT_FALSE(
232 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200233
234 // Already inserted kStartSize number of packets, inserting the last packet
235 // should increase the buffer size and also result in an assembled frame.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200236 EXPECT_FALSE(
237 Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700238}
239
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200240TEST_F(PacketBufferTest, SingleFrameExpandsBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100241 const uint16_t seq_num = Rand();
242
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200243 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
philipelaee3e0e2016-11-01 11:45:34 +0100244 for (int i = 1; i < kStartSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200245 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast);
246 EXPECT_THAT(Insert(seq_num + kStartSize, kKeyFrame, kNotFirst, kLast),
247 StartSeqNumsAre(seq_num));
philipelaee3e0e2016-11-01 11:45:34 +0100248}
249
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200250TEST_F(PacketBufferTest, ExpandBufferOverflow) {
philipelaee3e0e2016-11-01 11:45:34 +0100251 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700252
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200253 EXPECT_FALSE(Insert(seq_num, kKeyFrame, kFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200254 for (int i = 1; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200255 EXPECT_FALSE(
256 Insert(seq_num + i, kKeyFrame, kNotFirst, kNotLast).buffer_cleared);
Johannes Krona3705562019-08-26 16:37:11 +0200257
258 // Already inserted kMaxSize number of packets, inserting the last packet
259 // should overflow the buffer and result in false being returned.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200260 EXPECT_TRUE(
261 Insert(seq_num + kMaxSize, kKeyFrame, kNotFirst, kLast).buffer_cleared);
philipelc707ab72016-04-01 02:01:54 -0700262}
263
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200264TEST_F(PacketBufferTest, OnePacketOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100265 const uint16_t seq_num = Rand();
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200266 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
267 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700268}
269
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200270TEST_F(PacketBufferTest, TwoPacketsTwoFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100271 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200272
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200273 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
274 StartSeqNumsAre(seq_num));
275 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kFirst, kLast),
276 StartSeqNumsAre(seq_num + 1));
philipelc707ab72016-04-01 02:01:54 -0700277}
278
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200279TEST_F(PacketBufferTest, TwoPacketsOneFrames) {
philipelaee3e0e2016-11-01 11:45:34 +0100280 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200281
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200282 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
283 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kLast),
284 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700285}
286
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200287TEST_F(PacketBufferTest, ThreePacketReorderingOneFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100288 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700289
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200290 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kNotLast).frames, IsEmpty());
291 EXPECT_THAT(Insert(seq_num + 2, kKeyFrame, kNotFirst, kLast).frames,
292 IsEmpty());
293 EXPECT_THAT(Insert(seq_num + 1, kKeyFrame, kNotFirst, kNotLast),
294 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700295}
296
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200297TEST_F(PacketBufferTest, Frames) {
philipelaee3e0e2016-11-01 11:45:34 +0100298 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200299
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200300 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
301 StartSeqNumsAre(seq_num));
302 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
303 StartSeqNumsAre(seq_num + 1));
304 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
305 StartSeqNumsAre(seq_num + 2));
306 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
307 StartSeqNumsAre(seq_num + 3));
philipelf4139332016-04-20 10:26:34 +0200308}
309
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200310TEST_F(PacketBufferTest, ClearSinglePacket) {
philipelaee3e0e2016-11-01 11:45:34 +0100311 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200312
philipelaee3e0e2016-11-01 11:45:34 +0100313 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200314 Insert(seq_num + i, kDeltaFrame, kFirst, kLast);
philipelaee3e0e2016-11-01 11:45:34 +0100315
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200316 packet_buffer_.ClearTo(seq_num);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200317 EXPECT_FALSE(
318 Insert(seq_num + kMaxSize, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelaee3e0e2016-11-01 11:45:34 +0100319}
320
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200321TEST_F(PacketBufferTest, ClearFullBuffer) {
philipelc5fb4682017-08-02 04:28:57 -0700322 for (int i = 0; i < kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200323 Insert(i, kDeltaFrame, kFirst, kLast);
philipelc5fb4682017-08-02 04:28:57 -0700324
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200325 packet_buffer_.ClearTo(kMaxSize - 1);
philipelc5fb4682017-08-02 04:28:57 -0700326
327 for (int i = kMaxSize; i < 2 * kMaxSize; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200328 EXPECT_FALSE(Insert(i, kDeltaFrame, kFirst, kLast).buffer_cleared);
philipelc5fb4682017-08-02 04:28:57 -0700329}
330
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200331TEST_F(PacketBufferTest, DontClearNewerPacket) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200332 EXPECT_THAT(Insert(0, kKeyFrame, kFirst, kLast), StartSeqNumsAre(0));
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200333 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200334 EXPECT_THAT(Insert(2 * kStartSize, kKeyFrame, kFirst, kLast),
335 StartSeqNumsAre(2 * kStartSize));
336 EXPECT_THAT(Insert(3 * kStartSize + 1, kKeyFrame, kFirst, kNotLast).frames,
337 IsEmpty());
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200338 packet_buffer_.ClearTo(2 * kStartSize);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200339 EXPECT_THAT(Insert(3 * kStartSize + 2, kKeyFrame, kNotFirst, kLast),
340 StartSeqNumsAre(3 * kStartSize + 1));
philipelc5fb4682017-08-02 04:28:57 -0700341}
342
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200343TEST_F(PacketBufferTest, OneIncompleteFrame) {
philipelaee3e0e2016-11-01 11:45:34 +0100344 const uint16_t seq_num = Rand();
345
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200346 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
347 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kNotFirst, kLast),
348 StartSeqNumsAre(seq_num));
349 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
350 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100351}
352
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200353TEST_F(PacketBufferTest, TwoIncompleteFramesFullBuffer) {
philipelaee3e0e2016-11-01 11:45:34 +0100354 const uint16_t seq_num = Rand();
355
356 for (int i = 1; i < kMaxSize - 1; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200357 Insert(seq_num + i, kDeltaFrame, kNotFirst, kNotLast);
358 EXPECT_THAT(Insert(seq_num, kDeltaFrame, kFirst, kNotLast).frames, IsEmpty());
359 EXPECT_THAT(Insert(seq_num - 1, kDeltaFrame, kNotFirst, kLast).frames,
360 IsEmpty());
philipelaee3e0e2016-11-01 11:45:34 +0100361}
362
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200363TEST_F(PacketBufferTest, FramesReordered) {
philipelaee3e0e2016-11-01 11:45:34 +0100364 const uint16_t seq_num = Rand();
365
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200366 EXPECT_THAT(Insert(seq_num + 1, kDeltaFrame, kFirst, kLast),
367 StartSeqNumsAre(seq_num + 1));
368 EXPECT_THAT(Insert(seq_num, kKeyFrame, kFirst, kLast),
369 StartSeqNumsAre(seq_num));
370 EXPECT_THAT(Insert(seq_num + 3, kDeltaFrame, kFirst, kLast),
371 StartSeqNumsAre(seq_num + 3));
372 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kFirst, kLast),
373 StartSeqNumsAre(seq_num + 2));
philipelf4139332016-04-20 10:26:34 +0200374}
375
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200376TEST_F(PacketBufferTest, GetBitstream) {
philipelc707ab72016-04-01 02:01:54 -0700377 // "many bitstream, such data" with null termination.
Danil Chapovalove3c48842019-12-02 15:54:27 +0100378 uint8_t many[] = {0x6d, 0x61, 0x6e, 0x79, 0x20};
379 uint8_t bitstream[] = {0x62, 0x69, 0x74, 0x73, 0x74, 0x72,
380 0x65, 0x61, 0x6d, 0x2c, 0x20};
381 uint8_t such[] = {0x73, 0x75, 0x63, 0x68, 0x20};
382 uint8_t data[] = {0x64, 0x61, 0x74, 0x61, 0x0};
philipel41b8ca02016-11-07 15:42:24 +0100383
philipelaee3e0e2016-11-01 11:45:34 +0100384 const uint16_t seq_num = Rand();
philipelc707ab72016-04-01 02:01:54 -0700385
Danil Chapovalove3c48842019-12-02 15:54:27 +0100386 Insert(seq_num, kKeyFrame, kFirst, kNotLast, many);
387 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast, bitstream);
388 Insert(seq_num + 2, kDeltaFrame, kNotFirst, kNotLast, such);
389 auto frames = Insert(seq_num + 3, kDeltaFrame, kNotFirst, kLast, data).frames;
philipelf4139332016-04-20 10:26:34 +0200390
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200391 ASSERT_THAT(frames, SizeIs(1));
392 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
393 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
394 ElementsAreArray("many bitstream, such data"));
philipelc707ab72016-04-01 02:01:54 -0700395}
396
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200397TEST_F(PacketBufferTest, GetBitstreamOneFrameOnePacket) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100398 uint8_t bitstream[] = "All the bitstream data for this frame!";
philipel227f8b92017-08-04 06:39:31 -0700399
Danil Chapovalove3c48842019-12-02 15:54:27 +0100400 auto frames = Insert(0, kKeyFrame, kFirst, kLast, bitstream).frames;
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200401 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
402 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100403 ElementsAreArray(bitstream));
philipel227f8b92017-08-04 06:39:31 -0700404}
405
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200406TEST_F(PacketBufferTest, GetBitstreamOneFrameFullBuffer) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100407 uint8_t data_arr[kStartSize][1];
philipel227f8b92017-08-04 06:39:31 -0700408 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700409
410 for (uint8_t i = 0; i < kStartSize; ++i) {
philipel227f8b92017-08-04 06:39:31 -0700411 data_arr[i][0] = i;
412 expected[i] = i;
413 }
414
Danil Chapovalove3c48842019-12-02 15:54:27 +0100415 Insert(0, kKeyFrame, kFirst, kNotLast, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700416 for (uint8_t i = 1; i < kStartSize - 1; ++i)
Danil Chapovalove3c48842019-12-02 15:54:27 +0100417 Insert(i, kKeyFrame, kNotFirst, kNotLast, data_arr[i]);
418 auto frames = Insert(kStartSize - 1, kKeyFrame, kNotFirst, kLast,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200419 data_arr[kStartSize - 1])
420 .frames;
philipel227f8b92017-08-04 06:39:31 -0700421
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200422 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
423 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
424 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700425}
426
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100427TEST_F(PacketBufferTest, GetBitstreamAv1) {
428 const uint8_t data1[] = {0b01'01'0000, 0b0'0100'000, 'm', 'a', 'n', 'y', ' '};
429 const uint8_t data2[] = {0b10'01'0000, 'b', 'i', 't', 's', 0};
430
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100431 PacketBuffer::Packet packet1;
432 packet1.video_header.codec = kVideoCodecAV1;
433 packet1.seq_num = 13;
434 packet1.video_header.is_first_packet_in_frame = true;
435 packet1.video_header.is_last_packet_in_frame = false;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100436 packet1.video_payload = data1;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100437 auto frames = packet_buffer_.InsertPacket(&packet1).frames;
438 EXPECT_THAT(frames, IsEmpty());
439
440 PacketBuffer::Packet packet2;
441 packet2.video_header.codec = kVideoCodecAV1;
442 packet2.seq_num = 14;
443 packet2.video_header.is_first_packet_in_frame = false;
444 packet2.video_header.is_last_packet_in_frame = true;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100445 packet2.video_payload = data2;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100446 frames = packet_buffer_.InsertPacket(&packet2).frames;
447
448 ASSERT_THAT(frames, SizeIs(1));
449 EXPECT_EQ(frames[0]->first_seq_num(), 13);
450 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), 2),
451 ElementsAre(0b0'0100'010, 10)); // obu_header and obu_size.
452 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data() + 2, frames[0]->size() - 2),
453 ElementsAreArray("many bits"));
454}
455
456TEST_F(PacketBufferTest, GetBitstreamInvalidAv1) {
457 // Two av1 payloads that can't be combined into proper frame.
458 const uint8_t data1[] = {0b01'01'0000, 0b0'0100'000, 'm', 'a', 'n', 'y', ' '};
459 const uint8_t data2[] = {0b00'01'0000, 'b', 'i', 't', 's', 0};
460
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100461 PacketBuffer::Packet packet1;
462 packet1.video_header.codec = kVideoCodecAV1;
463 packet1.seq_num = 13;
464 packet1.video_header.is_first_packet_in_frame = true;
465 packet1.video_header.is_last_packet_in_frame = false;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100466 packet1.video_payload = data1;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100467 auto frames = packet_buffer_.InsertPacket(&packet1).frames;
468 EXPECT_THAT(frames, IsEmpty());
469
470 PacketBuffer::Packet packet2;
471 packet2.video_header.codec = kVideoCodecAV1;
472 packet2.seq_num = 14;
473 packet2.video_header.is_first_packet_in_frame = false;
474 packet2.video_header.is_last_packet_in_frame = true;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100475 packet2.video_payload = data2;
Danil Chapovalov0682ca92019-11-28 16:50:02 +0100476 frames = packet_buffer_.InsertPacket(&packet2).frames;
477
478 EXPECT_THAT(frames, IsEmpty());
479}
480
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200481TEST_F(PacketBufferTest, InsertPacketAfterSequenceNumberWrapAround) {
Johannes Kron957c62e2018-10-01 14:53:01 +0200482 uint16_t kFirstSeqNum = 0;
483 uint32_t kTimestampDelta = 100;
484 uint32_t timestamp = 10000;
485 uint16_t seq_num = kFirstSeqNum;
486
487 // Loop until seq_num wraps around.
Philip Eliasson1f850a62019-03-19 12:15:00 +0000488 SeqNumUnwrapper<uint16_t> unwrapper;
Johannes Kron957c62e2018-10-01 14:53:01 +0200489 while (unwrapper.Unwrap(seq_num) < std::numeric_limits<uint16_t>::max()) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100490 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200491 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100492 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200493 }
Danil Chapovalove3c48842019-12-02 15:54:27 +0100494 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200495 timestamp += kTimestampDelta;
496 }
497
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200498 // Receive frame with overlapping sequence numbers.
Danil Chapovalove3c48842019-12-02 15:54:27 +0100499 Insert(seq_num++, kKeyFrame, kFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200500 for (int i = 0; i < 5; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100501 Insert(seq_num++, kKeyFrame, kNotFirst, kNotLast, {}, timestamp);
Johannes Kron957c62e2018-10-01 14:53:01 +0200502 }
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200503 EXPECT_THAT(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100504 Insert(seq_num++, kKeyFrame, kNotFirst, kLast, {}, timestamp).frames,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200505 SizeIs(1));
Johannes Kron957c62e2018-10-01 14:53:01 +0200506}
507
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100508// If |sps_pps_idr_is_keyframe| is true, we require keyframes to contain
509// SPS/PPS/IDR and the keyframes we create as part of the test do contain
510// SPS/PPS/IDR. If |sps_pps_idr_is_keyframe| is false, we only require and
511// create keyframes containing only IDR.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200512class PacketBufferH264Test : public PacketBufferTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200513 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200514 explicit PacketBufferH264Test(bool sps_pps_idr_is_keyframe)
515 : PacketBufferTest(sps_pps_idr_is_keyframe
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100516 ? "WebRTC-SpsPpsIdrIsH264Keyframe/Enabled/"
517 : ""),
518 sps_pps_idr_is_keyframe_(sps_pps_idr_is_keyframe) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200519
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200520 PacketBufferInsertResult InsertH264(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100521 uint16_t seq_num, // packet sequence number
522 IsKeyFrame keyframe, // is keyframe
523 IsFirst first, // is first packet of frame
524 IsLast last, // is last packet of frame
525 uint32_t timestamp, // rtp timestamp
526 rtc::ArrayView<const uint8_t> data = {},
527 uint32_t width = 0, // width of frame (SPS/IDR)
528 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100529 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100530 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200531 auto& h264_header =
532 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100533 packet.seq_num = seq_num;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200534 packet.timestamp = timestamp;
535 if (keyframe == kKeyFrame) {
536 if (sps_pps_idr_is_keyframe_) {
philipel7d745e52018-08-02 14:03:53 +0200537 h264_header.nalus[0].type = H264::NaluType::kSps;
538 h264_header.nalus[1].type = H264::NaluType::kPps;
539 h264_header.nalus[2].type = H264::NaluType::kIdr;
540 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200541 } else {
philipel7d745e52018-08-02 14:03:53 +0200542 h264_header.nalus[0].type = H264::NaluType::kIdr;
543 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200544 }
545 }
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700546 packet.video_header.width = width;
547 packet.video_header.height = height;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100548 packet.video_header.is_first_packet_in_frame = first == kFirst;
549 packet.video_header.is_last_packet_in_frame = last == kLast;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100550 packet.video_payload.SetData(data.data(), data.size());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200551
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200552 return PacketBufferInsertResult(packet_buffer_.InsertPacket(&packet));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200553 }
554
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200555 PacketBufferInsertResult InsertH264KeyFrameWithAud(
Danil Chapovalove3c48842019-12-02 15:54:27 +0100556 uint16_t seq_num, // packet sequence number
557 IsKeyFrame keyframe, // is keyframe
558 IsFirst first, // is first packet of frame
559 IsLast last, // is last packet of frame
560 uint32_t timestamp, // rtp timestamp
561 rtc::ArrayView<const uint8_t> data = {},
562 uint32_t width = 0, // width of frame (SPS/IDR)
563 uint32_t height = 0) { // height of frame (SPS/IDR)
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100564 PacketBuffer::Packet packet;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700565 packet.video_header.codec = kVideoCodecH264;
566 auto& h264_header =
567 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100568 packet.seq_num = seq_num;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700569 packet.timestamp = timestamp;
570
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200571 // this should be the start of frame.
572 RTC_CHECK(first == kFirst);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700573
574 // Insert a AUD NALU / packet without width/height.
575 h264_header.nalus[0].type = H264::NaluType::kAud;
576 h264_header.nalus_length = 1;
577 packet.video_header.is_first_packet_in_frame = true;
578 packet.video_header.is_last_packet_in_frame = false;
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200579 IgnoreResult(packet_buffer_.InsertPacket(&packet));
580 // insert IDR
Danil Chapovalove3c48842019-12-02 15:54:27 +0100581 return InsertH264(seq_num + 1, keyframe, kNotFirst, last, timestamp, data,
582 width, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700583 }
584
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200585 const bool sps_pps_idr_is_keyframe_;
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100586};
587
588// This fixture is used to test the general behaviour of the packet buffer
589// in both configurations.
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200590class PacketBufferH264ParameterizedTest
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100591 : public ::testing::WithParamInterface<bool>,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200592 public PacketBufferH264Test {
Rasmus Brandt88f080a2017-11-02 14:28:06 +0100593 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200594 PacketBufferH264ParameterizedTest() : PacketBufferH264Test(GetParam()) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200595};
596
Mirko Bonadeic84f6612019-01-31 12:20:57 +0100597INSTANTIATE_TEST_SUITE_P(SpsPpsIdrIsKeyframe,
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200598 PacketBufferH264ParameterizedTest,
599 ::testing::Bool());
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200600
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200601TEST_P(PacketBufferH264ParameterizedTest, DontRemoveMissingPacketOnClearTo) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200602 InsertH264(0, kKeyFrame, kFirst, kLast, 0);
603 InsertH264(2, kDeltaFrame, kFirst, kNotLast, 2);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200604 packet_buffer_.ClearTo(0);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200605 // Expect no frame because of missing of packet #1
606 EXPECT_THAT(InsertH264(3, kDeltaFrame, kNotFirst, kLast, 2).frames,
607 IsEmpty());
philipelbc5a4082017-12-06 10:41:08 +0100608}
609
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200610TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamOneFrameFullBuffer) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100611 uint8_t data_arr[kStartSize][1];
philipel227f8b92017-08-04 06:39:31 -0700612 uint8_t expected[kStartSize];
philipel227f8b92017-08-04 06:39:31 -0700613
614 for (uint8_t i = 0; i < kStartSize; ++i) {
philipel227f8b92017-08-04 06:39:31 -0700615 data_arr[i][0] = i;
616 expected[i] = i;
617 }
618
Danil Chapovalove3c48842019-12-02 15:54:27 +0100619 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1, data_arr[0]);
philipel227f8b92017-08-04 06:39:31 -0700620 for (uint8_t i = 1; i < kStartSize - 1; ++i) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100621 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1, data_arr[i]);
philipel227f8b92017-08-04 06:39:31 -0700622 }
philipel227f8b92017-08-04 06:39:31 -0700623
Danil Chapovalove3c48842019-12-02 15:54:27 +0100624 auto frames = InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200625 data_arr[kStartSize - 1])
626 .frames;
627 ASSERT_THAT(StartSeqNums(frames), ElementsAre(0));
628 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
629 ElementsAreArray(expected));
philipel227f8b92017-08-04 06:39:31 -0700630}
631
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200632TEST_P(PacketBufferH264ParameterizedTest, GetBitstreamBufferPadding) {
philipel36928452016-11-07 10:42:36 +0100633 uint16_t seq_num = Rand();
Danil Chapovalove3c48842019-12-02 15:54:27 +0100634 uint8_t data[] = "some plain old data";
philipel36928452016-11-07 10:42:36 +0100635
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100636 PacketBuffer::Packet packet;
philipel7d745e52018-08-02 14:03:53 +0200637 auto& h264_header =
638 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
639 h264_header.nalus_length = 1;
640 h264_header.nalus[0].type = H264::NaluType::kIdr;
641 h264_header.packetization_type = kH264SingleNalu;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100642 packet.seq_num = seq_num;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100643 packet.video_header.codec = kVideoCodecH264;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100644 packet.video_payload = data;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100645 packet.video_header.is_first_packet_in_frame = true;
646 packet.video_header.is_last_packet_in_frame = true;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200647 auto frames = packet_buffer_.InsertPacket(&packet).frames;
philipel36928452016-11-07 10:42:36 +0100648
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200649 ASSERT_THAT(frames, SizeIs(1));
650 EXPECT_EQ(frames[0]->first_seq_num(), seq_num);
Danil Chapovalove3c48842019-12-02 15:54:27 +0100651 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data));
652 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200653 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100654 ElementsAreArray(data));
philipel36928452016-11-07 10:42:36 +0100655}
656
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200657TEST_P(PacketBufferH264ParameterizedTest, FrameResolution) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700658 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100659 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700660 uint32_t width = 640;
661 uint32_t height = 360;
662 uint32_t timestamp = 1000;
663
Danil Chapovalove3c48842019-12-02 15:54:27 +0100664 auto frames = InsertH264(seq_num, kKeyFrame, kFirst, kLast, timestamp, data,
665 width, height)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200666 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700667
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200668 ASSERT_THAT(frames, SizeIs(1));
669 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100670 ElementsAreArray(data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200671 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
672 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700673}
674
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200675TEST_P(PacketBufferH264ParameterizedTest, FrameResolutionNaluBeforeSPS) {
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700676 uint16_t seq_num = 100;
Danil Chapovalove3c48842019-12-02 15:54:27 +0100677 uint8_t data[] = "some plain old data";
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700678 uint32_t width = 640;
679 uint32_t height = 360;
680 uint32_t timestamp = 1000;
681
Danil Chapovalove3c48842019-12-02 15:54:27 +0100682 auto frames = InsertH264KeyFrameWithAud(seq_num, kKeyFrame, kFirst, kLast,
683 timestamp, data, width, height)
684 .frames;
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700685
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200686 ASSERT_THAT(StartSeqNums(frames), ElementsAre(seq_num));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700687
Danil Chapovalove3c48842019-12-02 15:54:27 +0100688 EXPECT_EQ(frames[0]->EncodedImage().size(), sizeof(data));
689 EXPECT_EQ(frames[0]->EncodedImage().capacity(), sizeof(data));
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200690 EXPECT_EQ(frames[0]->EncodedImage()._encodedWidth, width);
691 EXPECT_EQ(frames[0]->EncodedImage()._encodedHeight, height);
692 EXPECT_THAT(rtc::MakeArrayView(frames[0]->data(), frames[0]->size()),
Danil Chapovalove3c48842019-12-02 15:54:27 +0100693 ElementsAreArray(data));
Shyam Sadhwani5b2df172019-10-16 09:13:38 -0700694}
695
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200696TEST_F(PacketBufferTest, FreeSlotsOnFrameCreation) {
philipelaee3e0e2016-11-01 11:45:34 +0100697 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200698
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200699 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
700 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
701 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
702 StartSeqNumsAre(seq_num));
philipelc707ab72016-04-01 02:01:54 -0700703
philipel17deeb42016-08-11 15:09:26 +0200704 // Insert frame that fills the whole buffer.
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200705 Insert(seq_num + 3, kKeyFrame, kFirst, kNotLast);
philipel17deeb42016-08-11 15:09:26 +0200706 for (int i = 0; i < kMaxSize - 2; ++i)
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200707 Insert(seq_num + i + 4, kDeltaFrame, kNotFirst, kNotLast);
708 EXPECT_THAT(Insert(seq_num + kMaxSize + 2, kKeyFrame, kNotFirst, kLast),
709 StartSeqNumsAre(seq_num + 3));
philipelc707ab72016-04-01 02:01:54 -0700710}
711
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200712TEST_F(PacketBufferTest, Clear) {
philipelaee3e0e2016-11-01 11:45:34 +0100713 const uint16_t seq_num = Rand();
philipelf4139332016-04-20 10:26:34 +0200714
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200715 Insert(seq_num, kKeyFrame, kFirst, kNotLast);
716 Insert(seq_num + 1, kDeltaFrame, kNotFirst, kNotLast);
717 EXPECT_THAT(Insert(seq_num + 2, kDeltaFrame, kNotFirst, kLast),
718 StartSeqNumsAre(seq_num));
philipelf4139332016-04-20 10:26:34 +0200719
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200720 packet_buffer_.Clear();
philipelf4139332016-04-20 10:26:34 +0200721
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200722 Insert(seq_num + kStartSize, kKeyFrame, kFirst, kNotLast);
723 Insert(seq_num + kStartSize + 1, kDeltaFrame, kNotFirst, kNotLast);
724 EXPECT_THAT(Insert(seq_num + kStartSize + 2, kDeltaFrame, kNotFirst, kLast),
725 StartSeqNumsAre(seq_num + kStartSize));
philipelc707ab72016-04-01 02:01:54 -0700726}
727
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200728TEST_F(PacketBufferTest, FramesAfterClear) {
philipel20dce342016-11-28 16:14:57 +0100729 Insert(9025, kDeltaFrame, kFirst, kLast);
730 Insert(9024, kKeyFrame, kFirst, kLast);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200731 packet_buffer_.ClearTo(9025);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200732 EXPECT_THAT(Insert(9057, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
733 EXPECT_THAT(Insert(9026, kDeltaFrame, kFirst, kLast).frames, SizeIs(1));
philipel20dce342016-11-28 16:14:57 +0100734}
735
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200736TEST_F(PacketBufferTest, SameFrameDifferentTimestamps) {
Danil Chapovalove3c48842019-12-02 15:54:27 +0100737 Insert(0, kKeyFrame, kFirst, kNotLast, {}, 1000);
738 EXPECT_THAT(Insert(1, kKeyFrame, kNotFirst, kLast, {}, 1001).frames,
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200739 IsEmpty());
philipel8b6995b2019-01-09 12:39:18 +0100740}
741
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200742TEST_F(PacketBufferTest, ContinuousSeqNumDoubleMarkerBit) {
philipelea142f82017-01-11 02:01:56 -0800743 Insert(2, kKeyFrame, kNotFirst, kNotLast);
744 Insert(1, kKeyFrame, kFirst, kLast);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200745 EXPECT_THAT(Insert(3, kKeyFrame, kNotFirst, kLast).frames, IsEmpty());
philipelea142f82017-01-11 02:01:56 -0800746}
747
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200748TEST_F(PacketBufferTest, PacketTimestamps) {
Danil Chapovalov0040b662018-06-18 10:48:16 +0200749 absl::optional<int64_t> packet_ms;
750 absl::optional<int64_t> packet_keyframe_ms;
philipel3184f8e2017-05-18 08:08:53 -0700751
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200752 packet_ms = packet_buffer_.LastReceivedPacketMs();
753 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700754 EXPECT_FALSE(packet_ms);
755 EXPECT_FALSE(packet_keyframe_ms);
756
Danil Chapovalove3c48842019-12-02 15:54:27 +0100757 int64_t keyframe_ms = clock_.TimeInMilliseconds();
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100758 Insert(100, kKeyFrame, kFirst, kLast, {}, /*timestamp=*/1000);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200759 packet_ms = packet_buffer_.LastReceivedPacketMs();
760 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700761 EXPECT_TRUE(packet_ms);
762 EXPECT_TRUE(packet_keyframe_ms);
763 EXPECT_EQ(keyframe_ms, *packet_ms);
764 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
765
Danil Chapovalove3c48842019-12-02 15:54:27 +0100766 clock_.AdvanceTimeMilliseconds(100);
767 int64_t delta_ms = clock_.TimeInMilliseconds();
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100768 Insert(101, kDeltaFrame, kFirst, kLast, {}, /*timestamp=*/2000);
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200769 packet_ms = packet_buffer_.LastReceivedPacketMs();
770 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700771 EXPECT_TRUE(packet_ms);
772 EXPECT_TRUE(packet_keyframe_ms);
773 EXPECT_EQ(delta_ms, *packet_ms);
774 EXPECT_EQ(keyframe_ms, *packet_keyframe_ms);
775
Danil Chapovalovf7457e52019-09-20 17:57:15 +0200776 packet_buffer_.Clear();
777 packet_ms = packet_buffer_.LastReceivedPacketMs();
778 packet_keyframe_ms = packet_buffer_.LastReceivedKeyframePacketMs();
philipel3184f8e2017-05-18 08:08:53 -0700779 EXPECT_FALSE(packet_ms);
780 EXPECT_FALSE(packet_keyframe_ms);
781}
782
Danil Chapovalovc9e532a2019-12-10 17:03:00 +0100783TEST_F(PacketBufferTest,
784 LastReceivedKeyFrameReturnsReceiveTimeOfALastReceivedPacketOfAKeyFrame) {
785 clock_.AdvanceTimeMilliseconds(100);
786 Insert(/*seq_num=*/100, kKeyFrame, kFirst, kNotLast, {}, /*timestamp=*/1000);
787 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
788 clock_.TimeInMilliseconds());
789
790 clock_.AdvanceTimeMilliseconds(100);
791 Insert(/*seq_num=*/102, kDeltaFrame, kNotFirst, kLast, {},
792 /*timestamp=*/1000);
793 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
794 clock_.TimeInMilliseconds());
795
796 clock_.AdvanceTimeMilliseconds(100);
797 Insert(/*seq_num=*/101, kDeltaFrame, kNotFirst, kNotLast, {},
798 /*timestamp=*/1000);
799 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
800 clock_.TimeInMilliseconds());
801
802 clock_.AdvanceTimeMilliseconds(100);
803 Insert(/*seq_num=*/103, kDeltaFrame, kFirst, kNotLast, {},
804 /*timestamp=*/2000);
805 EXPECT_EQ(packet_buffer_.LastReceivedKeyframePacketMs(),
806 clock_.TimeInMilliseconds() - 100);
807}
808
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200809TEST_F(PacketBufferTest, IncomingCodecChange) {
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100810 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100811 packet.video_header.is_first_packet_in_frame = true;
812 packet.video_header.is_last_packet_in_frame = true;
philipel09133af2018-05-17 14:11:09 +0200813
Niels Möllerd5e02f02019-02-20 13:12:21 +0100814 packet.video_header.codec = kVideoCodecVP8;
815 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200816 packet.timestamp = 1;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100817 packet.seq_num = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200818 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200819 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(1));
philipel09133af2018-05-17 14:11:09 +0200820
Niels Möllerd5e02f02019-02-20 13:12:21 +0100821 packet.video_header.codec = kVideoCodecH264;
philipel7d745e52018-08-02 14:03:53 +0200822 auto& h264_header =
823 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
824 h264_header.nalus_length = 1;
philipel09133af2018-05-17 14:11:09 +0200825 packet.timestamp = 3;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100826 packet.seq_num = 3;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200827 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200828
Niels Möllerd5e02f02019-02-20 13:12:21 +0100829 packet.video_header.codec = kVideoCodecVP8;
830 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
philipel09133af2018-05-17 14:11:09 +0200831 packet.timestamp = 2;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100832 packet.seq_num = 2;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200833 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200834 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, SizeIs(2));
philipel09133af2018-05-17 14:11:09 +0200835}
836
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200837TEST_F(PacketBufferTest, TooManyNalusInPacket) {
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100838 PacketBuffer::Packet packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100839 packet.video_header.codec = kVideoCodecH264;
philipel09133af2018-05-17 14:11:09 +0200840 packet.timestamp = 1;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100841 packet.seq_num = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200842 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100843 packet.video_header.is_first_packet_in_frame = true;
844 packet.video_header.is_last_packet_in_frame = true;
philipel7d745e52018-08-02 14:03:53 +0200845 auto& h264_header =
846 packet.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
847 h264_header.nalus_length = kMaxNalusPerPacket;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200848 EXPECT_THAT(packet_buffer_.InsertPacket(&packet).frames, IsEmpty());
philipel09133af2018-05-17 14:11:09 +0200849}
850
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200851TEST_P(PacketBufferH264ParameterizedTest, OneFrameFillBuffer) {
philipel2c9f9f22017-06-13 02:47:28 -0700852 InsertH264(0, kKeyFrame, kFirst, kNotLast, 1000);
853 for (int i = 1; i < kStartSize - 1; ++i)
854 InsertH264(i, kKeyFrame, kNotFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200855 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kNotFirst, kLast, 1000),
856 StartSeqNumsAre(0));
philipel2c9f9f22017-06-13 02:47:28 -0700857}
858
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200859TEST_P(PacketBufferH264ParameterizedTest, CreateFramesAfterFilledBuffer) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200860 EXPECT_THAT(InsertH264(kStartSize - 2, kKeyFrame, kFirst, kLast, 0).frames,
861 SizeIs(1));
philipel227f8b92017-08-04 06:39:31 -0700862
863 InsertH264(kStartSize, kDeltaFrame, kFirst, kNotLast, 2000);
864 for (int i = 1; i < kStartSize; ++i)
865 InsertH264(kStartSize + i, kDeltaFrame, kNotFirst, kNotLast, 2000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200866 EXPECT_THAT(
867 InsertH264(kStartSize + kStartSize, kDeltaFrame, kNotFirst, kLast, 2000)
868 .frames,
869 IsEmpty());
philipel227f8b92017-08-04 06:39:31 -0700870
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200871 EXPECT_THAT(InsertH264(kStartSize - 1, kKeyFrame, kFirst, kLast, 1000),
872 StartSeqNumsAre(kStartSize - 1, kStartSize));
philipel227f8b92017-08-04 06:39:31 -0700873}
874
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200875TEST_P(PacketBufferH264ParameterizedTest, OneFrameMaxSeqNum) {
philipel2c9f9f22017-06-13 02:47:28 -0700876 InsertH264(65534, kKeyFrame, kFirst, kNotLast, 1000);
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200877 EXPECT_THAT(InsertH264(65535, kKeyFrame, kNotFirst, kLast, 1000),
878 StartSeqNumsAre(65534));
philipel2c9f9f22017-06-13 02:47:28 -0700879}
880
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200881TEST_P(PacketBufferH264ParameterizedTest, ClearMissingPacketsOnKeyframe) {
philipel2c9f9f22017-06-13 02:47:28 -0700882 InsertH264(0, kKeyFrame, kFirst, kLast, 1000);
883 InsertH264(2, kKeyFrame, kFirst, kLast, 3000);
884 InsertH264(3, kDeltaFrame, kFirst, kNotLast, 4000);
885 InsertH264(4, kDeltaFrame, kNotFirst, kLast, 4000);
886
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200887 EXPECT_THAT(InsertH264(kStartSize + 1, kKeyFrame, kFirst, kLast, 18000),
888 StartSeqNumsAre(kStartSize + 1));
philipel2c9f9f22017-06-13 02:47:28 -0700889}
890
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200891TEST_P(PacketBufferH264ParameterizedTest, FindFramesOnPadding) {
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200892 EXPECT_THAT(InsertH264(0, kKeyFrame, kFirst, kLast, 1000),
893 StartSeqNumsAre(0));
894 EXPECT_THAT(InsertH264(2, kDeltaFrame, kFirst, kLast, 1000).frames,
895 IsEmpty());
philipel2c9f9f22017-06-13 02:47:28 -0700896
Danil Chapovalov1dac7072019-10-24 12:44:23 +0200897 EXPECT_THAT(packet_buffer_.InsertPadding(1), StartSeqNumsAre(2));
philipel2c9f9f22017-06-13 02:47:28 -0700898}
899
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200900class PacketBufferH264XIsKeyframeTest : public PacketBufferH264Test {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200901 protected:
902 const uint16_t kSeqNum = 5;
903
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200904 explicit PacketBufferH264XIsKeyframeTest(bool sps_pps_idr_is_keyframe)
905 : PacketBufferH264Test(sps_pps_idr_is_keyframe) {
Niels Möllerd5e02f02019-02-20 13:12:21 +0100906 packet_.video_header.codec = kVideoCodecH264;
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100907 packet_.seq_num = kSeqNum;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200908
Niels Möllerd5e02f02019-02-20 13:12:21 +0100909 packet_.video_header.is_first_packet_in_frame = true;
910 packet_.video_header.is_last_packet_in_frame = true;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200911 }
912
Danil Chapovalovaa3f5da2019-11-14 14:57:33 +0100913 PacketBuffer::Packet packet_;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200914};
915
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200916class PacketBufferH264IdrIsKeyframeTest
917 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200918 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200919 PacketBufferH264IdrIsKeyframeTest()
920 : PacketBufferH264XIsKeyframeTest(false) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200921};
922
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200923TEST_F(PacketBufferH264IdrIsKeyframeTest, IdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200924 auto& h264_header =
925 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
926 h264_header.nalus[0].type = H264::NaluType::kIdr;
927 h264_header.nalus_length = 1;
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200928 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
929 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200930}
931
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200932TEST_F(PacketBufferH264IdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
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::kSps;
936 h264_header.nalus[1].type = H264::NaluType::kPps;
937 h264_header.nalus[2].type = H264::NaluType::kIdr;
938 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200939
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200940 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
941 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200942}
943
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200944class PacketBufferH264SpsPpsIdrIsKeyframeTest
945 : public PacketBufferH264XIsKeyframeTest {
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200946 protected:
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200947 PacketBufferH264SpsPpsIdrIsKeyframeTest()
948 : PacketBufferH264XIsKeyframeTest(true) {}
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200949};
950
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200951TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, IdrIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200952 auto& h264_header =
953 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
954 h264_header.nalus[0].type = H264::NaluType::kIdr;
955 h264_header.nalus_length = 1;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200956
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200957 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
958 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200959}
960
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200961TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIsNotKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200962 auto& h264_header =
963 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
964 h264_header.nalus[0].type = H264::NaluType::kSps;
965 h264_header.nalus[1].type = H264::NaluType::kPps;
966 h264_header.nalus_length = 2;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200967
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200968 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
969 ElementsAre(DeltaFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200970}
971
Danil Chapovalov05269ec2019-10-17 19:06:46 +0200972TEST_F(PacketBufferH264SpsPpsIdrIsKeyframeTest, SpsPpsIdrIsKeyframe) {
philipel7d745e52018-08-02 14:03:53 +0200973 auto& h264_header =
974 packet_.video_header.video_type_header.emplace<RTPVideoHeaderH264>();
975 h264_header.nalus[0].type = H264::NaluType::kSps;
976 h264_header.nalus[1].type = H264::NaluType::kPps;
977 h264_header.nalus[2].type = H264::NaluType::kIdr;
978 h264_header.nalus_length = 3;
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200979
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200980 EXPECT_THAT(packet_buffer_.InsertPacket(&packet_).frames,
981 ElementsAre(KeyFrame()));
Rasmus Brandtedf4ff72017-10-24 10:07:48 +0200982}
983
Danil Chapovalovce1ffcd2019-10-22 17:12:42 +0200984} // namespace
philipelc707ab72016-04-01 02:01:54 -0700985} // namespace video_coding
986} // namespace webrtc