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" | |
18 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
19 #include "webrtc/base/ptr_util.h" | 18 #include "webrtc/base/ptr_util.h" |
20 #include "webrtc/call/rsid_resolution_observer.h" | |
21 #include "webrtc/call/rtp_packet_sink_interface.h" | 19 #include "webrtc/call/rtp_packet_sink_interface.h" |
22 #include "webrtc/common_types.h" | |
23 #include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h" | 20 #include "webrtc/modules/rtp_rtcp/include/rtp_header_extension_map.h" |
24 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" | 21 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" |
25 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" | 22 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" |
26 #include "webrtc/test/gmock.h" | 23 #include "webrtc/test/gmock.h" |
27 #include "webrtc/test/gtest.h" | 24 #include "webrtc/test/gtest.h" |
28 | 25 |
29 namespace webrtc { | 26 namespace webrtc { |
30 | 27 |
31 namespace { | 28 namespace { |
32 | 29 |
33 using ::testing::_; | 30 using ::testing::_; |
34 using ::testing::AtLeast; | 31 using ::testing::AtLeast; |
35 using ::testing::InSequence; | 32 using ::testing::InSequence; |
36 using ::testing::NiceMock; | 33 using ::testing::NiceMock; |
37 | 34 |
38 class MockRtpPacketSink : public RtpPacketSinkInterface { | 35 class MockRtpPacketSink : public RtpPacketSinkInterface { |
39 public: | 36 public: |
40 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); | 37 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); |
41 }; | 38 }; |
42 | 39 |
43 class MockRsidResolutionObserver : public RsidResolutionObserver { | |
44 public: | |
45 MOCK_METHOD2(OnRsidResolved, void(const std::string& rsid, uint32_t ssrc)); | |
46 }; | |
47 | |
48 MATCHER_P(SamePacketAs, other, "") { | 40 MATCHER_P(SamePacketAs, other, "") { |
49 return arg.Ssrc() == other.Ssrc() && | 41 return arg.Ssrc() == other.Ssrc() && |
50 arg.SequenceNumber() == other.SequenceNumber(); | 42 arg.SequenceNumber() == other.SequenceNumber(); |
51 } | 43 } |
52 | 44 |
53 std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived( | 45 std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived( |
54 uint32_t ssrc, | 46 uint32_t ssrc, |
55 size_t sequence_number = 0) { | 47 size_t sequence_number = 0) { |
56 // |sequence_number| is declared |size_t| to prevent ugly casts when calling | 48 // |sequence_number| is declared |size_t| to prevent ugly casts when calling |
57 // the function, but should in reality always be a |uint16_t|. | 49 // the function, but should in reality always be a |uint16_t|. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 | 112 |
121 // Test tear-down | 113 // Test tear-down |
122 for (const auto& sink : sinks) { | 114 for (const auto& sink : sinks) { |
123 demuxer.RemoveSink(&sink); | 115 demuxer.RemoveSink(&sink); |
124 } | 116 } |
125 } | 117 } |
126 | 118 |
127 TEST(RtpDemuxerTest, PacketsDeliveredInRightOrder) { | 119 TEST(RtpDemuxerTest, PacketsDeliveredInRightOrder) { |
128 RtpDemuxer demuxer; | 120 RtpDemuxer demuxer; |
129 | 121 |
130 constexpr uint32_t ssrc = 101; | 122 constexpr uint32_t ssrcs[] = {101, 202, 303}; |
131 MockRtpPacketSink sink; | 123 MockRtpPacketSink sinks[arraysize(ssrcs)]; |
132 demuxer.AddSink(ssrc, &sink); | 124 for (size_t i = 0; i < arraysize(ssrcs); i++) { |
| 125 demuxer.AddSink(ssrcs[i], &sinks[i]); |
| 126 } |
133 | 127 |
134 std::unique_ptr<RtpPacketReceived> packets[5]; | 128 std::unique_ptr<RtpPacketReceived> packets[5]; |
135 for (size_t i = 0; i < arraysize(packets); i++) { | 129 for (size_t i = 0; i < arraysize(packets); i++) { |
136 packets[i] = CreateRtpPacketReceived(ssrc, i); | 130 packets[i] = CreateRtpPacketReceived(ssrcs[0], i); |
137 } | 131 } |
138 | 132 |
139 InSequence sequence; | 133 InSequence sequence; |
140 for (const auto& packet : packets) { | 134 for (const auto& packet : packets) { |
141 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | 135 EXPECT_CALL(sinks[0], OnRtpPacket(SamePacketAs(*packet))).Times(1); |
142 } | 136 } |
143 | 137 |
144 for (const auto& packet : packets) { | 138 for (const auto& packet : packets) { |
145 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | 139 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
146 } | 140 } |
147 | 141 |
148 // Test tear-down | 142 // Test tear-down |
149 demuxer.RemoveSink(&sink); | 143 for (const auto& sink : sinks) { |
| 144 demuxer.RemoveSink(&sink); |
| 145 } |
150 } | 146 } |
151 | 147 |
152 TEST(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { | 148 TEST(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { |
153 RtpDemuxer demuxer; | 149 RtpDemuxer demuxer; |
154 | 150 |
155 MockRtpPacketSink sinks[3]; | 151 MockRtpPacketSink sinks[3]; |
156 constexpr uint32_t ssrc = 404; | 152 constexpr uint32_t ssrc = 404; |
157 for (auto& sink : sinks) { | 153 for (auto& sink : sinks) { |
158 demuxer.AddSink(ssrc, &sink); | 154 demuxer.AddSink(ssrc, &sink); |
159 } | 155 } |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 auto packet = | 417 auto packet = |
422 CreateRtpPacketReceivedWithRsid(rsids[i], ssrc, sequence_number); | 418 CreateRtpPacketReceivedWithRsid(rsids[i], ssrc, sequence_number); |
423 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | 419 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); |
424 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | 420 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
425 } | 421 } |
426 | 422 |
427 // Test tear-down | 423 // Test tear-down |
428 demuxer.RemoveSink(&sink); | 424 demuxer.RemoveSink(&sink); |
429 } | 425 } |
430 | 426 |
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 | |
456 TEST(RtpDemuxerTest, SinkWithBothRsidAndSsrcAssociations) { | 427 TEST(RtpDemuxerTest, SinkWithBothRsidAndSsrcAssociations) { |
457 RtpDemuxer demuxer; | 428 RtpDemuxer demuxer; |
458 | 429 |
459 MockRtpPacketSink sink; | 430 MockRtpPacketSink sink; |
460 constexpr uint32_t standalone_ssrc = 10101; | 431 constexpr uint32_t standalone_ssrc = 10101; |
461 constexpr uint32_t rsid_ssrc = 20202; | 432 constexpr uint32_t rsid_ssrc = 20202; |
462 const std::string rsid = "a"; | 433 const std::string rsid = "a"; |
463 | 434 |
464 demuxer.AddSink(standalone_ssrc, &sink); | 435 demuxer.AddSink(standalone_ssrc, &sink); |
465 demuxer.AddSink(rsid, &sink); | 436 demuxer.AddSink(rsid, &sink); |
(...skipping 24 matching lines...) Expand all Loading... |
490 | 461 |
491 constexpr uint16_t seq_num = 999; | 462 constexpr uint16_t seq_num = 999; |
492 auto packet = CreateRtpPacketReceivedWithRsid(rsid, ssrc, seq_num); | 463 auto packet = CreateRtpPacketReceivedWithRsid(rsid, ssrc, seq_num); |
493 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | 464 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); |
494 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | 465 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
495 | 466 |
496 // Test tear-down | 467 // Test tear-down |
497 demuxer.RemoveSink(&sink); | 468 demuxer.RemoveSink(&sink); |
498 } | 469 } |
499 | 470 |
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 | |
582 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 471 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
583 TEST(RtpDemuxerTest, RsidMustBeNonEmpty) { | 472 TEST(RtpDemuxerTest, RsidMustBeNonEmpty) { |
584 RtpDemuxer demuxer; | 473 RtpDemuxer demuxer; |
585 MockRtpPacketSink sink; | 474 MockRtpPacketSink sink; |
586 EXPECT_DEATH(demuxer.AddSink("", &sink), ""); | 475 EXPECT_DEATH(demuxer.AddSink("", &sink), ""); |
587 } | 476 } |
588 | 477 |
589 TEST(RtpDemuxerTest, RsidMustBeAlphaNumeric) { | 478 TEST(RtpDemuxerTest, RsidMustBeAlphaNumeric) { |
590 RtpDemuxer demuxer; | 479 RtpDemuxer demuxer; |
591 MockRtpPacketSink sink; | 480 MockRtpPacketSink sink; |
592 EXPECT_DEATH(demuxer.AddSink("a_3", &sink), ""); | 481 EXPECT_DEATH(demuxer.AddSink("a_3", &sink), ""); |
593 } | 482 } |
594 | 483 |
595 TEST(RtpDemuxerTest, RsidMustNotExceedMaximumLength) { | 484 TEST(RtpDemuxerTest, RsidMustNotExceedMaximumLength) { |
596 RtpDemuxer demuxer; | 485 RtpDemuxer demuxer; |
597 MockRtpPacketSink sink; | 486 MockRtpPacketSink sink; |
598 std::string rsid(StreamId::kMaxSize + 1, 'a'); | 487 std::string rsid(StreamId::kMaxSize + 1, 'a'); |
599 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); | 488 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); |
600 } | 489 } |
601 | 490 |
602 TEST(RtpDemuxerTest, RepeatedRsidAssociationsDisallowed) { | 491 TEST(RtpDemuxerTest, RepeatedRsidAssociationsDisallowed) { |
603 RtpDemuxer demuxer; | 492 RtpDemuxer demuxer; |
604 MockRtpPacketSink sink; | 493 MockRtpPacketSink sink; |
605 demuxer.AddSink("a", &sink); | 494 demuxer.AddSink("a", &sink); |
606 EXPECT_DEATH(demuxer.AddSink("a", &sink), ""); | 495 EXPECT_DEATH(demuxer.AddSink("a", &sink), ""); |
607 demuxer.RemoveSink(&sink); | |
608 } | 496 } |
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 | |
626 #endif | 497 #endif |
627 | 498 |
628 } // namespace | 499 } // namespace |
629 } // namespace webrtc | 500 } // namespace webrtc |
OLD | NEW |