Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: webrtc/call/rtp_demuxer_unittest.cc

Issue 2920993002: Add RSID-based demuxing to RtpDemuxer (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
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 webrtc::RtpHeaderExtensionMap extensions;
53 extensions.Register<webrtc::RtpStreamId>(kRsidExtensionId);
54 rtp::Packet::ExtensionManager extensions_manager(extensions);
danilchap 2017/06/02 17:42:19 why not just RtpPacketReceieved::ExtensionManager
eladalon 2017/06/02 19:44:04 1. I'd like to make it very clear when the packet
danilchap 2017/06/07 13:45:41 Good reason! Did you consider two functions to mak
eladalon 2017/06/07 19:30:00 Done.
55 packet = rtc::MakeUnique<RtpPacketReceived>(&extensions_manager);
56 packet->SetExtension<webrtc::RtpStreamId>(*rsid);
57 }
41 packet->SetSsrc(ssrc); 58 packet->SetSsrc(ssrc);
59 packet->SetSequenceNumber(sequence_number);
42 return packet; 60 return packet;
43 } 61 }
44 62
45 class RtpDemuxerTest : public ::testing::Test { 63 class RtpDemuxerTest : public ::testing::Test {
46 protected: 64 protected:
47 RtpDemuxerTest() { 65 RtpDemuxerTest() = default;
danilchap 2017/06/02 17:42:19 feel free to omit default constructor/destructor f
eladalon 2017/06/02 19:44:04 Done.
48 for (size_t i = 0; i < arraysize(sinks); i++) { 66 ~RtpDemuxerTest() override = default;
49 demuxer.AddSink(kSsrcs[i], &sinks[i]);
50 }
51 }
52
53 ~RtpDemuxerTest() override {
54 for (auto& sink : sinks) {
55 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
56 }
57 }
58 67
59 RtpDemuxer demuxer; 68 RtpDemuxer demuxer;
danilchap 2017/06/02 17:42:20 fixture that small easy not to use at all: just an
eladalon 2017/06/02 19:44:04 Done.
60 MockRtpPacketSink sinks[arraysize(kSsrcs)];
61 }; 69 };
62 70
63 TEST_F(RtpDemuxerTest, OnRtpPacketCalledOnCorrectSink) { 71 TEST_F(RtpDemuxerTest, OnRtpPacketCalledOnCorrectSink) {
72 constexpr uint32_t ssrcs[] = {101, 202, 303};
73 MockRtpPacketSink sinks[arraysize(ssrcs)];
74 for (size_t i = 0; i < arraysize(ssrcs); i++) {
75 demuxer.AddSink(ssrcs[i], &sinks[i]);
76 }
77
64 for (size_t i = 0; i < arraysize(sinks); i++) { 78 for (size_t i = 0; i < arraysize(sinks); i++) {
65 auto packet = CreateRtpPacketReceived(kSsrcs[i]); 79 auto packet = CreateRtpPacketReceived(ssrcs[i]);
66 EXPECT_CALL(sinks[i], OnRtpPacket(SsrcSameAsIn(*packet))); 80 EXPECT_CALL(sinks[i], OnRtpPacket(SamePacketAs(*packet))).Times(1);
danilchap 2017/06/02 17:42:19 .Times(1) can by omitted if you wish https://githu
eladalon 2017/06/02 19:44:04 Some people see it as self-documentation. I am sti
67 demuxer.OnRtpPacket(*packet); 81 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
danilchap 2017/06/02 17:42:19 EXPECT_TRUE
eladalon 2017/06/02 19:44:04 Yes, that does look silly.Almost like "if (x == tr
82 }
83
84 // Test tear-down
danilchap 2017/06/02 17:42:19 end comments with a '.'
eladalon 2017/06/02 19:44:04 I believe full stops belong at the end of a senten
85 for (size_t i = 0; i < arraysize(ssrcs); i++) {
86 EXPECT_EQ(demuxer.RemoveSink(&sinks[i]), 1u);
87 }
88 }
89
90 TEST_F(RtpDemuxerTest, PacketsDeliveredInRightOrder) {
91 constexpr uint32_t ssrcs[] = {101, 202, 303};
92 MockRtpPacketSink sinks[arraysize(ssrcs)];
93 for (size_t i = 0; i < arraysize(ssrcs); i++) {
94 demuxer.AddSink(ssrcs[i], &sinks[i]);
95 }
96
97 std::unique_ptr<RtpPacketReceived> packets[5];
98 for (size_t i = 0; i < arraysize(packets); i++) {
99 packets[i] = CreateRtpPacketReceived(ssrcs[0], static_cast<uint16_t>(i));
danilchap 2017/06/02 17:42:20 if you wish to be more explicit, then beeing expli
eladalon 2017/06/02 19:44:04 I'm actually doing this to avoid compiler errors.
100 }
101
102 InSequence sequence;
103 for (auto& packet : packets) {
danilchap 2017/06/02 17:42:19 may by const auto& since you do not change the val
eladalon 2017/06/02 19:44:04 Done.
104 EXPECT_CALL(sinks[0], OnRtpPacket(SamePacketAs(*packet))).Times(1);
105 }
106
107 for (auto& packet : packets) {
108 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
109 }
110
111 // Test tear-down
112 for (size_t i = 0; i < arraysize(ssrcs); i++) {
113 EXPECT_EQ(demuxer.RemoveSink(&sinks[i]), 1u);
68 } 114 }
69 } 115 }
70 116
71 TEST_F(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { 117 TEST_F(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) {
72 // |sinks| associated with different SSRCs each. Add a few additional sinks 118 MockRtpPacketSink sinks[3];
73 // that are all associated with one new, distinct SSRC. 119 constexpr uint32_t ssrc = 404;
74 MockRtpPacketSink same_ssrc_sinks[arraysize(sinks)]; 120 for (auto& sink : sinks) {
75 constexpr uint32_t kSharedSsrc = 404; 121 demuxer.AddSink(ssrc, &sink);
76 for (auto& sink : same_ssrc_sinks) {
77 demuxer.AddSink(kSharedSsrc, &sink);
78 } 122 }
79 123
80 // Reception of an RTP packet associated with the shared SSRC triggers the 124 // Reception of an RTP packet associated with the shared SSRC triggers the
81 // callback on all of the interfaces associated with it. 125 // callback on all of the sinks associated with it.
82 auto packet = CreateRtpPacketReceived(kSharedSsrc); 126 auto packet = CreateRtpPacketReceived(ssrc);
83 for (auto& sink : same_ssrc_sinks) { 127 for (auto& sink : sinks) {
84 EXPECT_CALL(sink, OnRtpPacket(SsrcSameAsIn(*packet))); 128 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet)));
85 } 129 }
86 demuxer.OnRtpPacket(*packet); 130 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
87 131
88 // Test-specific tear-down 132 // Test tear-down
89 for (auto& sink : same_ssrc_sinks) { 133 for (auto& sink : sinks) {
danilchap 2017/06/02 17:42:20 may be const auto&
eladalon 2017/06/02 19:44:04 Done.
90 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u); 134 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
91 } 135 }
92 } 136 }
93 137
94 TEST_F(RtpDemuxerTest, SinkMappedToMultipleSsrcs) { 138 TEST_F(RtpDemuxerTest, SinkMappedToMultipleSsrcs) {
95 // |sinks| associated with different SSRCs each. We set one of them to also 139 constexpr uint32_t ssrcs[] = {404, 505, 606};
96 // be mapped to additional SSRCs. 140 MockRtpPacketSink sink;
97 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; 141 for (uint32_t ssrc : ssrcs) {
98 MockRtpPacketSink multi_ssrc_sink; 142 demuxer.AddSink(ssrc, &sink);
99 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) {
100 demuxer.AddSink(ssrc, &multi_ssrc_sink);
101 } 143 }
102 144
103 // The sink which is associated with multiple SSRCs gets the callback 145 // The sink which is associated with multiple SSRCs gets the callback
104 // triggered for each of those SSRCs. 146 // triggered for each of those SSRCs.
105 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { 147 for (uint32_t ssrc : ssrcs) {
106 auto packet = CreateRtpPacketReceived(ssrc); 148 auto packet = CreateRtpPacketReceived(ssrc);
107 EXPECT_CALL(multi_ssrc_sink, OnRtpPacket(SsrcSameAsIn(*packet))); 149 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet)));
108 demuxer.OnRtpPacket(*packet); 150 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
109 } 151 }
110 152
111 // Test-specific tear-down 153 // Test tear-down
112 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), 154 EXPECT_EQ(demuxer.RemoveSink(&sink), arraysize(ssrcs));
113 arraysize(kSsrcsOfMultiSsrcSink)); 155 }
114 } 156
115 157 TEST_F(RtpDemuxerTest, NoCallbackOnSsrcSinkRemovedBeforeFirstPacket) {
116 TEST_F(RtpDemuxerTest, OnRtpPacketNotCalledOnRemovedSinks) { 158 constexpr uint32_t ssrc = 404;
danilchap 2017/06/02 17:42:19 404 is very good number for test where ssrc will n
eladalon 2017/06/02 19:44:04 :-)
117 // |sinks| associated with different SSRCs each. We set one of them to also 159 MockRtpPacketSink sink;
118 // be mapped to additional SSRCs. 160 demuxer.AddSink(ssrc, &sink);
119 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; 161
120 MockRtpPacketSink multi_ssrc_sink; 162 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
121 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { 163
122 demuxer.AddSink(ssrc, &multi_ssrc_sink); 164 // The removed sink does not get callbacks.
123 } 165 auto packet = CreateRtpPacketReceived(ssrc);
124 166 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0);
125 // Remove the sink. 167 EXPECT_EQ(demuxer.OnRtpPacket(*packet), false);
danilchap 2017/06/02 17:42:19 EXPECT_FALSE
eladalon 2017/06/02 19:44:04 Done.
126 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), 168 }
127 arraysize(kSsrcsOfMultiSsrcSink)); 169
128 170 TEST_F(RtpDemuxerTest, NoCallbackOnSsrcSinkRemovedAfterFirstPacket) {
129 // The removed sink does not get callbacks triggered for any of the SSRCs 171 constexpr uint32_t ssrc = 404;
130 // with which it was previously associated. 172 MockRtpPacketSink sink;
131 EXPECT_CALL(multi_ssrc_sink, OnRtpPacket(_)).Times(0); 173 demuxer.AddSink(ssrc, &sink);
132 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { 174
133 auto packet = CreateRtpPacketReceived(ssrc); 175 InSequence sequence;
134 demuxer.OnRtpPacket(*packet); 176 uint16_t seq_num;
danilchap 2017/06/02 17:42:19 do you use the variable outside the for loop?
eladalon 2017/06/02 19:44:04 Actually, I'd meant to do it for the last packet (
135 } 177 for (seq_num = 0; seq_num < 10; seq_num++) {
178 auto packet = CreateRtpPacketReceived(ssrc, seq_num);
179 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1);
180 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
181 }
182
183 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
184
185 // The removed sink does not get callbacks.
186 auto packet = CreateRtpPacketReceived(ssrc);
187 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0);
188 EXPECT_EQ(demuxer.OnRtpPacket(*packet), false);
189 }
190
191 TEST_F(RtpDemuxerTest, RepeatedSsrcAssociationsDoNotTriggerRepeatedCallbacks) {
192 constexpr uint32_t ssrc = 111;
193 MockRtpPacketSink sink;
194
195 demuxer.AddSink(ssrc, &sink);
196 demuxer.AddSink(ssrc, &sink);
197
198 auto packet = CreateRtpPacketReceived(ssrc);
199 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1);
200 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
201
202 // Test tear-down
203 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
204 }
205
206 TEST_F(RtpDemuxerTest, OnRtpPacketCalledForRsidSink) {
207 MockRtpPacketSink sink;
208 const std::string rsid = "a";
209 demuxer.AddSink(rsid, &sink);
210
211 // Create a sequence of RTP packets, where only the first one actually
212 // mentions the RSID.
213 std::unique_ptr<RtpPacketReceived> packets[5];
214 constexpr uint32_t rsid_ssrc = 111;
215 packets[0] =
216 CreateRtpPacketReceived(rsid_ssrc, static_cast<uint16_t>(0), &rsid);
217 for (size_t i = 1; i < arraysize(packets); i++) {
218 packets[i] = CreateRtpPacketReceived(rsid_ssrc, static_cast<uint16_t>(i));
219 }
220
221 // The first packet associates the RSID with the SSRC, thereby allowing the
222 // demuxer to correctly demux all of the packets.
223 InSequence sequence;
224 for (auto& packet : packets) {
225 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1);
226 }
227 for (auto& packet : packets) {
228 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
229 }
230
231 // Test tear-down
232 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
233 }
234
235 TEST_F(RtpDemuxerTest, NoCallbackOnRsidSinkRemovedBeforeFirstPacket) {
236 MockRtpPacketSink sink;
237 const std::string rsid = "a";
238 demuxer.AddSink(rsid, &sink);
239
240 // Sink removed - it won't get triggers even if packets with its RSID arrive.
241 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
242
243 constexpr uint32_t ssrc = 111;
244 constexpr uint16_t seq_num = 222;
245 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid);
246 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0); // Not called.
247 EXPECT_EQ(demuxer.OnRtpPacket(*packet), false);
248 }
249
250 TEST_F(RtpDemuxerTest, NoCallbackOnRsidSinkRemovedAfterFirstPacket) {
251 MockRtpPacketSink sink;
252 const std::string rsid = "a";
253 demuxer.AddSink(rsid, &sink);
254
255 InSequence sequence;
256 constexpr uint32_t ssrc = 111;
257 uint16_t seq_num;
258 for (seq_num = 0; seq_num < 10; seq_num++) {
259 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid);
260 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1);
261 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
262 }
263
264 // Sink removed - it won't get triggers even if packets with its RSID arrive.
265 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
266
267 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid);
268 EXPECT_CALL(sink, OnRtpPacket(_)).Times(0); // Not called.
269 EXPECT_EQ(demuxer.OnRtpPacket(*packet), false);
270 }
271
272 // The RSID to SSRC mapping should be one-to-one. If we end up receiving
273 // two (or more) packets with the same SSRC, but different RSIDs, we guarantee
274 // remembering the first one; no guarantees are made about further associations.
275 TEST_F(RtpDemuxerTest, FirstSsrcAssociatedWithAnRsidIsNotForgotten) {
276 // Each sink has a distinct RSID.
277 MockRtpPacketSink sink_a;
278 const std::string rsid_a = "a";
279 demuxer.AddSink(rsid_a, &sink_a);
280
281 MockRtpPacketSink sink_b;
282 const std::string rsid_b = "b";
283 demuxer.AddSink(rsid_b, &sink_b);
284
285 InSequence sequence; // Verify that the order of delivery is unchanged.
286
287 constexpr uint32_t kSharedSsrc = 100;
288
289 // First a packet with |rsid_a| is received, and |sink_a| is associated with
290 // its SSRC.
291 auto packet_a =
292 CreateRtpPacketReceived(kSharedSsrc, static_cast<uint16_t>(10), &rsid_a);
293 EXPECT_CALL(sink_a, OnRtpPacket(SamePacketAs(*packet_a))).Times(1);
294 EXPECT_EQ(demuxer.OnRtpPacket(*packet_a), true);
295
296 // Second, a packet with |rsid_b| is received. Its RSID is ignored.
297 auto packet_b =
298 CreateRtpPacketReceived(kSharedSsrc, static_cast<uint16_t>(20), &rsid_b);
299 EXPECT_CALL(sink_a, OnRtpPacket(SamePacketAs(*packet_b))).Times(1);
300 EXPECT_EQ(demuxer.OnRtpPacket(*packet_b), true);
301
302 // Known edge-case; adding a new RSID association makes us re-examine all
303 // SSRCs. |sink_b| may or may not be associated with the SSRC now; we make
304 // no promises on that. We do however still guarantee that |sink_a| still
305 // receives the new packets.
306 MockRtpPacketSink sink_ignored;
307 demuxer.AddSink("ignored", &sink_ignored);
308 auto packet_c =
309 CreateRtpPacketReceived(kSharedSsrc, static_cast<uint16_t>(30), &rsid_b);
310 EXPECT_CALL(sink_a, OnRtpPacket(SamePacketAs(*packet_c))).Times(1);
311 EXPECT_CALL(sink_b, OnRtpPacket(SamePacketAs(*packet_c))).Times(AtLeast(0));
312 EXPECT_EQ(demuxer.OnRtpPacket(*packet_c), true);
313
314 // Test tear-down
315 EXPECT_EQ(demuxer.RemoveSink(&sink_a), 1u);
316 EXPECT_EQ(demuxer.RemoveSink(&sink_b), 1u);
317 EXPECT_EQ(demuxer.RemoveSink(&sink_ignored), 1u);
318 }
319
320 TEST_F(RtpDemuxerTest, MultipleRsidsOnSameSink) {
321 MockRtpPacketSink sink;
322 const std::string rsids[] = {"a", "b", "c"};
323
324 for (const std::string& rsid : rsids) {
325 demuxer.AddSink(rsid, &sink);
326 }
327
328 InSequence sequence;
329 for (size_t i = 0; i < arraysize(rsids); i++) {
330 // Assign different SSRCs and sequence numbers to all packets.
331 const uint32_t ssrc = 1000 + static_cast<uint32_t>(i);
danilchap 2017/06/02 17:42:19 static_cast is probably an overkill here. Do you t
eladalon 2017/06/02 19:44:04 Not readability; trying to keep the trybots' vario
332 const uint16_t sequence_number = 50 + static_cast<uint32_t>(i);
333 auto packet = CreateRtpPacketReceived(ssrc, sequence_number, &rsids[i]);
334 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1);
335 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
336 }
337
338 // Test tear-down
339 EXPECT_EQ(demuxer.RemoveSink(&sink), arraysize(rsids));
340 }
341
342 TEST_F(RtpDemuxerTest, SinkWithBothRsidAndSsrcAssociations) {
343 MockRtpPacketSink sink;
344 constexpr uint32_t standalone_ssrc = 10101;
345 constexpr uint32_t rsid_ssrc = 20202;
346 const std::string rsid = "a";
347
348 demuxer.AddSink(standalone_ssrc, &sink);
349 demuxer.AddSink(rsid, &sink);
350
351 InSequence sequence;
352
353 auto ssrc_packet = CreateRtpPacketReceived(standalone_ssrc, 11);
354 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*ssrc_packet))).Times(1);
355 EXPECT_EQ(demuxer.OnRtpPacket(*ssrc_packet), true);
356
357 auto rsid_packet = CreateRtpPacketReceived(rsid_ssrc, 22, &rsid);
358 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*rsid_packet))).Times(1);
359 EXPECT_EQ(demuxer.OnRtpPacket(*rsid_packet), true);
360
361 // Test tear-down
362 EXPECT_EQ(demuxer.RemoveSink(&sink), 2u);
363 }
364
365 TEST_F(RtpDemuxerTest, AssociatingByRsidAndBySsrcCannotTriggerDoubleCall) {
366 MockRtpPacketSink sink;
367
368 constexpr uint32_t ssrc = 10101;
369 demuxer.AddSink(ssrc, &sink);
370
371 const std::string rsid = "a";
372 demuxer.AddSink(rsid, &sink);
373
374 constexpr uint16_t seq_num = 999;
375 auto packet = CreateRtpPacketReceived(ssrc, seq_num, &rsid);
376 EXPECT_CALL(sink, OnRtpPacket(SamePacketAs(*packet))).Times(1);
377 EXPECT_EQ(demuxer.OnRtpPacket(*packet), true);
378
379 // Test tear-down
380
381 // The RSID and the SSRC associations above have merged into one.
382 EXPECT_EQ(demuxer.RemoveSink(&sink), 1u);
136 } 383 }
137 384
138 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 385 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
139 TEST_F(RtpDemuxerTest, RepeatedAssociationsForbidden) { 386 TEST_F(RtpDemuxerTest, RsidMustBeNonEmpty) {
140 // Set-up already associated sinks[0] with kSsrcs[0]. Repeating the 387 MockRtpPacketSink sink;
141 // association is an error. 388 EXPECT_DEATH(demuxer.AddSink("", &sink), "");
142 EXPECT_DEATH(demuxer.AddSink(kSsrcs[0], &sinks[0]), ""); 389 }
390
391 TEST_F(RtpDemuxerTest, RsidMustBeAlphaNumeric) {
392 MockRtpPacketSink sink;
393 EXPECT_DEATH(demuxer.AddSink("a_3", &sink), "");
394 }
395
396 TEST_F(RtpDemuxerTest, RsidMustNotExceedMaximumLength) {
397 std::stringstream ss;
398 for (size_t i = 0; i < StreamId::kMaxSize + 1; i++) {
399 ss << "a";
400 }
danilchap 2017/06/02 17:42:19 std::string long_rsid(StreamId::kMaxSize + 1, 'a')
eladalon 2017/06/02 19:44:04 Done.
401 MockRtpPacketSink sink;
402 EXPECT_DEATH(demuxer.AddSink(ss.str(), &sink), "");
403 }
404
405 TEST_F(RtpDemuxerTest, RepeatedRsidAssociationsDisallowed) {
406 MockRtpPacketSink sink;
407 demuxer.AddSink("a", &sink);
408 EXPECT_DEATH(demuxer.AddSink("a", &sink), "");
143 } 409 }
144 #endif 410 #endif
145 411
146 } // namespace 412 } // namespace
147 } // namespace webrtc 413 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/call/rtp_demuxer.cc ('k') | webrtc/common_types.h » ('j') | webrtc/common_types.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698