Chromium Code Reviews| 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/source/byte_io.h" | |
| 16 #include "webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h" | 17 #include "webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h" |
| 17 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | 18 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
| 18 | 19 |
| 19 namespace webrtc { | 20 namespace webrtc { |
| 20 | 21 |
| 21 using ::testing::Eq; | 22 using ::testing::Eq; |
| 22 using ::testing::Return; | 23 using ::testing::Return; |
| 23 using ::testing::_; | 24 using ::testing::_; |
| 24 | 25 |
| 25 static const char* kTypicalPayloadName = "name"; | 26 static const char* kTypicalPayloadName = "name"; |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) { | 251 TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) { |
| 251 int payload_type = GetParam(); | 252 int payload_type = GetParam(); |
| 252 | 253 |
| 253 bool ignored; | 254 bool ignored; |
| 254 | 255 |
| 255 EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload("generic-codec", | 256 EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload("generic-codec", |
| 256 static_cast<int8_t>(payload_type), | 257 static_cast<int8_t>(payload_type), |
| 257 19, 1, 17, &ignored)); // dummy values, except for payload_type | 258 19, 1, 17, &ignored)); // dummy values, except for payload_type |
| 258 } | 259 } |
| 259 | 260 |
| 261 // Generates an RTX packet for the given length and original sequence number. | |
| 262 // The RTX sequence number and ssrc will use the default value of 9999. The | |
|
stefan-webrtc
2015/10/13 13:07:56
s/"number and"/"number and"
noahric
2015/10/13 17:03:31
Done.
| |
| 263 // caller takes ownership of the returned buffer. | |
| 264 const uint8_t* GenerateRtxPacket(size_t header_length, | |
| 265 size_t payload_length, | |
| 266 int original_sequence_number) { | |
| 267 uint8_t* packet = | |
| 268 new uint8_t[kRtxHeaderSize + header_length + payload_length](); | |
| 269 // Write a junk sequence number. It should be thrown away when the packet is | |
| 270 // restored. | |
| 271 ByteWriter<uint16_t>::WriteBigEndian(packet + 2, 9999); | |
| 272 // Write a junk ssrc. It should also be thrown away when the packet is | |
| 273 // restored. | |
| 274 ByteWriter<uint32_t>::WriteBigEndian(packet + 8, 9999); | |
| 275 | |
| 276 // Now write the RTX header. It occurs at the start of the payload block, and | |
| 277 // contains just the sequence number. | |
| 278 ByteWriter<uint16_t>::WriteBigEndian(packet + header_length, | |
| 279 original_sequence_number); | |
| 280 return packet; | |
| 281 } | |
| 282 | |
| 283 void TestRtxPacket(RTPPayloadRegistry* rtp_payload_registry, | |
| 284 int rtx_payload_type, | |
| 285 int expected_payload_type, | |
| 286 bool should_succeed) { | |
| 287 size_t header_length = 100; | |
| 288 size_t payload_length = 200; | |
| 289 size_t original_length = header_length + payload_length + kRtxHeaderSize; | |
| 290 | |
| 291 RTPHeader header; | |
| 292 header.ssrc = 1000; | |
| 293 header.sequenceNumber = 100; | |
| 294 header.payloadType = rtx_payload_type; | |
| 295 header.headerLength = header_length; | |
| 296 | |
| 297 int original_sequence_number = 1234; | |
| 298 int original_ssrc = 500; | |
| 299 | |
| 300 rtc::scoped_ptr<const uint8_t[]> packet(GenerateRtxPacket( | |
| 301 header_length, payload_length, original_sequence_number)); | |
| 302 rtc::scoped_ptr<uint8_t[]> restored_packet( | |
| 303 new uint8_t[header_length + payload_length]); | |
| 304 size_t length = original_length; | |
| 305 bool success = rtp_payload_registry->RestoreOriginalPacket( | |
| 306 restored_packet.get(), packet.get(), &length, original_ssrc, header); | |
| 307 ASSERT_EQ(should_succeed, success) | |
| 308 << "Test success should match should_succeed."; | |
| 309 if (!success) { | |
| 310 return; | |
| 311 } | |
| 312 | |
| 313 EXPECT_EQ(original_length - kRtxHeaderSize, length) | |
| 314 << "The restored packet should be exactly kRtxHeaderSize smaller."; | |
| 315 EXPECT_EQ(static_cast<uint16_t>(original_sequence_number), | |
| 316 ByteReader<uint16_t>::ReadBigEndian(restored_packet.get() + 2)) | |
| 317 << "The restored packet should have the original sequence number " | |
| 318 << "in the correct location in the RTP header."; | |
| 319 int payload_type = restored_packet.get()[1] & ~kRtpMarkerBitMask; | |
| 320 EXPECT_EQ(expected_payload_type, payload_type) | |
| 321 << "The restored packet should have the correct payload type."; | |
| 322 EXPECT_EQ(static_cast<uint32_t>(original_ssrc), | |
| 323 ByteReader<uint32_t>::ReadBigEndian(restored_packet.get() + 8)) | |
| 324 << "The restored packet should have the correct ssrc."; | |
|
stefan-webrtc
2015/10/13 13:07:56
You could instead use the RtpHeaderParser and simp
noahric
2015/10/13 17:03:31
Done. Also cleaned up the types to remove the stat
| |
| 325 } | |
| 326 | |
| 327 TEST_F(RtpPayloadRegistryTest, MultipleRtxPayloadTypes) { | |
| 328 // Set the incoming payload type to 90. | |
| 329 RTPHeader header; | |
| 330 header.payloadType = 90; | |
| 331 header.ssrc = 1; | |
| 332 rtp_payload_registry_->SetIncomingPayloadType(header); | |
| 333 rtp_payload_registry_->SetRtxSsrc(100); | |
| 334 // Map two RTX payload types. | |
| 335 rtp_payload_registry_->SetRtxPayloadType(105, 95); | |
| 336 rtp_payload_registry_->SetRtxPayloadType(106, 96); | |
| 337 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(true); | |
| 338 | |
| 339 TestRtxPacket(rtp_payload_registry_.get(), 105, 95, true); | |
| 340 TestRtxPacket(rtp_payload_registry_.get(), 106, 96, true); | |
| 341 | |
| 342 // If the option is off, the map will be ignored. | |
| 343 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(false); | |
| 344 TestRtxPacket(rtp_payload_registry_.get(), 105, 90, true); | |
| 345 TestRtxPacket(rtp_payload_registry_.get(), 106, 90, true); | |
| 346 } | |
| 347 | |
| 348 // TODO(holmer): Ignored by default for compatibility with misconfigured RTX | |
| 349 // streams in Chrome. When that is fixed, remove this. | |
| 350 TEST_F(RtpPayloadRegistryTest, IgnoresRtxPayloadTypeMappingByDefault) { | |
| 351 // Set the incoming payload type to 90. | |
| 352 RTPHeader header; | |
| 353 header.payloadType = 90; | |
| 354 header.ssrc = 1; | |
| 355 rtp_payload_registry_->SetIncomingPayloadType(header); | |
| 356 rtp_payload_registry_->SetRtxSsrc(100); | |
| 357 // Map two RTX payload types. | |
| 358 rtp_payload_registry_->SetRtxPayloadType(105, 95); | |
| 359 rtp_payload_registry_->SetRtxPayloadType(106, 96); | |
| 360 | |
| 361 TestRtxPacket(rtp_payload_registry_.get(), 105, 90, true); | |
| 362 TestRtxPacket(rtp_payload_registry_.get(), 106, 90, true); | |
| 363 } | |
| 364 | |
| 365 TEST_F(RtpPayloadRegistryTest, InferLastReceivedPacketIfPayloadTypeUnknown) { | |
| 366 rtp_payload_registry_->SetRtxSsrc(100); | |
| 367 // Set the incoming payload type to 90. | |
| 368 RTPHeader header; | |
| 369 header.payloadType = 90; | |
| 370 header.ssrc = 1; | |
| 371 rtp_payload_registry_->SetIncomingPayloadType(header); | |
| 372 rtp_payload_registry_->SetRtxPayloadType(105, 95); | |
| 373 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(true); | |
| 374 // Mapping respected for known type. | |
| 375 TestRtxPacket(rtp_payload_registry_.get(), 105, 95, true); | |
| 376 // Mapping ignored for unknown type, even though the option is on. | |
| 377 TestRtxPacket(rtp_payload_registry_.get(), 106, 90, true); | |
| 378 } | |
| 379 | |
| 380 TEST_F(RtpPayloadRegistryTest, InvalidRtxConfiguration) { | |
| 381 rtp_payload_registry_->SetRtxSsrc(100); | |
| 382 // Fails because no mappings exist and the incoming payload type isn't known. | |
| 383 TestRtxPacket(rtp_payload_registry_.get(), 105, 0, false); | |
| 384 // Succeeds when the mapping is used, but fails for the implicit fallback. | |
| 385 rtp_payload_registry_->SetRtxPayloadType(105, 95); | |
| 386 rtp_payload_registry_->set_use_rtx_payload_mapping_on_restore(true); | |
| 387 TestRtxPacket(rtp_payload_registry_.get(), 105, 95, true); | |
| 388 TestRtxPacket(rtp_payload_registry_.get(), 106, 0, false); | |
| 389 } | |
| 390 | |
| 260 INSTANTIATE_TEST_CASE_P(TestDynamicRange, RtpPayloadRegistryGenericTest, | 391 INSTANTIATE_TEST_CASE_P(TestDynamicRange, RtpPayloadRegistryGenericTest, |
| 261 testing::Range(96, 127+1)); | 392 testing::Range(96, 127+1)); |
| 262 | 393 |
| 263 } // namespace webrtc | 394 } // namespace webrtc |
| OLD | NEW |