| Index: webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
|
| diff --git a/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
|
| index 03082a420d2cd9d1a09c2aa9c22fac65c462a485..ccaef1a9f4745fe97cd68b8c36a1e112cdb3348d 100644
|
| --- a/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
|
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc
|
| @@ -49,6 +49,27 @@ enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F };
|
| // Bit masks for FU (A and B) headers.
|
| enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 };
|
|
|
| +void CreateThreeFragments(RTPFragmentationHeader* fragmentation,
|
| + size_t frameSize,
|
| + size_t payloadOffset) {
|
| + fragmentation->VerifyAndAllocateFragmentationHeader(3);
|
| + fragmentation->fragmentationOffset[0] = 0;
|
| + fragmentation->fragmentationLength[0] = 2;
|
| + fragmentation->fragmentationOffset[1] = 2;
|
| + fragmentation->fragmentationLength[1] = 2;
|
| + fragmentation->fragmentationOffset[2] = 4;
|
| + fragmentation->fragmentationLength[2] =
|
| + kNalHeaderSize + frameSize - payloadOffset;
|
| +}
|
| +
|
| +RtpPacketizer* CreateH264Packetizer(H264PacketizationMode mode,
|
| + size_t max_payload_size) {
|
| + RTPVideoTypeHeader type_header;
|
| + type_header.H264.packetization_mode = mode;
|
| + return RtpPacketizer::Create(kRtpVideoH264, max_payload_size, &type_header,
|
| + kEmptyFrame);
|
| +}
|
| +
|
| void VerifyFua(size_t fua_index,
|
| const uint8_t* expected_payload,
|
| int offset,
|
| @@ -88,8 +109,8 @@ void TestFua(size_t frame_size,
|
| fragmentation.VerifyAndAllocateFragmentationHeader(1);
|
| fragmentation.fragmentationOffset[0] = 0;
|
| fragmentation.fragmentationLength[0] = frame_size;
|
| - std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create(
|
| - kRtpVideoH264, max_payload_size, NULL, kEmptyFrame));
|
| + std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
|
| + H264PacketizationMode::NonInterleaved, max_payload_size));
|
| packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation);
|
|
|
| RtpPacketToSend packet(kNoExtensions);
|
| @@ -149,14 +170,19 @@ void VerifySingleNaluPayload(const RTPFragmentationHeader& fragmentation,
|
| }
|
| } // namespace
|
|
|
| -TEST(RtpPacketizerH264Test, TestSingleNalu) {
|
| +// Tests that should work with both packetization mode 0 and
|
| +// packetization mode 1.
|
| +class RtpPacketizerH264ModeTest
|
| + : public ::testing::TestWithParam<H264PacketizationMode> {};
|
| +
|
| +TEST_P(RtpPacketizerH264ModeTest, TestSingleNalu) {
|
| const uint8_t frame[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5.
|
| RTPFragmentationHeader fragmentation;
|
| fragmentation.VerifyAndAllocateFragmentationHeader(1);
|
| fragmentation.fragmentationOffset[0] = 0;
|
| fragmentation.fragmentationLength[0] = sizeof(frame);
|
| std::unique_ptr<RtpPacketizer> packetizer(
|
| - RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame));
|
| + CreateH264Packetizer(GetParam(), kMaxPayloadSize));
|
| packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation);
|
| RtpPacketToSend packet(kNoExtensions);
|
| ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity());
|
| @@ -168,7 +194,7 @@ TEST(RtpPacketizerH264Test, TestSingleNalu) {
|
| EXPECT_FALSE(packetizer->NextPacket(&packet, &last));
|
| }
|
|
|
| -TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) {
|
| +TEST_P(RtpPacketizerH264ModeTest, TestSingleNaluTwoPackets) {
|
| const size_t kFrameSize = kMaxPayloadSize + 100;
|
| uint8_t frame[kFrameSize] = {0};
|
| for (size_t i = 0; i < kFrameSize; ++i)
|
| @@ -184,7 +210,7 @@ TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) {
|
| frame[fragmentation.fragmentationOffset[1]] = 0x01;
|
|
|
| std::unique_ptr<RtpPacketizer> packetizer(
|
| - RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame));
|
| + CreateH264Packetizer(GetParam(), kMaxPayloadSize));
|
| packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
|
|
|
| RtpPacketToSend packet(kNoExtensions);
|
| @@ -201,6 +227,12 @@ TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) {
|
| EXPECT_FALSE(packetizer->NextPacket(&packet, &last));
|
| }
|
|
|
| +INSTANTIATE_TEST_CASE_P(
|
| + PacketMode,
|
| + RtpPacketizerH264ModeTest,
|
| + ::testing::Values(H264PacketizationMode::SingleNalUnit,
|
| + H264PacketizationMode::NonInterleaved));
|
| +
|
| TEST(RtpPacketizerH264Test, TestStapA) {
|
| const size_t kFrameSize =
|
| kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize;
|
| @@ -211,16 +243,9 @@ TEST(RtpPacketizerH264Test, TestStapA) {
|
| for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i)
|
| frame[i + kPayloadOffset] = i;
|
| RTPFragmentationHeader fragmentation;
|
| - fragmentation.VerifyAndAllocateFragmentationHeader(3);
|
| - fragmentation.fragmentationOffset[0] = 0;
|
| - fragmentation.fragmentationLength[0] = 2;
|
| - fragmentation.fragmentationOffset[1] = 2;
|
| - fragmentation.fragmentationLength[1] = 2;
|
| - fragmentation.fragmentationOffset[2] = 4;
|
| - fragmentation.fragmentationLength[2] =
|
| - kNalHeaderSize + kFrameSize - kPayloadOffset;
|
| - std::unique_ptr<RtpPacketizer> packetizer(
|
| - RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame));
|
| + CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
|
| + std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
|
| + H264PacketizationMode::NonInterleaved, kMaxPayloadSize));
|
| packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
|
|
|
| RtpPacketToSend packet(kNoExtensions);
|
| @@ -237,6 +262,31 @@ TEST(RtpPacketizerH264Test, TestStapA) {
|
| EXPECT_FALSE(packetizer->NextPacket(&packet, &last));
|
| }
|
|
|
| +TEST(RtpPacketizerH264Test, TestSingleNalUnitModeHasNoStapA) {
|
| + // This is the same setup as for the TestStapA test.
|
| + const size_t kFrameSize =
|
| + kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize;
|
| + uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS).
|
| + 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS).
|
| + 0x05}; // F=0, NRI=0, Type=5 (IDR).
|
| + const size_t kPayloadOffset = 5;
|
| + for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i)
|
| + frame[i + kPayloadOffset] = i;
|
| + RTPFragmentationHeader fragmentation;
|
| + CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset);
|
| + std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
|
| + H264PacketizationMode::SingleNalUnit, kMaxPayloadSize));
|
| + packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
|
| +
|
| + RtpPacketToSend packet(kNoExtensions);
|
| + bool last = false;
|
| + // The three fragments should be returned as three packets.
|
| + ASSERT_TRUE(packetizer->NextPacket(&packet, &last));
|
| + ASSERT_TRUE(packetizer->NextPacket(&packet, &last));
|
| + ASSERT_TRUE(packetizer->NextPacket(&packet, &last));
|
| + EXPECT_FALSE(packetizer->NextPacket(&packet, &last));
|
| +}
|
| +
|
| TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) {
|
| const size_t kFrameSize = kMaxPayloadSize - 1;
|
| uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7.
|
| @@ -254,8 +304,8 @@ TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) {
|
| fragmentation.fragmentationOffset[2] = 4;
|
| fragmentation.fragmentationLength[2] =
|
| kNalHeaderSize + kFrameSize - kPayloadOffset;
|
| - std::unique_ptr<RtpPacketizer> packetizer(
|
| - RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame));
|
| + std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
|
| + H264PacketizationMode::NonInterleaved, kMaxPayloadSize));
|
| packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
|
|
|
| RtpPacketToSend packet(kNoExtensions);
|
| @@ -302,8 +352,8 @@ TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) {
|
| frame[nalu_offset + j] = i + j;
|
| }
|
| }
|
| - std::unique_ptr<RtpPacketizer> packetizer(
|
| - RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame));
|
| + std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
|
| + H264PacketizationMode::NonInterleaved, kMaxPayloadSize));
|
| packetizer->SetPayloadData(frame, kFrameSize, &fragmentation);
|
|
|
| // First expecting two FU-A packets.
|
| @@ -376,6 +426,28 @@ TEST(RtpPacketizerH264Test, TestFUABig) {
|
| sizeof(kExpectedPayloadSizes) / sizeof(size_t)));
|
| }
|
|
|
| +#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
| +
|
| +TEST(RtpPacketizerH264DeathTest, SendOverlongDataInPacketizationMode0) {
|
| + const size_t kFrameSize = kMaxPayloadSize + 1;
|
| + uint8_t frame[kFrameSize] = {0};
|
| + for (size_t i = 0; i < kFrameSize; ++i)
|
| + frame[i] = i;
|
| + RTPFragmentationHeader fragmentation;
|
| + fragmentation.VerifyAndAllocateFragmentationHeader(1);
|
| + fragmentation.fragmentationOffset[0] = 0;
|
| + fragmentation.fragmentationLength[0] = kFrameSize;
|
| + // Set NAL headers.
|
| + frame[fragmentation.fragmentationOffset[0]] = 0x01;
|
| +
|
| + std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer(
|
| + H264PacketizationMode::SingleNalUnit, kMaxPayloadSize));
|
| + EXPECT_DEATH(packetizer->SetPayloadData(frame, kFrameSize, &fragmentation),
|
| + "payload_size");
|
| +}
|
| +
|
| +#endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
| +
|
| namespace {
|
| const uint8_t kStartSequence[] = {0x00, 0x00, 0x00, 0x01};
|
| const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03,
|
| @@ -416,9 +488,9 @@ TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) {
|
| const size_t kHeaderOverhead = kFuAHeaderSize + 1;
|
|
|
| // Set size to fragment SPS into two FU-A packets.
|
| - packetizer_.reset(RtpPacketizer::Create(
|
| - kRtpVideoH264, sizeof(kOriginalSps) - 2 + kHeaderOverhead, nullptr,
|
| - kEmptyFrame));
|
| + packetizer_.reset(
|
| + CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
|
| + sizeof(kOriginalSps) - 2 + kHeaderOverhead));
|
|
|
| packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
|
| &fragmentation_header_);
|
| @@ -450,9 +522,8 @@ 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_.reset(RtpPacketizer::Create(kRtpVideoH264,
|
| - kExpectedTotalSize + kHeaderOverhead,
|
| - nullptr, kEmptyFrame));
|
| + packetizer_.reset(CreateH264Packetizer(H264PacketizationMode::NonInterleaved,
|
| + kExpectedTotalSize + kHeaderOverhead));
|
|
|
| packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(),
|
| &fragmentation_header_);
|
|
|