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 <memory> | |
12 | |
13 #include "webrtc/common_types.h" | |
14 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" | |
15 #include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h" | |
16 #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h" | |
17 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" | |
18 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_impl.h" | |
19 #include "webrtc/test/gtest.h" | |
20 | |
21 namespace webrtc { | |
22 | |
danilchap
2017/04/10 12:14:06
tests, specially with constants, better to place i
| |
23 const uint32_t kTestRate = 64000u; | |
24 const uint8_t kTestPayload[] = {'t', 'e', 's', 't'}; | |
25 const uint8_t kPcmuPayloadType = 96; | |
26 const int64_t kGetSourcesTimeoutMs = 10000; | |
27 const int kSourceListsSize = 20; | |
28 | |
29 class RtpReceiverTest : public ::testing::Test { | |
30 protected: | |
31 RtpReceiverTest() | |
32 : fake_clock_(123456), | |
33 rtp_receiver_( | |
34 RtpReceiver::CreateAudioReceiver(&fake_clock_, | |
35 nullptr, | |
36 nullptr, | |
37 &rtp_payload_registry_)) { | |
38 CodecInst voice_codec = {}; | |
39 voice_codec.pltype = kPcmuPayloadType; | |
40 voice_codec.plfreq = 8000; | |
41 voice_codec.rate = kTestRate; | |
42 memcpy(voice_codec.plname, "PCMU", 5); | |
43 rtp_receiver_->RegisterReceivePayload(voice_codec); | |
44 } | |
45 ~RtpReceiverTest() {} | |
46 | |
47 bool FindSourceByIdAndType(const std::vector<RtpSource>& sources, | |
48 uint32_t source_id, | |
49 RtpSourceType type, | |
50 RtpSource* source) { | |
51 for (size_t i = 0; i < sources.size(); ++i) { | |
52 if (sources[i].source_id() == source_id && | |
53 sources[i].source_type() == type) { | |
54 (*source) = sources[i]; | |
55 return true; | |
56 } | |
57 } | |
58 return false; | |
59 } | |
60 | |
61 SimulatedClock fake_clock_; | |
62 RTPPayloadRegistry rtp_payload_registry_; | |
63 std::unique_ptr<RtpReceiver> rtp_receiver_; | |
64 }; | |
65 | |
66 TEST_F(RtpReceiverTest, GetSources) { | |
67 RTPHeader header; | |
68 header.payloadType = kPcmuPayloadType; | |
69 header.ssrc = 1; | |
danilchap
2017/04/10 12:14:06
might be better to name all [cs]src constants, spe
| |
70 header.timestamp = fake_clock_.TimeInMilliseconds(); | |
danilchap
2017/04/10 12:14:06
it looks wrong to use current_time as rtp timestam
| |
71 header.numCSRCs = 2; | |
72 header.arrOfCSRCs[0] = 111; | |
73 header.arrOfCSRCs[1] = 222; | |
74 PayloadUnion payload_specific = {AudioPayload()}; | |
75 bool in_order = false; | |
danilchap
2017/04/10 12:14:06
may be bool in_order = true; // or better kInOrder
| |
76 RtpSource source(0, 0, RtpSourceType::SSRC); | |
77 | |
78 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
danilchap
2017/04/10 12:14:06
may be sizeof(kTestPayload) instead of 'magic' val
| |
79 payload_specific, in_order)); | |
80 auto sources = rtp_receiver_->GetSources(); | |
81 // One SSRC source and two CSRC sources. | |
82 ASSERT_EQ(3u, sources.size()); | |
danilchap
2017/04/10 12:14:06
with gmock and RtpSource::operator== or customer m
| |
83 ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source)); | |
84 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms()); | |
85 ASSERT_TRUE( | |
86 FindSourceByIdAndType(sources, 222u, RtpSourceType::CSRC, &source)); | |
87 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms()); | |
88 ASSERT_TRUE( | |
89 FindSourceByIdAndType(sources, 111u, RtpSourceType::CSRC, &source)); | |
90 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms()); | |
91 | |
92 // Advance the fake clock and the method is expected to return the | |
93 // contributing source object with same source id and updated timestamp. | |
94 fake_clock_.AdvanceTimeMilliseconds(1); | |
95 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
96 payload_specific, in_order)); | |
97 sources = rtp_receiver_->GetSources(); | |
98 ASSERT_EQ(3u, sources.size()); | |
99 ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source)); | |
100 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms()); | |
101 ASSERT_TRUE( | |
102 FindSourceByIdAndType(sources, 222u, RtpSourceType::CSRC, &source)); | |
103 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms()); | |
104 ASSERT_TRUE( | |
105 FindSourceByIdAndType(sources, 111u, RtpSourceType::CSRC, &source)); | |
106 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), source.timestamp_ms()); | |
107 | |
108 // Test the edge case that the sources are still there just before the | |
109 // timeout. | |
110 int64_t prev_timestamp = fake_clock_.TimeInMilliseconds(); | |
111 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs); | |
112 sources = rtp_receiver_->GetSources(); | |
113 ASSERT_EQ(3u, sources.size()); | |
114 ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source)); | |
115 EXPECT_EQ(prev_timestamp, source.timestamp_ms()); | |
116 ASSERT_TRUE( | |
117 FindSourceByIdAndType(sources, 222u, RtpSourceType::CSRC, &source)); | |
118 EXPECT_EQ(prev_timestamp, source.timestamp_ms()); | |
119 ASSERT_TRUE( | |
120 FindSourceByIdAndType(sources, 111u, RtpSourceType::CSRC, &source)); | |
121 EXPECT_EQ(prev_timestamp, source.timestamp_ms()); | |
122 | |
123 // Time out. | |
124 fake_clock_.AdvanceTimeMilliseconds(1); | |
125 sources = rtp_receiver_->GetSources(); | |
126 // All the sources should be out of date. | |
127 ASSERT_EQ(0u, sources.size()); | |
128 } | |
129 | |
130 // Test the case that the SSRC is changed. | |
131 TEST_F(RtpReceiverTest, GetSourcesChangeSSRC) { | |
132 int64_t prev_time = -1; | |
133 int64_t cur_time = fake_clock_.TimeInMilliseconds(); | |
danilchap
2017/04/10 12:14:07
now_ms is probably more common name in the codebas
| |
134 RTPHeader header; | |
135 header.payloadType = kPcmuPayloadType; | |
136 header.ssrc = 1; | |
137 header.timestamp = cur_time; | |
138 PayloadUnion payload_specific = {AudioPayload()}; | |
139 bool in_order = false; | |
140 RtpSource source(0, 0, RtpSourceType::SSRC); | |
141 | |
142 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
143 payload_specific, in_order)); | |
144 auto sources = rtp_receiver_->GetSources(); | |
145 ASSERT_EQ(1u, sources.size()); | |
146 EXPECT_EQ(1u, sources[0].source_id()); | |
147 EXPECT_EQ(cur_time, sources[0].timestamp_ms()); | |
148 | |
149 // The SSRC is changed and the old SSRC is expected to be returned. | |
150 fake_clock_.AdvanceTimeMilliseconds(100); | |
151 prev_time = cur_time; | |
152 cur_time = fake_clock_.TimeInMilliseconds(); | |
153 header.ssrc = 2; | |
154 header.timestamp = cur_time; | |
155 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
156 payload_specific, in_order)); | |
157 sources = rtp_receiver_->GetSources(); | |
158 ASSERT_EQ(2u, sources.size()); | |
159 ASSERT_TRUE(FindSourceByIdAndType(sources, 2u, RtpSourceType::SSRC, &source)); | |
160 EXPECT_EQ(cur_time, source.timestamp_ms()); | |
161 ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source)); | |
162 EXPECT_EQ(prev_time, source.timestamp_ms()); | |
163 | |
164 // The SSRC is changed again and happen to be changed back to 1. No | |
165 // duplication is expected. | |
166 fake_clock_.AdvanceTimeMilliseconds(100); | |
167 header.ssrc = 1; | |
168 header.timestamp = cur_time; | |
169 prev_time = cur_time; | |
170 cur_time = fake_clock_.TimeInMilliseconds(); | |
171 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
172 payload_specific, in_order)); | |
173 sources = rtp_receiver_->GetSources(); | |
174 ASSERT_EQ(2u, sources.size()); | |
175 ASSERT_TRUE(FindSourceByIdAndType(sources, 1u, RtpSourceType::SSRC, &source)); | |
176 EXPECT_EQ(cur_time, source.timestamp_ms()); | |
177 ASSERT_TRUE(FindSourceByIdAndType(sources, 2u, RtpSourceType::SSRC, &source)); | |
178 EXPECT_EQ(prev_time, source.timestamp_ms()); | |
179 | |
180 // Old SSRC source timeout. | |
181 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs); | |
182 cur_time = fake_clock_.TimeInMilliseconds(); | |
183 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
184 payload_specific, in_order)); | |
185 sources = rtp_receiver_->GetSources(); | |
186 ASSERT_EQ(1u, sources.size()); | |
187 EXPECT_EQ(1u, sources[0].source_id()); | |
188 EXPECT_EQ(cur_time, sources[0].timestamp_ms()); | |
189 EXPECT_EQ(RtpSourceType::SSRC, sources[0].source_type()); | |
190 } | |
191 | |
192 TEST_F(RtpReceiverTest, GetSourcesRemoveOutdatedSource) { | |
193 int64_t timestamp = fake_clock_.TimeInMilliseconds(); | |
194 bool in_order = false; | |
195 RTPHeader header; | |
196 header.payloadType = kPcmuPayloadType; | |
197 header.timestamp = timestamp; | |
198 PayloadUnion payload_specific = {AudioPayload()}; | |
199 header.numCSRCs = 1; | |
200 RtpSource source(0, 0, RtpSourceType::SSRC); | |
201 | |
202 for (size_t i = 0; i < kSourceListsSize; ++i) { | |
danilchap
2017/04/10 12:14:06
any plan to use this constant in another test? if
| |
203 header.ssrc = i; | |
204 header.arrOfCSRCs[0] = (i + 1); | |
danilchap
2017/04/10 12:14:06
is it intended CSRC is same as SSRC of the next pa
| |
205 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
206 payload_specific, in_order)); | |
207 } | |
208 | |
209 auto sources = rtp_receiver_->GetSources(); | |
210 // Expect |kSourceListsSize| SSRC sources and |kSourceListsSize| CSRC sources. | |
211 ASSERT_TRUE(sources.size() == 2 * kSourceListsSize); | |
212 for (size_t i = 0; i < kSourceListsSize; ++i) { | |
213 // The SSRC source IDs are expected to be 19, 18, 17 ... 0 | |
214 ASSERT_TRUE( | |
215 FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source)); | |
216 EXPECT_EQ(timestamp, source.timestamp_ms()); | |
217 | |
218 // The CSRC source IDs are expected to be 20, 19, 18 ... 1 | |
219 ASSERT_TRUE( | |
220 FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source)); | |
221 EXPECT_EQ(timestamp, source.timestamp_ms()); | |
222 } | |
223 | |
224 fake_clock_.AdvanceTimeMilliseconds(kGetSourcesTimeoutMs); | |
225 for (size_t i = 0; i < kSourceListsSize; ++i) { | |
226 // The SSRC source IDs are expected to be 19, 18, 17 ... 0 | |
227 ASSERT_TRUE( | |
228 FindSourceByIdAndType(sources, i, RtpSourceType::SSRC, &source)); | |
229 EXPECT_EQ(timestamp, source.timestamp_ms()); | |
230 | |
231 // The CSRC source IDs are expected to be 20, 19, 18 ... 1 | |
232 ASSERT_TRUE( | |
233 FindSourceByIdAndType(sources, (i + 1), RtpSourceType::CSRC, &source)); | |
234 EXPECT_EQ(timestamp, source.timestamp_ms()); | |
235 } | |
236 | |
237 // Timeout. All the existing objects are out of date and are expected to be | |
238 // removed. | |
239 fake_clock_.AdvanceTimeMilliseconds(1); | |
240 header.ssrc = 111; | |
241 header.arrOfCSRCs[0] = 222; | |
242 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, kTestPayload, 4, | |
243 payload_specific, in_order)); | |
244 auto rtp_receiver_impl = static_cast<RtpReceiverImpl*>(rtp_receiver_.get()); | |
245 auto ssrc_sources = rtp_receiver_impl->ssrc_sources_for_testing(); | |
246 ASSERT_EQ(1u, ssrc_sources.size()); | |
247 EXPECT_EQ(111u, ssrc_sources.begin()->source_id()); | |
248 EXPECT_EQ(RtpSourceType::SSRC, ssrc_sources.begin()->source_type()); | |
249 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), | |
250 ssrc_sources.begin()->timestamp_ms()); | |
251 | |
252 auto csrc_sources = rtp_receiver_impl->csrc_sources_for_testing(); | |
253 ASSERT_EQ(1u, csrc_sources.size()); | |
254 EXPECT_EQ(222u, csrc_sources.begin()->source_id()); | |
255 EXPECT_EQ(RtpSourceType::CSRC, csrc_sources.begin()->source_type()); | |
256 EXPECT_EQ(fake_clock_.TimeInMilliseconds(), | |
257 csrc_sources.begin()->timestamp_ms()); | |
258 } | |
259 | |
260 } // namespace webrtc | |
OLD | NEW |