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