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:

committed by
Commit Bot

parent
9c147ddc91
commit
fd5fbd0b58
@ -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 =
|
||||
|
@ -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_);
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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)),
|
||||
|
Reference in New Issue
Block a user