blob: d981b0b013b6a59e14f897586b86eba45cdc02bc [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>
kwibergb25345e2016-03-12 06:10:44 -080012#include <memory>
solenbergc7a8b082015-10-16 14:35:07 -070013
kjellandera69d9732016-08-31 07:33:05 -070014#include "webrtc/api/call/audio_state.h"
solenbergc7a8b082015-10-16 14:35:07 -070015#include "webrtc/call.h"
skvlad11a9cbf2016-10-07 11:53:05 -070016#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
ossu29b1a8d2016-06-13 07:34:51 -070017#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_decoder_factory.h"
kwibergac9f8762016-09-30 22:29:43 -070018#include "webrtc/test/gtest.h"
Fredrik Solenberg0ccae132015-11-03 10:15:49 +010019#include "webrtc/test/mock_voice_engine.h"
solenbergc7a8b082015-10-16 14:35:07 -070020
21namespace {
22
23struct CallHelper {
ossu29b1a8d2016-06-13 07:34:51 -070024 explicit CallHelper(
25 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory = nullptr)
26 : voice_engine_(decoder_factory) {
solenberg566ef242015-11-06 15:34:49 -080027 webrtc::AudioState::Config audio_state_config;
28 audio_state_config.voice_engine = &voice_engine_;
aleloidd310712016-11-17 06:28:59 -080029 EXPECT_CALL(voice_engine_, audio_device_module());
30 EXPECT_CALL(voice_engine_, audio_processing());
31 EXPECT_CALL(voice_engine_, audio_transport());
skvlad11a9cbf2016-10-07 11:53:05 -070032 webrtc::Call::Config config(&event_log_);
solenberg566ef242015-11-06 15:34:49 -080033 config.audio_state = webrtc::AudioState::Create(audio_state_config);
solenbergc7a8b082015-10-16 14:35:07 -070034 call_.reset(webrtc::Call::Create(config));
35 }
36
37 webrtc::Call* operator->() { return call_.get(); }
solenberg7602aab2016-11-14 11:30:07 -080038 webrtc::test::MockVoiceEngine* voice_engine() { return &voice_engine_; }
solenbergc7a8b082015-10-16 14:35:07 -070039
40 private:
solenberg3a941542015-11-16 07:34:50 -080041 testing::NiceMock<webrtc::test::MockVoiceEngine> voice_engine_;
skvlad11a9cbf2016-10-07 11:53:05 -070042 webrtc::RtcEventLogNullImpl event_log_;
kwibergb25345e2016-03-12 06:10:44 -080043 std::unique_ptr<webrtc::Call> call_;
solenbergc7a8b082015-10-16 14:35:07 -070044};
45} // namespace
46
47namespace webrtc {
48
49TEST(CallTest, ConstructDestruct) {
50 CallHelper call;
51}
52
53TEST(CallTest, CreateDestroy_AudioSendStream) {
54 CallHelper call;
55 AudioSendStream::Config config(nullptr);
56 config.rtp.ssrc = 42;
57 config.voe_channel_id = 123;
58 AudioSendStream* stream = call->CreateAudioSendStream(config);
59 EXPECT_NE(stream, nullptr);
60 call->DestroyAudioSendStream(stream);
61}
62
63TEST(CallTest, CreateDestroy_AudioReceiveStream) {
ossu29b1a8d2016-06-13 07:34:51 -070064 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
65 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
66 CallHelper call(decoder_factory);
solenbergc7a8b082015-10-16 14:35:07 -070067 AudioReceiveStream::Config config;
68 config.rtp.remote_ssrc = 42;
69 config.voe_channel_id = 123;
ossu29b1a8d2016-06-13 07:34:51 -070070 config.decoder_factory = decoder_factory;
solenbergc7a8b082015-10-16 14:35:07 -070071 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
72 EXPECT_NE(stream, nullptr);
73 call->DestroyAudioReceiveStream(stream);
74}
75
76TEST(CallTest, CreateDestroy_AudioSendStreams) {
77 CallHelper call;
78 AudioSendStream::Config config(nullptr);
79 config.voe_channel_id = 123;
80 std::list<AudioSendStream*> streams;
81 for (int i = 0; i < 2; ++i) {
82 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
83 config.rtp.ssrc = ssrc;
84 AudioSendStream* stream = call->CreateAudioSendStream(config);
85 EXPECT_NE(stream, nullptr);
86 if (ssrc & 1) {
87 streams.push_back(stream);
88 } else {
89 streams.push_front(stream);
90 }
91 }
92 for (auto s : streams) {
93 call->DestroyAudioSendStream(s);
94 }
95 streams.clear();
96 }
97}
98
99TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
ossu29b1a8d2016-06-13 07:34:51 -0700100 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
101 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
102 CallHelper call(decoder_factory);
solenbergc7a8b082015-10-16 14:35:07 -0700103 AudioReceiveStream::Config config;
104 config.voe_channel_id = 123;
ossu29b1a8d2016-06-13 07:34:51 -0700105 config.decoder_factory = decoder_factory;
solenbergc7a8b082015-10-16 14:35:07 -0700106 std::list<AudioReceiveStream*> streams;
107 for (int i = 0; i < 2; ++i) {
108 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
109 config.rtp.remote_ssrc = ssrc;
110 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
111 EXPECT_NE(stream, nullptr);
112 if (ssrc & 1) {
113 streams.push_back(stream);
114 } else {
115 streams.push_front(stream);
116 }
117 }
118 for (auto s : streams) {
119 call->DestroyAudioReceiveStream(s);
120 }
121 streams.clear();
122 }
123}
brandtr25445d32016-10-23 23:37:14 -0700124
solenberg7602aab2016-11-14 11:30:07 -0800125TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
126 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
127 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
128 CallHelper call(decoder_factory);
129
130 constexpr int kRecvChannelId = 101;
131
132 // Set up the mock to create a channel proxy which we know of, so that we can
133 // add our expectations to it.
134 test::MockVoEChannelProxy* recv_channel_proxy = nullptr;
135 EXPECT_CALL(*call.voice_engine(), ChannelProxyFactory(testing::_))
136 .WillRepeatedly(testing::Invoke([&](int channel_id) {
137 test::MockVoEChannelProxy* channel_proxy =
138 new testing::NiceMock<test::MockVoEChannelProxy>();
139 EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
140 .WillRepeatedly(testing::ReturnRef(decoder_factory));
141 // If being called for the send channel, save a pointer to the channel
142 // proxy for later.
143 if (channel_id == kRecvChannelId) {
144 EXPECT_FALSE(recv_channel_proxy);
145 recv_channel_proxy = channel_proxy;
146 }
147 return channel_proxy;
148 }));
149
150 AudioReceiveStream::Config recv_config;
151 recv_config.rtp.remote_ssrc = 42;
152 recv_config.rtp.local_ssrc = 777;
153 recv_config.voe_channel_id = kRecvChannelId;
154 recv_config.decoder_factory = decoder_factory;
155 AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
156 EXPECT_NE(recv_stream, nullptr);
157
158 EXPECT_CALL(*recv_channel_proxy, AssociateSendChannel(testing::_)).Times(1);
159 AudioSendStream::Config send_config(nullptr);
160 send_config.rtp.ssrc = 777;
161 send_config.voe_channel_id = 123;
162 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
163 EXPECT_NE(send_stream, nullptr);
164
165 EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
166 call->DestroyAudioSendStream(send_stream);
167
168 EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
169 call->DestroyAudioReceiveStream(recv_stream);
170}
171
172TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
173 rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
174 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
175 CallHelper call(decoder_factory);
176
177 constexpr int kRecvChannelId = 101;
178
179 // Set up the mock to create a channel proxy which we know of, so that we can
180 // add our expectations to it.
181 test::MockVoEChannelProxy* recv_channel_proxy = nullptr;
182 EXPECT_CALL(*call.voice_engine(), ChannelProxyFactory(testing::_))
183 .WillRepeatedly(testing::Invoke([&](int channel_id) {
184 test::MockVoEChannelProxy* channel_proxy =
185 new testing::NiceMock<test::MockVoEChannelProxy>();
186 EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
187 .WillRepeatedly(testing::ReturnRef(decoder_factory));
188 // If being called for the send channel, save a pointer to the channel
189 // proxy for later.
190 if (channel_id == kRecvChannelId) {
191 EXPECT_FALSE(recv_channel_proxy);
192 recv_channel_proxy = channel_proxy;
193 // We need to set this expectation here since the channel proxy is
194 // created as a side effect of CreateAudioReceiveStream().
195 EXPECT_CALL(*recv_channel_proxy,
196 AssociateSendChannel(testing::_)).Times(1);
197 }
198 return channel_proxy;
199 }));
200
201 AudioSendStream::Config send_config(nullptr);
202 send_config.rtp.ssrc = 777;
203 send_config.voe_channel_id = 123;
204 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
205 EXPECT_NE(send_stream, nullptr);
206
207 AudioReceiveStream::Config recv_config;
208 recv_config.rtp.remote_ssrc = 42;
209 recv_config.rtp.local_ssrc = 777;
210 recv_config.voe_channel_id = kRecvChannelId;
211 recv_config.decoder_factory = decoder_factory;
212 AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
213 EXPECT_NE(recv_stream, nullptr);
214
215 EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
216 call->DestroyAudioReceiveStream(recv_stream);
217
218 call->DestroyAudioSendStream(send_stream);
219}
220
brandtr25445d32016-10-23 23:37:14 -0700221TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
222 CallHelper call;
223 FlexfecReceiveStream::Config config;
224 config.flexfec_payload_type = 118;
225 config.flexfec_ssrc = 38837212;
226 config.protected_media_ssrcs = {27273};
227
228 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
229 EXPECT_NE(stream, nullptr);
230 call->DestroyFlexfecReceiveStream(stream);
231}
232
233TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
234 CallHelper call;
235 FlexfecReceiveStream::Config config;
236 config.flexfec_payload_type = 118;
237 std::list<FlexfecReceiveStream*> streams;
238
239 for (int i = 0; i < 2; ++i) {
240 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
241 config.flexfec_ssrc = ssrc;
242 config.protected_media_ssrcs = {ssrc + 1};
243 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
244 EXPECT_NE(stream, nullptr);
245 if (ssrc & 1) {
246 streams.push_back(stream);
247 } else {
248 streams.push_front(stream);
249 }
250 }
251 for (auto s : streams) {
252 call->DestroyFlexfecReceiveStream(s);
253 }
254 streams.clear();
255 }
256}
257
258TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
259 CallHelper call;
260 FlexfecReceiveStream::Config config;
261 config.flexfec_payload_type = 118;
262 config.protected_media_ssrcs = {1324234};
263 FlexfecReceiveStream* stream;
264 std::list<FlexfecReceiveStream*> streams;
265
266 config.flexfec_ssrc = 838383;
267 stream = call->CreateFlexfecReceiveStream(config);
268 EXPECT_NE(stream, nullptr);
269 streams.push_back(stream);
270
271 config.flexfec_ssrc = 424993;
272 stream = call->CreateFlexfecReceiveStream(config);
273 EXPECT_NE(stream, nullptr);
274 streams.push_back(stream);
275
276 config.flexfec_ssrc = 99383;
277 stream = call->CreateFlexfecReceiveStream(config);
278 EXPECT_NE(stream, nullptr);
279 streams.push_back(stream);
280
281 config.flexfec_ssrc = 5548;
282 stream = call->CreateFlexfecReceiveStream(config);
283 EXPECT_NE(stream, nullptr);
284 streams.push_back(stream);
285
286 for (auto s : streams) {
287 call->DestroyFlexfecReceiveStream(s);
288 }
289}
290
solenbergc7a8b082015-10-16 14:35:07 -0700291} // namespace webrtc