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 "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" | 11 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" |
12 | 12 |
13 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
15 #include "webrtc/base/scoped_ptr.h" | 15 #include "webrtc/base/scoped_ptr.h" |
| 16 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" |
| 17 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
16 #include "webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h" | 18 #include "webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h" |
17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | 19 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
18 | 20 |
19 namespace webrtc { | 21 namespace webrtc { |
20 | 22 |
21 using ::testing::Eq; | 23 using ::testing::Eq; |
22 using ::testing::Return; | 24 using ::testing::Return; |
23 using ::testing::_; | 25 using ::testing::_; |
24 | 26 |
25 static const char* kTypicalPayloadName = "name"; | 27 static const char* kTypicalPayloadName = "name"; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) { | 252 TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) { |
251 int payload_type = GetParam(); | 253 int payload_type = GetParam(); |
252 | 254 |
253 bool ignored; | 255 bool ignored; |
254 | 256 |
255 EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload("generic-codec", | 257 EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload("generic-codec", |
256 static_cast<int8_t>(payload_type), | 258 static_cast<int8_t>(payload_type), |
257 19, 1, 17, &ignored)); // dummy values, except for payload_type | 259 19, 1, 17, &ignored)); // dummy values, except for payload_type |
258 } | 260 } |
259 | 261 |
| 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 rtc::scoped_ptr<const uint8_t[]> packet(GenerateRtxPacket( |
| 306 header_length, payload_length, original_sequence_number)); |
| 307 rtc::scoped_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 ASSERT_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 rtc::scoped_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_F(RtpPayloadRegistryTest, MultipleRtxPayloadTypes) { |
| 335 // Set the incoming payload type to 90. |
| 336 RTPHeader header; |
| 337 header.payloadType = 90; |
| 338 header.ssrc = 1; |
| 339 rtp_payload_registry_->SetIncomingPayloadType(header); |
| 340 rtp_payload_registry_->SetRtxSsrc(100); |
| 341 // Map two RTX payload types. |
| 342 rtp_payload_registry_->SetRtxPayloadType(105, 95); |
| 343 rtp_payload_registry_->SetRtxPayloadType(106, 96); |
| 344 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(true); |
| 345 |
| 346 TestRtxPacket(rtp_payload_registry_.get(), 105, 95, true); |
| 347 TestRtxPacket(rtp_payload_registry_.get(), 106, 96, true); |
| 348 |
| 349 // If the option is off, the map will be ignored. |
| 350 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(false); |
| 351 TestRtxPacket(rtp_payload_registry_.get(), 105, 90, true); |
| 352 TestRtxPacket(rtp_payload_registry_.get(), 106, 90, true); |
| 353 } |
| 354 |
| 355 // TODO(holmer): Ignored by default for compatibility with misconfigured RTX |
| 356 // streams in Chrome. When that is fixed, remove this. |
| 357 TEST_F(RtpPayloadRegistryTest, IgnoresRtxPayloadTypeMappingByDefault) { |
| 358 // Set the incoming payload type to 90. |
| 359 RTPHeader header; |
| 360 header.payloadType = 90; |
| 361 header.ssrc = 1; |
| 362 rtp_payload_registry_->SetIncomingPayloadType(header); |
| 363 rtp_payload_registry_->SetRtxSsrc(100); |
| 364 // Map two RTX payload types. |
| 365 rtp_payload_registry_->SetRtxPayloadType(105, 95); |
| 366 rtp_payload_registry_->SetRtxPayloadType(106, 96); |
| 367 |
| 368 TestRtxPacket(rtp_payload_registry_.get(), 105, 90, true); |
| 369 TestRtxPacket(rtp_payload_registry_.get(), 106, 90, true); |
| 370 } |
| 371 |
| 372 TEST_F(RtpPayloadRegistryTest, InferLastReceivedPacketIfPayloadTypeUnknown) { |
| 373 rtp_payload_registry_->SetRtxSsrc(100); |
| 374 // Set the incoming payload type to 90. |
| 375 RTPHeader header; |
| 376 header.payloadType = 90; |
| 377 header.ssrc = 1; |
| 378 rtp_payload_registry_->SetIncomingPayloadType(header); |
| 379 rtp_payload_registry_->SetRtxPayloadType(105, 95); |
| 380 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(true); |
| 381 // Mapping respected for known type. |
| 382 TestRtxPacket(rtp_payload_registry_.get(), 105, 95, true); |
| 383 // Mapping ignored for unknown type, even though the option is on. |
| 384 TestRtxPacket(rtp_payload_registry_.get(), 106, 90, true); |
| 385 } |
| 386 |
| 387 TEST_F(RtpPayloadRegistryTest, InvalidRtxConfiguration) { |
| 388 rtp_payload_registry_->SetRtxSsrc(100); |
| 389 // Fails because no mappings exist and the incoming payload type isn't known. |
| 390 TestRtxPacket(rtp_payload_registry_.get(), 105, 0, false); |
| 391 // Succeeds when the mapping is used, but fails for the implicit fallback. |
| 392 rtp_payload_registry_->SetRtxPayloadType(105, 95); |
| 393 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(true); |
| 394 TestRtxPacket(rtp_payload_registry_.get(), 105, 95, true); |
| 395 TestRtxPacket(rtp_payload_registry_.get(), 106, 0, false); |
| 396 } |
| 397 |
260 INSTANTIATE_TEST_CASE_P(TestDynamicRange, RtpPayloadRegistryGenericTest, | 398 INSTANTIATE_TEST_CASE_P(TestDynamicRange, RtpPayloadRegistryGenericTest, |
261 testing::Range(96, 127+1)); | 399 testing::Range(96, 127+1)); |
262 | 400 |
263 } // namespace webrtc | 401 } // namespace webrtc |
OLD | NEW |