OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2016 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/api/trackmediainfomap.h" | |
12 | |
13 #include <initializer_list> | |
14 #include <memory> | |
15 #include <utility> | |
16 #include <vector> | |
17 | |
18 #include "webrtc/api/audiotrack.h" | |
19 #include "webrtc/api/rtpreceiverinterface.h" | |
20 #include "webrtc/api/rtpsenderinterface.h" | |
21 #include "webrtc/api/test/mock_rtpreceiver.h" | |
22 #include "webrtc/api/test/mock_rtpsender.h" | |
23 #include "webrtc/api/test/fakevideotracksource.h" | |
24 #include "webrtc/api/videotrack.h" | |
25 #include "webrtc/base/refcount.h" | |
26 #include "webrtc/media/base/mediachannel.h" | |
27 #include "webrtc/test/gtest.h" | |
28 | |
29 namespace webrtc { | |
30 | |
31 namespace { | |
32 | |
33 RtpParameters CreateRtpParametersWithSsrcs( | |
34 std::initializer_list<uint32_t> ssrcs) { | |
35 RtpParameters params; | |
36 for (uint32_t ssrc : ssrcs) { | |
37 RtpEncodingParameters encoding_params; | |
38 encoding_params.ssrc = rtc::Optional<uint32_t>(ssrc); | |
39 params.encodings.push_back(encoding_params); | |
40 } | |
41 return params; | |
42 } | |
43 | |
44 rtc::scoped_refptr<MockRtpSender> CreateMockRtpSender( | |
45 cricket::MediaType media_type, std::initializer_list<uint32_t> ssrcs, | |
Taylor Brandstetter
2017/01/11 22:12:05
I didn't know about std::initializer_list, this is
| |
46 rtc::scoped_refptr<MediaStreamTrackInterface> track) { | |
47 uint32_t first_ssrc; | |
48 if (ssrcs.size()) { | |
49 first_ssrc = *ssrcs.begin(); | |
50 } else { | |
51 first_ssrc = 0; | |
52 } | |
53 rtc::scoped_refptr<MockRtpSender> sender( | |
54 new rtc::RefCountedObject<MockRtpSender>()); | |
55 EXPECT_CALL(*sender, track()).WillRepeatedly(testing::Return(track)); | |
56 EXPECT_CALL(*sender, ssrc()).WillRepeatedly(testing::Return(first_ssrc)); | |
57 EXPECT_CALL(*sender, media_type()).WillRepeatedly(testing::Return( | |
58 media_type)); | |
59 EXPECT_CALL(*sender, GetParameters()).WillRepeatedly(testing::Return( | |
60 CreateRtpParametersWithSsrcs(ssrcs))); | |
61 return sender; | |
62 } | |
63 | |
64 rtc::scoped_refptr<MockRtpReceiver> CreateMockRtpReceiver( | |
65 cricket::MediaType media_type, std::initializer_list<uint32_t> ssrcs, | |
66 rtc::scoped_refptr<MediaStreamTrackInterface> track) { | |
67 rtc::scoped_refptr<MockRtpReceiver> receiver( | |
68 new rtc::RefCountedObject<MockRtpReceiver>()); | |
69 EXPECT_CALL(*receiver, track()).WillRepeatedly(testing::Return(track)); | |
70 EXPECT_CALL(*receiver, media_type()).WillRepeatedly(testing::Return( | |
71 media_type)); | |
72 EXPECT_CALL(*receiver, GetParameters()).WillRepeatedly(testing::Return( | |
73 CreateRtpParametersWithSsrcs(ssrcs))); | |
74 return receiver; | |
75 } | |
76 | |
77 class TrackMediaInfoMapTest : public testing::Test { | |
78 public: | |
79 TrackMediaInfoMapTest() | |
80 : voice_media_info_(new cricket::VoiceMediaInfo()), | |
81 video_media_info_(new cricket::VideoMediaInfo()), | |
82 local_audio_track_(AudioTrack::Create("LocalAudioTrack", nullptr)), | |
83 remote_audio_track_(AudioTrack::Create("RemoteAudioTrack", nullptr)), | |
84 local_video_track_( | |
85 VideoTrack::Create("LocalVideoTrack", | |
86 FakeVideoTrackSource::Create(false))), | |
87 remote_video_track_( | |
88 VideoTrack::Create("RemoteVideoTrack", | |
89 FakeVideoTrackSource::Create(false))) { | |
90 } | |
91 | |
92 ~TrackMediaInfoMapTest() { | |
93 // If we have a map the ownership has been passed to the map, only delete if | |
94 // |CreateMap| has not been called. | |
95 if (!map_) { | |
96 delete voice_media_info_; | |
97 delete video_media_info_; | |
98 } | |
99 } | |
100 | |
101 void AddRtpSenderWithSsrcs(std::initializer_list<uint32_t> ssrcs, | |
102 MediaStreamTrackInterface* local_track) { | |
103 rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockRtpSender( | |
104 local_track->kind() == MediaStreamTrackInterface::kAudioKind ? | |
105 cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO, | |
106 ssrcs, local_track); | |
107 rtp_senders_.push_back(rtp_sender); | |
108 AddSenderInfos(ssrcs, local_track); | |
Taylor Brandstetter
2017/01/11 22:12:05
This isn't quite right; if an RtpSender uses multi
hbos
2017/01/12 11:03:14
Done. Changed so that:
AddRtp[Sender/Receiver]Wit
| |
109 } | |
110 | |
111 void AddRtpReceiverWithSsrcs(std::initializer_list<uint32_t> ssrcs, | |
112 MediaStreamTrackInterface* remote_track) { | |
113 rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockRtpReceiver( | |
114 remote_track->kind() == MediaStreamTrackInterface::kAudioKind ? | |
115 cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO, | |
116 ssrcs, remote_track); | |
117 rtp_receivers_.push_back(rtp_receiver); | |
118 AddReceiverInfos(ssrcs, remote_track); | |
119 } | |
120 | |
121 void AddRtpSendersOnePerSsrc(std::initializer_list<uint32_t> ssrcs, | |
122 MediaStreamTrackInterface* local_track) { | |
123 for (uint32_t ssrc : ssrcs) { | |
124 rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockRtpSender( | |
125 local_track->kind() == MediaStreamTrackInterface::kAudioKind ? | |
126 cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO, | |
127 { ssrc }, local_track); | |
128 rtp_senders_.push_back(rtp_sender); | |
129 } | |
130 AddSenderInfos(ssrcs, local_track); | |
131 } | |
132 | |
133 void AddRtpReceiverOnePerSsrc(std::initializer_list<uint32_t> ssrcs, | |
Taylor Brandstetter
2017/01/11 22:12:05
nit: "AddRtpSendersOnePerSsrc" is plural ("senders
hbos
2017/01/12 11:03:14
Function removed.
| |
134 MediaStreamTrackInterface* remote_track) { | |
135 for (uint32_t ssrc : ssrcs) { | |
136 rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockRtpReceiver( | |
137 remote_track->kind() == MediaStreamTrackInterface::kAudioKind ? | |
138 cricket::MEDIA_TYPE_AUDIO : cricket::MEDIA_TYPE_VIDEO, | |
139 { ssrc }, remote_track); | |
140 rtp_receivers_.push_back(rtp_receiver); | |
141 } | |
142 AddReceiverInfos(ssrcs, remote_track); | |
143 } | |
144 | |
145 void CreateMap() { | |
146 RTC_DCHECK(!map_); | |
147 map_.reset(new TrackMediaInfoMap( | |
148 std::unique_ptr<cricket::VoiceMediaInfo>(voice_media_info_), | |
149 std::unique_ptr<cricket::VideoMediaInfo>(video_media_info_), | |
150 rtp_senders_, | |
151 rtp_receivers_)); | |
152 } | |
153 | |
154 private: | |
155 void AddSenderInfos(std::initializer_list<uint32_t> ssrcs, | |
156 MediaStreamTrackInterface* local_track) { | |
157 if (local_track->kind() == MediaStreamTrackInterface::kAudioKind) { | |
158 for (uint32_t ssrc : ssrcs) { | |
159 cricket::VoiceSenderInfo voice_sender_info; | |
160 voice_sender_info.local_stats.push_back(cricket::SsrcSenderInfo()); | |
161 voice_sender_info.local_stats[0].ssrc = ssrc; | |
162 voice_media_info_->senders.push_back(voice_sender_info); | |
163 } | |
164 } else { | |
165 for (uint32_t ssrc : ssrcs) { | |
166 cricket::VideoSenderInfo video_sender_info; | |
167 video_sender_info.local_stats.push_back(cricket::SsrcSenderInfo()); | |
168 video_sender_info.local_stats[0].ssrc = ssrc; | |
169 video_media_info_->senders.push_back(video_sender_info); | |
170 } | |
171 } | |
172 } | |
173 | |
174 void AddReceiverInfos(std::initializer_list<uint32_t> ssrcs, | |
175 MediaStreamTrackInterface* remote_track) { | |
176 if (remote_track->kind() == MediaStreamTrackInterface::kAudioKind) { | |
177 for (uint32_t ssrc : ssrcs) { | |
178 cricket::VoiceReceiverInfo voice_receiver_info; | |
179 voice_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo()); | |
180 voice_receiver_info.local_stats[0].ssrc = ssrc; | |
181 voice_media_info_->receivers.push_back(voice_receiver_info); | |
182 } | |
183 } else { | |
184 for (uint32_t ssrc : ssrcs) { | |
185 cricket::VideoReceiverInfo video_receiver_info; | |
186 video_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo()); | |
187 video_receiver_info.local_stats[0].ssrc = ssrc; | |
188 video_media_info_->receivers.push_back(video_receiver_info); | |
189 } | |
190 } | |
191 } | |
192 | |
193 protected: | |
194 cricket::VoiceMediaInfo* voice_media_info_; | |
195 cricket::VideoMediaInfo* video_media_info_; | |
196 std::vector<rtc::scoped_refptr<RtpSenderInterface>> rtp_senders_; | |
197 std::vector<rtc::scoped_refptr<RtpReceiverInterface>> rtp_receivers_; | |
198 std::unique_ptr<TrackMediaInfoMap> map_; | |
199 rtc::scoped_refptr<AudioTrack> local_audio_track_; | |
200 rtc::scoped_refptr<AudioTrack> remote_audio_track_; | |
201 rtc::scoped_refptr<VideoTrack> local_video_track_; | |
202 rtc::scoped_refptr<VideoTrack> remote_video_track_; | |
203 }; | |
204 | |
205 } // namespace | |
206 | |
207 TEST_F(TrackMediaInfoMapTest, SingleSenderAndReceiverWithOneSsrc) { | |
208 AddRtpSenderWithSsrcs({ 1 }, local_audio_track_); | |
209 AddRtpReceiverWithSsrcs({ 2 }, remote_audio_track_); | |
210 AddRtpSenderWithSsrcs({ 3 }, local_video_track_); | |
211 AddRtpReceiverWithSsrcs({ 4 }, remote_video_track_); | |
212 CreateMap(); | |
213 | |
214 // Local audio track <-> RTP audio sender | |
215 ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); | |
216 EXPECT_EQ(*map_->GetVoiceSenderInfos(*local_audio_track_), | |
217 std::vector<cricket::VoiceSenderInfo*>({ | |
218 &voice_media_info_->senders[0] })); | |
219 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), | |
220 local_audio_track_.get()); | |
221 | |
222 // Remote audio track <-> RTP audio receiver | |
223 EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_), | |
224 &voice_media_info_->receivers[0]); | |
225 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]), | |
226 remote_audio_track_.get()); | |
227 | |
228 // Local video track <-> RTP video sender | |
229 ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); | |
230 EXPECT_EQ(*map_->GetVideoSenderInfos(*local_video_track_), | |
231 std::vector<cricket::VideoSenderInfo*>({ | |
232 &video_media_info_->senders[0] })); | |
233 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), | |
234 local_video_track_.get()); | |
235 | |
236 // Remote video track <-> RTP video receiver | |
237 EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_), | |
238 &video_media_info_->receivers[0]); | |
239 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]), | |
240 remote_video_track_.get()); | |
241 } | |
242 | |
243 TEST_F(TrackMediaInfoMapTest, SingleSenderWithMissingSsrc) { | |
244 AddRtpSenderWithSsrcs({}, local_audio_track_); | |
245 AddRtpSenderWithSsrcs({}, local_video_track_); | |
246 CreateMap(); | |
247 | |
248 EXPECT_FALSE(map_->GetVoiceSenderInfos(*local_audio_track_)); | |
249 EXPECT_FALSE(map_->GetVideoSenderInfos(*local_video_track_)); | |
250 } | |
251 | |
252 TEST_F(TrackMediaInfoMapTest, SingleSenderAudioAndVideoUseSameSsrc) { | |
253 AddRtpSenderWithSsrcs({ 1 }, local_audio_track_); | |
254 AddRtpReceiverWithSsrcs({ 2 }, remote_audio_track_); | |
255 AddRtpSenderWithSsrcs({ 1 }, local_video_track_); | |
256 AddRtpReceiverWithSsrcs({ 2 }, remote_video_track_); | |
257 CreateMap(); | |
258 | |
259 // Local audio track <-> RTP audio sender | |
260 ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); | |
261 EXPECT_EQ(*map_->GetVoiceSenderInfos(*local_audio_track_), | |
262 std::vector<cricket::VoiceSenderInfo*>({ | |
263 &voice_media_info_->senders[0] })); | |
264 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), | |
265 local_audio_track_.get()); | |
266 | |
267 // Remote audio track <-> RTP audio receiver | |
268 EXPECT_EQ(map_->GetVoiceReceiverInfo(*remote_audio_track_), | |
269 &voice_media_info_->receivers[0]); | |
270 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->receivers[0]), | |
271 remote_audio_track_.get()); | |
272 | |
273 // Local video track <-> RTP video sender | |
274 ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); | |
275 EXPECT_EQ(*map_->GetVideoSenderInfos(*local_video_track_), | |
276 std::vector<cricket::VideoSenderInfo*>({ | |
277 &video_media_info_->senders[0] })); | |
278 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), | |
279 local_video_track_.get()); | |
280 | |
281 // Remote video track <-> RTP video receiver | |
282 EXPECT_EQ(map_->GetVideoReceiverInfo(*remote_video_track_), | |
283 &video_media_info_->receivers[0]); | |
284 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->receivers[0]), | |
285 remote_video_track_.get()); | |
286 } | |
287 | |
288 TEST_F(TrackMediaInfoMapTest, SingleSenderWithMultipleSsrcs) { | |
289 AddRtpSenderWithSsrcs({ 1, 2 }, local_audio_track_); | |
290 AddRtpSenderWithSsrcs({ 3, 4 }, local_video_track_); | |
291 CreateMap(); | |
292 | |
293 // Local audio track <-> RTP audio senders | |
294 ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); | |
295 EXPECT_EQ(*map_->GetVoiceSenderInfos(*local_audio_track_), | |
296 std::vector<cricket::VoiceSenderInfo*>({ | |
297 &voice_media_info_->senders[0], | |
298 &voice_media_info_->senders[1] })); | |
299 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), | |
300 local_audio_track_.get()); | |
301 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[1]), | |
302 local_audio_track_.get()); | |
303 | |
304 // Local video track <-> RTP video senders | |
305 ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); | |
306 EXPECT_EQ(*map_->GetVideoSenderInfos(*local_video_track_), | |
307 std::vector<cricket::VideoSenderInfo*>({ | |
308 &video_media_info_->senders[0], | |
309 &video_media_info_->senders[1] })); | |
310 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), | |
311 local_video_track_.get()); | |
312 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[1]), | |
313 local_video_track_.get()); | |
314 } | |
315 | |
316 TEST_F(TrackMediaInfoMapTest, MultipleSendersWithOneSsrc) { | |
317 AddRtpSendersOnePerSsrc({ 1, 2 }, local_audio_track_); | |
318 AddRtpSendersOnePerSsrc({ 3, 4 }, local_video_track_); | |
319 CreateMap(); | |
320 | |
321 // Local audio track <-> RTP audio senders | |
322 ASSERT_TRUE(map_->GetVoiceSenderInfos(*local_audio_track_)); | |
323 EXPECT_EQ(*map_->GetVoiceSenderInfos(*local_audio_track_), | |
324 std::vector<cricket::VoiceSenderInfo*>({ | |
325 &voice_media_info_->senders[0], | |
326 &voice_media_info_->senders[1] })); | |
327 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[0]), | |
328 local_audio_track_.get()); | |
329 EXPECT_EQ(map_->GetAudioTrack(voice_media_info_->senders[1]), | |
330 local_audio_track_.get()); | |
331 | |
332 // Local video track <-> RTP video senders | |
333 ASSERT_TRUE(map_->GetVideoSenderInfos(*local_video_track_)); | |
334 EXPECT_EQ(*map_->GetVideoSenderInfos(*local_video_track_), | |
335 std::vector<cricket::VideoSenderInfo*>({ | |
336 &video_media_info_->senders[0], | |
337 &video_media_info_->senders[1] })); | |
338 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[0]), | |
339 local_video_track_.get()); | |
340 EXPECT_EQ(map_->GetVideoTrack(video_media_info_->senders[1]), | |
341 local_video_track_.get()); | |
342 } | |
343 | |
344 // Death tests. | |
345 // Disabled on Android because death tests misbehave on Android, see | |
346 // base/test/gtest_util.h. | |
347 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
Taylor Brandstetter
2017/01/11 22:12:05
Is it common to have tests for DCHECKs? I haven't
hbos
2017/01/12 11:03:14
This exact #if statement is commonly used for deat
| |
348 | |
349 class TrackMediaInfoMapDeathTest : public TrackMediaInfoMapTest { | |
350 }; | |
351 | |
352 TEST_F(TrackMediaInfoMapDeathTest, SingleReceiverWithMultipleSsrcs) { | |
353 AddRtpReceiverWithSsrcs({ 1, 2 }, remote_audio_track_); | |
354 AddRtpReceiverWithSsrcs({ 3, 4 }, remote_video_track_); | |
355 EXPECT_DEATH(CreateMap(), ""); | |
356 } | |
357 | |
358 TEST_F(TrackMediaInfoMapDeathTest, MultipleReceiversWithOneSsrc) { | |
Taylor Brandstetter
2017/01/11 22:12:05
Maybe MultipleReceiversWithSameTrack would be a mo
hbos
2017/01/12 11:03:14
Need to take into account # senders/receivers and
| |
359 AddRtpReceiverOnePerSsrc({ 1, 2 }, remote_audio_track_); | |
360 AddRtpReceiverOnePerSsrc({ 3, 4 }, remote_video_track_); | |
361 EXPECT_DEATH(CreateMap(), ""); | |
362 } | |
363 | |
364 TEST_F(TrackMediaInfoMapDeathTest, SingleSenderAndReceiverWithSsrcNotUnique) { | |
365 AddRtpSenderWithSsrcs({ 1 }, local_audio_track_); | |
366 AddRtpReceiverWithSsrcs({ 1 }, remote_audio_track_); | |
367 AddRtpSenderWithSsrcs({ 1 }, local_video_track_); | |
368 AddRtpReceiverWithSsrcs({ 1 }, remote_video_track_); | |
369 EXPECT_DEATH(CreateMap(), ""); | |
370 } | |
371 | |
372 #endif // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
373 | |
374 } // namespace webrtc | |
OLD | NEW |