| 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 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 static const size_t kNalHeaderSize = 1; | 43 static const size_t kNalHeaderSize = 1; |
| 44 static const size_t kFuAHeaderSize = 2; | 44 static const size_t kFuAHeaderSize = 2; |
| 45 | 45 |
| 46 // Bit masks for FU (A and B) indicators. | 46 // Bit masks for FU (A and B) indicators. |
| 47 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F }; | 47 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F }; |
| 48 | 48 |
| 49 // Bit masks for FU (A and B) headers. | 49 // Bit masks for FU (A and B) headers. |
| 50 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 }; | 50 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 }; |
| 51 | 51 |
| 52 void CreateThreeFragments(RTPFragmentationHeader* fragmentation, | |
| 53 size_t frameSize, | |
| 54 size_t payloadOffset) { | |
| 55 fragmentation->VerifyAndAllocateFragmentationHeader(3); | |
| 56 fragmentation->fragmentationOffset[0] = 0; | |
| 57 fragmentation->fragmentationLength[0] = 2; | |
| 58 fragmentation->fragmentationOffset[1] = 2; | |
| 59 fragmentation->fragmentationLength[1] = 2; | |
| 60 fragmentation->fragmentationOffset[2] = 4; | |
| 61 fragmentation->fragmentationLength[2] = | |
| 62 kNalHeaderSize + frameSize - payloadOffset; | |
| 63 } | |
| 64 | |
| 65 RtpPacketizer* CreateH264Packetizer(H264PacketizationMode mode, | |
| 66 size_t max_payload_size) { | |
| 67 RTPVideoTypeHeader type_header; | |
| 68 type_header.H264.packetization_mode = mode; | |
| 69 return RtpPacketizer::Create(kRtpVideoH264, max_payload_size, &type_header, | |
| 70 kEmptyFrame); | |
| 71 } | |
| 72 | |
| 73 void VerifyFua(size_t fua_index, | 52 void VerifyFua(size_t fua_index, |
| 74 const uint8_t* expected_payload, | 53 const uint8_t* expected_payload, |
| 75 int offset, | 54 int offset, |
| 76 rtc::ArrayView<const uint8_t> packet, | 55 rtc::ArrayView<const uint8_t> packet, |
| 77 const std::vector<size_t>& expected_sizes) { | 56 const std::vector<size_t>& expected_sizes) { |
| 78 ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, packet.size()) | 57 ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, packet.size()) |
| 79 << "FUA index: " << fua_index; | 58 << "FUA index: " << fua_index; |
| 80 const uint8_t kFuIndicator = 0x1C; // F=0, NRI=0, Type=28. | 59 const uint8_t kFuIndicator = 0x1C; // F=0, NRI=0, Type=28. |
| 81 EXPECT_EQ(kFuIndicator, packet[0]) << "FUA index: " << fua_index; | 60 EXPECT_EQ(kFuIndicator, packet[0]) << "FUA index: " << fua_index; |
| 82 bool should_be_last_fua = (fua_index == expected_sizes.size() - 1); | 61 bool should_be_last_fua = (fua_index == expected_sizes.size() - 1); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 102 std::unique_ptr<uint8_t[]> frame; | 81 std::unique_ptr<uint8_t[]> frame; |
| 103 frame.reset(new uint8_t[frame_size]); | 82 frame.reset(new uint8_t[frame_size]); |
| 104 frame[0] = 0x05; // F=0, NRI=0, Type=5. | 83 frame[0] = 0x05; // F=0, NRI=0, Type=5. |
| 105 for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) { | 84 for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) { |
| 106 frame[i + kNalHeaderSize] = i; | 85 frame[i + kNalHeaderSize] = i; |
| 107 } | 86 } |
| 108 RTPFragmentationHeader fragmentation; | 87 RTPFragmentationHeader fragmentation; |
| 109 fragmentation.VerifyAndAllocateFragmentationHeader(1); | 88 fragmentation.VerifyAndAllocateFragmentationHeader(1); |
| 110 fragmentation.fragmentationOffset[0] = 0; | 89 fragmentation.fragmentationOffset[0] = 0; |
| 111 fragmentation.fragmentationLength[0] = frame_size; | 90 fragmentation.fragmentationLength[0] = frame_size; |
| 112 std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer( | 91 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( |
| 113 H264PacketizationMode::NonInterleaved, max_payload_size)); | 92 kRtpVideoH264, max_payload_size, NULL, kEmptyFrame)); |
| 114 packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation); | 93 packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation); |
| 115 | 94 |
| 116 RtpPacketToSend packet(kNoExtensions); | 95 RtpPacketToSend packet(kNoExtensions); |
| 117 ASSERT_LE(max_payload_size, packet.FreeCapacity()); | 96 ASSERT_LE(max_payload_size, packet.FreeCapacity()); |
| 118 bool last = false; | 97 bool last = false; |
| 119 size_t offset = kNalHeaderSize; | 98 size_t offset = kNalHeaderSize; |
| 120 for (size_t i = 0; i < expected_sizes.size(); ++i) { | 99 for (size_t i = 0; i < expected_sizes.size(); ++i) { |
| 121 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | 100 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 122 VerifyFua(i, frame.get(), offset, packet.payload(), expected_sizes); | 101 VerifyFua(i, frame.get(), offset, packet.payload(), expected_sizes); |
| 123 EXPECT_EQ(i == expected_sizes.size() - 1, last) << "FUA index: " << i; | 102 EXPECT_EQ(i == expected_sizes.size() - 1, last) << "FUA index: " << i; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 void VerifySingleNaluPayload(const RTPFragmentationHeader& fragmentation, | 142 void VerifySingleNaluPayload(const RTPFragmentationHeader& fragmentation, |
| 164 size_t nalu_index, | 143 size_t nalu_index, |
| 165 rtc::ArrayView<const uint8_t> frame, | 144 rtc::ArrayView<const uint8_t> frame, |
| 166 rtc::ArrayView<const uint8_t> packet) { | 145 rtc::ArrayView<const uint8_t> packet) { |
| 167 auto fragment = frame.subview(fragmentation.fragmentationOffset[nalu_index], | 146 auto fragment = frame.subview(fragmentation.fragmentationOffset[nalu_index], |
| 168 fragmentation.fragmentationLength[nalu_index]); | 147 fragmentation.fragmentationLength[nalu_index]); |
| 169 EXPECT_THAT(packet, ElementsAreArray(fragment.begin(), fragment.end())); | 148 EXPECT_THAT(packet, ElementsAreArray(fragment.begin(), fragment.end())); |
| 170 } | 149 } |
| 171 } // namespace | 150 } // namespace |
| 172 | 151 |
| 173 // Tests that should work with both packetization mode 0 and | 152 TEST(RtpPacketizerH264Test, TestSingleNalu) { |
| 174 // packetization mode 1. | |
| 175 class RtpPacketizerH264ModeTest | |
| 176 : public ::testing::TestWithParam<H264PacketizationMode> {}; | |
| 177 | |
| 178 TEST_P(RtpPacketizerH264ModeTest, TestSingleNalu) { | |
| 179 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. |
| 180 RTPFragmentationHeader fragmentation; | 154 RTPFragmentationHeader fragmentation; |
| 181 fragmentation.VerifyAndAllocateFragmentationHeader(1); | 155 fragmentation.VerifyAndAllocateFragmentationHeader(1); |
| 182 fragmentation.fragmentationOffset[0] = 0; | 156 fragmentation.fragmentationOffset[0] = 0; |
| 183 fragmentation.fragmentationLength[0] = sizeof(frame); | 157 fragmentation.fragmentationLength[0] = sizeof(frame); |
| 184 std::unique_ptr<RtpPacketizer> packetizer( | 158 std::unique_ptr<RtpPacketizer> packetizer( |
| 185 CreateH264Packetizer(GetParam(), kMaxPayloadSize)); | 159 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 186 packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation); | 160 packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation); |
| 187 RtpPacketToSend packet(kNoExtensions); | 161 RtpPacketToSend packet(kNoExtensions); |
| 188 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); | 162 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 189 bool last = false; | 163 bool last = false; |
| 190 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | 164 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 191 EXPECT_EQ(2u, packet.payload_size()); | 165 EXPECT_EQ(2u, packet.payload_size()); |
| 192 EXPECT_TRUE(last); | 166 EXPECT_TRUE(last); |
| 193 VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload()); | 167 VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload()); |
| 194 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); | 168 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 195 } | 169 } |
| 196 | 170 |
| 197 TEST_P(RtpPacketizerH264ModeTest, TestSingleNaluTwoPackets) { | 171 TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) { |
| 198 const size_t kFrameSize = kMaxPayloadSize + 100; | 172 const size_t kFrameSize = kMaxPayloadSize + 100; |
| 199 uint8_t frame[kFrameSize] = {0}; | 173 uint8_t frame[kFrameSize] = {0}; |
| 200 for (size_t i = 0; i < kFrameSize; ++i) | 174 for (size_t i = 0; i < kFrameSize; ++i) |
| 201 frame[i] = i; | 175 frame[i] = i; |
| 202 RTPFragmentationHeader fragmentation; | 176 RTPFragmentationHeader fragmentation; |
| 203 fragmentation.VerifyAndAllocateFragmentationHeader(2); | 177 fragmentation.VerifyAndAllocateFragmentationHeader(2); |
| 204 fragmentation.fragmentationOffset[0] = 0; | 178 fragmentation.fragmentationOffset[0] = 0; |
| 205 fragmentation.fragmentationLength[0] = kMaxPayloadSize; | 179 fragmentation.fragmentationLength[0] = kMaxPayloadSize; |
| 206 fragmentation.fragmentationOffset[1] = kMaxPayloadSize; | 180 fragmentation.fragmentationOffset[1] = kMaxPayloadSize; |
| 207 fragmentation.fragmentationLength[1] = 100; | 181 fragmentation.fragmentationLength[1] = 100; |
| 208 // Set NAL headers. | 182 // Set NAL headers. |
| 209 frame[fragmentation.fragmentationOffset[0]] = 0x01; | 183 frame[fragmentation.fragmentationOffset[0]] = 0x01; |
| 210 frame[fragmentation.fragmentationOffset[1]] = 0x01; | 184 frame[fragmentation.fragmentationOffset[1]] = 0x01; |
| 211 | 185 |
| 212 std::unique_ptr<RtpPacketizer> packetizer( | 186 std::unique_ptr<RtpPacketizer> packetizer( |
| 213 CreateH264Packetizer(GetParam(), kMaxPayloadSize)); | 187 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 214 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 188 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 215 | 189 |
| 216 RtpPacketToSend packet(kNoExtensions); | 190 RtpPacketToSend packet(kNoExtensions); |
| 217 bool last = false; | 191 bool last = false; |
| 218 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | 192 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 219 ASSERT_EQ(fragmentation.fragmentationOffset[1], packet.payload_size()); | 193 ASSERT_EQ(fragmentation.fragmentationOffset[1], packet.payload_size()); |
| 220 VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload()); | 194 VerifySingleNaluPayload(fragmentation, 0, frame, packet.payload()); |
| 221 | 195 |
| 222 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | 196 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 223 ASSERT_EQ(fragmentation.fragmentationLength[1], packet.payload_size()); | 197 ASSERT_EQ(fragmentation.fragmentationLength[1], packet.payload_size()); |
| 224 VerifySingleNaluPayload(fragmentation, 1, frame, packet.payload()); | 198 VerifySingleNaluPayload(fragmentation, 1, frame, packet.payload()); |
| 225 EXPECT_TRUE(last); | 199 EXPECT_TRUE(last); |
| 226 | 200 |
| 227 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); | 201 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 228 } | 202 } |
| 229 | 203 |
| 230 INSTANTIATE_TEST_CASE_P( | |
| 231 PacketMode, | |
| 232 RtpPacketizerH264ModeTest, | |
| 233 ::testing::Values(H264PacketizationMode::SingleNalUnit, | |
| 234 H264PacketizationMode::NonInterleaved)); | |
| 235 | |
| 236 TEST(RtpPacketizerH264Test, TestStapA) { | 204 TEST(RtpPacketizerH264Test, TestStapA) { |
| 237 const size_t kFrameSize = | 205 const size_t kFrameSize = |
| 238 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; | 206 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; |
| 239 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). |
| 240 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). | 208 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). |
| 241 0x05}; // F=0, NRI=0, Type=5 (IDR). | 209 0x05}; // F=0, NRI=0, Type=5 (IDR). |
| 242 const size_t kPayloadOffset = 5; | 210 const size_t kPayloadOffset = 5; |
| 243 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) | 211 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) |
| 244 frame[i + kPayloadOffset] = i; | 212 frame[i + kPayloadOffset] = i; |
| 245 RTPFragmentationHeader fragmentation; | 213 RTPFragmentationHeader fragmentation; |
| 246 CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset); | 214 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
| 247 std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer( | 215 fragmentation.fragmentationOffset[0] = 0; |
| 248 H264PacketizationMode::NonInterleaved, kMaxPayloadSize)); | 216 fragmentation.fragmentationLength[0] = 2; |
| 217 fragmentation.fragmentationOffset[1] = 2; |
| 218 fragmentation.fragmentationLength[1] = 2; |
| 219 fragmentation.fragmentationOffset[2] = 4; |
| 220 fragmentation.fragmentationLength[2] = |
| 221 kNalHeaderSize + kFrameSize - kPayloadOffset; |
| 222 std::unique_ptr<RtpPacketizer> packetizer( |
| 223 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 249 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 224 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 250 | 225 |
| 251 RtpPacketToSend packet(kNoExtensions); | 226 RtpPacketToSend packet(kNoExtensions); |
| 252 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); | 227 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 253 bool last = false; | 228 bool last = false; |
| 254 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | 229 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 255 size_t expected_packet_size = | 230 size_t expected_packet_size = |
| 256 kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize; | 231 kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize; |
| 257 ASSERT_EQ(expected_packet_size, packet.payload_size()); | 232 ASSERT_EQ(expected_packet_size, packet.payload_size()); |
| 258 EXPECT_TRUE(last); | 233 EXPECT_TRUE(last); |
| 259 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) | 234 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) |
| 260 VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload()); | 235 VerifyStapAPayload(fragmentation, 0, i, frame, packet.payload()); |
| 261 | 236 |
| 262 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); | 237 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); |
| 263 } | 238 } |
| 264 | 239 |
| 265 TEST(RtpPacketizerH264Test, TestSingleNalUnitModeHasNoStapA) { | |
| 266 // This is the same setup as for the TestStapA test. | |
| 267 const size_t kFrameSize = | |
| 268 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; | |
| 269 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS). | |
| 270 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). | |
| 271 0x05}; // F=0, NRI=0, Type=5 (IDR). | |
| 272 const size_t kPayloadOffset = 5; | |
| 273 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) | |
| 274 frame[i + kPayloadOffset] = i; | |
| 275 RTPFragmentationHeader fragmentation; | |
| 276 CreateThreeFragments(&fragmentation, kFrameSize, kPayloadOffset); | |
| 277 std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer( | |
| 278 H264PacketizationMode::SingleNalUnit, kMaxPayloadSize)); | |
| 279 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | |
| 280 | |
| 281 RtpPacketToSend packet(kNoExtensions); | |
| 282 bool last = false; | |
| 283 // The three fragments should be returned as three packets. | |
| 284 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | |
| 285 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | |
| 286 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | |
| 287 EXPECT_FALSE(packetizer->NextPacket(&packet, &last)); | |
| 288 } | |
| 289 | |
| 290 TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) { | 240 TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) { |
| 291 const size_t kFrameSize = kMaxPayloadSize - 1; | 241 const size_t kFrameSize = kMaxPayloadSize - 1; |
| 292 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. |
| 293 0x08, 0xFF, // F=0, NRI=0, Type=8. | 243 0x08, 0xFF, // F=0, NRI=0, Type=8. |
| 294 0x05}; // F=0, NRI=0, Type=5. | 244 0x05}; // F=0, NRI=0, Type=5. |
| 295 const size_t kPayloadOffset = 5; | 245 const size_t kPayloadOffset = 5; |
| 296 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) | 246 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) |
| 297 frame[i + kPayloadOffset] = i; | 247 frame[i + kPayloadOffset] = i; |
| 298 RTPFragmentationHeader fragmentation; | 248 RTPFragmentationHeader fragmentation; |
| 299 fragmentation.VerifyAndAllocateFragmentationHeader(3); | 249 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
| 300 fragmentation.fragmentationOffset[0] = 0; | 250 fragmentation.fragmentationOffset[0] = 0; |
| 301 fragmentation.fragmentationLength[0] = 2; | 251 fragmentation.fragmentationLength[0] = 2; |
| 302 fragmentation.fragmentationOffset[1] = 2; | 252 fragmentation.fragmentationOffset[1] = 2; |
| 303 fragmentation.fragmentationLength[1] = 2; | 253 fragmentation.fragmentationLength[1] = 2; |
| 304 fragmentation.fragmentationOffset[2] = 4; | 254 fragmentation.fragmentationOffset[2] = 4; |
| 305 fragmentation.fragmentationLength[2] = | 255 fragmentation.fragmentationLength[2] = |
| 306 kNalHeaderSize + kFrameSize - kPayloadOffset; | 256 kNalHeaderSize + kFrameSize - kPayloadOffset; |
| 307 std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer( | 257 std::unique_ptr<RtpPacketizer> packetizer( |
| 308 H264PacketizationMode::NonInterleaved, kMaxPayloadSize)); | 258 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 309 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 259 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 310 | 260 |
| 311 RtpPacketToSend packet(kNoExtensions); | 261 RtpPacketToSend packet(kNoExtensions); |
| 312 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); | 262 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 313 bool last = false; | 263 bool last = false; |
| 314 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); | 264 ASSERT_TRUE(packetizer->NextPacket(&packet, &last)); |
| 315 size_t expected_packet_size = kNalHeaderSize; | 265 size_t expected_packet_size = kNalHeaderSize; |
| 316 for (size_t i = 0; i < 2; ++i) { | 266 for (size_t i = 0; i < 2; ++i) { |
| 317 expected_packet_size += | 267 expected_packet_size += |
| 318 kLengthFieldLength + fragmentation.fragmentationLength[i]; | 268 kLengthFieldLength + fragmentation.fragmentationLength[i]; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 345 const size_t kFrameSize = kFuaNaluSize + 2 * kStapANaluSize; | 295 const size_t kFrameSize = kFuaNaluSize + 2 * kStapANaluSize; |
| 346 uint8_t frame[kFrameSize]; | 296 uint8_t frame[kFrameSize]; |
| 347 size_t nalu_offset = 0; | 297 size_t nalu_offset = 0; |
| 348 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) { | 298 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) { |
| 349 nalu_offset = fragmentation.fragmentationOffset[i]; | 299 nalu_offset = fragmentation.fragmentationOffset[i]; |
| 350 frame[nalu_offset] = 0x05; // F=0, NRI=0, Type=5. | 300 frame[nalu_offset] = 0x05; // F=0, NRI=0, Type=5. |
| 351 for (size_t j = 1; j < fragmentation.fragmentationLength[i]; ++j) { | 301 for (size_t j = 1; j < fragmentation.fragmentationLength[i]; ++j) { |
| 352 frame[nalu_offset + j] = i + j; | 302 frame[nalu_offset + j] = i + j; |
| 353 } | 303 } |
| 354 } | 304 } |
| 355 std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer( | 305 std::unique_ptr<RtpPacketizer> packetizer( |
| 356 H264PacketizationMode::NonInterleaved, kMaxPayloadSize)); | 306 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); |
| 357 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 307 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 358 | 308 |
| 359 // First expecting two FU-A packets. | 309 // First expecting two FU-A packets. |
| 360 std::vector<size_t> fua_sizes; | 310 std::vector<size_t> fua_sizes; |
| 361 fua_sizes.push_back(1100); | 311 fua_sizes.push_back(1100); |
| 362 fua_sizes.push_back(1099); | 312 fua_sizes.push_back(1099); |
| 363 RtpPacketToSend packet(kNoExtensions); | 313 RtpPacketToSend packet(kNoExtensions); |
| 364 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); | 314 ASSERT_LE(kMaxPayloadSize, packet.FreeCapacity()); |
| 365 bool last = false; | 315 bool last = false; |
| 366 int fua_offset = kNalHeaderSize; | 316 int fua_offset = kNalHeaderSize; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 // Generate 10 full sized packets, leave room for FU-A headers minus the NALU | 369 // Generate 10 full sized packets, leave room for FU-A headers minus the NALU |
| 420 // header. | 370 // header. |
| 421 TestFua( | 371 TestFua( |
| 422 10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize, | 372 10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize, |
| 423 kMaxPayloadSize, | 373 kMaxPayloadSize, |
| 424 std::vector<size_t>(kExpectedPayloadSizes, | 374 std::vector<size_t>(kExpectedPayloadSizes, |
| 425 kExpectedPayloadSizes + | 375 kExpectedPayloadSizes + |
| 426 sizeof(kExpectedPayloadSizes) / sizeof(size_t))); | 376 sizeof(kExpectedPayloadSizes) / sizeof(size_t))); |
| 427 } | 377 } |
| 428 | 378 |
| 429 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
| 430 | |
| 431 TEST(RtpPacketizerH264DeathTest, SendOverlongDataInPacketizationMode0) { | |
| 432 const size_t kFrameSize = kMaxPayloadSize + 1; | |
| 433 uint8_t frame[kFrameSize] = {0}; | |
| 434 for (size_t i = 0; i < kFrameSize; ++i) | |
| 435 frame[i] = i; | |
| 436 RTPFragmentationHeader fragmentation; | |
| 437 fragmentation.VerifyAndAllocateFragmentationHeader(1); | |
| 438 fragmentation.fragmentationOffset[0] = 0; | |
| 439 fragmentation.fragmentationLength[0] = kFrameSize; | |
| 440 // Set NAL headers. | |
| 441 frame[fragmentation.fragmentationOffset[0]] = 0x01; | |
| 442 | |
| 443 std::unique_ptr<RtpPacketizer> packetizer(CreateH264Packetizer( | |
| 444 H264PacketizationMode::SingleNalUnit, kMaxPayloadSize)); | |
| 445 EXPECT_DEATH(packetizer->SetPayloadData(frame, kFrameSize, &fragmentation), | |
| 446 "payload_size"); | |
| 447 } | |
| 448 | |
| 449 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
| 450 | |
| 451 namespace { | 379 namespace { |
| 452 const uint8_t kStartSequence[] = {0x00, 0x00, 0x00, 0x01}; | 380 const uint8_t kStartSequence[] = {0x00, 0x00, 0x00, 0x01}; |
| 453 const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, | 381 const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, |
| 454 0xF4, 0x05, 0x03, 0xC7, 0xC0}; | 382 0xF4, 0x05, 0x03, 0xC7, 0xC0}; |
| 455 const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03, | 383 const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03, |
| 456 0xC7, 0xE0, 0x1B, 0x41, 0x10, 0x8D, 0x00}; | 384 0xC7, 0xE0, 0x1B, 0x41, 0x10, 0x8D, 0x00}; |
| 457 const uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04}; | 385 const uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04}; |
| 458 const uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11}; | 386 const uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11}; |
| 459 } | 387 } |
| 460 | 388 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 481 protected: | 409 protected: |
| 482 rtc::Buffer in_buffer_; | 410 rtc::Buffer in_buffer_; |
| 483 RTPFragmentationHeader fragmentation_header_; | 411 RTPFragmentationHeader fragmentation_header_; |
| 484 std::unique_ptr<RtpPacketizer> packetizer_; | 412 std::unique_ptr<RtpPacketizer> packetizer_; |
| 485 }; | 413 }; |
| 486 | 414 |
| 487 TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) { | 415 TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) { |
| 488 const size_t kHeaderOverhead = kFuAHeaderSize + 1; | 416 const size_t kHeaderOverhead = kFuAHeaderSize + 1; |
| 489 | 417 |
| 490 // Set size to fragment SPS into two FU-A packets. | 418 // Set size to fragment SPS into two FU-A packets. |
| 491 packetizer_.reset( | 419 packetizer_.reset(RtpPacketizer::Create( |
| 492 CreateH264Packetizer(H264PacketizationMode::NonInterleaved, | 420 kRtpVideoH264, sizeof(kOriginalSps) - 2 + kHeaderOverhead, nullptr, |
| 493 sizeof(kOriginalSps) - 2 + kHeaderOverhead)); | 421 kEmptyFrame)); |
| 494 | 422 |
| 495 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), | 423 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), |
| 496 &fragmentation_header_); | 424 &fragmentation_header_); |
| 497 | 425 |
| 498 bool last_packet = true; | 426 bool last_packet = true; |
| 499 RtpPacketToSend packet(kNoExtensions); | 427 RtpPacketToSend packet(kNoExtensions); |
| 500 ASSERT_LE(sizeof(kOriginalSps) + kHeaderOverhead, packet.FreeCapacity()); | 428 ASSERT_LE(sizeof(kOriginalSps) + kHeaderOverhead, packet.FreeCapacity()); |
| 501 | 429 |
| 502 EXPECT_TRUE(packetizer_->NextPacket(&packet, &last_packet)); | 430 EXPECT_TRUE(packetizer_->NextPacket(&packet, &last_packet)); |
| 503 size_t offset = H264::kNaluTypeSize; | 431 size_t offset = H264::kNaluTypeSize; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 515 EXPECT_EQ(offset, sizeof(kRewrittenSps)); | 443 EXPECT_EQ(offset, sizeof(kRewrittenSps)); |
| 516 } | 444 } |
| 517 | 445 |
| 518 TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) { | 446 TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) { |
| 519 const size_t kHeaderOverhead = kFuAHeaderSize + 1; | 447 const size_t kHeaderOverhead = kFuAHeaderSize + 1; |
| 520 const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type. | 448 const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type. |
| 521 sizeof(kRewrittenSps) + sizeof(kIdrOne) + | 449 sizeof(kRewrittenSps) + sizeof(kIdrOne) + |
| 522 sizeof(kIdrTwo) + (kLengthFieldLength * 3); | 450 sizeof(kIdrTwo) + (kLengthFieldLength * 3); |
| 523 | 451 |
| 524 // 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. |
| 525 packetizer_.reset(CreateH264Packetizer(H264PacketizationMode::NonInterleaved, | 453 packetizer_.reset(RtpPacketizer::Create(kRtpVideoH264, |
| 526 kExpectedTotalSize + kHeaderOverhead)); | 454 kExpectedTotalSize + kHeaderOverhead, |
| 455 nullptr, kEmptyFrame)); |
| 527 | 456 |
| 528 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), | 457 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), |
| 529 &fragmentation_header_); | 458 &fragmentation_header_); |
| 530 | 459 |
| 531 bool last_packet = true; | 460 bool last_packet = true; |
| 532 RtpPacketToSend packet(kNoExtensions); | 461 RtpPacketToSend packet(kNoExtensions); |
| 533 ASSERT_LE(kExpectedTotalSize + kHeaderOverhead, packet.FreeCapacity()); | 462 ASSERT_LE(kExpectedTotalSize + kHeaderOverhead, packet.FreeCapacity()); |
| 534 | 463 |
| 535 EXPECT_TRUE(packetizer_->NextPacket(&packet, &last_packet)); | 464 EXPECT_TRUE(packetizer_->NextPacket(&packet, &last_packet)); |
| 536 EXPECT_EQ(kExpectedTotalSize, packet.payload_size()); | 465 EXPECT_EQ(kExpectedTotalSize, packet.payload_size()); |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 const RTPVideoHeaderH264& h264 = payload.type.Video.codecHeader.H264; | 818 const RTPVideoHeaderH264& h264 = payload.type.Video.codecHeader.H264; |
| 890 EXPECT_EQ(kH264SingleNalu, h264.packetization_type); | 819 EXPECT_EQ(kH264SingleNalu, h264.packetization_type); |
| 891 EXPECT_EQ(kSei, h264.nalu_type); | 820 EXPECT_EQ(kSei, h264.nalu_type); |
| 892 ASSERT_EQ(1u, h264.nalus_length); | 821 ASSERT_EQ(1u, h264.nalus_length); |
| 893 EXPECT_EQ(static_cast<H264::NaluType>(kSei), h264.nalus[0].type); | 822 EXPECT_EQ(static_cast<H264::NaluType>(kSei), h264.nalus[0].type); |
| 894 EXPECT_EQ(-1, h264.nalus[0].sps_id); | 823 EXPECT_EQ(-1, h264.nalus[0].sps_id); |
| 895 EXPECT_EQ(-1, h264.nalus[0].pps_id); | 824 EXPECT_EQ(-1, h264.nalus[0].pps_id); |
| 896 } | 825 } |
| 897 | 826 |
| 898 } // namespace webrtc | 827 } // namespace webrtc |
| OLD | NEW |