Chromium Code Reviews| 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 894415da8a7960d70bad206f115182e67e35f235..82d569ac94d1867134f7129be53de1e60d797dbc 100644 |
| --- a/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc |
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_format_h264_unittest.cc |
| @@ -43,6 +43,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, |
| @@ -84,8 +105,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); |
| std::unique_ptr<uint8_t[]> packet(new uint8_t[max_payload_size]); |
| @@ -152,14 +173,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); |
| uint8_t packet[kMaxPayloadSize] = {0}; |
| size_t length = 0; |
| @@ -167,12 +193,12 @@ TEST(RtpPacketizerH264Test, TestSingleNalu) { |
| ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
| EXPECT_EQ(2u, length); |
| EXPECT_TRUE(last); |
| - VerifySingleNaluPayload( |
| - fragmentation, 0, frame, sizeof(frame), packet, length); |
| + VerifySingleNaluPayload(fragmentation, 0, frame, sizeof(frame), packet, |
| + length); |
| EXPECT_FALSE(packetizer->NextPacket(packet, &length, &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) |
| @@ -188,7 +214,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); |
| uint8_t packet[kMaxPayloadSize] = {0}; |
| @@ -206,6 +232,12 @@ TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) { |
| EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); |
| } |
| +INSTANTIATE_TEST_CASE_P( |
| + PacketMode, |
| + RtpPacketizerH264ModeTest, |
| + ::testing::Values(H264PacketizationMode::SingleNalUnit, |
| + H264PacketizationMode::NonInterleaved)); |
| + |
| TEST(RtpPacketizerH264Test, TestStapA) { |
| const size_t kFrameSize = |
| kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; |
| @@ -216,16 +248,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); |
| uint8_t packet[kMaxPayloadSize] = {0}; |
| @@ -242,6 +267,32 @@ TEST(RtpPacketizerH264Test, TestStapA) { |
| EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); |
| } |
| +TEST(RtpPacketizerH264Test, TestMode0HasNoStapA) { |
|
hbos
2016/12/02 10:21:26
nit/optional: Naming difference "mode" vs enum nam
hta-webrtc
2016/12/02 11:09:01
Done.
|
| + // 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); |
| + |
| + uint8_t packet[kMaxPayloadSize] = {0}; |
| + size_t length = 0; |
| + bool last = false; |
| + // The three fragments should be returned as three packets. |
| + ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
| + ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
| + ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
| + EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); |
| +} |
| + |
| TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) { |
| const size_t kFrameSize = kMaxPayloadSize - 1; |
| uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7. |
| @@ -259,8 +310,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); |
| uint8_t packet[kMaxPayloadSize] = {0}; |
| @@ -307,8 +358,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. |
| @@ -381,6 +432,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 + 100; |
|
hbos
2016/12/02 10:21:26
nit: I prefer to test the edge case + 1
hta-webrtc
2016/12/02 11:09:01
Done.
|
| + 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, |
| @@ -421,9 +494,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_); |
| @@ -459,9 +532,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_); |