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 25 matching lines...) Expand all Loading... |
36 | 36 |
37 static const size_t kNalHeaderSize = 1; | 37 static const size_t kNalHeaderSize = 1; |
38 static const size_t kFuAHeaderSize = 2; | 38 static const size_t kFuAHeaderSize = 2; |
39 | 39 |
40 // Bit masks for FU (A and B) indicators. | 40 // Bit masks for FU (A and B) indicators. |
41 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F }; | 41 enum NalDefs { kFBit = 0x80, kNriMask = 0x60, kTypeMask = 0x1F }; |
42 | 42 |
43 // Bit masks for FU (A and B) headers. | 43 // Bit masks for FU (A and B) headers. |
44 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 }; | 44 enum FuDefs { kSBit = 0x80, kEBit = 0x40, kRBit = 0x20 }; |
45 | 45 |
| 46 RtpPacketizer* CreateH264Packetizer(H264PacketizationMode mode, |
| 47 size_t max_payload_size) { |
| 48 RTPVideoTypeHeader type_header; |
| 49 type_header.H264.packetization_mode = mode; |
| 50 return RtpPacketizer::Create(kRtpVideoH264, max_payload_size, &type_header, |
| 51 kEmptyFrame); |
| 52 } |
| 53 |
46 void VerifyFua(size_t fua_index, | 54 void VerifyFua(size_t fua_index, |
47 const uint8_t* expected_payload, | 55 const uint8_t* expected_payload, |
48 int offset, | 56 int offset, |
49 const uint8_t* packet, | 57 const uint8_t* packet, |
50 size_t length, | 58 size_t length, |
51 const std::vector<size_t>& expected_sizes) { | 59 const std::vector<size_t>& expected_sizes) { |
52 ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, length) | 60 ASSERT_EQ(expected_sizes[fua_index] + kFuAHeaderSize, length) |
53 << "FUA index: " << fua_index; | 61 << "FUA index: " << fua_index; |
54 const uint8_t kFuIndicator = 0x1C; // F=0, NRI=0, Type=28. | 62 const uint8_t kFuIndicator = 0x1C; // F=0, NRI=0, Type=28. |
55 EXPECT_EQ(kFuIndicator, packet[0]) << "FUA index: " << fua_index; | 63 EXPECT_EQ(kFuIndicator, packet[0]) << "FUA index: " << fua_index; |
(...skipping 21 matching lines...) Expand all Loading... |
77 std::unique_ptr<uint8_t[]> frame; | 85 std::unique_ptr<uint8_t[]> frame; |
78 frame.reset(new uint8_t[frame_size]); | 86 frame.reset(new uint8_t[frame_size]); |
79 frame[0] = 0x05; // F=0, NRI=0, Type=5. | 87 frame[0] = 0x05; // F=0, NRI=0, Type=5. |
80 for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) { | 88 for (size_t i = 0; i < frame_size - kNalHeaderSize; ++i) { |
81 frame[i + kNalHeaderSize] = i; | 89 frame[i + kNalHeaderSize] = i; |
82 } | 90 } |
83 RTPFragmentationHeader fragmentation; | 91 RTPFragmentationHeader fragmentation; |
84 fragmentation.VerifyAndAllocateFragmentationHeader(1); | 92 fragmentation.VerifyAndAllocateFragmentationHeader(1); |
85 fragmentation.fragmentationOffset[0] = 0; | 93 fragmentation.fragmentationOffset[0] = 0; |
86 fragmentation.fragmentationLength[0] = frame_size; | 94 fragmentation.fragmentationLength[0] = frame_size; |
87 std::unique_ptr<RtpPacketizer> packetizer(RtpPacketizer::Create( | 95 std::unique_ptr<RtpPacketizer> packetizer( |
88 kRtpVideoH264, max_payload_size, NULL, kEmptyFrame)); | 96 CreateH264Packetizer(kH264PacketizationMode1, max_payload_size)); |
89 packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation); | 97 packetizer->SetPayloadData(frame.get(), frame_size, &fragmentation); |
90 | 98 |
91 std::unique_ptr<uint8_t[]> packet(new uint8_t[max_payload_size]); | 99 std::unique_ptr<uint8_t[]> packet(new uint8_t[max_payload_size]); |
92 size_t length = 0; | 100 size_t length = 0; |
93 bool last = false; | 101 bool last = false; |
94 size_t offset = kNalHeaderSize; | 102 size_t offset = kNalHeaderSize; |
95 for (size_t i = 0; i < expected_sizes.size(); ++i) { | 103 for (size_t i = 0; i < expected_sizes.size(); ++i) { |
96 ASSERT_TRUE(packetizer->NextPacket(packet.get(), &length, &last)); | 104 ASSERT_TRUE(packetizer->NextPacket(packet.get(), &length, &last)); |
97 VerifyFua(i, frame.get(), offset, packet.get(), length, expected_sizes); | 105 VerifyFua(i, frame.get(), offset, packet.get(), length, expected_sizes); |
98 EXPECT_EQ(i == expected_sizes.size() - 1, last) << "FUA index: " << i; | 106 EXPECT_EQ(i == expected_sizes.size() - 1, last) << "FUA index: " << i; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 size_t packet_length) { | 153 size_t packet_length) { |
146 std::vector<uint8_t> expected_payload_vector( | 154 std::vector<uint8_t> expected_payload_vector( |
147 &frame[fragmentation.fragmentationOffset[nalu_index]], | 155 &frame[fragmentation.fragmentationOffset[nalu_index]], |
148 &frame[fragmentation.fragmentationOffset[nalu_index] + | 156 &frame[fragmentation.fragmentationOffset[nalu_index] + |
149 fragmentation.fragmentationLength[nalu_index]]); | 157 fragmentation.fragmentationLength[nalu_index]]); |
150 EXPECT_THAT(expected_payload_vector, | 158 EXPECT_THAT(expected_payload_vector, |
151 ::testing::ElementsAreArray(packet, packet_length)); | 159 ::testing::ElementsAreArray(packet, packet_length)); |
152 } | 160 } |
153 } // namespace | 161 } // namespace |
154 | 162 |
155 TEST(RtpPacketizerH264Test, TestSingleNalu) { | 163 TEST(RtpPacketizerH264Test, TestStapA) { |
156 const uint8_t frame[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5. | 164 const size_t kFrameSize = |
| 165 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; |
| 166 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS). |
| 167 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). |
| 168 0x05}; // F=0, NRI=0, Type=5 (IDR). |
| 169 const size_t kPayloadOffset = 5; |
| 170 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) |
| 171 frame[i + kPayloadOffset] = i; |
157 RTPFragmentationHeader fragmentation; | 172 RTPFragmentationHeader fragmentation; |
158 fragmentation.VerifyAndAllocateFragmentationHeader(1); | 173 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
159 fragmentation.fragmentationOffset[0] = 0; | 174 fragmentation.fragmentationOffset[0] = 0; |
160 fragmentation.fragmentationLength[0] = sizeof(frame); | 175 fragmentation.fragmentationLength[0] = 2; |
| 176 fragmentation.fragmentationOffset[1] = 2; |
| 177 fragmentation.fragmentationLength[1] = 2; |
| 178 fragmentation.fragmentationOffset[2] = 4; |
| 179 fragmentation.fragmentationLength[2] = |
| 180 kNalHeaderSize + kFrameSize - kPayloadOffset; |
161 std::unique_ptr<RtpPacketizer> packetizer( | 181 std::unique_ptr<RtpPacketizer> packetizer( |
162 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 182 CreateH264Packetizer(kH264PacketizationMode1, kMaxPayloadSize)); |
163 packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation); | |
164 uint8_t packet[kMaxPayloadSize] = {0}; | |
165 size_t length = 0; | |
166 bool last = false; | |
167 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | |
168 EXPECT_EQ(2u, length); | |
169 EXPECT_TRUE(last); | |
170 VerifySingleNaluPayload( | |
171 fragmentation, 0, frame, sizeof(frame), packet, length); | |
172 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | |
173 } | |
174 | |
175 TEST(RtpPacketizerH264Test, TestSingleNaluTwoPackets) { | |
176 const size_t kFrameSize = kMaxPayloadSize + 100; | |
177 uint8_t frame[kFrameSize] = {0}; | |
178 for (size_t i = 0; i < kFrameSize; ++i) | |
179 frame[i] = i; | |
180 RTPFragmentationHeader fragmentation; | |
181 fragmentation.VerifyAndAllocateFragmentationHeader(2); | |
182 fragmentation.fragmentationOffset[0] = 0; | |
183 fragmentation.fragmentationLength[0] = kMaxPayloadSize; | |
184 fragmentation.fragmentationOffset[1] = kMaxPayloadSize; | |
185 fragmentation.fragmentationLength[1] = 100; | |
186 // Set NAL headers. | |
187 frame[fragmentation.fragmentationOffset[0]] = 0x01; | |
188 frame[fragmentation.fragmentationOffset[1]] = 0x01; | |
189 | |
190 std::unique_ptr<RtpPacketizer> packetizer( | |
191 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | |
192 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 183 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
193 | 184 |
194 uint8_t packet[kMaxPayloadSize] = {0}; | 185 uint8_t packet[kMaxPayloadSize] = {0}; |
195 size_t length = 0; | 186 size_t length = 0; |
196 bool last = false; | 187 bool last = false; |
197 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 188 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
198 ASSERT_EQ(fragmentation.fragmentationOffset[1], length); | 189 size_t expected_packet_size = |
199 VerifySingleNaluPayload(fragmentation, 0, frame, kFrameSize, packet, length); | 190 kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize; |
200 | 191 ASSERT_EQ(expected_packet_size, length); |
201 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | |
202 ASSERT_EQ(fragmentation.fragmentationLength[1], length); | |
203 VerifySingleNaluPayload(fragmentation, 1, frame, kFrameSize, packet, length); | |
204 EXPECT_TRUE(last); | 192 EXPECT_TRUE(last); |
| 193 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) |
| 194 VerifyStapAPayload(fragmentation, 0, i, frame, kFrameSize, packet, length); |
205 | 195 |
206 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | 196 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); |
207 } | 197 } |
208 | 198 |
209 TEST(RtpPacketizerH264Test, TestStapA) { | 199 TEST(RtpPacketizerH264Test, TestMode0HasNoStapA) { |
| 200 // This is the same setup as for the TestStapA test. |
210 const size_t kFrameSize = | 201 const size_t kFrameSize = |
211 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; | 202 kMaxPayloadSize - 3 * kLengthFieldLength - kNalHeaderSize; |
212 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS). | 203 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7 (SPS). |
213 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). | 204 0x08, 0xFF, // F=0, NRI=0, Type=8 (PPS). |
214 0x05}; // F=0, NRI=0, Type=5 (IDR). | 205 0x05}; // F=0, NRI=0, Type=5 (IDR). |
215 const size_t kPayloadOffset = 5; | 206 const size_t kPayloadOffset = 5; |
216 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) | 207 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) |
217 frame[i + kPayloadOffset] = i; | 208 frame[i + kPayloadOffset] = i; |
218 RTPFragmentationHeader fragmentation; | 209 RTPFragmentationHeader fragmentation; |
219 fragmentation.VerifyAndAllocateFragmentationHeader(3); | 210 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
220 fragmentation.fragmentationOffset[0] = 0; | 211 fragmentation.fragmentationOffset[0] = 0; |
221 fragmentation.fragmentationLength[0] = 2; | 212 fragmentation.fragmentationLength[0] = 2; |
222 fragmentation.fragmentationOffset[1] = 2; | 213 fragmentation.fragmentationOffset[1] = 2; |
223 fragmentation.fragmentationLength[1] = 2; | 214 fragmentation.fragmentationLength[1] = 2; |
224 fragmentation.fragmentationOffset[2] = 4; | 215 fragmentation.fragmentationOffset[2] = 4; |
225 fragmentation.fragmentationLength[2] = | 216 fragmentation.fragmentationLength[2] = |
226 kNalHeaderSize + kFrameSize - kPayloadOffset; | 217 kNalHeaderSize + kFrameSize - kPayloadOffset; |
227 std::unique_ptr<RtpPacketizer> packetizer( | 218 std::unique_ptr<RtpPacketizer> packetizer( |
228 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 219 CreateH264Packetizer(kH264PacketizationMode0, kMaxPayloadSize)); |
229 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 220 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
230 | 221 |
231 uint8_t packet[kMaxPayloadSize] = {0}; | 222 uint8_t packet[kMaxPayloadSize] = {0}; |
232 size_t length = 0; | 223 size_t length = 0; |
233 bool last = false; | 224 bool last = false; |
| 225 // The three fragments should be returned as three packets. |
234 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 226 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
235 size_t expected_packet_size = | 227 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
236 kNalHeaderSize + 3 * kLengthFieldLength + kFrameSize; | 228 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
237 ASSERT_EQ(expected_packet_size, length); | |
238 EXPECT_TRUE(last); | |
239 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) | |
240 VerifyStapAPayload(fragmentation, 0, i, frame, kFrameSize, packet, length); | |
241 | |
242 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); | 229 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); |
243 } | 230 } |
244 | 231 |
245 TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) { | 232 TEST(RtpPacketizerH264Test, TestTooSmallForStapAHeaders) { |
246 const size_t kFrameSize = kMaxPayloadSize - 1; | 233 const size_t kFrameSize = kMaxPayloadSize - 1; |
247 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7. | 234 uint8_t frame[kFrameSize] = {0x07, 0xFF, // F=0, NRI=0, Type=7. |
248 0x08, 0xFF, // F=0, NRI=0, Type=8. | 235 0x08, 0xFF, // F=0, NRI=0, Type=8. |
249 0x05}; // F=0, NRI=0, Type=5. | 236 0x05}; // F=0, NRI=0, Type=5. |
250 const size_t kPayloadOffset = 5; | 237 const size_t kPayloadOffset = 5; |
251 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) | 238 for (size_t i = 0; i < kFrameSize - kPayloadOffset; ++i) |
252 frame[i + kPayloadOffset] = i; | 239 frame[i + kPayloadOffset] = i; |
253 RTPFragmentationHeader fragmentation; | 240 RTPFragmentationHeader fragmentation; |
254 fragmentation.VerifyAndAllocateFragmentationHeader(3); | 241 fragmentation.VerifyAndAllocateFragmentationHeader(3); |
255 fragmentation.fragmentationOffset[0] = 0; | 242 fragmentation.fragmentationOffset[0] = 0; |
256 fragmentation.fragmentationLength[0] = 2; | 243 fragmentation.fragmentationLength[0] = 2; |
257 fragmentation.fragmentationOffset[1] = 2; | 244 fragmentation.fragmentationOffset[1] = 2; |
258 fragmentation.fragmentationLength[1] = 2; | 245 fragmentation.fragmentationLength[1] = 2; |
259 fragmentation.fragmentationOffset[2] = 4; | 246 fragmentation.fragmentationOffset[2] = 4; |
260 fragmentation.fragmentationLength[2] = | 247 fragmentation.fragmentationLength[2] = |
261 kNalHeaderSize + kFrameSize - kPayloadOffset; | 248 kNalHeaderSize + kFrameSize - kPayloadOffset; |
262 std::unique_ptr<RtpPacketizer> packetizer( | 249 std::unique_ptr<RtpPacketizer> packetizer( |
263 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 250 CreateH264Packetizer(kH264PacketizationMode1, kMaxPayloadSize)); |
264 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 251 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
265 | 252 |
266 uint8_t packet[kMaxPayloadSize] = {0}; | 253 uint8_t packet[kMaxPayloadSize] = {0}; |
267 size_t length = 0; | 254 size_t length = 0; |
268 bool last = false; | 255 bool last = false; |
269 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); | 256 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
270 size_t expected_packet_size = kNalHeaderSize; | 257 size_t expected_packet_size = kNalHeaderSize; |
271 for (size_t i = 0; i < 2; ++i) { | 258 for (size_t i = 0; i < 2; ++i) { |
272 expected_packet_size += | 259 expected_packet_size += |
273 kLengthFieldLength + fragmentation.fragmentationLength[i]; | 260 kLengthFieldLength + fragmentation.fragmentationLength[i]; |
(...skipping 27 matching lines...) Expand all Loading... |
301 uint8_t frame[kFrameSize]; | 288 uint8_t frame[kFrameSize]; |
302 size_t nalu_offset = 0; | 289 size_t nalu_offset = 0; |
303 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) { | 290 for (size_t i = 0; i < fragmentation.fragmentationVectorSize; ++i) { |
304 nalu_offset = fragmentation.fragmentationOffset[i]; | 291 nalu_offset = fragmentation.fragmentationOffset[i]; |
305 frame[nalu_offset] = 0x05; // F=0, NRI=0, Type=5. | 292 frame[nalu_offset] = 0x05; // F=0, NRI=0, Type=5. |
306 for (size_t j = 1; j < fragmentation.fragmentationLength[i]; ++j) { | 293 for (size_t j = 1; j < fragmentation.fragmentationLength[i]; ++j) { |
307 frame[nalu_offset + j] = i + j; | 294 frame[nalu_offset + j] = i + j; |
308 } | 295 } |
309 } | 296 } |
310 std::unique_ptr<RtpPacketizer> packetizer( | 297 std::unique_ptr<RtpPacketizer> packetizer( |
311 RtpPacketizer::Create(kRtpVideoH264, kMaxPayloadSize, NULL, kEmptyFrame)); | 298 CreateH264Packetizer(kH264PacketizationMode1, kMaxPayloadSize)); |
312 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); | 299 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
313 | 300 |
314 // First expecting two FU-A packets. | 301 // First expecting two FU-A packets. |
315 std::vector<size_t> fua_sizes; | 302 std::vector<size_t> fua_sizes; |
316 fua_sizes.push_back(1100); | 303 fua_sizes.push_back(1100); |
317 fua_sizes.push_back(1099); | 304 fua_sizes.push_back(1099); |
318 uint8_t packet[kMaxPayloadSize] = {0}; | 305 uint8_t packet[kMaxPayloadSize] = {0}; |
319 size_t length = 0; | 306 size_t length = 0; |
320 bool last = false; | 307 bool last = false; |
321 int fua_offset = kNalHeaderSize; | 308 int fua_offset = kNalHeaderSize; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 // Generate 10 full sized packets, leave room for FU-A headers minus the NALU | 361 // Generate 10 full sized packets, leave room for FU-A headers minus the NALU |
375 // header. | 362 // header. |
376 TestFua( | 363 TestFua( |
377 10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize, | 364 10 * (kMaxPayloadSize - kFuAHeaderSize) + kNalHeaderSize, |
378 kMaxPayloadSize, | 365 kMaxPayloadSize, |
379 std::vector<size_t>(kExpectedPayloadSizes, | 366 std::vector<size_t>(kExpectedPayloadSizes, |
380 kExpectedPayloadSizes + | 367 kExpectedPayloadSizes + |
381 sizeof(kExpectedPayloadSizes) / sizeof(size_t))); | 368 sizeof(kExpectedPayloadSizes) / sizeof(size_t))); |
382 } | 369 } |
383 | 370 |
| 371 // Tests that should work with both packetization mode 0 and |
| 372 // packetization mode 1. |
| 373 class RtpPacketizerH264ModeTest |
| 374 : public ::testing::TestWithParam<H264PacketizationMode> {}; |
| 375 |
| 376 TEST_P(RtpPacketizerH264ModeTest, TestSingleNalu) { |
| 377 const uint8_t frame[2] = {0x05, 0xFF}; // F=0, NRI=0, Type=5. |
| 378 RTPFragmentationHeader fragmentation; |
| 379 fragmentation.VerifyAndAllocateFragmentationHeader(1); |
| 380 fragmentation.fragmentationOffset[0] = 0; |
| 381 fragmentation.fragmentationLength[0] = sizeof(frame); |
| 382 std::unique_ptr<RtpPacketizer> packetizer( |
| 383 CreateH264Packetizer(GetParam(), kMaxPayloadSize)); |
| 384 packetizer->SetPayloadData(frame, sizeof(frame), &fragmentation); |
| 385 uint8_t packet[kMaxPayloadSize] = {0}; |
| 386 size_t length = 0; |
| 387 bool last = false; |
| 388 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
| 389 EXPECT_EQ(2u, length); |
| 390 EXPECT_TRUE(last); |
| 391 VerifySingleNaluPayload(fragmentation, 0, frame, sizeof(frame), packet, |
| 392 length); |
| 393 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); |
| 394 } |
| 395 |
| 396 TEST_P(RtpPacketizerH264ModeTest, TestSingleNaluTwoPackets) { |
| 397 const size_t kFrameSize = kMaxPayloadSize + 100; |
| 398 uint8_t frame[kFrameSize] = {0}; |
| 399 for (size_t i = 0; i < kFrameSize; ++i) |
| 400 frame[i] = i; |
| 401 RTPFragmentationHeader fragmentation; |
| 402 fragmentation.VerifyAndAllocateFragmentationHeader(2); |
| 403 fragmentation.fragmentationOffset[0] = 0; |
| 404 fragmentation.fragmentationLength[0] = kMaxPayloadSize; |
| 405 fragmentation.fragmentationOffset[1] = kMaxPayloadSize; |
| 406 fragmentation.fragmentationLength[1] = 100; |
| 407 // Set NAL headers. |
| 408 frame[fragmentation.fragmentationOffset[0]] = 0x01; |
| 409 frame[fragmentation.fragmentationOffset[1]] = 0x01; |
| 410 |
| 411 std::unique_ptr<RtpPacketizer> packetizer( |
| 412 CreateH264Packetizer(GetParam(), kMaxPayloadSize)); |
| 413 packetizer->SetPayloadData(frame, kFrameSize, &fragmentation); |
| 414 |
| 415 uint8_t packet[kMaxPayloadSize] = {0}; |
| 416 size_t length = 0; |
| 417 bool last = false; |
| 418 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
| 419 ASSERT_EQ(fragmentation.fragmentationOffset[1], length); |
| 420 VerifySingleNaluPayload(fragmentation, 0, frame, kFrameSize, packet, length); |
| 421 |
| 422 ASSERT_TRUE(packetizer->NextPacket(packet, &length, &last)); |
| 423 ASSERT_EQ(fragmentation.fragmentationLength[1], length); |
| 424 VerifySingleNaluPayload(fragmentation, 1, frame, kFrameSize, packet, length); |
| 425 EXPECT_TRUE(last); |
| 426 |
| 427 EXPECT_FALSE(packetizer->NextPacket(packet, &length, &last)); |
| 428 } |
| 429 |
| 430 INSTANTIATE_TEST_CASE_P(PacketMode, |
| 431 RtpPacketizerH264ModeTest, |
| 432 ::testing::Values(kH264PacketizationMode0, |
| 433 kH264PacketizationMode1)); |
| 434 |
| 435 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
| 436 |
| 437 TEST(RtpPacketizerH264DeathTest, SendOverlongDataInPacketizationMode0) { |
| 438 const size_t kFrameSize = kMaxPayloadSize + 100; |
| 439 uint8_t frame[kFrameSize] = {0}; |
| 440 for (size_t i = 0; i < kFrameSize; ++i) |
| 441 frame[i] = i; |
| 442 RTPFragmentationHeader fragmentation; |
| 443 fragmentation.VerifyAndAllocateFragmentationHeader(1); |
| 444 fragmentation.fragmentationOffset[0] = 0; |
| 445 fragmentation.fragmentationLength[0] = kFrameSize; |
| 446 // Set NAL headers. |
| 447 frame[fragmentation.fragmentationOffset[0]] = 0x01; |
| 448 |
| 449 std::unique_ptr<RtpPacketizer> packetizer( |
| 450 CreateH264Packetizer(kH264PacketizationMode0, kMaxPayloadSize)); |
| 451 EXPECT_DEATH(packetizer->SetPayloadData(frame, kFrameSize, &fragmentation), |
| 452 "payload_size"); |
| 453 } |
| 454 |
| 455 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
| 456 |
384 namespace { | 457 namespace { |
385 const uint8_t kStartSequence[] = {0x00, 0x00, 0x00, 0x01}; | 458 const uint8_t kStartSequence[] = {0x00, 0x00, 0x00, 0x01}; |
386 const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, | 459 const uint8_t kOriginalSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, |
387 0xF4, 0x05, 0x03, 0xC7, 0xC0}; | 460 0xF4, 0x05, 0x03, 0xC7, 0xC0}; |
388 const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03, | 461 const uint8_t kRewrittenSps[] = {kSps, 0x00, 0x00, 0x03, 0x03, 0xF4, 0x05, 0x03, |
389 0xC7, 0xE0, 0x1B, 0x41, 0x10, 0x8D, 0x00}; | 462 0xC7, 0xE0, 0x1B, 0x41, 0x10, 0x8D, 0x00}; |
390 const uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04}; | 463 const uint8_t kIdrOne[] = {kIdr, 0xFF, 0x00, 0x00, 0x04}; |
391 const uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11}; | 464 const uint8_t kIdrTwo[] = {kIdr, 0xFF, 0x00, 0x11}; |
392 } | 465 } |
393 | 466 |
(...skipping 20 matching lines...) Expand all Loading... |
414 protected: | 487 protected: |
415 rtc::Buffer in_buffer_; | 488 rtc::Buffer in_buffer_; |
416 RTPFragmentationHeader fragmentation_header_; | 489 RTPFragmentationHeader fragmentation_header_; |
417 std::unique_ptr<RtpPacketizer> packetizer_; | 490 std::unique_ptr<RtpPacketizer> packetizer_; |
418 }; | 491 }; |
419 | 492 |
420 TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) { | 493 TEST_F(RtpPacketizerH264TestSpsRewriting, FuASps) { |
421 const size_t kHeaderOverhead = kFuAHeaderSize + 1; | 494 const size_t kHeaderOverhead = kFuAHeaderSize + 1; |
422 | 495 |
423 // Set size to fragment SPS into two FU-A packets. | 496 // Set size to fragment SPS into two FU-A packets. |
424 packetizer_.reset(RtpPacketizer::Create( | 497 packetizer_.reset(CreateH264Packetizer( |
425 kRtpVideoH264, sizeof(kOriginalSps) - 2 + kHeaderOverhead, nullptr, | 498 kH264PacketizationMode1, sizeof(kOriginalSps) - 2 + kHeaderOverhead)); |
426 kEmptyFrame)); | |
427 | 499 |
428 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), | 500 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), |
429 &fragmentation_header_); | 501 &fragmentation_header_); |
430 | 502 |
431 bool last_packet = true; | 503 bool last_packet = true; |
432 uint8_t buffer[sizeof(kOriginalSps) + kHeaderOverhead] = {}; | 504 uint8_t buffer[sizeof(kOriginalSps) + kHeaderOverhead] = {}; |
433 size_t num_bytes = 0; | 505 size_t num_bytes = 0; |
434 | 506 |
435 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet)); | 507 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet)); |
436 size_t offset = H264::kNaluTypeSize; | 508 size_t offset = H264::kNaluTypeSize; |
(...skipping 15 matching lines...) Expand all Loading... |
452 EXPECT_EQ(offset, sizeof(kRewrittenSps)); | 524 EXPECT_EQ(offset, sizeof(kRewrittenSps)); |
453 } | 525 } |
454 | 526 |
455 TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) { | 527 TEST_F(RtpPacketizerH264TestSpsRewriting, StapASps) { |
456 const size_t kHeaderOverhead = kFuAHeaderSize + 1; | 528 const size_t kHeaderOverhead = kFuAHeaderSize + 1; |
457 const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type. | 529 const size_t kExpectedTotalSize = H264::kNaluTypeSize + // Stap-A type. |
458 sizeof(kRewrittenSps) + sizeof(kIdrOne) + | 530 sizeof(kRewrittenSps) + sizeof(kIdrOne) + |
459 sizeof(kIdrTwo) + (kLengthFieldLength * 3); | 531 sizeof(kIdrTwo) + (kLengthFieldLength * 3); |
460 | 532 |
461 // Set size to include SPS and the rest of the packets in a Stap-A package. | 533 // Set size to include SPS and the rest of the packets in a Stap-A package. |
462 packetizer_.reset(RtpPacketizer::Create(kRtpVideoH264, | 534 packetizer_.reset(CreateH264Packetizer(kH264PacketizationMode1, |
463 kExpectedTotalSize + kHeaderOverhead, | 535 kExpectedTotalSize + kHeaderOverhead)); |
464 nullptr, kEmptyFrame)); | |
465 | 536 |
466 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), | 537 packetizer_->SetPayloadData(in_buffer_.data(), in_buffer_.size(), |
467 &fragmentation_header_); | 538 &fragmentation_header_); |
468 | 539 |
469 bool last_packet = true; | 540 bool last_packet = true; |
470 uint8_t buffer[kExpectedTotalSize + kHeaderOverhead] = {}; | 541 uint8_t buffer[kExpectedTotalSize + kHeaderOverhead] = {}; |
471 size_t num_bytes = 0; | 542 size_t num_bytes = 0; |
472 | 543 |
473 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet)); | 544 EXPECT_TRUE(packetizer_->NextPacket(buffer, &num_bytes, &last_packet)); |
474 EXPECT_EQ(kExpectedTotalSize, num_bytes); | 545 EXPECT_EQ(kExpectedTotalSize, num_bytes); |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 const RTPVideoHeaderH264& h264 = payload.type.Video.codecHeader.H264; | 902 const RTPVideoHeaderH264& h264 = payload.type.Video.codecHeader.H264; |
832 EXPECT_EQ(kH264SingleNalu, h264.packetization_type); | 903 EXPECT_EQ(kH264SingleNalu, h264.packetization_type); |
833 EXPECT_EQ(kSei, h264.nalu_type); | 904 EXPECT_EQ(kSei, h264.nalu_type); |
834 ASSERT_EQ(1u, h264.nalus_length); | 905 ASSERT_EQ(1u, h264.nalus_length); |
835 EXPECT_EQ(static_cast<H264::NaluType>(kSei), h264.nalus[0].type); | 906 EXPECT_EQ(static_cast<H264::NaluType>(kSei), h264.nalus[0].type); |
836 EXPECT_EQ(-1, h264.nalus[0].sps_id); | 907 EXPECT_EQ(-1, h264.nalus[0].sps_id); |
837 EXPECT_EQ(-1, h264.nalus[0].pps_id); | 908 EXPECT_EQ(-1, h264.nalus[0].pps_id); |
838 } | 909 } |
839 | 910 |
840 } // namespace webrtc | 911 } // namespace webrtc |
OLD | NEW |