| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <vector> | 12 #include <vector> |
| 13 | 13 |
| 14 #include "webrtc/base/array_view.h" |
| 14 #include "webrtc/common_video/h264/h264_common.h" | 15 #include "webrtc/common_video/h264/h264_common.h" |
| 15 #include "webrtc/modules/include/module_common_types.h" | 16 #include "webrtc/modules/include/module_common_types.h" |
| 16 #include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" | 17 #include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h" |
| 17 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 18 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 18 #include "webrtc/modules/rtp_rtcp/source/rtp_format.h" | 19 #include "webrtc/modules/rtp_rtcp/source/rtp_format.h" |
| 20 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h" |
| 19 #include "webrtc/test/gmock.h" | 21 #include "webrtc/test/gmock.h" |
| 20 #include "webrtc/test/gtest.h" | 22 #include "webrtc/test/gtest.h" |
| 21 | 23 |
| 22 namespace webrtc { | 24 namespace webrtc { |
| 23 namespace { | 25 namespace { |
| 26 |
| 27 using ::testing::ElementsAreArray; |
| 28 |
| 29 constexpr RtpPacketToSend::ExtensionManager* kNoExtensions = nullptr; |
| 24 const size_t kMaxPayloadSize = 1200; | 30 const size_t kMaxPayloadSize = 1200; |
| 25 const size_t kLengthFieldLength = 2; | 31 const size_t kLengthFieldLength = 2; |
| 26 | 32 |
| 27 enum Nalu { | 33 enum Nalu { |
| 28 kSlice = 1, | 34 kSlice = 1, |
| 29 kIdr = 5, | 35 kIdr = 5, |
| 30 kSei = 6, | 36 kSei = 6, |
| 31 kSps = 7, | 37 kSps = 7, |
| 32 kPps = 8, | 38 kPps = 8, |
| 33 kStapA = 24, | 39 kStapA = 24, |
| 34 kFuA = 28 | 40 kFuA = 28 |
| 35 }; | 41 }; |
| 36 | 42 |
| 37 static const size_t kNalHeaderSize = 1; | 43 static const size_t kNalHeaderSize = 1; |
| 38 static const size_t kFuAHeaderSize = 2; | 44 static const size_t kFuAHeaderSize = 2; |
| 39 | 45 |
| 40 // Bit masks for FU (A and B) indicators. | 46 // Bit masks for FU (A and B) indicators. |
| 41 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F }; | 47 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F }; |
| 42 | 48 |
| 43 // Bit masks for FU (A and B) headers. | 49 // Bit masks for FU (A and B) headers. |
| 44 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 }; | 50 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 }; |
| 45 | 51 |
| 46 void VerifyFua(size_t fua_index, | 52 void VerifyFua(size_t fua_index, |
| 47 const uint8_t* expected_payload, | 53 const uint8_t* expected_payload, |
| 48 int offset, | 54 int offset, |
| 49 const uint8_t* packet, | 55 rtc::ArrayView<const uint8_t> packet, |
| 50 size_t length, | |
| 51 const std::vector<size_t>& expected_sizes) { | 56 const std::vector<size_t>& expected_sizes) { |
| 52 ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, length) | 57 ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, packet.size()) |
| 53 << "FUA index: " << fua_index; | 58 << "FUA index: " << fua_index; |
| 54 const uint8_t kFuIndicator = 0x1C; // F=0, NRI=0, Type=28. | 59 const uint8_t kFuIndicator = 0x1C; // F=0, NRI=0, Type=28. |
| 55 EXPECT_EQ(kFuIndicator, packet[0]) << "FUA index: " << fua_index; | 60 EXPECT_EQ(kFuIndicator, packet[0]) << "FUA index: " << fua_index; |
| 56 bool should_be_last_fua = (fua_index == expected_sizes.size() - 1); | 61 bool should_be_last_fua = (fua_index == expected_sizes.size() - 1); |
| 57 uint8_t fu_header = 0; | 62 uint8_t fu_header = 0; |
| 58 if (fua_index == 0) | 63 if (fua_index == 0) |
| 59 fu_header = 0x85; // S=1, E=0, R=0, Type=5. | 64 fu_header = 0x85; // S=1, E=0, R=0, Type=5. |
| 60 else if (should_be_last_fua) | 65 else if (should_be_last_fua) |
| 61 fu_header = 0x45; // S=0, E=1, R=0, Type=5. | 66 fu_header = 0x45; // S=0, E=1, R=0, Type=5. |
| 62 else | 67 else |
| 63 fu_header = 0x05; // S=0, E=0, R=0, Type=5. | 68 fu_header = 0x05; // S=0, E=0, R=0, Type=5. |
| 64 EXPECT_EQ(fu_header, packet[1]) << "FUA index: " << fua_index; | 69 EXPECT_EQ(fu_header, packet[1]) << "FUA index: " << fua_index; |
| 65 std::vector<uint8_t> expected_packet_payload( | 70 std::vector<uint8_t> expected_packet_payload( |
| 66 &expected_payload[offset], | 71 &expected_payload[offset], |
| 67 &expected_payload[offset + expected_sizes[fua_index]]); | 72 &expected_payload[offset + expected_sizes[fua_index]]); |
| 68 EXPECT_THAT( | 73 EXPECT_THAT(expected_packet_payload, |
| 69 expected_packet_payload, | 74 ElementsAreArray(&packet[2], expected_sizes[fua_index])) |
| 70 ::testing::ElementsAreArray(&packet[2], expected_sizes[fua_index])) | |
| 71 << "FUA index: " << fua_index; | 75 << "FUA index: " << fua_index; |
| 72 } | 76 } |
| 73 | 77 |
| 74 void TestFua(size_t frame_size, | 78 void TestFua(size_t frame_size, |
| 75 size_t max_payload_size, | 79 size_t max_payload_size, |
| 76 const std::vector<size_t>& expected_sizes) { | 80 const std::vector<size_t>& expected_sizes) { |
| 77 std::unique_ptr<uint8_t[]> frame; | 81 std::unique_ptr<uint8_t[]> frame; |
| 78 frame.reset(new uint8_t[frame_size]); | 82 frame.reset(new uint8_t[frame_size]); |
| 79 frame[0] = 0x05; // F=0, NRI=0, Type=5. | 83 frame[0] = 0x05; // F=0, NRI=0, Type=5. |
| 80 for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) { | 84 for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) { |
| 81 frame[i + kNalHeaderSize] = i; | 85 frame[i + kNalHeaderSize] = i; |
| 82 } | 86 } |
| 83 RTPFragmentationHeader fragmentation; | 87 RTPFragmentationHeader fragmentation; |
| 84 fragmentation.VerifyAndAllocateFragmentationHeader(1); | 88 fragmentation.VerifyAndAllocateFragmentationHeader(1); |
| 85 fragmentation.fragmentationOffset[0] = 0; | 89 fragmentation.fragmentationOffset[0] = 0; |
| 86 fragmentation.fragmentationLength[0] = frame_size; | 90 fragmentation.fragmentationLength[0] = frame_size; |
| 87 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 91 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
| 88 kRtpVideoH264, max_payload_size, NULL, kEmptyFrame)); | 92 kRtpVideoH264, max_payload_size, NULL, kEmptyFrame)); |
| 89 packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation); | 93 packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation); |
| 90 | 94 |
| 91 std::unique_ptr<uint8_t[]> packet(new uint8_t[max_payload_size]); | 95 RtpPacketToSend packet(kNoExtensions); |
| 92 size_t length = 0; | 96 ASSERT_LE(max_payload_size, packet.FreeCapacity()); |
| 93 bool last = false; | 97 bool last = false; |
| 94 size_t offset = kNalHeaderSize; | 98 size_t offset = kNalHeaderSize; |
| 95 for (size_t i = 0; i < expected_sizes.size(); ++i) { | 99 for (size_t i = 0; i < expected_sizes.size(); ++i) { |
| 96 ASSERT_TRUE(packetizer->NextPacket(packet.get(), &length, &last)); | 100 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 97 VerifyFua(i, frame.get(), offset, packet.get(), length, expected_sizes); | 101 VerifyFua(i, frame.get(), offset, packet.payload(), expected_sizes); |
| 98 EXPECT_EQ(i == expected_sizes.size() - 1, last) << "FUA index: " << i; | 102 EXPECT_EQ(i == expected_sizes.size() - 1, last) << "FUA index: " << i; |
| 99 offset += expected_sizes[i]; | 103 offset += expected_sizes[i]; |
| 100 } | 104 } |
| 101 | 105 |
| 102 EXPECT_FALSE(packetizer->NextPacket(packet.get(), &length, &last)); | 106 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 103 } | 107 } |
| 104 | 108 |
| 105 size_t GetExpectedNaluOffset(const RTPFragmentationHeader& fragmentation, | 109 size_t GetExpectedNaluOffset(const RTPFragmentationHeader& fragmentation, |
| 106 size_t start_index, | 110 size_t start_index, |
| 107 size_t nalu_index) { | 111 size_t nalu_index) { |
| 108 assert(nalu_index < fragmentation.fragmentationVectorSize); | 112 assert(nalu_index < fragmentation.fragmentationVectorSize); |
| 109 size_t expected_nalu_offset = kNalHeaderSize; // STAP-A header. | 113 size_t expected_nalu_offset = kNalHeaderSize; // STAP-A header. |
| 110 for (size_t i = start_index; i < nalu_index; ++i) { | 114 for (size_t i = start_index; i < nalu_index; ++i) { |
| 111 expected_nalu_offset += | 115 expected_nalu_offset += |
| 112 kLengthFieldLength + fragmentation.fragmentationLength[i]; | 116 kLengthFieldLength + fragmentation.fragmentationLength[i]; |
| 113 } | 117 } |
| 114 return expected_nalu_offset; | 118 return expected_nalu_offset; |
| 115 } | 119 } |
| 116 | 120 |
| 117 void VerifyStapAPayload(const RTPFragmentationHeader& fragmentation, | 121 void VerifyStapAPayload(const RTPFragmentationHeader& fragmentation, |
| 118 size_t first_stapa_index, | 122 size_t first_stapa_index, |
| 119 size_t nalu_index, | 123 size_t nalu_index, |
| 120 const uint8_t* frame, | 124 rtc::ArrayView<const uint8_t> frame, |
| 121 size_t frame_length, | 125 rtc::ArrayView<const uint8_t> packet) { |
| 122 const uint8_t* packet, | |
| 123 size_t packet_length) { | |
| 124 size_t expected_payload_offset = | 126 size_t expected_payload_offset = |
| 125 GetExpectedNaluOffset(fragmentation, first_stapa_index, nalu_index) + | 127 GetExpectedNaluOffset(fragmentation, first_stapa_index, nalu_index) + |
| 126 kLengthFieldLength; | 128 kLengthFieldLength; |
| 127 size_t offset = fragmentation.fragmentationOffset[nalu_index]; | 129 size_t offset = fragmentation.fragmentationOffset[nalu_index]; |
| 128 const uint8_t* expected_payload = &frame[offset]; | 130 const uint8_t* expected_payload = &frame[offset]; |
| 129 size_t expected_payload_length = | 131 size_t expected_payload_length = |
| 130 fragmentation.fragmentationLength[nalu_index]; | 132 fragmentation.fragmentationLength[nalu_index]; |
| 131 ASSERT_LE(offset + expected_payload_length, frame_length); | 133 ASSERT_LE(offset + expected_payload_length, frame.size()); |
| 132 ASSERT_LE(expected_payload_offset + expected_payload_length, packet_length); | 134 ASSERT_LE(expected_payload_offset + expected_payload_length, packet.size()); |
| 133 std::vector<uint8_t> expected_payload_vector( | 135 std::vector<uint8_t> expected_payload_vector( |
| 134 expected_payload, &expected_payload[expected_payload_length]); | 136 expected_payload, &expected_payload[expected_payload_length]); |
| 135 EXPECT_THAT(expected_payload_vector, | 137 EXPECT_THAT(expected_payload_vector, |
| 136 ::testing::ElementsAreArray(&packet[expected_payload_offset], | 138 ElementsAreArray(&packet[expected_payload_offset], |
| 137 expected_payload_length)); | 139 expected_payload_length)); |
| 138 } | 140 } |
| 139 | 141 |
| 140 void VerifySingleNaluPayload(const RTPFragmentationHeader& fragmentation, | 142 void VerifySingleNaluPayload(const RTPFragmentationHeader& fragmentation, |
| 141 size_t nalu_index, | 143 size_t nalu_index, |
| 142 const uint8_t* frame, | 144 rtc::ArrayView<const uint8_t> frame, |
| 143 size_t frame_length, | 145 rtc::ArrayView<const uint8_t> packet) { |
| 144 const uint8_t* packet, | 146 auto fragment = frame.subview(fragmentation.fragmentationOffset[nalu_index], |
| 145 size_t packet_length) { | 147 fragmentation.fragmentationLength[nalu_index]); |
| 146 std::vector<uint8_t> expected_payload_vector( | 148 EXPECT_THAT(packet, ElementsAreArray(fragment.begin(), fragment.end())); |
| 147 &frame[fragmentation.fragmentationOffset[nalu_index]], | |
| 148 &frame[fragmentation.fragmentationOffset[nalu_index] + | |
| 149 fragmentation.fragmentationLength[nalu_index]]); | |
| 150 EXPECT_THAT(expected_payload_vector, | |
| 151 ::testing::ElementsAreArray(packet, packet_length)); | |
| 152 } | 149 } |
| 153 } // namespace | 150 } // namespace |
| 154 | 151 |
| 155 TEST(RtpPacketizerH264Test, TestSingleNalu) { | 152 TEST(RtpPacketizerH264Test, TestSingleNalu) { |
| 156 const uint8_t frame[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5. | 153 const uint8_t frame[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5. |
| 157 RTPFragmentationHeader fragmentation; | 154 RTPFragmentationHeader fragmentation; |
| 158 fragmentation.VerifyAndAllocateFragmentationHeader(1); | 155 fragmentation.VerifyAndAllocateFragmentationHeader(1); |
| 159 fragmentation.fragmentationOffset[0] = 0; | 156 fragmentation.fragmentationOffset[0] = 0; |
| 160 fragmentation.fragmentationLength[0] = sizeof(frame); | 157 fragmentation.fragmentationLength[0] = sizeof(frame); |
| 161 std::unique_ptr<RtpPacketizer> packetizer( | 158 std::unique_ptr<RtpPacketizer> packetizer( |
| 162 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 159 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 163 packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation); | 160 packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation); |
| 164 uint8_t packet[kMaxPayloadSize] = {0}; | 161 RtpPacketToSend packet(kNoExtensions); |
| 165 size_t length = 0; | 162 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 166 bool last = false; | 163 bool last = false; |
| 167 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 164 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 168 EXPECT_EQ(2u, length); | 165 EXPECT_EQ(2u, packet.payload_size()); |
| 169 EXPECT_TRUE(last); | 166 EXPECT_TRUE(last); |
| 170 VerifySingleNaluPayload( | 167 VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload()); |
| 171 fragmentation, 0, frame, sizeof(frame), packet, length); | 168 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 172 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | |
| 173 } | 169 } |
| 174 | 170 |
| 175 TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) { | 171 TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) { |
| 176 const size_t kFrameSize = kMaxPayloadSize + 100; | 172 const size_t kFrameSize = kMaxPayloadSize + 100; |
| 177 uint8_t frame[kFrameSize] = {0}; | 173 uint8_t frame[kFrameSize] = {0}; |
| 178 for (size_t i = 0; i < kFrameSize; ++i) | 174 for (size_t i = 0; i < kFrameSize; ++i) |
| 179 frame[i] = i; | 175 frame[i] = i; |
| 180 RTPFragmentationHeader fragmentation; | 176 RTPFragmentationHeader fragmentation; |
| 181 fragmentation.VerifyAndAllocateFragmentationHeader(2); | 177 fragmentation.VerifyAndAllocateFragmentationHeader(2); |
| 182 fragmentation.fragmentationOffset[0] = 0; | 178 fragmentation.fragmentationOffset[0] = 0; |
| 183 fragmentation.fragmentationLength[0] = kMaxPayloadSize; | 179 fragmentation.fragmentationLength[0] = kMaxPayloadSize; |
| 184 fragmentation.fragmentationOffset[1] = kMaxPayloadSize; | 180 fragmentation.fragmentationOffset[1] = kMaxPayloadSize; |
| 185 fragmentation.fragmentationLength[1] = 100; | 181 fragmentation.fragmentationLength[1] = 100; |
| 186 // Set NAL headers. | 182 // Set NAL headers. |
| 187 frame[fragmentation.fragmentationOffset[0]] = 0x01; | 183 frame[fragmentation.fragmentationOffset[0]] = 0x01; |
| 188 frame[fragmentation.fragmentationOffset[1]] = 0x01; | 184 frame[fragmentation.fragmentationOffset[1]] = 0x01; |
| 189 | 185 |
| 190 std::unique_ptr<RtpPacketizer> packetizer( | 186 std::unique_ptr<RtpPacketizer> packetizer( |
| 191 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 187 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 192 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 188 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 193 | 189 |
| 194 uint8_t packet[kMaxPayloadSize] = {0}; | 190 RtpPacketToSend packet(kNoExtensions); |
| 195 size_t length = 0; | |
| 196 bool last = false; | 191 bool last = false; |
| 197 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 192 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 198 ASSERT_EQ(fragmentation.fragmentationOffset[1], length); | 193 ASSERT_EQ(fragmentation.fragmentationOffset[1], packet.payload_size()); |
| 199 VerifySingleNaluPayload(fragmentation, 0, frame, kFrameSize, packet, length); | 194 VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload()); |
| 200 | 195 |
| 201 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 196 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 202 ASSERT_EQ(fragmentation.fragmentationLength[1], length); | 197 ASSERT_EQ(fragmentation.fragmentationLength[1], packet.payload_size()); |
| 203 VerifySingleNaluPayload(fragmentation, 1, frame, kFrameSize, packet, length); | 198 VerifySingleNaluPayload(fragmentation, 1, frame, packet.payload()); |
| 204 EXPECT_TRUE(last); | 199 EXPECT_TRUE(last); |
| 205 | 200 |
| 206 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | 201 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 207 } | 202 } |
| 208 | 203 |
| 209 TEST(RtpPacketizerH264Test, TestStapA) { | 204 TEST(RtpPacketizerH264Test, TestStapA) { |
| 210 const size_t kFrameSize = | 205 const size_t kFrameSize = |
| 211 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; | 206 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; |
| 212 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS). | 207 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS). |
| 213 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). | 208 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). |
| 214 0x05}; // F=0, NRI=0, Type=5 (IDR). | 209 0x05}; // F=0, NRI=0, Type=5 (IDR). |
| 215 const size_t kPayloadOffset = 5; | 210 const size_t kPayloadOffset = 5; |
| 216 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) | 211 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) |
| 217 frame[i + kPayloadOffset] = i; | 212 frame[i + kPayloadOffset] = i; |
| 218 RTPFragmentationHeader fragmentation; | 213 RTPFragmentationHeader fragmentation; |
| 219 fragmentation.VerifyAndAllocateFragmentationHeader(3); | 214 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
| 220 fragmentation.fragmentationOffset[0] = 0; | 215 fragmentation.fragmentationOffset[0] = 0; |
| 221 fragmentation.fragmentationLength[0] = 2; | 216 fragmentation.fragmentationLength[0] = 2; |
| 222 fragmentation.fragmentationOffset[1] = 2; | 217 fragmentation.fragmentationOffset[1] = 2; |
| 223 fragmentation.fragmentationLength[1] = 2; | 218 fragmentation.fragmentationLength[1] = 2; |
| 224 fragmentation.fragmentationOffset[2] = 4; | 219 fragmentation.fragmentationOffset[2] = 4; |
| 225 fragmentation.fragmentationLength[2] = | 220 fragmentation.fragmentationLength[2] = |
| 226 kNalHeaderSize + kFrameSize - kPayloadOffset; | 221 kNalHeaderSize + kFrameSize - kPayloadOffset; |
| 227 std::unique_ptr<RtpPacketizer> packetizer( | 222 std::unique_ptr<RtpPacketizer> packetizer( |
| 228 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 223 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 229 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 224 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 230 | 225 |
| 231 uint8_t packet[kMaxPayloadSize] = {0}; | 226 RtpPacketToSend packet(kNoExtensions); |
| 232 size_t length = 0; | 227 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 233 bool last = false; | 228 bool last = false; |
| 234 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 229 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 235 size_t expected_packet_size = | 230 size_t expected_packet_size = |
| 236 kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize; | 231 kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize; |
| 237 ASSERT_EQ(expected_packet_size, length); | 232 ASSERT_EQ(expected_packet_size, packet.payload_size()); |
| 238 EXPECT_TRUE(last); | 233 EXPECT_TRUE(last); |
| 239 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) | 234 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) |
| 240 VerifyStapAPayload(fragmentation, 0, i, frame, kFrameSize, packet, length); | 235 VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload()); |
| 241 | 236 |
| 242 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | 237 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 243 } | 238 } |
| 244 | 239 |
| 245 TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) { | 240 TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) { |
| 246 const size_t kFrameSize = kMaxPayloadSize - 1; | 241 const size_t kFrameSize = kMaxPayloadSize - 1; |
| 247 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7. | 242 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7. |
| 248 0x08, 0xFF, // F=0, NRI=0, Type=8. | 243 0x08, 0xFF, // F=0, NRI=0, Type=8. |
| 249 0x05}; // F=0, NRI=0, Type=5. | 244 0x05}; // F=0, NRI=0, Type=5. |
| 250 const size_t kPayloadOffset = 5; | 245 const size_t kPayloadOffset = 5; |
| 251 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) | 246 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) |
| 252 frame[i + kPayloadOffset] = i; | 247 frame[i + kPayloadOffset] = i; |
| 253 RTPFragmentationHeader fragmentation; | 248 RTPFragmentationHeader fragmentation; |
| 254 fragmentation.VerifyAndAllocateFragmentationHeader(3); | 249 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
| 255 fragmentation.fragmentationOffset[0] = 0; | 250 fragmentation.fragmentationOffset[0] = 0; |
| 256 fragmentation.fragmentationLength[0] = 2; | 251 fragmentation.fragmentationLength[0] = 2; |
| 257 fragmentation.fragmentationOffset[1] = 2; | 252 fragmentation.fragmentationOffset[1] = 2; |
| 258 fragmentation.fragmentationLength[1] = 2; | 253 fragmentation.fragmentationLength[1] = 2; |
| 259 fragmentation.fragmentationOffset[2] = 4; | 254 fragmentation.fragmentationOffset[2] = 4; |
| 260 fragmentation.fragmentationLength[2] = | 255 fragmentation.fragmentationLength[2] = |
| 261 kNalHeaderSize + kFrameSize - kPayloadOffset; | 256 kNalHeaderSize + kFrameSize - kPayloadOffset; |
| 262 std::unique_ptr<RtpPacketizer> packetizer( | 257 std::unique_ptr<RtpPacketizer> packetizer( |
| 263 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 258 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 264 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 259 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 265 | 260 |
| 266 uint8_t packet[kMaxPayloadSize] = {0}; | 261 RtpPacketToSend packet(kNoExtensions); |
| 267 size_t length = 0; | 262 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 268 bool last = false; | 263 bool last = false; |
| 269 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 264 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 270 size_t expected_packet_size = kNalHeaderSize; | 265 size_t expected_packet_size = kNalHeaderSize; |
| 271 for (size_t i = 0; i < 2; ++i) { | 266 for (size_t i = 0; i < 2; ++i) { |
| 272 expected_packet_size += | 267 expected_packet_size += |
| 273 kLengthFieldLength + fragmentation.fragmentationLength[i]; | 268 kLengthFieldLength + fragmentation.fragmentationLength[i]; |
| 274 } | 269 } |
| 275 ASSERT_EQ(expected_packet_size, length); | 270 ASSERT_EQ(expected_packet_size, packet.payload_size()); |
| 276 EXPECT_FALSE(last); | 271 EXPECT_FALSE(last); |
| 277 for (size_t i = 0; i < 2; ++i) | 272 for (size_t i = 0; i < 2; ++i) |
| 278 VerifyStapAPayload(fragmentation, 0, i, frame, kFrameSize, packet, length); | 273 VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload()); |
| 279 | 274 |
| 280 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 275 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 281 expected_packet_size = fragmentation.fragmentationLength[2]; | 276 expected_packet_size = fragmentation.fragmentationLength[2]; |
| 282 ASSERT_EQ(expected_packet_size, length); | 277 ASSERT_EQ(expected_packet_size, packet.payload_size()); |
| 283 EXPECT_TRUE(last); | 278 EXPECT_TRUE(last); |
| 284 VerifySingleNaluPayload(fragmentation, 2, frame, kFrameSize, packet, length); | 279 VerifySingleNaluPayload(fragmentation, 2, frame, packet.payload()); |
| 285 | 280 |
| 286 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | 281 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 287 } | 282 } |
| 288 | 283 |
| 289 TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) { | 284 TEST(RtpPacketizerH264Test, TestMixedStapA_FUA) { |
| 290 const size_t kFuaNaluSize = 2 * (kMaxPayloadSize - 100); | 285 const size_t kFuaNaluSize = 2 * (kMaxPayloadSize - 100); |
| 291 const size_t kStapANaluSize = 100; | 286 const size_t kStapANaluSize = 100; |
| 292 RTPFragmentationHeader fragmentation; | 287 RTPFragmentationHeader fragmentation; |
| 293 fragmentation.VerifyAndAllocateFragmentationHeader(3); | 288 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
| 294 fragmentation.fragmentationOffset[0] = 0; | 289 fragmentation.fragmentationOffset[0] = 0; |
| 295 fragmentation.fragmentationLength[0] = kFuaNaluSize; | 290 fragmentation.fragmentationLength[0] = kFuaNaluSize; |
| 296 fragmentation.fragmentationOffset[1] = kFuaNaluSize; | 291 fragmentation.fragmentationOffset[1] = kFuaNaluSize; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 308 } | 303 } |
| 309 } | 304 } |
| 310 std::unique_ptr<RtpPacketizer> packetizer( | 305 std::unique_ptr<RtpPacketizer> packetizer( |
| 311 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 306 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 312 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 307 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 313 | 308 |
| 314 // First expecting two FU-A packets. | 309 // First expecting two FU-A packets. |
| 315 std::vector<size_t> fua_sizes; | 310 std::vector<size_t> fua_sizes; |
| 316 fua_sizes.push_back(1100); | 311 fua_sizes.push_back(1100); |
| 317 fua_sizes.push_back(1099); | 312 fua_sizes.push_back(1099); |
| 318 uint8_t packet[kMaxPayloadSize] = {0}; | 313 RtpPacketToSend packet(kNoExtensions); |
| 319 size_t length = 0; | 314 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 320 bool last = false; | 315 bool last = false; |
| 321 int fua_offset = kNalHeaderSize; | 316 int fua_offset = kNalHeaderSize; |
| 322 for (size_t i = 0; i < 2; ++i) { | 317 for (size_t i = 0; i < 2; ++i) { |
| 323 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 318 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 324 VerifyFua(i, frame, fua_offset, packet, length, fua_sizes); | 319 VerifyFua(i, frame, fua_offset, packet.payload(), fua_sizes); |
| 325 EXPECT_FALSE(last); | 320 EXPECT_FALSE(last); |
| 326 fua_offset += fua_sizes[i]; | 321 fua_offset += fua_sizes[i]; |
| 327 } | 322 } |
| 328 // Then expecting one STAP-A packet with two nal units. | 323 // Then expecting one STAP-A packet with two nal units. |
| 329 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 324 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 330 size_t expected_packet_size = | 325 size_t expected_packet_size = |
| 331 kNalHeaderSize + 2 * kLengthFieldLength + 2 * kStapANaluSize; | 326 kNalHeaderSize + 2 * kLengthFieldLength + 2 * kStapANaluSize; |
| 332 ASSERT_EQ(expected_packet_size, length); | 327 ASSERT_EQ(expected_packet_size, packet.payload_size()); |
| 333 EXPECT_TRUE(last); | 328 EXPECT_TRUE(last); |
| 334 for (size_t i = 1; i < fragmentation.fragmentationVectorSize; ++i) | 329 for (size_t i = 1; i < fragmentation.fragmentationVectorSize; ++i) |
| 335 VerifyStapAPayload(fragmentation, 1, i, frame, kFrameSize, packet, length); | 330 VerifyStapAPayload(fragmentation, 1, i, frame, packet.payload()); |
| 336 | 331 |
| 337 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | 332 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 338 } | 333 } |
| 339 | 334 |
| 340 TEST(RtpPacketizerH264Test, TestFUAOddSize) { | 335 TEST(RtpPacketizerH264Test, TestFUAOddSize) { |
| 341 const size_t kExpectedPayloadSizes[2] = {600, 600}; | 336 const size_t kExpectedPayloadSizes[2] = {600, 600}; |
| 342 TestFua( | 337 TestFua( |
| 343 kMaxPayloadSize + 1, | 338 kMaxPayloadSize + 1, |
| 344 kMaxPayloadSize, | 339 kMaxPayloadSize, |
| 345 std::vector<size_t>(kExpectedPayloadSizes, | 340 std::vector<size_t>(kExpectedPayloadSizes, |
| 346 kExpectedPayloadSizes + | 341 kExpectedPayloadSizes + |
| 347 sizeof(kExpectedPayloadSizes) / sizeof(size_t))); | 342 sizeof(kExpectedPayloadSizes) / sizeof(size_t))); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 417 |
| 423 // Set size to fragment SPS into two FU-A packets. | 418 // Set size to fragment SPS into two FU-A packets. |
| 424 packetizer_.reset(RtpPacketizer::Create( | 419 packetizer_.reset(RtpPacketizer::Create( |
| 425 kRtpVideoH264, sizeof(kOriginalSps) - 2 + kHeaderOverhead, nullptr, | 420 kRtpVideoH264, sizeof(kOriginalSps) - 2 + kHeaderOverhead, nullptr, |
| 426 kEmptyFrame)); | 421 kEmptyFrame)); |
| 427 | 422 |
| 428 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), | 423 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), |
| 429 &fragmentation_header_); | 424 &fragmentation_header_); |
| 430 | 425 |
| 431 bool last_packet = true; | 426 bool last_packet = true; |
| 432 uint8_t buffer[sizeof(kOriginalSps) + kHeaderOverhead] = {}; | 427 RtpPacketToSend packet(kNoExtensions); |
| 433 size_t num_bytes = 0; | 428 ASSERT_LE(sizeof(kOriginalSps) + kHeaderOverhead, packet.FreeCapacity()); |
| 434 | 429 |
| 435 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet)); | 430 EXPECT_TRUE(packetizer_->NextPacket(&packet, &last_packet)); |
| 436 size_t offset = H264::kNaluTypeSize; | 431 size_t offset = H264::kNaluTypeSize; |
| 437 size_t length = num_bytes - kFuAHeaderSize; | 432 size_t length = packet.payload_size() - kFuAHeaderSize; |
| 438 std::vector<uint8_t> expected_payload(&kRewrittenSps[offset], | 433 EXPECT_THAT(packet.payload().subview(kFuAHeaderSize), |
| 439 &kRewrittenSps[offset + length]); | 434 ElementsAreArray(&kRewrittenSps[offset], length)); |
| 440 EXPECT_THAT(expected_payload, | |
| 441 ::testing::ElementsAreArray(&buffer[kFuAHeaderSize], length)); | |
| 442 offset += length; | 435 offset += length; |
| 443 | 436 |
| 444 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet)); | 437 EXPECT_TRUE(packetizer_->NextPacket(&packet, &last_packet)); |
| 445 length = num_bytes - kFuAHeaderSize; | 438 length = packet.payload_size() - kFuAHeaderSize; |
| 446 expected_payload = std::vector<uint8_t>(&kRewrittenSps[offset], | 439 EXPECT_THAT(packet.payload().subview(kFuAHeaderSize), |
| 447 &kRewrittenSps[offset + length]); | 440 ElementsAreArray(&kRewrittenSps[offset], length)); |
| 448 EXPECT_THAT(expected_payload, | |
| 449 ::testing::ElementsAreArray(&buffer[kFuAHeaderSize], length)); | |
| 450 offset += length; | 441 offset += length; |
| 451 | 442 |
| 452 EXPECT_EQ(offset, sizeof(kRewrittenSps)); | 443 EXPECT_EQ(offset, sizeof(kRewrittenSps)); |
| 453 } | 444 } |
| 454 | 445 |
| 455 TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) { | 446 TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) { |
| 456 const size_t kHeaderOverhead = kFuAHeaderSize + 1; | 447 const size_t kHeaderOverhead = kFuAHeaderSize + 1; |
| 457 const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type. | 448 const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type. |
| 458 sizeof(kRewrittenSps) + sizeof(kIdrOne) + | 449 sizeof(kRewrittenSps) + sizeof(kIdrOne) + |
| 459 sizeof(kIdrTwo) + (kLengthFieldLength * 3); | 450 sizeof(kIdrTwo) + (kLengthFieldLength * 3); |
| 460 | 451 |
| 461 // Set size to include SPS and the rest of the packets in a Stap-A package. | 452 // Set size to include SPS and the rest of the packets in a Stap-A package. |
| 462 packetizer_.reset(RtpPacketizer::Create(kRtpVideoH264, | 453 packetizer_.reset(RtpPacketizer::Create(kRtpVideoH264, |
| 463 kExpectedTotalSize + kHeaderOverhead, | 454 kExpectedTotalSize + kHeaderOverhead, |
| 464 nullptr, kEmptyFrame)); | 455 nullptr, kEmptyFrame)); |
| 465 | 456 |
| 466 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), | 457 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), |
| 467 &fragmentation_header_); | 458 &fragmentation_header_); |
| 468 | 459 |
| 469 bool last_packet = true; | 460 bool last_packet = true; |
| 470 uint8_t buffer[kExpectedTotalSize + kHeaderOverhead] = {}; | 461 RtpPacketToSend packet(kNoExtensions); |
| 471 size_t num_bytes = 0; | 462 ASSERT_LE(kExpectedTotalSize + kHeaderOverhead, packet.FreeCapacity()); |
| 472 | 463 |
| 473 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet)); | 464 EXPECT_TRUE(packetizer_->NextPacket(&packet, &last_packet)); |
| 474 EXPECT_EQ(kExpectedTotalSize, num_bytes); | 465 EXPECT_EQ(kExpectedTotalSize, packet.payload_size()); |
| 475 | 466 EXPECT_THAT(packet.payload().subview(H264::kNaluTypeSize + kLengthFieldLength, |
| 476 std::vector<uint8_t> expected_payload(kRewrittenSps, | 467 sizeof(kRewrittenSps)), |
| 477 &kRewrittenSps[sizeof(kRewrittenSps)]); | 468 ElementsAreArray(kRewrittenSps)); |
| 478 EXPECT_THAT(expected_payload, | |
| 479 ::testing::ElementsAreArray( | |
| 480 &buffer[H264::kNaluTypeSize + kLengthFieldLength], | |
| 481 sizeof(kRewrittenSps))); | |
| 482 } | 469 } |
| 483 | 470 |
| 484 class RtpDepacketizerH264Test : public ::testing::Test { | 471 class RtpDepacketizerH264Test : public ::testing::Test { |
| 485 protected: | 472 protected: |
| 486 RtpDepacketizerH264Test() | 473 RtpDepacketizerH264Test() |
| 487 : depacketizer_(RtpDepacketizer::Create(kRtpVideoH264)) {} | 474 : depacketizer_(RtpDepacketizer::Create(kRtpVideoH264)) {} |
| 488 | 475 |
| 489 void ExpectPacket(RtpDepacketizer::ParsedPayload* parsed_payload, | 476 void ExpectPacket(RtpDepacketizer::ParsedPayload* parsed_payload, |
| 490 const uint8_t* data, | 477 const uint8_t* data, |
| 491 size_t length) { | 478 size_t length) { |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 const RTPVideoHeaderH264& h264 = payload.type.Video.codecHeader.H264; | 818 const RTPVideoHeaderH264& h264 = payload.type.Video.codecHeader.H264; |
| 832 EXPECT_EQ(kH264SingleNalu, h264.packetization_type); | 819 EXPECT_EQ(kH264SingleNalu, h264.packetization_type); |
| 833 EXPECT_EQ(kSei, h264.nalu_type); | 820 EXPECT_EQ(kSei, h264.nalu_type); |
| 834 ASSERT_EQ(1u, h264.nalus_length); | 821 ASSERT_EQ(1u, h264.nalus_length); |
| 835 EXPECT_EQ(static_cast<H264::NaluType>(kSei), h264.nalus[0].type); | 822 EXPECT_EQ(static_cast<H264::NaluType>(kSei), h264.nalus[0].type); |
| 836 EXPECT_EQ(-1, h264.nalus[0].sps_id); | 823 EXPECT_EQ(-1, h264.nalus[0].sps_id); |
| 837 EXPECT_EQ(-1, h264.nalus[0].pps_id); | 824 EXPECT_EQ(-1, h264.nalus[0].pps_id); |
| 838 } | 825 } |
| 839 | 826 |
| 840 } // namespace webrtc | 827 } // namespace webrtc |
| OLD | NEW |