OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 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/call/rtp_demuxer.h" | 11 #include "webrtc/call/rtp_demuxer.h" |
12 | 12 |
13 #include <memory> | 13 #include <memory> |
14 #include <string> | 14 #include <string> |
15 | 15 |
16 #include "webrtc/base/arraysize.h" | 16 #include "webrtc/base/arraysize.h" |
| 17 #include "webrtc/base/basictypes.h" |
17 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
18 #include "webrtc/base/ptr_util.h" | 19 #include "webrtc/base/ptr_util.h" |
| 20 #include "webrtc/call/rsid_resolution_observer.h" |
19 #include "webrtc/call/rtp_packet_sink_interface.h" | 21 #include "webrtc/call/rtp_packet_sink_interface.h" |
| 22 #include "webrtc/common_types.h" |
20 #include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h" | 23 #include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h" |
21 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" | 24 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" |
22 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" | 25 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" |
23 #include "webrtc/test/gmock.h" | 26 #include "webrtc/test/gmock.h" |
24 #include "webrtc/test/gtest.h" | 27 #include "webrtc/test/gtest.h" |
25 | 28 |
26 namespace webrtc { | 29 namespace webrtc { |
27 | 30 |
28 namespace { | 31 namespace { |
29 | 32 |
30 using ::testing::_; | 33 using ::testing::_; |
31 using ::testing::AtLeast; | 34 using ::testing::AtLeast; |
32 using ::testing::InSequence; | 35 using ::testing::InSequence; |
33 using ::testing::NiceMock; | 36 using ::testing::NiceMock; |
34 | 37 |
35 class MockRtpPacketSink : public RtpPacketSinkInterface { | 38 class MockRtpPacketSink : public RtpPacketSinkInterface { |
36 public: | 39 public: |
37 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); | 40 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); |
38 }; | 41 }; |
39 | 42 |
| 43 class MockRsidResolutionObserver : public RsidResolutionObserver { |
| 44 public: |
| 45 MOCK_METHOD2(OnRsidResolved, void(const std::string& rsid, uint32_t ssrc)); |
| 46 }; |
| 47 |
40 MATCHER_P(SamePacketAs, other, "") { | 48 MATCHER_P(SamePacketAs, other, "") { |
41 return arg.Ssrc() == other.Ssrc() && | 49 return arg.Ssrc() == other.Ssrc() && |
42 arg.SequenceNumber() == other.SequenceNumber(); | 50 arg.SequenceNumber() == other.SequenceNumber(); |
43 } | 51 } |
44 | 52 |
45 std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived( | 53 std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived( |
46 uint32_t ssrc, | 54 uint32_t ssrc, |
47 size_t sequence_number = 0) { | 55 size_t sequence_number = 0) { |
48 // |sequence_number| is declared |size_t| to prevent ugly casts when calling | 56 // |sequence_number| is declared |size_t| to prevent ugly casts when calling |
49 // the function, but should in reality always be a |uint16_t|. | 57 // the function, but should in reality always be a |uint16_t|. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 | 120 |
113 // Test tear-down | 121 // Test tear-down |
114 for (const auto& sink : sinks) { | 122 for (const auto& sink : sinks) { |
115 demuxer.RemoveSink(&sink); | 123 demuxer.RemoveSink(&sink); |
116 } | 124 } |
117 } | 125 } |
118 | 126 |
119 TEST(RtpDemuxerTest, PacketsDeliveredInRightOrder) { | 127 TEST(RtpDemuxerTest, PacketsDeliveredInRightOrder) { |
120 RtpDemuxer demuxer; | 128 RtpDemuxer demuxer; |
121 | 129 |
122 constexpr uint32_t ssrcs[] = {101, 202, 303}; | 130 constexpr uint32_t ssrc = 101; |
123 MockRtpPacketSink sinks[arraysize(ssrcs)]; | 131 MockRtpPacketSink sink; |
124 for (size_t i = 0; i < arraysize(ssrcs); i++) { | 132 demuxer.AddSink(ssrc, &sink); |
125 demuxer.AddSink(ssrcs[i], &sinks[i]); | |
126 } | |
127 | 133 |
128 std::unique_ptr<RtpPacketReceived> packets[5]; | 134 std::unique_ptr<RtpPacketReceived> packets[5]; |
129 for (size_t i = 0; i < arraysize(packets); i++) { | 135 for (size_t i = 0; i < arraysize(packets); i++) { |
130 packets[i] = CreateRtpPacketReceived(ssrcs[0], i); | 136 packets[i] = CreateRtpPacketReceived(ssrc, i); |
131 } | 137 } |
132 | 138 |
133 InSequence sequence; | 139 InSequence sequence; |
134 for (const auto& packet : packets) { | 140 for (const auto& packet : packets) { |
135 EXPECT_CALL(sinks[0], OnRtpPacket(SamePacketAs(*packet))).Times(1); | 141 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); |
136 } | 142 } |
137 | 143 |
138 for (const auto& packet : packets) { | 144 for (const auto& packet : packets) { |
139 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | 145 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
140 } | 146 } |
141 | 147 |
142 // Test tear-down | 148 // Test tear-down |
143 for (const auto& sink : sinks) { | 149 demuxer.RemoveSink(&sink); |
144 demuxer.RemoveSink(&sink); | |
145 } | |
146 } | 150 } |
147 | 151 |
148 TEST(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { | 152 TEST(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { |
149 RtpDemuxer demuxer; | 153 RtpDemuxer demuxer; |
150 | 154 |
151 MockRtpPacketSink sinks[3]; | 155 MockRtpPacketSink sinks[3]; |
152 constexpr uint32_t ssrc = 404; | 156 constexpr uint32_t ssrc = 404; |
153 for (auto& sink : sinks) { | 157 for (auto& sink : sinks) { |
154 demuxer.AddSink(ssrc, &sink); | 158 demuxer.AddSink(ssrc, &sink); |
155 } | 159 } |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 auto packet = | 421 auto packet = |
418 CreateRtpPacketReceivedWithRsid(rsids[i], ssrc, sequence_number); | 422 CreateRtpPacketReceivedWithRsid(rsids[i], ssrc, sequence_number); |
419 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | 423 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); |
420 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | 424 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
421 } | 425 } |
422 | 426 |
423 // Test tear-down | 427 // Test tear-down |
424 demuxer.RemoveSink(&sink); | 428 demuxer.RemoveSink(&sink); |
425 } | 429 } |
426 | 430 |
| 431 TEST(RtpDemuxerTest, RsidUsedByMultipleSinks) { |
| 432 RtpDemuxer demuxer; |
| 433 |
| 434 MockRtpPacketSink sinks[3]; |
| 435 const std::string shared_rsid = "a"; |
| 436 |
| 437 for (MockRtpPacketSink& sink : sinks) { |
| 438 demuxer.AddSink(shared_rsid, &sink); |
| 439 } |
| 440 |
| 441 constexpr uint32_t shared_ssrc = 888; |
| 442 auto packet = CreateRtpPacketReceivedWithRsid(shared_rsid, shared_ssrc); |
| 443 |
| 444 for (auto& sink : sinks) { |
| 445 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); |
| 446 } |
| 447 |
| 448 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
| 449 |
| 450 // Test tear-down |
| 451 for (MockRtpPacketSink& sink : sinks) { |
| 452 demuxer.RemoveSink(&sink); |
| 453 } |
| 454 } |
| 455 |
427 TEST(RtpDemuxerTest, SinkWithBothRsidAndSsrcAssociations) { | 456 TEST(RtpDemuxerTest, SinkWithBothRsidAndSsrcAssociations) { |
428 RtpDemuxer demuxer; | 457 RtpDemuxer demuxer; |
429 | 458 |
430 MockRtpPacketSink sink; | 459 MockRtpPacketSink sink; |
431 constexpr uint32_t standalone_ssrc = 10101; | 460 constexpr uint32_t standalone_ssrc = 10101; |
432 constexpr uint32_t rsid_ssrc = 20202; | 461 constexpr uint32_t rsid_ssrc = 20202; |
433 const std::string rsid = "a"; | 462 const std::string rsid = "a"; |
434 | 463 |
435 demuxer.AddSink(standalone_ssrc, &sink); | 464 demuxer.AddSink(standalone_ssrc, &sink); |
436 demuxer.AddSink(rsid, &sink); | 465 demuxer.AddSink(rsid, &sink); |
(...skipping 24 matching lines...) Expand all Loading... |
461 | 490 |
462 constexpr uint16_t seq_num = 999; | 491 constexpr uint16_t seq_num = 999; |
463 auto packet = CreateRtpPacketReceivedWithRsid(rsid, ssrc, seq_num); | 492 auto packet = CreateRtpPacketReceivedWithRsid(rsid, ssrc, seq_num); |
464 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | 493 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); |
465 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | 494 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
466 | 495 |
467 // Test tear-down | 496 // Test tear-down |
468 demuxer.RemoveSink(&sink); | 497 demuxer.RemoveSink(&sink); |
469 } | 498 } |
470 | 499 |
| 500 TEST(RtpDemuxerTest, RsidObserversInformedOfResolutions) { |
| 501 RtpDemuxer demuxer; |
| 502 |
| 503 constexpr uint32_t ssrc = 111; |
| 504 const std::string rsid = "a"; |
| 505 |
| 506 MockRsidResolutionObserver rsid_resolution_observers[3]; |
| 507 for (auto& observer : rsid_resolution_observers) { |
| 508 demuxer.RegisterRsidResolutionObserver(&observer); |
| 509 EXPECT_CALL(observer, OnRsidResolved(rsid, ssrc)).Times(1); |
| 510 } |
| 511 |
| 512 // The expected calls to OnRsidResolved() will be triggered by this. |
| 513 demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); |
| 514 |
| 515 // Test tear-down |
| 516 for (auto& observer : rsid_resolution_observers) { |
| 517 demuxer.DeregisterRsidResolutionObserver(&observer); |
| 518 } |
| 519 } |
| 520 |
| 521 // Normally, we only produce one notification per resolution (though no such |
| 522 // guarantee is made), but when a new observer is added, we reset |
| 523 // this suppression - we "re-resolve" associations for the benefit of the |
| 524 // new observer.. |
| 525 TEST(RtpDemuxerTest, NotificationSuppressionResetWhenNewObserverAdded) { |
| 526 RtpDemuxer demuxer; |
| 527 |
| 528 constexpr uint32_t ssrc = 111; |
| 529 const std::string rsid = "a"; |
| 530 |
| 531 // First observer registered, then gets a notification. |
| 532 NiceMock<MockRsidResolutionObserver> first_observer; |
| 533 demuxer.RegisterRsidResolutionObserver(&first_observer); |
| 534 demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); |
| 535 |
| 536 // Second observer registered, then gets a notification. No guarantee is made |
| 537 // about whether the first observer would get an additional notification. |
| 538 MockRsidResolutionObserver second_observer; |
| 539 demuxer.RegisterRsidResolutionObserver(&second_observer); |
| 540 EXPECT_CALL(first_observer, OnRsidResolved(rsid, ssrc)).Times(AtLeast(0)); |
| 541 EXPECT_CALL(second_observer, OnRsidResolved(rsid, ssrc)).Times(1); |
| 542 demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); |
| 543 |
| 544 // Test tear-down |
| 545 demuxer.DeregisterRsidResolutionObserver(&first_observer); |
| 546 demuxer.DeregisterRsidResolutionObserver(&second_observer); |
| 547 } |
| 548 |
| 549 TEST(RtpDemuxerTest, DeregisteredRsidObserversNotInformedOfResolutions) { |
| 550 RtpDemuxer demuxer; |
| 551 |
| 552 constexpr uint32_t ssrc = 111; |
| 553 const std::string rsid = "a"; |
| 554 NiceMock<MockRtpPacketSink> sink; |
| 555 demuxer.AddSink(rsid, &sink); |
| 556 |
| 557 // Register several, then deregister only one, to show that not all of the |
| 558 // observers had been forgotten when one was removed. |
| 559 MockRsidResolutionObserver observer_1; |
| 560 MockRsidResolutionObserver observer_2_removed; |
| 561 MockRsidResolutionObserver observer_3; |
| 562 |
| 563 demuxer.RegisterRsidResolutionObserver(&observer_1); |
| 564 demuxer.RegisterRsidResolutionObserver(&observer_2_removed); |
| 565 demuxer.RegisterRsidResolutionObserver(&observer_3); |
| 566 |
| 567 demuxer.DeregisterRsidResolutionObserver(&observer_2_removed); |
| 568 |
| 569 EXPECT_CALL(observer_1, OnRsidResolved(rsid, ssrc)).Times(1); |
| 570 EXPECT_CALL(observer_2_removed, OnRsidResolved(_, _)).Times(0); |
| 571 EXPECT_CALL(observer_3, OnRsidResolved(rsid, ssrc)).Times(1); |
| 572 |
| 573 // The expected calls to OnRsidResolved() will be triggered by this. |
| 574 demuxer.OnRtpPacket(*CreateRtpPacketReceivedWithRsid(rsid, ssrc)); |
| 575 |
| 576 // Test tear-down |
| 577 demuxer.RemoveSink(&sink); |
| 578 demuxer.DeregisterRsidResolutionObserver(&observer_1); |
| 579 demuxer.DeregisterRsidResolutionObserver(&observer_3); |
| 580 } |
| 581 |
471 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 582 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
472 TEST(RtpDemuxerTest, RsidMustBeNonEmpty) { | 583 TEST(RtpDemuxerTest, RsidMustBeNonEmpty) { |
473 RtpDemuxer demuxer; | 584 RtpDemuxer demuxer; |
474 MockRtpPacketSink sink; | 585 MockRtpPacketSink sink; |
475 EXPECT_DEATH(demuxer.AddSink("", &sink), ""); | 586 EXPECT_DEATH(demuxer.AddSink("", &sink), ""); |
476 } | 587 } |
477 | 588 |
478 TEST(RtpDemuxerTest, RsidMustBeAlphaNumeric) { | 589 TEST(RtpDemuxerTest, RsidMustBeAlphaNumeric) { |
479 RtpDemuxer demuxer; | 590 RtpDemuxer demuxer; |
480 MockRtpPacketSink sink; | 591 MockRtpPacketSink sink; |
481 EXPECT_DEATH(demuxer.AddSink("a_3", &sink), ""); | 592 EXPECT_DEATH(demuxer.AddSink("a_3", &sink), ""); |
482 } | 593 } |
483 | 594 |
484 TEST(RtpDemuxerTest, RsidMustNotExceedMaximumLength) { | 595 TEST(RtpDemuxerTest, RsidMustNotExceedMaximumLength) { |
485 RtpDemuxer demuxer; | 596 RtpDemuxer demuxer; |
486 MockRtpPacketSink sink; | 597 MockRtpPacketSink sink; |
487 std::string rsid(StreamId::kMaxSize + 1, 'a'); | 598 std::string rsid(StreamId::kMaxSize + 1, 'a'); |
488 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); | 599 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); |
489 } | 600 } |
490 | 601 |
491 TEST(RtpDemuxerTest, RepeatedRsidAssociationsDisallowed) { | 602 TEST(RtpDemuxerTest, RepeatedRsidAssociationsDisallowed) { |
492 RtpDemuxer demuxer; | 603 RtpDemuxer demuxer; |
493 MockRtpPacketSink sink; | 604 MockRtpPacketSink sink; |
494 demuxer.AddSink("a", &sink); | 605 demuxer.AddSink("a", &sink); |
495 EXPECT_DEATH(demuxer.AddSink("a", &sink), ""); | 606 EXPECT_DEATH(demuxer.AddSink("a", &sink), ""); |
| 607 demuxer.RemoveSink(&sink); |
496 } | 608 } |
| 609 |
| 610 TEST(RtpDemuxerTest, |
| 611 DoubleRegisterationOfNeverRegisteredRsidResolutionObserverDisallowed) { |
| 612 RtpDemuxer demuxer; |
| 613 MockRsidResolutionObserver observer; |
| 614 demuxer.RegisterRsidResolutionObserver(&observer); |
| 615 EXPECT_DEATH(demuxer.RegisterRsidResolutionObserver(&observer), ""); |
| 616 demuxer.DeregisterRsidResolutionObserver(&observer); |
| 617 } |
| 618 |
| 619 TEST(RtpDemuxerTest, |
| 620 DregisterationOfNeverRegisteredRsidResolutionObserverDisallowed) { |
| 621 RtpDemuxer demuxer; |
| 622 MockRsidResolutionObserver observer; |
| 623 EXPECT_DEATH(demuxer.DeregisterRsidResolutionObserver(&observer), ""); |
| 624 } |
| 625 |
497 #endif | 626 #endif |
498 | 627 |
499 } // namespace | 628 } // namespace |
500 } // namespace webrtc | 629 } // namespace webrtc |
OLD | NEW |