OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 | 12 |
13 #include "webrtc/common_types.h" | 13 #include "webrtc/common_types.h" |
14 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | 14 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
15 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | 15 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" |
16 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | |
17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | 16 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
18 #include "webrtc/test/gmock.h" | 17 #include "webrtc/test/gmock.h" |
19 #include "webrtc/test/gtest.h" | 18 #include "webrtc/test/gtest.h" |
20 | 19 |
21 namespace webrtc { | 20 namespace webrtc { |
22 | 21 |
23 using ::testing::Eq; | 22 using ::testing::Eq; |
24 using ::testing::Return; | 23 using ::testing::Return; |
25 using ::testing::StrEq; | 24 using ::testing::StrEq; |
26 using ::testing::_; | 25 using ::testing::_; |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 CodecInst audio_codec; | 251 CodecInst audio_codec; |
253 // Dummy values, except for payload_type. | 252 // Dummy values, except for payload_type. |
254 strncpy(audio_codec.plname, "generic-codec", RTP_PAYLOAD_NAME_SIZE); | 253 strncpy(audio_codec.plname, "generic-codec", RTP_PAYLOAD_NAME_SIZE); |
255 audio_codec.pltype = GetParam(); | 254 audio_codec.pltype = GetParam(); |
256 audio_codec.plfreq = 1900; | 255 audio_codec.plfreq = 1900; |
257 audio_codec.channels = 1; | 256 audio_codec.channels = 1; |
258 EXPECT_EQ(0, | 257 EXPECT_EQ(0, |
259 rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored)); | 258 rtp_payload_registry.RegisterReceivePayload(audio_codec, &ignored)); |
260 } | 259 } |
261 | 260 |
262 // Generates an RTX packet for the given length and original sequence number. | |
263 // The RTX sequence number and ssrc will use the default value of 9999. The | |
264 // caller takes ownership of the returned buffer. | |
265 const uint8_t* GenerateRtxPacket(size_t header_length, | |
266 size_t payload_length, | |
267 uint16_t original_sequence_number) { | |
268 uint8_t* packet = | |
269 new uint8_t[kRtxHeaderSize + header_length + payload_length](); | |
270 // Write the RTP version to the first byte, so the resulting header can be | |
271 // parsed. | |
272 static const int kRtpExpectedVersion = 2; | |
273 packet[0] = static_cast<uint8_t>(kRtpExpectedVersion << 6); | |
274 // Write a junk sequence number. It should be thrown away when the packet is | |
275 // restored. | |
276 ByteWriter<uint16_t>::WriteBigEndian(packet + 2, 9999); | |
277 // Write a junk ssrc. It should also be thrown away when the packet is | |
278 // restored. | |
279 ByteWriter<uint32_t>::WriteBigEndian(packet + 8, 9999); | |
280 | |
281 // Now write the RTX header. It occurs at the start of the payload block, and | |
282 // contains just the sequence number. | |
283 ByteWriter<uint16_t>::WriteBigEndian(packet + header_length, | |
284 original_sequence_number); | |
285 return packet; | |
286 } | |
287 | |
288 void TestRtxPacket(RTPPayloadRegistry* rtp_payload_registry, | |
289 int rtx_payload_type, | |
290 int expected_payload_type, | |
291 bool should_succeed) { | |
292 size_t header_length = 100; | |
293 size_t payload_length = 200; | |
294 size_t original_length = header_length + payload_length + kRtxHeaderSize; | |
295 | |
296 RTPHeader header; | |
297 header.ssrc = 1000; | |
298 header.sequenceNumber = 100; | |
299 header.payloadType = rtx_payload_type; | |
300 header.headerLength = header_length; | |
301 | |
302 uint16_t original_sequence_number = 1234; | |
303 uint32_t original_ssrc = 500; | |
304 | |
305 std::unique_ptr<const uint8_t[]> packet(GenerateRtxPacket( | |
306 header_length, payload_length, original_sequence_number)); | |
307 std::unique_ptr<uint8_t[]> restored_packet( | |
308 new uint8_t[header_length + payload_length]); | |
309 size_t length = original_length; | |
310 bool success = rtp_payload_registry->RestoreOriginalPacket( | |
311 restored_packet.get(), packet.get(), &length, original_ssrc, header); | |
312 EXPECT_EQ(should_succeed, success) | |
313 << "Test success should match should_succeed."; | |
314 if (!success) { | |
315 return; | |
316 } | |
317 | |
318 EXPECT_EQ(original_length - kRtxHeaderSize, length) | |
319 << "The restored packet should be exactly kRtxHeaderSize smaller."; | |
320 | |
321 std::unique_ptr<RtpHeaderParser> header_parser(RtpHeaderParser::Create()); | |
322 RTPHeader restored_header; | |
323 ASSERT_TRUE( | |
324 header_parser->Parse(restored_packet.get(), length, &restored_header)); | |
325 EXPECT_EQ(original_sequence_number, restored_header.sequenceNumber) | |
326 << "The restored packet should have the original sequence number " | |
327 << "in the correct location in the RTP header."; | |
328 EXPECT_EQ(expected_payload_type, restored_header.payloadType) | |
329 << "The restored packet should have the correct payload type."; | |
330 EXPECT_EQ(original_ssrc, restored_header.ssrc) | |
331 << "The restored packet should have the correct ssrc."; | |
332 } | |
333 | |
334 TEST(RtpPayloadRegistryTest, MultipleRtxPayloadTypes) { | |
335 RTPPayloadRegistry rtp_payload_registry; | |
336 // Set the incoming payload type to 90. | |
337 RTPHeader header; | |
338 header.payloadType = 90; | |
339 header.ssrc = 1; | |
340 rtp_payload_registry.SetIncomingPayloadType(header); | |
341 rtp_payload_registry.SetRtxSsrc(100); | |
342 // Map two RTX payload types. | |
343 rtp_payload_registry.SetRtxPayloadType(105, 95); | |
344 rtp_payload_registry.SetRtxPayloadType(106, 96); | |
345 | |
346 TestRtxPacket(&rtp_payload_registry, 105, 95, true); | |
347 TestRtxPacket(&rtp_payload_registry, 106, 96, true); | |
348 } | |
349 | |
350 TEST(RtpPayloadRegistryTest, InvalidRtxConfiguration) { | |
351 RTPPayloadRegistry rtp_payload_registry; | |
352 rtp_payload_registry.SetRtxSsrc(100); | |
353 // Fails because no mappings exist and the incoming payload type isn't known. | |
354 TestRtxPacket(&rtp_payload_registry, 105, 0, false); | |
355 // Succeeds when the mapping is used, but fails for the implicit fallback. | |
356 rtp_payload_registry.SetRtxPayloadType(105, 95); | |
357 TestRtxPacket(&rtp_payload_registry, 105, 95, true); | |
358 TestRtxPacket(&rtp_payload_registry, 106, 0, false); | |
359 } | |
360 | |
361 INSTANTIATE_TEST_CASE_P(TestDynamicRange, | 261 INSTANTIATE_TEST_CASE_P(TestDynamicRange, |
362 RtpPayloadRegistryGenericTest, | 262 RtpPayloadRegistryGenericTest, |
363 testing::Range(96, 127 + 1)); | 263 testing::Range(96, 127 + 1)); |
364 | 264 |
365 } // namespace webrtc | 265 } // namespace webrtc |
OLD | NEW |