OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | |
3 * | |
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 | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/call/rtp_demuxer.h" | |
12 | |
13 #include <memory> | |
14 | |
15 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" | |
16 | |
17 #include "webrtc/base/arraysize.h" | |
18 #include "webrtc/base/checks.h" | |
19 #include "webrtc/test/gmock.h" | |
20 #include "webrtc/test/gtest.h" | |
21 | |
22 namespace webrtc { | |
23 | |
24 namespace { | |
25 | |
26 class MockRtpPacketSink : public RtpPacketSinkInterface { | |
27 public: | |
28 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); | |
29 }; | |
30 | |
31 constexpr uint32_t kSsrcs[] = {101, 202, 303}; | |
32 | |
33 MATCHER_P(SsrcSameAsIn, other, "") { | |
34 return arg.Ssrc() == other.Ssrc(); | |
35 } | |
36 | |
37 std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived(uint32_t ssrc) { | |
38 std::unique_ptr<RtpPacketReceived> packet(new RtpPacketReceived()); | |
39 packet->SetSsrc(ssrc); | |
40 return packet; | |
41 } | |
42 | |
43 class RtpDemuxerTest : public ::testing::Test { | |
44 protected: | |
45 RtpDemuxerTest() { | |
46 for (size_t i = 0; i < kNumOfSinks; i++) { | |
47 demuxer.AddSink(kSsrcs[i], &sinks[i]); | |
48 } | |
49 } | |
50 | |
51 ~RtpDemuxerTest() override { | |
52 for (size_t i = 0; i < kNumOfSinks; i++) { | |
53 EXPECT_EQ(demuxer.RemoveSink(&sinks[i]), 1u); | |
54 } | |
55 } | |
56 | |
57 RtpDemuxer demuxer; | |
58 static constexpr size_t kNumOfSinks = 3; | |
nisse-webrtc
2017/05/29 07:58:22
I'm no real c++ guru, but does static really make
danilchap
2017/05/29 08:59:53
afaik it is a compile error to use constexpr witho
| |
59 MockRtpPacketSink sinks[kNumOfSinks]; | |
60 }; | |
61 | |
62 TEST_F(RtpDemuxerTest, OnRtpPacketCalledOnCorrectSink) { | |
63 for (size_t i = 0; i < kNumOfSinks; i++) { | |
64 auto packet = CreateRtpPacketReceived(kSsrcs[i]); | |
65 EXPECT_CALL(sinks[i], OnRtpPacket(SsrcSameAsIn(*packet))); | |
nisse-webrtc
2017/05/29 07:58:22
You could compare the address of the packet, which
eladalon
2017/05/30 14:23:37
Thanks for the tip, but I think it would introduce
| |
66 demuxer.OnRtpPacket(*packet); | |
67 testing::Mock::VerifyAndClearExpectations(&sinks[i]); | |
nisse-webrtc
2017/05/29 07:58:22
Why do you need to call this explicitly? If it's r
eladalon
2017/05/30 14:23:37
I'll remove, then.
| |
68 } | |
69 } | |
70 | |
71 TEST_F(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { | |
72 // |sinks| associated with different SSRCs each. Add a few additional sinks | |
73 // that are all associated with one new, distinct SSRC. | |
74 constexpr size_t kNumOfSameSsrcSinks = 3; | |
75 MockRtpPacketSink same_ssrc_sinks[kNumOfSameSsrcSinks]; | |
76 constexpr uint32_t kSharedSsrc = 404; | |
77 for (size_t i = 0; i < kNumOfSameSsrcSinks; i++) { | |
78 demuxer.AddSink(kSharedSsrc, &same_ssrc_sinks[i]); | |
79 } | |
80 | |
81 // Reception of an RTP packet associated with the shared SSRC triggers the | |
82 // callback on all of the interfaces associated with it. | |
83 auto packet = CreateRtpPacketReceived(kSharedSsrc); | |
84 for (size_t i = 0; i < kNumOfSameSsrcSinks; i++) { | |
85 EXPECT_CALL(same_ssrc_sinks[i], OnRtpPacket(SsrcSameAsIn(*packet))); | |
86 } | |
87 demuxer.OnRtpPacket(*packet); | |
88 | |
89 // Test-specific tear-down | |
90 for (size_t i = 0; i < kNumOfSameSsrcSinks; i++) { | |
91 EXPECT_EQ(demuxer.RemoveSink(&same_ssrc_sinks[i]), 1u); | |
92 } | |
93 } | |
94 | |
95 TEST_F(RtpDemuxerTest, SinkMappedToMultipleSsrcs) { | |
96 // |sinks| associated with different SSRCs each. We set one of them to also | |
97 // be mapped to additional SSRCs. | |
98 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; | |
99 MockRtpPacketSink multi_ssrc_sink; | |
100 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
101 demuxer.AddSink(ssrc, &multi_ssrc_sink); | |
102 } | |
103 | |
104 // The sink which is associated with multiple SSRCs gets the callback | |
105 // triggered for each of those SSRCs. | |
106 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
107 auto packet = CreateRtpPacketReceived(ssrc); | |
108 EXPECT_CALL(multi_ssrc_sink, OnRtpPacket(SsrcSameAsIn(*packet))); | |
109 demuxer.OnRtpPacket(*packet); | |
110 testing::Mock::VerifyAndClearExpectations(&multi_ssrc_sink); | |
111 } | |
112 | |
113 // Test-specific tear-down | |
114 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), | |
115 arraysize(kSsrcsOfMultiSsrcSink)); | |
116 } | |
117 | |
118 TEST_F(RtpDemuxerTest, OnRtpPacketNotCalledOnRemovedSinks) { | |
119 // |sinks| associated with different SSRCs each. We set one of them to also | |
120 // be mapped to additional SSRCs. | |
121 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; | |
122 MockRtpPacketSink multi_ssrc_sink; | |
123 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
124 demuxer.AddSink(ssrc, &multi_ssrc_sink); | |
125 } | |
126 | |
127 // Remove the sink. | |
128 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), | |
129 arraysize(kSsrcsOfMultiSsrcSink)); | |
130 | |
131 // The removed sink does not get callbacks triggered for any of the SSRCs | |
132 // with which it was previously associated. | |
133 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
134 auto packet = CreateRtpPacketReceived(ssrc); | |
135 demuxer.OnRtpPacket(*packet); | |
136 } | |
137 } | |
138 | |
139 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
140 TEST_F(RtpDemuxerTest, RepeatedAssociationsForbidden) { | |
141 // Set-up already associated sinks[0] with kSsrcs[0]. Repeating the | |
142 // association is an error. | |
143 EXPECT_DEATH(demuxer.AddSink(kSsrcs[0], &sinks[0]), ""); | |
144 } | |
145 | |
146 TEST_F(RtpDemuxerTest, SinksMustBeRemovedBeforeDestruction) { | |
147 std::unique_ptr<RtpDemuxer> bad_demuxer(new RtpDemuxer()); | |
148 MockRtpPacketSink sink; | |
149 constexpr uint32_t ssrc = 111; | |
150 bad_demuxer->AddSink(ssrc, &sink); | |
151 EXPECT_DEATH(bad_demuxer.reset(), ""); | |
152 EXPECT_EQ(bad_demuxer->RemoveSink(&sink), 1u); | |
153 } | |
154 #endif | |
155 | |
156 } // namespace | |
157 } // namespace webrtc | |
OLD | NEW |