blob: a45b91cb727b28ce22dbf60b61c6b11a393197fa [file] [log] [blame]
solenbergc7a8b082015-10-16 14:35:07 -07001/*
2 * Copyright (c) 2015 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 <list>
kwiberg1724cfb2017-03-24 03:16:04 -070012#include <map>
kwibergb25345e2016-03-12 06:10:44 -080013#include <memory>
solenbergc7a8b082015-10-16 14:35:07 -070014
ossuf515ab82016-12-07 04:52:58 -080015#include "webrtc/call/audio_state.h"
16#include "webrtc/call/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070017#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
ossu29b1a8d2016-06-13 07:34:51 -070018#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
ossuf515ab82016-12-07 04:52:58 -080019#include "webrtc/modules/audio_mixer/audio_mixer_impl.h"
kwibergac9f8762016-09-30 22:29:43 -070020#include "webrtc/test/gtest.h"
brandtr8313a6f2017-01-13 07:41:19 -080021#include "webrtc/test/mock_transport.h"
Fredrik Solenberg0ccae132015-11-03 10:15:49 +010022#include "webrtc/test/mock_voice_engine.h"
solenbergc7a8b082015-10-16 14:35:07 -070023
24namespace {
25
26struct CallHelper {
ossu29b1a8d2016-06-13 07:34:51 -070027 explicit CallHelper(
28 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory = nullptr)
29 : voice_engine_(decoder_factory) {
solenberg566ef242015-11-06 15:34:49 -080030 webrtc::AudioState::Config audio_state_config;
31 audio_state_config.voice_engine = &voice_engine_;
aleloi10111bc2016-11-17 06:48:48 -080032 audio_state_config.audio_mixer = webrtc::AudioMixerImpl::Create();
aleloidd310712016-11-17 06:28:59 -080033 EXPECT_CALL(voice_engine_, audio_device_module());
34 EXPECT_CALL(voice_engine_, audio_processing());
35 EXPECT_CALL(voice_engine_, audio_transport());
skvlad11a9cbf2016-10-07 11:53:05 -070036 webrtc::Call::Config config(&event_log_);
solenberg566ef242015-11-06 15:34:49 -080037 config.audio_state = webrtc::AudioState::Create(audio_state_config);
solenbergc7a8b082015-10-16 14:35:07 -070038 call_.reset(webrtc::Call::Create(config));
39 }
40
41 webrtc::Call* operator->() { return call_.get(); }
solenberg7602aab2016-11-14 11:30:07 -080042 webrtc::test::MockVoiceEngine* voice_engine() { return &voice_engine_; }
solenbergc7a8b082015-10-16 14:35:07 -070043
44 private:
solenberg3a941542015-11-16 07:34:50 -080045 testing::NiceMock<webrtc::test::MockVoiceEngine> voice_engine_;
skvlad11a9cbf2016-10-07 11:53:05 -070046 webrtc::RtcEventLogNullImpl event_log_;
kwibergb25345e2016-03-12 06:10:44 -080047 std::unique_ptr<webrtc::Call> call_;
solenbergc7a8b082015-10-16 14:35:07 -070048};
49} // namespace
50
51namespace webrtc {
52
53TEST(CallTest, ConstructDestruct) {
54 CallHelper call;
55}
56
57TEST(CallTest, CreateDestroy_AudioSendStream) {
58 CallHelper call;
59 AudioSendStream::Config config(nullptr);
60 config.rtp.ssrc = 42;
61 config.voe_channel_id = 123;
62 AudioSendStream* stream = call->CreateAudioSendStream(config);
63 EXPECT_NE(stream, nullptr);
64 call->DestroyAudioSendStream(stream);
65}
66
67TEST(CallTest, CreateDestroy_AudioReceiveStream) {
ossu29b1a8d2016-06-13 07:34:51 -070068 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
69 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
70 CallHelper call(decoder_factory);
solenbergc7a8b082015-10-16 14:35:07 -070071 AudioReceiveStream::Config config;
72 config.rtp.remote_ssrc = 42;
73 config.voe_channel_id = 123;
ossu29b1a8d2016-06-13 07:34:51 -070074 config.decoder_factory = decoder_factory;
solenbergc7a8b082015-10-16 14:35:07 -070075 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
76 EXPECT_NE(stream, nullptr);
77 call->DestroyAudioReceiveStream(stream);
78}
79
80TEST(CallTest, CreateDestroy_AudioSendStreams) {
81 CallHelper call;
82 AudioSendStream::Config config(nullptr);
83 config.voe_channel_id = 123;
84 std::list<AudioSendStream*> streams;
85 for (int i = 0; i < 2; ++i) {
86 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
87 config.rtp.ssrc = ssrc;
88 AudioSendStream* stream = call->CreateAudioSendStream(config);
89 EXPECT_NE(stream, nullptr);
90 if (ssrc & 1) {
91 streams.push_back(stream);
92 } else {
93 streams.push_front(stream);
94 }
95 }
96 for (auto s : streams) {
97 call->DestroyAudioSendStream(s);
98 }
99 streams.clear();
100 }
101}
102
103TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
ossu29b1a8d2016-06-13 07:34:51 -0700104 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
105 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
106 CallHelper call(decoder_factory);
solenbergc7a8b082015-10-16 14:35:07 -0700107 AudioReceiveStream::Config config;
108 config.voe_channel_id = 123;
ossu29b1a8d2016-06-13 07:34:51 -0700109 config.decoder_factory = decoder_factory;
solenbergc7a8b082015-10-16 14:35:07 -0700110 std::list<AudioReceiveStream*> streams;
111 for (int i = 0; i < 2; ++i) {
112 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
113 config.rtp.remote_ssrc = ssrc;
114 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
115 EXPECT_NE(stream, nullptr);
116 if (ssrc & 1) {
117 streams.push_back(stream);
118 } else {
119 streams.push_front(stream);
120 }
121 }
122 for (auto s : streams) {
123 call->DestroyAudioReceiveStream(s);
124 }
125 streams.clear();
126 }
127}
brandtr25445d32016-10-23 23:37:14 -0700128
solenberg7602aab2016-11-14 11:30:07 -0800129TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
130 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
131 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
132 CallHelper call(decoder_factory);
133
134 constexpr int kRecvChannelId = 101;
135
136 // Set up the mock to create a channel proxy which we know of, so that we can
137 // add our expectations to it.
138 test::MockVoEChannelProxy* recv_channel_proxy = nullptr;
139 EXPECT_CALL(*call.voice_engine(), ChannelProxyFactory(testing::_))
140 .WillRepeatedly(testing::Invoke([&](int channel_id) {
141 test::MockVoEChannelProxy* channel_proxy =
142 new testing::NiceMock<test::MockVoEChannelProxy>();
143 EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
144 .WillRepeatedly(testing::ReturnRef(decoder_factory));
kwiberg1724cfb2017-03-24 03:16:04 -0700145 EXPECT_CALL(*channel_proxy, SetReceiveCodecs(testing::_))
146 .WillRepeatedly(testing::Invoke(
147 [](const std::map<int, SdpAudioFormat>& codecs) {
148 EXPECT_THAT(codecs, testing::IsEmpty());
149 }));
solenberg7602aab2016-11-14 11:30:07 -0800150 // If being called for the send channel, save a pointer to the channel
151 // proxy for later.
152 if (channel_id == kRecvChannelId) {
153 EXPECT_FALSE(recv_channel_proxy);
154 recv_channel_proxy = channel_proxy;
155 }
156 return channel_proxy;
157 }));
158
159 AudioReceiveStream::Config recv_config;
160 recv_config.rtp.remote_ssrc = 42;
161 recv_config.rtp.local_ssrc = 777;
162 recv_config.voe_channel_id = kRecvChannelId;
163 recv_config.decoder_factory = decoder_factory;
164 AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
165 EXPECT_NE(recv_stream, nullptr);
166
167 EXPECT_CALL(*recv_channel_proxy, AssociateSendChannel(testing::_)).Times(1);
168 AudioSendStream::Config send_config(nullptr);
169 send_config.rtp.ssrc = 777;
170 send_config.voe_channel_id = 123;
171 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
172 EXPECT_NE(send_stream, nullptr);
173
174 EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
175 call->DestroyAudioSendStream(send_stream);
176
177 EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
178 call->DestroyAudioReceiveStream(recv_stream);
179}
180
181TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
182 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
183 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
184 CallHelper call(decoder_factory);
185
186 constexpr int kRecvChannelId = 101;
187
188 // Set up the mock to create a channel proxy which we know of, so that we can
189 // add our expectations to it.
190 test::MockVoEChannelProxy* recv_channel_proxy = nullptr;
191 EXPECT_CALL(*call.voice_engine(), ChannelProxyFactory(testing::_))
192 .WillRepeatedly(testing::Invoke([&](int channel_id) {
193 test::MockVoEChannelProxy* channel_proxy =
194 new testing::NiceMock<test::MockVoEChannelProxy>();
195 EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
196 .WillRepeatedly(testing::ReturnRef(decoder_factory));
kwiberg1724cfb2017-03-24 03:16:04 -0700197 EXPECT_CALL(*channel_proxy, SetReceiveCodecs(testing::_))
198 .WillRepeatedly(testing::Invoke(
199 [](const std::map<int, SdpAudioFormat>& codecs) {
200 EXPECT_THAT(codecs, testing::IsEmpty());
201 }));
solenberg7602aab2016-11-14 11:30:07 -0800202 // If being called for the send channel, save a pointer to the channel
203 // proxy for later.
204 if (channel_id == kRecvChannelId) {
205 EXPECT_FALSE(recv_channel_proxy);
206 recv_channel_proxy = channel_proxy;
207 // We need to set this expectation here since the channel proxy is
208 // created as a side effect of CreateAudioReceiveStream().
209 EXPECT_CALL(*recv_channel_proxy,
210 AssociateSendChannel(testing::_)).Times(1);
211 }
212 return channel_proxy;
213 }));
214
215 AudioSendStream::Config send_config(nullptr);
216 send_config.rtp.ssrc = 777;
217 send_config.voe_channel_id = 123;
218 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
219 EXPECT_NE(send_stream, nullptr);
220
221 AudioReceiveStream::Config recv_config;
222 recv_config.rtp.remote_ssrc = 42;
223 recv_config.rtp.local_ssrc = 777;
224 recv_config.voe_channel_id = kRecvChannelId;
225 recv_config.decoder_factory = decoder_factory;
226 AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
227 EXPECT_NE(recv_stream, nullptr);
228
229 EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
230 call->DestroyAudioReceiveStream(recv_stream);
231
232 call->DestroyAudioSendStream(send_stream);
233}
234
brandtr25445d32016-10-23 23:37:14 -0700235TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
236 CallHelper call;
brandtr8313a6f2017-01-13 07:41:19 -0800237 MockTransport rtcp_send_transport;
238 FlexfecReceiveStream::Config config(&rtcp_send_transport);
brandtr1cfbd602016-12-08 04:17:53 -0800239 config.payload_type = 118;
240 config.remote_ssrc = 38837212;
brandtr25445d32016-10-23 23:37:14 -0700241 config.protected_media_ssrcs = {27273};
242
243 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
244 EXPECT_NE(stream, nullptr);
245 call->DestroyFlexfecReceiveStream(stream);
246}
247
248TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
249 CallHelper call;
brandtr8313a6f2017-01-13 07:41:19 -0800250 MockTransport rtcp_send_transport;
251 FlexfecReceiveStream::Config config(&rtcp_send_transport);
brandtr1cfbd602016-12-08 04:17:53 -0800252 config.payload_type = 118;
brandtr25445d32016-10-23 23:37:14 -0700253 std::list<FlexfecReceiveStream*> streams;
254
255 for (int i = 0; i < 2; ++i) {
256 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
brandtr1cfbd602016-12-08 04:17:53 -0800257 config.remote_ssrc = ssrc;
brandtr25445d32016-10-23 23:37:14 -0700258 config.protected_media_ssrcs = {ssrc + 1};
259 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
260 EXPECT_NE(stream, nullptr);
261 if (ssrc & 1) {
262 streams.push_back(stream);
263 } else {
264 streams.push_front(stream);
265 }
266 }
267 for (auto s : streams) {
268 call->DestroyFlexfecReceiveStream(s);
269 }
270 streams.clear();
271 }
272}
273
274TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
275 CallHelper call;
brandtr8313a6f2017-01-13 07:41:19 -0800276 MockTransport rtcp_send_transport;
277 FlexfecReceiveStream::Config config(&rtcp_send_transport);
brandtr1cfbd602016-12-08 04:17:53 -0800278 config.payload_type = 118;
brandtr25445d32016-10-23 23:37:14 -0700279 config.protected_media_ssrcs = {1324234};
280 FlexfecReceiveStream* stream;
281 std::list<FlexfecReceiveStream*> streams;
282
brandtr1cfbd602016-12-08 04:17:53 -0800283 config.remote_ssrc = 838383;
brandtr25445d32016-10-23 23:37:14 -0700284 stream = call->CreateFlexfecReceiveStream(config);
285 EXPECT_NE(stream, nullptr);
286 streams.push_back(stream);
287
brandtr1cfbd602016-12-08 04:17:53 -0800288 config.remote_ssrc = 424993;
brandtr25445d32016-10-23 23:37:14 -0700289 stream = call->CreateFlexfecReceiveStream(config);
290 EXPECT_NE(stream, nullptr);
291 streams.push_back(stream);
292
brandtr1cfbd602016-12-08 04:17:53 -0800293 config.remote_ssrc = 99383;
brandtr25445d32016-10-23 23:37:14 -0700294 stream = call->CreateFlexfecReceiveStream(config);
295 EXPECT_NE(stream, nullptr);
296 streams.push_back(stream);
297
brandtr1cfbd602016-12-08 04:17:53 -0800298 config.remote_ssrc = 5548;
brandtr25445d32016-10-23 23:37:14 -0700299 stream = call->CreateFlexfecReceiveStream(config);
300 EXPECT_NE(stream, nullptr);
301 streams.push_back(stream);
302
303 for (auto s : streams) {
304 call->DestroyFlexfecReceiveStream(s);
305 }
306}
307
solenbergc7a8b082015-10-16 14:35:07 -0700308} // namespace webrtc