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 | 15 |
15 #include "webrtc/base/arraysize.h" | 16 #include "webrtc/base/arraysize.h" |
16 #include "webrtc/base/checks.h" | 17 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/ptr_util.h" | 18 #include "webrtc/base/ptr_util.h" |
19 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h" | |
danilchap
2017/06/07 13:45:42
thanks to your poke this can be replaced with /rtp
eladalon
2017/06/07 19:30:01
Done.
| |
20 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" | |
18 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" | 21 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" |
19 #include "webrtc/test/gmock.h" | 22 #include "webrtc/test/gmock.h" |
20 #include "webrtc/test/gtest.h" | 23 #include "webrtc/test/gtest.h" |
21 | 24 |
22 namespace webrtc { | 25 namespace webrtc { |
23 | 26 |
24 namespace { | 27 namespace { |
25 | 28 |
26 using ::testing::_; | 29 using ::testing::_; |
30 using ::testing::AtLeast; | |
31 using ::testing::InSequence; | |
27 | 32 |
28 class MockRtpPacketSink : public RtpPacketSinkInterface { | 33 class MockRtpPacketSink : public RtpPacketSinkInterface { |
29 public: | 34 public: |
30 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); | 35 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); |
31 }; | 36 }; |
32 | 37 |
33 constexpr uint32_t kSsrcs[] = {101, 202, 303}; | 38 MATCHER_P(SamePacketAs, other, "") { |
34 | 39 return arg.Ssrc() == other.Ssrc() && |
35 MATCHER_P(SsrcSameAsIn, other, "") { | 40 arg.SequenceNumber() == other.SequenceNumber(); |
36 return arg.Ssrc() == other.Ssrc(); | 41 } |
37 } | 42 |
38 | 43 std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived( |
39 std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived(uint32_t ssrc) { | 44 uint32_t ssrc, |
40 auto packet = rtc::MakeUnique<RtpPacketReceived>(); | 45 uint16_t sequence_number = 0, |
46 const std::string* rsid = nullptr) { | |
47 std::unique_ptr<RtpPacketReceived> packet; | |
48 if (rsid == nullptr) { | |
49 packet = rtc::MakeUnique<RtpPacketReceived>(); | |
50 } else { | |
51 const int kRsidExtensionId = 6; | |
52 rtp::Packet::ExtensionManager extension_manager; | |
danilchap
2017/06/07 13:45:42
may be RtpPacketReceived instead of rtp::Packet
(t
eladalon
2017/06/07 19:30:01
Done.
| |
53 extension_manager.Register<webrtc::RtpStreamId>(kRsidExtensionId); | |
54 packet = rtc::MakeUnique<RtpPacketReceived>(&extension_manager); | |
55 packet->SetExtension<webrtc::RtpStreamId>(*rsid); | |
56 } | |
41 packet->SetSsrc(ssrc); | 57 packet->SetSsrc(ssrc); |
58 packet->SetSequenceNumber(sequence_number); | |
42 return packet; | 59 return packet; |
43 } | 60 } |
44 | 61 |
45 class RtpDemuxerTest : public ::testing::Test { | 62 TEST(RtpDemuxerTest, OnRtpPacketCalledOnCorrectSink) { |
danilchap
2017/06/07 13:45:42
with new demuxer responsibilities may be describe
eladalon
2017/06/07 19:30:01
Appended "BySsrc".
| |
46 protected: | 63 RtpDemuxer demuxer; |
47 RtpDemuxerTest() { | 64 |
48 for (size_t i = 0; i < arraysize(sinks); i++) { | 65 constexpr uint32_t ssrcs[] = {101, 202, 303}; |
49 demuxer.AddSink(kSsrcs[i], &sinks[i]); | 66 MockRtpPacketSink sinks[arraysize(ssrcs)]; |
50 } | 67 for (size_t i = 0; i < arraysize(ssrcs); i++) { |
51 } | 68 demuxer.AddSink(ssrcs[i], &sinks[i]); |
52 | 69 } |
53 ~RtpDemuxerTest() override { | 70 |
54 for (auto& sink : sinks) { | |
55 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | |
56 } | |
57 } | |
58 | |
59 RtpDemuxer demuxer; | |
60 MockRtpPacketSink sinks[arraysize(kSsrcs)]; | |
61 }; | |
62 | |
63 TEST_F(RtpDemuxerTest, OnRtpPacketCalledOnCorrectSink) { | |
64 for (size_t i = 0; i < arraysize(sinks); i++) { | 71 for (size_t i = 0; i < arraysize(sinks); i++) { |
danilchap
2017/06/07 13:45:43
may be, for in-test consistency, use arraysize(sam
eladalon
2017/06/07 19:30:01
Done.
| |
65 auto packet = CreateRtpPacketReceived(kSsrcs[i]); | 72 auto packet = CreateRtpPacketReceived(ssrcs[i]); |
66 EXPECT_CALL(sinks[i], OnRtpPacket(SsrcSameAsIn(*packet))); | 73 EXPECT_CALL(sinks[i], OnRtpPacket(SamePacketAs(*packet))).Times(1); |
67 demuxer.OnRtpPacket(*packet); | 74 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
68 } | 75 } |
69 } | 76 |
70 | 77 // Test tear-down |
71 TEST_F(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { | 78 for (size_t i = 0; i < arraysize(ssrcs); i++) { |
danilchap
2017/06/07 13:45:42
may be use c++11 for loop like in MultipleSinksMap
eladalon
2017/06/07 19:30:01
Done.
| |
72 // |sinks| associated with different SSRCs each. Add a few additional sinks | 79 EXPECT_EQ(demuxer.RemoveSink(&sinks[i]), 1u); |
73 // that are all associated with one new, distinct SSRC. | 80 } |
74 MockRtpPacketSink same_ssrc_sinks[arraysize(sinks)]; | 81 } |
75 constexpr uint32_t kSharedSsrc = 404; | 82 |
76 for (auto& sink : same_ssrc_sinks) { | 83 TEST(RtpDemuxerTest, PacketsDeliveredInRightOrder) { |
danilchap
2017/06/07 13:45:42
I'm not sure what is the value of this test.
Packe
eladalon
2017/06/07 19:30:01
Clarification - the code neither re-orders the pac
| |
77 demuxer.AddSink(kSharedSsrc, &sink); | 84 RtpDemuxer demuxer; |
85 | |
86 constexpr uint32_t ssrcs[] = {101, 202, 303}; | |
87 MockRtpPacketSink sinks[arraysize(ssrcs)]; | |
88 for (size_t i = 0; i < arraysize(ssrcs); i++) { | |
89 demuxer.AddSink(ssrcs[i], &sinks[i]); | |
90 } | |
91 | |
92 std::unique_ptr<RtpPacketReceived> packets[5]; | |
93 for (size_t i = 0; i < arraysize(packets); i++) { | |
94 packets[i] = CreateRtpPacketReceived(ssrcs[0], static_cast<uint16_t>(i)); | |
95 } | |
96 | |
97 InSequence sequence; | |
98 for (const auto& packet : packets) { | |
99 EXPECT_CALL(sinks[0], OnRtpPacket(SamePacketAs(*packet))).Times(1); | |
100 } | |
101 | |
102 for (const auto& packet : packets) { | |
103 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | |
104 } | |
105 | |
106 // Test tear-down | |
107 for (size_t i = 0; i < arraysize(ssrcs); i++) { | |
108 EXPECT_EQ(demuxer.RemoveSink(&sinks[i]), 1u); | |
109 } | |
110 } | |
111 | |
112 TEST(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { | |
danilchap
2017/06/07 13:45:42
may be improve test name by describing what Demuxe
eladalon
2017/06/07 19:30:01
IMHO, clear from context - the demuxer delivers pa
| |
113 RtpDemuxer demuxer; | |
114 | |
115 MockRtpPacketSink sinks[3]; | |
116 constexpr uint32_t ssrc = 404; | |
117 for (auto& sink : sinks) { | |
118 demuxer.AddSink(ssrc, &sink); | |
78 } | 119 } |
79 | 120 |
80 // Reception of an RTP packet associated with the shared SSRC triggers the | 121 // Reception of an RTP packet associated with the shared SSRC triggers the |
81 // callback on all of the interfaces associated with it. | 122 // callback on all of the sinks associated with it. |
82 auto packet = CreateRtpPacketReceived(kSharedSsrc); | 123 auto packet = CreateRtpPacketReceived(ssrc); |
83 for (auto& sink : same_ssrc_sinks) { | 124 for (auto& sink : sinks) { |
84 EXPECT_CALL(sink, OnRtpPacket(SsrcSameAsIn(*packet))); | 125 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))); |
85 } | 126 } |
86 demuxer.OnRtpPacket(*packet); | 127 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
87 | 128 |
88 // Test-specific tear-down | 129 // Test tear-down |
89 for (auto& sink : same_ssrc_sinks) { | 130 for (const auto& sink : sinks) { |
90 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | 131 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); |
91 } | 132 } |
92 } | 133 } |
93 | 134 |
94 TEST_F(RtpDemuxerTest, SinkMappedToMultipleSsrcs) { | 135 TEST(RtpDemuxerTest, SinkMappedToMultipleSsrcs) { |
95 // |sinks| associated with different SSRCs each. We set one of them to also | 136 RtpDemuxer demuxer; |
96 // be mapped to additional SSRCs. | 137 |
97 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; | 138 constexpr uint32_t ssrcs[] = {404, 505, 606}; |
98 MockRtpPacketSink multi_ssrc_sink; | 139 MockRtpPacketSink sink; |
99 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | 140 for (uint32_t ssrc : ssrcs) { |
100 demuxer.AddSink(ssrc, &multi_ssrc_sink); | 141 demuxer.AddSink(ssrc, &sink); |
101 } | 142 } |
102 | 143 |
103 // The sink which is associated with multiple SSRCs gets the callback | 144 // The sink which is associated with multiple SSRCs gets the callback |
104 // triggered for each of those SSRCs. | 145 // triggered for each of those SSRCs. |
105 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | 146 for (uint32_t ssrc : ssrcs) { |
106 auto packet = CreateRtpPacketReceived(ssrc); | 147 auto packet = CreateRtpPacketReceived(ssrc); |
107 EXPECT_CALL(multi_ssrc_sink, OnRtpPacket(SsrcSameAsIn(*packet))); | 148 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))); |
108 demuxer.OnRtpPacket(*packet); | 149 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); |
109 } | 150 } |
110 | 151 |
111 // Test-specific tear-down | 152 // Test tear-down |
112 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), | 153 EXPECT_EQ(demuxer.RemoveSink(&sink), arraysize(ssrcs)); |
113 arraysize(kSsrcsOfMultiSsrcSink)); | 154 } |
114 } | 155 |
115 | 156 TEST(RtpDemuxerTest, NoCallbackOnSsrcSinkRemovedBeforeFirstPacket) { |
116 TEST_F(RtpDemuxerTest, OnRtpPacketNotCalledOnRemovedSinks) { | 157 RtpDemuxer demuxer; |
117 // |sinks| associated with different SSRCs each. We set one of them to also | 158 |
118 // be mapped to additional SSRCs. | 159 constexpr uint32_t ssrc = 404; |
119 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; | 160 MockRtpPacketSink sink; |
120 MockRtpPacketSink multi_ssrc_sink; | 161 demuxer.AddSink(ssrc, &sink); |
121 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | 162 |
122 demuxer.AddSink(ssrc, &multi_ssrc_sink); | 163 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); |
123 } | 164 |
124 | 165 // The removed sink does not get callbacks. |
125 // Remove the sink. | 166 auto packet = CreateRtpPacketReceived(ssrc); |
126 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), | 167 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0); |
127 arraysize(kSsrcsOfMultiSsrcSink)); | 168 EXPECT_FALSE(demuxer.OnRtpPacket(*packet)); |
128 | 169 } |
129 // The removed sink does not get callbacks triggered for any of the SSRCs | 170 |
130 // with which it was previously associated. | 171 TEST(RtpDemuxerTest, NoCallbackOnSsrcSinkRemovedAfterFirstPacket) { |
131 EXPECT_CALL(multi_ssrc_sink, OnRtpPacket(_)).Times(0); | 172 RtpDemuxer demuxer; |
132 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | 173 |
133 auto packet = CreateRtpPacketReceived(ssrc); | 174 constexpr uint32_t ssrc = 404; |
134 demuxer.OnRtpPacket(*packet); | 175 MockRtpPacketSink sink; |
135 } | 176 demuxer.AddSink(ssrc, &sink); |
177 | |
178 InSequence sequence; | |
179 uint16_t seq_num; | |
180 for (seq_num = 0; seq_num < 10; seq_num++) { | |
181 auto packet = CreateRtpPacketReceived(ssrc, seq_num); | |
182 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | |
183 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | |
184 } | |
185 | |
186 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | |
187 | |
188 // The removed sink does not get callbacks. | |
189 auto packet = CreateRtpPacketReceived(ssrc, seq_num); | |
190 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0); | |
191 EXPECT_FALSE(demuxer.OnRtpPacket(*packet)); | |
192 } | |
193 | |
194 TEST(RtpDemuxerTest, RepeatedSsrcAssociationsDoNotTriggerRepeatedCallbacks) { | |
195 RtpDemuxer demuxer; | |
196 | |
197 constexpr uint32_t ssrc = 111; | |
198 MockRtpPacketSink sink; | |
199 | |
200 demuxer.AddSink(ssrc, &sink); | |
201 demuxer.AddSink(ssrc, &sink); | |
202 | |
203 auto packet = CreateRtpPacketReceived(ssrc); | |
204 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | |
205 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | |
206 | |
207 // Test tear-down | |
208 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | |
209 } | |
210 | |
211 TEST(RtpDemuxerTest, OnRtpPacketCalledForRsidSink) { | |
212 RtpDemuxer demuxer; | |
213 | |
214 MockRtpPacketSink sink; | |
215 const std::string rsid = "a"; | |
216 demuxer.AddSink(rsid, &sink); | |
217 | |
218 // Create a sequence of RTP packets, where only the first one actually | |
219 // mentions the RSID. | |
220 std::unique_ptr<RtpPacketReceived> packets[5]; | |
221 constexpr uint32_t rsid_ssrc = 111; | |
222 packets[0] = | |
223 CreateRtpPacketReceived(rsid_ssrc, static_cast<uint16_t>(0), &rsid); | |
224 for (size_t i = 1; i < arraysize(packets); i++) { | |
225 packets[i] = CreateRtpPacketReceived(rsid_ssrc, static_cast<uint16_t>(i)); | |
danilchap
2017/06/07 13:45:42
may be change CreateRtpPacket to take int for sequ
eladalon
2017/06/07 19:30:01
I've adopted, but took size_t instead of int, beca
| |
226 } | |
227 | |
228 // The first packet associates the RSID with the SSRC, thereby allowing the | |
229 // demuxer to correctly demux all of the packets. | |
230 InSequence sequence; | |
231 for (const auto& packet : packets) { | |
232 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | |
233 } | |
234 for (const auto& packet : packets) { | |
235 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | |
236 } | |
237 | |
238 // Test tear-down | |
239 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | |
240 } | |
241 | |
242 TEST(RtpDemuxerTest, NoCallbackOnRsidSinkRemovedBeforeFirstPacket) { | |
243 RtpDemuxer demuxer; | |
244 | |
245 MockRtpPacketSink sink; | |
246 const std::string rsid = "a"; | |
247 demuxer.AddSink(rsid, &sink); | |
248 | |
249 // Sink removed - it won't get triggers even if packets with its RSID arrive. | |
250 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | |
251 | |
252 constexpr uint32_t ssrc = 111; | |
253 constexpr uint16_t seq_num = 222; | |
254 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid); | |
255 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0); // Not called. | |
256 EXPECT_FALSE(demuxer.OnRtpPacket(*packet)); | |
257 } | |
258 | |
259 TEST(RtpDemuxerTest, NoCallbackOnRsidSinkRemovedAfterFirstPacket) { | |
260 RtpDemuxer demuxer; | |
261 | |
262 MockRtpPacketSink sink; | |
263 const std::string rsid = "a"; | |
264 demuxer.AddSink(rsid, &sink); | |
265 | |
266 InSequence sequence; | |
267 constexpr uint32_t ssrc = 111; | |
268 uint16_t seq_num; | |
269 for (seq_num = 0; seq_num < 10; seq_num++) { | |
270 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid); | |
271 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | |
272 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | |
273 } | |
274 | |
275 // Sink removed - it won't get triggers even if packets with its RSID arrive. | |
276 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | |
277 | |
278 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid); | |
279 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0); // Not called. | |
280 EXPECT_FALSE(demuxer.OnRtpPacket(*packet)); | |
281 } | |
282 | |
283 // The RSID to SSRC mapping should be one-to-one. If we end up receiving | |
284 // two (or more) packets with the same SSRC, but different RSIDs, we guarantee | |
285 // remembering the first one; no guarantees are made about further associations. | |
286 TEST(RtpDemuxerTest, FirstSsrcAssociatedWithAnRsidIsNotForgotten) { | |
287 RtpDemuxer demuxer; | |
288 | |
289 // Each sink has a distinct RSID. | |
290 MockRtpPacketSink sink_a; | |
291 const std::string rsid_a = "a"; | |
292 demuxer.AddSink(rsid_a, &sink_a); | |
293 | |
294 MockRtpPacketSink sink_b; | |
295 const std::string rsid_b = "b"; | |
296 demuxer.AddSink(rsid_b, &sink_b); | |
297 | |
298 InSequence sequence; // Verify that the order of delivery is unchanged. | |
299 | |
300 constexpr uint32_t kSharedSsrc = 100; | |
danilchap
2017/06/07 13:45:42
sometimes you use constant name style for ssrc con
eladalon
2017/06/07 19:30:01
Done.
| |
301 | |
302 // First a packet with |rsid_a| is received, and |sink_a| is associated with | |
303 // its SSRC. | |
304 auto packet_a = | |
danilchap
2017/06/07 13:45:42
since packet 'b' doesn't map to sink 'b' may be us
eladalon
2017/06/07 19:30:01
Please refer to this comment:
// Second, a packet
| |
305 CreateRtpPacketReceived(kSharedSsrc, static_cast<uint16_t>(10), &rsid_a); | |
306 EXPECT_CALL(sink_a, OnRtpPacket(SamePacketAs(*packet_a))).Times(1); | |
307 EXPECT_TRUE(demuxer.OnRtpPacket(*packet_a)); | |
308 | |
309 // Second, a packet with |rsid_b| is received. Its RSID is ignored. | |
310 auto packet_b = | |
311 CreateRtpPacketReceived(kSharedSsrc, static_cast<uint16_t>(20), &rsid_b); | |
312 EXPECT_CALL(sink_a, OnRtpPacket(SamePacketAs(*packet_b))).Times(1); | |
313 EXPECT_TRUE(demuxer.OnRtpPacket(*packet_b)); | |
314 | |
315 // Known edge-case; adding a new RSID association makes us re-examine all | |
316 // SSRCs. |sink_b| may or may not be associated with the SSRC now; we make | |
317 // no promises on that. We do however still guarantee that |sink_a| still | |
318 // receives the new packets. | |
319 MockRtpPacketSink sink_ignored; | |
320 demuxer.AddSink("ignored", &sink_ignored); | |
321 auto packet_c = | |
322 CreateRtpPacketReceived(kSharedSsrc, static_cast<uint16_t>(30), &rsid_b); | |
323 EXPECT_CALL(sink_a, OnRtpPacket(SamePacketAs(*packet_c))).Times(1); | |
324 EXPECT_CALL(sink_b, OnRtpPacket(SamePacketAs(*packet_c))).Times(AtLeast(0)); | |
325 EXPECT_TRUE(demuxer.OnRtpPacket(*packet_c)); | |
326 | |
327 // Test tear-down | |
328 EXPECT_EQ(demuxer.RemoveSink(&sink_a), 1u); | |
329 EXPECT_EQ(demuxer.RemoveSink(&sink_b), 1u); | |
330 EXPECT_EQ(demuxer.RemoveSink(&sink_ignored), 1u); | |
331 } | |
332 | |
333 TEST(RtpDemuxerTest, MultipleRsidsOnSameSink) { | |
334 RtpDemuxer demuxer; | |
335 | |
336 MockRtpPacketSink sink; | |
337 const std::string rsids[] = {"a", "b", "c"}; | |
338 | |
339 for (const std::string& rsid : rsids) { | |
340 demuxer.AddSink(rsid, &sink); | |
341 } | |
342 | |
343 InSequence sequence; | |
344 for (size_t i = 0; i < arraysize(rsids); i++) { | |
345 // Assign different SSRCs and sequence numbers to all packets. | |
346 const uint32_t ssrc = 1000 + static_cast<uint32_t>(i); | |
347 const uint16_t sequence_number = 50 + static_cast<uint32_t>(i); | |
348 auto packet = CreateRtpPacketReceived(ssrc, sequence_number, &rsids[i]); | |
349 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | |
350 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | |
351 } | |
352 | |
353 // Test tear-down | |
354 EXPECT_EQ(demuxer.RemoveSink(&sink), arraysize(rsids)); | |
355 } | |
356 | |
357 TEST(RtpDemuxerTest, SinkWithBothRsidAndSsrcAssociations) { | |
358 RtpDemuxer demuxer; | |
359 | |
360 MockRtpPacketSink sink; | |
361 constexpr uint32_t standalone_ssrc = 10101; | |
362 constexpr uint32_t rsid_ssrc = 20202; | |
363 const std::string rsid = "a"; | |
364 | |
365 demuxer.AddSink(standalone_ssrc, &sink); | |
366 demuxer.AddSink(rsid, &sink); | |
367 | |
368 InSequence sequence; | |
369 | |
370 auto ssrc_packet = CreateRtpPacketReceived(standalone_ssrc, 11); | |
371 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*ssrc_packet))).Times(1); | |
372 EXPECT_TRUE(demuxer.OnRtpPacket(*ssrc_packet)); | |
373 | |
374 auto rsid_packet = CreateRtpPacketReceived(rsid_ssrc, 22, &rsid); | |
375 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*rsid_packet))).Times(1); | |
376 EXPECT_TRUE(demuxer.OnRtpPacket(*rsid_packet)); | |
377 | |
378 // Test tear-down | |
379 EXPECT_EQ(demuxer.RemoveSink(&sink), 2u); | |
380 } | |
381 | |
382 TEST(RtpDemuxerTest, AssociatingByRsidAndBySsrcCannotTriggerDoubleCall) { | |
383 RtpDemuxer demuxer; | |
384 MockRtpPacketSink sink; | |
385 | |
386 constexpr uint32_t ssrc = 10101; | |
387 demuxer.AddSink(ssrc, &sink); | |
388 | |
389 const std::string rsid = "a"; | |
390 demuxer.AddSink(rsid, &sink); | |
391 | |
392 constexpr uint16_t seq_num = 999; | |
393 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid); | |
394 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1); | |
395 EXPECT_TRUE(demuxer.OnRtpPacket(*packet)); | |
396 | |
397 // Test tear-down | |
398 | |
399 // The RSID and the SSRC associations above have merged into one. | |
danilchap
2017/06/07 13:45:42
what is deletion count? is it number of times AddS
eladalon
2017/06/07 19:30:01
I've previously discussed this problem with nisse@
| |
400 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); | |
136 } | 401 } |
137 | 402 |
138 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | 403 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) |
139 TEST_F(RtpDemuxerTest, RepeatedAssociationsForbidden) { | 404 TEST(RtpDemuxerTest, RsidMustBeNonEmpty) { |
140 // Set-up already associated sinks[0] with kSsrcs[0]. Repeating the | 405 RtpDemuxer demuxer; |
141 // association is an error. | 406 MockRtpPacketSink sink; |
142 EXPECT_DEATH(demuxer.AddSink(kSsrcs[0], &sinks[0]), ""); | 407 EXPECT_DEATH(demuxer.AddSink("", &sink), ""); |
408 } | |
409 | |
410 TEST(RtpDemuxerTest, RsidMustBeAlphaNumeric) { | |
411 RtpDemuxer demuxer; | |
412 MockRtpPacketSink sink; | |
413 EXPECT_DEATH(demuxer.AddSink("a_3", &sink), ""); | |
414 } | |
415 | |
416 TEST(RtpDemuxerTest, RsidMustNotExceedMaximumLength) { | |
417 RtpDemuxer demuxer; | |
418 MockRtpPacketSink sink; | |
419 std::string rsid(StreamId::kMaxSize + 1, 'a'); | |
420 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); | |
421 } | |
422 | |
423 TEST(RtpDemuxerTest, RepeatedRsidAssociationsDisallowed) { | |
424 RtpDemuxer demuxer; | |
425 MockRtpPacketSink sink; | |
426 demuxer.AddSink("a", &sink); | |
427 EXPECT_DEATH(demuxer.AddSink("a", &sink), ""); | |
143 } | 428 } |
144 #endif | 429 #endif |
145 | 430 |
146 } // namespace | 431 } // namespace |
147 } // namespace webrtc | 432 } // namespace webrtc |
OLD | NEW |