Cleanup RtpPacketizerH264 constructor

Merge SetPayloadData into constructor.
Add TODO to support first_packet_reduction_len

Bug: webrtc:9680
Change-Id: I65e771848e0ffe8968cd084840e77afc0152caeb
Reviewed-on: https://webrtc-review.googlesource.com/99505
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24702}
This commit is contained in:
Danil Chapovalov
2018-09-12 10:23:15 +02:00
committed by Commit Bot
parent 9c147ddc91
commit fd5fbd0b58
4 changed files with 133 additions and 162 deletions

View File

@ -31,13 +31,11 @@ std::unique_ptr<RtpPacketizer> RtpPacketizer::Create(
const RTPFragmentationHeader* fragmentation) {
switch (type) {
case kVideoCodecH264: {
RTC_CHECK(fragmentation);
const auto& h264 =
absl::get<RTPVideoHeaderH264>(rtp_video_header.video_type_header);
auto packetizer = absl::make_unique<RtpPacketizerH264>(
limits.max_payload_len, limits.last_packet_reduction_len,
h264.packetization_mode);
packetizer->SetPayloadData(payload.data(), payload.size(), fragmentation);
return std::move(packetizer);
return absl::make_unique<RtpPacketizerH264>(
payload, limits, h264.packetization_mode, *fragmentation);
}
case kVideoCodecVP8: {
const auto& vp8 =

View File

@ -79,39 +79,24 @@ bool ParseStapAStartOffsets(const uint8_t* nalu_ptr,
} // namespace
RtpPacketizerH264::RtpPacketizerH264(size_t max_payload_len,
size_t last_packet_reduction_len,
H264PacketizationMode packetization_mode)
: max_payload_len_(max_payload_len),
last_packet_reduction_len_(last_packet_reduction_len),
num_packets_left_(0),
packetization_mode_(packetization_mode) {
RtpPacketizerH264::RtpPacketizerH264(
rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
H264PacketizationMode packetization_mode,
const RTPFragmentationHeader& fragmentation)
: max_payload_len_(limits.max_payload_len),
// TODO(bugs.webrtc.org/9680): Do not ignore first_packet_reduction_len.
last_packet_reduction_len_(limits.last_packet_reduction_len),
num_packets_left_(0) {
// Guard against uninitialized memory in packetization_mode.
RTC_CHECK(packetization_mode == H264PacketizationMode::NonInterleaved ||
packetization_mode == H264PacketizationMode::SingleNalUnit);
RTC_CHECK_GT(max_payload_len, last_packet_reduction_len);
}
RTC_CHECK_GT(limits.max_payload_len, limits.last_packet_reduction_len);
RtpPacketizerH264::~RtpPacketizerH264() {}
RtpPacketizerH264::Fragment::~Fragment() = default;
RtpPacketizerH264::Fragment::Fragment(const uint8_t* buffer, size_t length)
: buffer(buffer), length(length) {}
RtpPacketizerH264::Fragment::Fragment(const Fragment& fragment)
: buffer(fragment.buffer), length(fragment.length) {}
size_t RtpPacketizerH264::SetPayloadData(
const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation) {
RTC_DCHECK(packets_.empty());
RTC_DCHECK(input_fragments_.empty());
RTC_DCHECK(fragmentation);
for (int i = 0; i < fragmentation->fragmentationVectorSize; ++i) {
for (int i = 0; i < fragmentation.fragmentationVectorSize; ++i) {
const uint8_t* buffer =
&payload_data[fragmentation->fragmentationOffset[i]];
size_t length = fragmentation->fragmentationLength[i];
payload.data() + fragmentation.fragmentationOffset[i];
size_t length = fragmentation.fragmentationLength[i];
bool updated_sps = false;
H264::NaluType nalu_type = H264::ParseNaluType(buffer[0]);
@ -169,7 +154,7 @@ size_t RtpPacketizerH264::SetPayloadData(
if (!updated_sps)
input_fragments_.push_back(Fragment(buffer, length));
}
if (!GeneratePackets()) {
if (!GeneratePackets(packetization_mode)) {
// If failed to generate all the packets, discard already generated
// packets in case the caller would ignore return value and still try to
// call NextPacket().
@ -177,18 +162,26 @@ size_t RtpPacketizerH264::SetPayloadData(
while (!packets_.empty()) {
packets_.pop();
}
return 0;
}
return num_packets_left_;
}
RtpPacketizerH264::~RtpPacketizerH264() = default;
RtpPacketizerH264::Fragment::~Fragment() = default;
RtpPacketizerH264::Fragment::Fragment(const uint8_t* buffer, size_t length)
: buffer(buffer), length(length) {}
RtpPacketizerH264::Fragment::Fragment(const Fragment& fragment)
: buffer(fragment.buffer), length(fragment.length) {}
size_t RtpPacketizerH264::NumPackets() const {
return num_packets_left_;
}
bool RtpPacketizerH264::GeneratePackets() {
bool RtpPacketizerH264::GeneratePackets(
H264PacketizationMode packetization_mode) {
for (size_t i = 0; i < input_fragments_.size();) {
switch (packetization_mode_) {
switch (packetization_mode) {
case H264PacketizationMode::SingleNalUnit:
if (!PacketizeSingleNalu(i))
return false;
@ -340,11 +333,9 @@ bool RtpPacketizerH264::NextPacket(RtpPacketToSend* rtp_packet) {
packets_.pop();
input_fragments_.pop_front();
} else if (packet.aggregated) {
RTC_CHECK(H264PacketizationMode::NonInterleaved == packetization_mode_);
bool is_last_packet = num_packets_left_ == 1;
NextAggregatePacket(rtp_packet, is_last_packet);
} else {
RTC_CHECK(H264PacketizationMode::NonInterleaved == packetization_mode_);
NextFragmentPacket(rtp_packet);
}
RTC_DCHECK_LE(rtp_packet->payload_size(), max_payload_len_);

View File

@ -26,16 +26,13 @@ class RtpPacketizerH264 : public RtpPacketizer {
public:
// Initialize with payload from encoder.
// The payload_data must be exactly one encoded H264 frame.
RtpPacketizerH264(size_t max_payload_len,
size_t last_packet_reduction_len,
H264PacketizationMode packetization_mode);
RtpPacketizerH264(rtc::ArrayView<const uint8_t> payload,
PayloadSizeLimits limits,
H264PacketizationMode packetization_mode,
const RTPFragmentationHeader& fragmentation);
~RtpPacketizerH264() override;
size_t SetPayloadData(const uint8_t* payload_data,
size_t payload_size,
const RTPFragmentationHeader* fragmentation);
size_t NumPackets() const override;
// Get the next payload with H264 payload header.
@ -80,7 +77,7 @@ class RtpPacketizerH264 : public RtpPacketizer {
uint8_t header;
};
bool GeneratePackets();
bool GeneratePackets(H264PacketizationMode packetization_mode);
void PacketizeFuA(size_t fragment_index);
size_t PacketizeStapA(size_t fragment_index);
bool PacketizeSingleNalu(size_t fragment_index);
@ -90,7 +87,6 @@ class RtpPacketizerH264 : public RtpPacketizer {
const size_t max_payload_len_;
const size_t last_packet_reduction_len_;
size_t num_packets_left_;
const H264PacketizationMode packetization_mode_;
std::deque<Fragment> input_fragments_;
std::queue<PacketUnit> packets_;

View File

@ -33,8 +33,9 @@ struct H264ParsedPayload : public RtpDepacketizer::ParsedPayload {
};
constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr;
const size_t kMaxPayloadSize = 1200;
const size_t kLengthFieldLength = 2;
constexpr size_t kMaxPayloadSize = 1200;
constexpr size_t kLengthFieldLength = 2;
constexpr RtpPacketizer::PayloadSizeLimits kNoLimits;
enum Nalu {
kSlice = 1,
@ -68,19 +69,11 @@ void CreateThreeFragments(RTPFragmentationHeader* fragmentation,
kNalHeaderSize + frameSize - payloadOffset;
}
std::unique_ptr<RtpPacketizerH264> CreateH264Packetizer(
H264PacketizationMode mode,
size_t max_payload_size,
size_t last_packet_reduction) {
return absl::make_unique<RtpPacketizerH264>(max_payload_size,
last_packet_reduction, mode);
}
void VerifyFua(size_t fua_index,
const uint8_t* expected_payload,
int offset,
rtc::ArrayView<const uint8_t> packet,
const std::vector<size_t>& expected_sizes) {
rtc::ArrayView<const size_t> expected_sizes) {
ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, packet.size())
<< "FUA index: " << fua_index;
const uint8_t kFuIndicator = 0x1C; // F=0, NRI=0, Type=28.
@ -105,34 +98,34 @@ void VerifyFua(size_t fua_index,
void TestFua(size_t frame_size,
size_t max_payload_size,
size_t last_packet_reduction,
const std::vector<size_t>& expected_sizes) {
std::unique_ptr<uint8_t[]> frame;
frame.reset(new uint8_t[frame_size]);
rtc::ArrayView<const size_t> expected_sizes) {
std::vector<uint8_t> frame(frame_size);
frame[0] = 0x05; // F=0, NRI=0, Type=5.
for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) {
frame[i + kNalHeaderSize] = i;
}
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = max_payload_size;
limits.last_packet_reduction_len = last_packet_reduction;
RTPFragmentationHeader fragmentation;
fragmentation.VerifyAndAllocateFragmentationHeader(1);
fragmentation.fragmentationOffset[0] = 0;
fragmentation.fragmentationLength[0] = frame_size;
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
max_payload_size, last_packet_reduction));
EXPECT_EQ(
expected_sizes.size(),
packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation));
RtpPacketizerH264 packetizer(
frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
EXPECT_EQ(packetizer.NumPackets(), expected_sizes.size());
RtpPacketToSend packet(kNoExtensions);
ASSERT_LE(max_payload_size, packet.FreeCapacity());
size_t offset = kNalHeaderSize;
for (size_t i = 0; i < expected_sizes.size(); ++i) {
ASSERT_TRUE(packetizer->NextPacket(&packet));
VerifyFua(i, frame.get(), offset, packet.payload(), expected_sizes);
ASSERT_TRUE(packetizer.NextPacket(&packet));
VerifyFua(i, frame.data(), offset, packet.payload(), expected_sizes);
offset += expected_sizes[i];
}
EXPECT_FALSE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
size_t GetExpectedNaluOffset(const RTPFragmentationHeader& fragmentation,
@ -189,21 +182,22 @@ TEST_P(RtpPacketizerH264ModeTest, TestSingleNalu) {
fragmentation.VerifyAndAllocateFragmentationHeader(1);
fragmentation.fragmentationOffset[0] = 0;
fragmentation.fragmentationLength[0] = sizeof(frame);
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
ASSERT_EQ(1u,
packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation));
RtpPacketizerH264 packetizer(frame, kNoLimits, GetParam(), fragmentation);
ASSERT_EQ(packetizer.NumPackets(), 1u);
RtpPacketToSend packet(kNoExtensions);
ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
EXPECT_EQ(2u, packet.payload_size());
VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload());
EXPECT_FALSE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
TEST_P(RtpPacketizerH264ModeTest, TestSingleNaluTwoPackets) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kMaxPayloadSize;
const size_t kFrameSize = kMaxPayloadSize + 100;
uint8_t frame[kFrameSize] = {0};
uint8_t frame[kFrameSize];
for (size_t i = 0; i < kFrameSize; ++i)
frame[i] = i;
RTPFragmentationHeader fragmentation;
@ -216,20 +210,19 @@ TEST_P(RtpPacketizerH264ModeTest, TestSingleNaluTwoPackets) {
frame[fragmentation.fragmentationOffset[0]] = 0x01;
frame[fragmentation.fragmentationOffset[1]] = 0x01;
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(GetParam(), kMaxPayloadSize, 0));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
RtpPacketizerH264 packetizer(frame, limits, GetParam(), fragmentation);
ASSERT_EQ(packetizer.NumPackets(), 2u);
RtpPacketToSend packet(kNoExtensions);
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
ASSERT_EQ(fragmentation.fragmentationOffset[1], packet.payload_size());
VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload());
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
ASSERT_EQ(fragmentation.fragmentationLength[1], packet.payload_size());
VerifySingleNaluPayload(fragmentation, 1, frame, packet.payload());
EXPECT_FALSE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
INSTANTIATE_TEST_CASE_P(
@ -239,6 +232,8 @@ INSTANTIATE_TEST_CASE_P(
H264PacketizationMode::NonInterleaved));
TEST(RtpPacketizerH264Test, TestStapA) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kMaxPayloadSize;
const size_t kFrameSize =
kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize;
uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS).
@ -249,13 +244,14 @@ TEST(RtpPacketizerH264Test, TestStapA) {
frame[i + kPayloadOffset] = i;
RTPFragmentationHeader fragmentation;
CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(1u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
RtpPacketizerH264 packetizer(
frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
ASSERT_EQ(packetizer.NumPackets(), 1u);
RtpPacketToSend packet(kNoExtensions);
ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
size_t expected_packet_size =
kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize;
ASSERT_EQ(expected_packet_size, packet.payload_size());
@ -263,12 +259,14 @@ TEST(RtpPacketizerH264Test, TestStapA) {
for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i)
VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload());
EXPECT_FALSE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
TEST(RtpPacketizerH264Test, TestStapARespectsPacketReduction) {
const size_t kLastPacketReduction = 100;
const size_t kFrameSize = kMaxPayloadSize - 1 - kLastPacketReduction;
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kMaxPayloadSize;
limits.last_packet_reduction_len = 100;
const size_t kFrameSize = kMaxPayloadSize - 1 - 100;
uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7.
0x08, 0xFF, // F=0, NRI=0, Type=8.
0x05}; // F=0, NRI=0, Type=5.
@ -284,14 +282,14 @@ TEST(RtpPacketizerH264Test, TestStapARespectsPacketReduction) {
fragmentation.fragmentationOffset[2] = 4;
fragmentation.fragmentationLength[2] =
kNalHeaderSize + kFrameSize - kPayloadOffset;
std::unique_ptr<RtpPacketizerH264> packetizer(
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
kMaxPayloadSize, kLastPacketReduction));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
RtpPacketizerH264 packetizer(
frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
ASSERT_EQ(packetizer.NumPackets(), 2u);
RtpPacketToSend packet(kNoExtensions);
ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
size_t expected_packet_size = kNalHeaderSize;
for (size_t i = 0; i < 2; ++i) {
expected_packet_size +=
@ -301,16 +299,18 @@ TEST(RtpPacketizerH264Test, TestStapARespectsPacketReduction) {
for (size_t i = 0; i < 2; ++i)
VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload());
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
expected_packet_size = fragmentation.fragmentationLength[2];
ASSERT_EQ(expected_packet_size, packet.payload_size());
VerifySingleNaluPayload(fragmentation, 2, frame, packet.payload());
EXPECT_FALSE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
TEST(RtpPacketizerH264Test, TestSingleNalUnitModeHasNoStapA) {
// This is the same setup as for the TestStapA test.
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kMaxPayloadSize;
const size_t kFrameSize =
kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize;
uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS).
@ -321,19 +321,22 @@ TEST(RtpPacketizerH264Test, TestSingleNalUnitModeHasNoStapA) {
frame[i + kPayloadOffset] = i;
RTPFragmentationHeader fragmentation;
CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
RtpPacketizerH264 packetizer(
frame, limits, H264PacketizationMode::SingleNalUnit, fragmentation);
EXPECT_EQ(packetizer.NumPackets(), 3u);
RtpPacketToSend packet(kNoExtensions);
// The three fragments should be returned as three packets.
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kMaxPayloadSize;
const size_t kFrameSize = kMaxPayloadSize - 1;
uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7.
0x08, 0xFF, // F=0, NRI=0, Type=8.
@ -350,13 +353,13 @@ TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) {
fragmentation.fragmentationOffset[2] = 4;
fragmentation.fragmentationLength[2] =
kNalHeaderSize + kFrameSize - kPayloadOffset;
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(2u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
RtpPacketizerH264 packetizer(
frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
ASSERT_EQ(packetizer.NumPackets(), 2u);
RtpPacketToSend packet(kNoExtensions);
ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
size_t expected_packet_size = kNalHeaderSize;
for (size_t i = 0; i < 2; ++i) {
expected_packet_size +=
@ -366,15 +369,17 @@ TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) {
for (size_t i = 0; i < 2; ++i)
VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload());
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
expected_packet_size = fragmentation.fragmentationLength[2];
ASSERT_EQ(expected_packet_size, packet.payload_size());
VerifySingleNaluPayload(fragmentation, 2, frame, packet.payload());
EXPECT_FALSE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kMaxPayloadSize;
const size_t kFuaNaluSize = 2 * (kMaxPayloadSize - 100);
const size_t kStapANaluSize = 100;
RTPFragmentationHeader fragmentation;
@ -395,9 +400,9 @@ TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) {
frame[nalu_offset + j] = i + j;
}
}
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::NonInterleaved, kMaxPayloadSize, 0));
ASSERT_EQ(3u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
RtpPacketizerH264 packetizer(
frame, limits, H264PacketizationMode::NonInterleaved, fragmentation);
ASSERT_EQ(packetizer.NumPackets(), 3u);
// First expecting two FU-A packets.
std::vector<size_t> fua_sizes;
@ -407,56 +412,40 @@ TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) {
ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
int fua_offset = kNalHeaderSize;
for (size_t i = 0; i < 2; ++i) {
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
VerifyFua(i, frame, fua_offset, packet.payload(), fua_sizes);
fua_offset += fua_sizes[i];
}
// Then expecting one STAP-A packet with two nal units.
ASSERT_TRUE(packetizer->NextPacket(&packet));
ASSERT_TRUE(packetizer.NextPacket(&packet));
size_t expected_packet_size =
kNalHeaderSize + 2 * kLengthFieldLength + 2 * kStapANaluSize;
ASSERT_EQ(expected_packet_size, packet.payload_size());
for (size_t i = 1; i < fragmentation.fragmentationVectorSize; ++i)
VerifyStapAPayload(fragmentation, 1, i, frame, packet.payload());
EXPECT_FALSE(packetizer->NextPacket(&packet));
EXPECT_FALSE(packetizer.NextPacket(&packet));
}
TEST(RtpPacketizerH264Test, TestFUAOddSize) {
const size_t kExpectedPayloadSizes[2] = {600, 600};
TestFua(
kMaxPayloadSize + 1, kMaxPayloadSize, 0,
std::vector<size_t>(kExpectedPayloadSizes,
kExpectedPayloadSizes +
sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
TestFua(kMaxPayloadSize + 1, kMaxPayloadSize, 0, kExpectedPayloadSizes);
}
TEST(RtpPacketizerH264Test, TestFUAWithLastPacketReduction) {
const size_t kExpectedPayloadSizes[2] = {601, 597};
TestFua(
kMaxPayloadSize - 1, kMaxPayloadSize, 4,
std::vector<size_t>(kExpectedPayloadSizes,
kExpectedPayloadSizes +
sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
TestFua(kMaxPayloadSize - 1, kMaxPayloadSize, 4, kExpectedPayloadSizes);
}
TEST(RtpPacketizerH264Test, TestFUAEvenSize) {
const size_t kExpectedPayloadSizes[2] = {600, 601};
TestFua(
kMaxPayloadSize + 2, kMaxPayloadSize, 0,
std::vector<size_t>(kExpectedPayloadSizes,
kExpectedPayloadSizes +
sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
TestFua(kMaxPayloadSize + 2, kMaxPayloadSize, 0, kExpectedPayloadSizes);
}
TEST(RtpPacketizerH264Test, TestFUARounding) {
const size_t kExpectedPayloadSizes[8] = {1265, 1265, 1265, 1265,
1265, 1266, 1266, 1266};
TestFua(
10124, 1448, 0,
std::vector<size_t>(kExpectedPayloadSizes,
kExpectedPayloadSizes +
sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
TestFua(10124, 1448, 0, kExpectedPayloadSizes);
}
TEST(RtpPacketizerH264Test, TestFUABig) {
@ -464,15 +453,13 @@ TEST(RtpPacketizerH264Test, TestFUABig) {
1198, 1198, 1198, 1198, 1198};
// Generate 10 full sized packets, leave room for FU-A headers minus the NALU
// header.
TestFua(
10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize, kMaxPayloadSize,
0,
std::vector<size_t>(kExpectedPayloadSizes,
kExpectedPayloadSizes +
sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
TestFua(10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize,
kMaxPayloadSize, 0, kExpectedPayloadSizes);
}
TEST(RtpPacketizerH264Test, SendOverlongDataInPacketizationMode0) {
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kMaxPayloadSize;
const size_t kFrameSize = kMaxPayloadSize + 1;
uint8_t frame[kFrameSize] = {0};
for (size_t i = 0; i < kFrameSize; ++i)
@ -484,9 +471,9 @@ TEST(RtpPacketizerH264Test, SendOverlongDataInPacketizationMode0) {
// Set NAL headers.
frame[fragmentation.fragmentationOffset[0]] = 0x01;
std::unique_ptr<RtpPacketizerH264> packetizer(CreateH264Packetizer(
H264PacketizationMode::SingleNalUnit, kMaxPayloadSize, 0));
EXPECT_EQ(0u, packetizer->SetPayloadData(frame, kFrameSize, &fragmentation));
RtpPacketizerH264 packetizer(
frame, limits, H264PacketizationMode::SingleNalUnit, fragmentation);
EXPECT_EQ(packetizer.NumPackets(), 0u);
}
namespace {
@ -522,31 +509,29 @@ class RtpPacketizerH264TestSpsRewriting : public ::testing::Test {
protected:
rtc::Buffer in_buffer_;
RTPFragmentationHeader fragmentation_header_;
std::unique_ptr<RtpPacketizerH264> packetizer_;
};
TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) {
const size_t kHeaderOverhead = kFuAHeaderSize + 1;
// Set size to fragment SPS into two FU-A packets.
packetizer_ =
CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
sizeof(kOriginalSps) - 2 + kHeaderOverhead, 0);
packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
&fragmentation_header_);
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = sizeof(kOriginalSps) - 2 + kHeaderOverhead;
RtpPacketizerH264 packetizer(in_buffer_, limits,
H264PacketizationMode::NonInterleaved,
fragmentation_header_);
RtpPacketToSend packet(kNoExtensions);
ASSERT_LE(sizeof(kOriginalSps) + kHeaderOverhead, packet.FreeCapacity());
EXPECT_TRUE(packetizer_->NextPacket(&packet));
EXPECT_TRUE(packetizer.NextPacket(&packet));
size_t offset = H264::kNaluTypeSize;
size_t length = packet.payload_size() - kFuAHeaderSize;
EXPECT_THAT(packet.payload().subview(kFuAHeaderSize),
ElementsAreArray(&kRewrittenSps[offset], length));
offset += length;
EXPECT_TRUE(packetizer_->NextPacket(&packet));
EXPECT_TRUE(packetizer.NextPacket(&packet));
length = packet.payload_size() - kFuAHeaderSize;
EXPECT_THAT(packet.payload().subview(kFuAHeaderSize),
ElementsAreArray(&kRewrittenSps[offset], length));
@ -562,16 +547,17 @@ TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) {
sizeof(kIdrTwo) + (kLengthFieldLength * 3);
// Set size to include SPS and the rest of the packets in a Stap-A package.
packetizer_ = CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
kExpectedTotalSize + kHeaderOverhead, 0);
RtpPacketizer::PayloadSizeLimits limits;
limits.max_payload_len = kExpectedTotalSize + kHeaderOverhead;
packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
&fragmentation_header_);
RtpPacketizerH264 packetizer(in_buffer_, limits,
H264PacketizationMode::NonInterleaved,
fragmentation_header_);
RtpPacketToSend packet(kNoExtensions);
ASSERT_LE(kExpectedTotalSize + kHeaderOverhead, packet.FreeCapacity());
EXPECT_TRUE(packetizer_->NextPacket(&packet));
EXPECT_TRUE(packetizer.NextPacket(&packet));
EXPECT_EQ(kExpectedTotalSize, packet.payload_size());
EXPECT_THAT(packet.payload().subview(H264::kNaluTypeSize + kLengthFieldLength,
sizeof(kRewrittenSps)),