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 "call/call.h"
12
13 #include <list>
14 #include <map>
15 #include <memory>
16 #include <utility>
17
18 #include "absl/memory/memory.h"
19 #include "api/audio_codecs/builtin_audio_decoder_factory.h"
20 #include "api/rtc_event_log/rtc_event_log.h"
21 #include "api/task_queue/default_task_queue_factory.h"
22 #include "api/test/mock_audio_mixer.h"
23 #include "api/test/video/function_video_encoder_factory.h"
24 #include "api/transport/field_trial_based_config.h"
25 #include "api/video/builtin_video_bitrate_allocator_factory.h"
26 #include "audio/audio_receive_stream.h"
27 #include "audio/audio_send_stream.h"
28 #include "call/adaptation/test/fake_resource.h"
29 #include "call/adaptation/test/mock_resource_listener.h"
30 #include "call/audio_state.h"
31 #include "modules/audio_device/include/mock_audio_device.h"
32 #include "modules/audio_processing/include/mock_audio_processing.h"
33 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
34 #include "test/fake_encoder.h"
35 #include "test/gtest.h"
36 #include "test/mock_audio_decoder_factory.h"
37 #include "test/mock_transport.h"
38 #include "test/run_loop.h"
39
40 namespace {
41
42 using ::testing::_;
43 using ::testing::Contains;
44 using ::testing::StrictMock;
45
46 struct CallHelper {
CallHelper__anoncc09d7280111::CallHelper47 explicit CallHelper(bool use_null_audio_processing) {
48 task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
49 webrtc::AudioState::Config audio_state_config;
50 audio_state_config.audio_mixer =
51 new rtc::RefCountedObject<webrtc::test::MockAudioMixer>();
52 audio_state_config.audio_processing =
53 use_null_audio_processing
54 ? nullptr
55 : new rtc::RefCountedObject<webrtc::test::MockAudioProcessing>();
56 audio_state_config.audio_device_module =
57 new rtc::RefCountedObject<webrtc::test::MockAudioDeviceModule>();
58 webrtc::Call::Config config(&event_log_);
59 config.audio_state = webrtc::AudioState::Create(audio_state_config);
60 config.task_queue_factory = task_queue_factory_.get();
61 config.trials = &field_trials_;
62 call_.reset(webrtc::Call::Create(config));
63 }
64
operator ->__anoncc09d7280111::CallHelper65 webrtc::Call* operator->() { return call_.get(); }
66
67 private:
68 webrtc::test::RunLoop loop_;
69 webrtc::RtcEventLogNull event_log_;
70 webrtc::FieldTrialBasedConfig field_trials_;
71 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
72 std::unique_ptr<webrtc::Call> call_;
73 };
74 } // namespace
75
76 namespace webrtc {
77
78 namespace {
79
FindResourceWhoseNameContains(const std::vector<rtc::scoped_refptr<Resource>> & resources,const std::string & name_contains)80 rtc::scoped_refptr<Resource> FindResourceWhoseNameContains(
81 const std::vector<rtc::scoped_refptr<Resource>>& resources,
82 const std::string& name_contains) {
83 for (const auto& resource : resources) {
84 if (resource->Name().find(name_contains) != std::string::npos)
85 return resource;
86 }
87 return nullptr;
88 }
89
90 } // namespace
91
TEST(CallTest,ConstructDestruct)92 TEST(CallTest, ConstructDestruct) {
93 for (bool use_null_audio_processing : {false, true}) {
94 CallHelper call(use_null_audio_processing);
95 }
96 }
97
TEST(CallTest,CreateDestroy_AudioSendStream)98 TEST(CallTest, CreateDestroy_AudioSendStream) {
99 for (bool use_null_audio_processing : {false, true}) {
100 CallHelper call(use_null_audio_processing);
101 MockTransport send_transport;
102 AudioSendStream::Config config(&send_transport);
103 config.rtp.ssrc = 42;
104 AudioSendStream* stream = call->CreateAudioSendStream(config);
105 EXPECT_NE(stream, nullptr);
106 call->DestroyAudioSendStream(stream);
107 }
108 }
109
TEST(CallTest,CreateDestroy_AudioReceiveStream)110 TEST(CallTest, CreateDestroy_AudioReceiveStream) {
111 for (bool use_null_audio_processing : {false, true}) {
112 CallHelper call(use_null_audio_processing);
113 AudioReceiveStream::Config config;
114 MockTransport rtcp_send_transport;
115 config.rtp.remote_ssrc = 42;
116 config.rtcp_send_transport = &rtcp_send_transport;
117 config.decoder_factory =
118 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
119 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
120 EXPECT_NE(stream, nullptr);
121 call->DestroyAudioReceiveStream(stream);
122 }
123 }
124
TEST(CallTest,CreateDestroy_AudioSendStreams)125 TEST(CallTest, CreateDestroy_AudioSendStreams) {
126 for (bool use_null_audio_processing : {false, true}) {
127 CallHelper call(use_null_audio_processing);
128 MockTransport send_transport;
129 AudioSendStream::Config config(&send_transport);
130 std::list<AudioSendStream*> streams;
131 for (int i = 0; i < 2; ++i) {
132 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
133 config.rtp.ssrc = ssrc;
134 AudioSendStream* stream = call->CreateAudioSendStream(config);
135 EXPECT_NE(stream, nullptr);
136 if (ssrc & 1) {
137 streams.push_back(stream);
138 } else {
139 streams.push_front(stream);
140 }
141 }
142 for (auto s : streams) {
143 call->DestroyAudioSendStream(s);
144 }
145 streams.clear();
146 }
147 }
148 }
149
TEST(CallTest,CreateDestroy_AudioReceiveStreams)150 TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
151 for (bool use_null_audio_processing : {false, true}) {
152 CallHelper call(use_null_audio_processing);
153 AudioReceiveStream::Config config;
154 MockTransport rtcp_send_transport;
155 config.rtcp_send_transport = &rtcp_send_transport;
156 config.decoder_factory =
157 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
158 std::list<AudioReceiveStream*> streams;
159 for (int i = 0; i < 2; ++i) {
160 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
161 config.rtp.remote_ssrc = ssrc;
162 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
163 EXPECT_NE(stream, nullptr);
164 if (ssrc & 1) {
165 streams.push_back(stream);
166 } else {
167 streams.push_front(stream);
168 }
169 }
170 for (auto s : streams) {
171 call->DestroyAudioReceiveStream(s);
172 }
173 streams.clear();
174 }
175 }
176 }
177
TEST(CallTest,CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst)178 TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
179 for (bool use_null_audio_processing : {false, true}) {
180 CallHelper call(use_null_audio_processing);
181 AudioReceiveStream::Config recv_config;
182 MockTransport rtcp_send_transport;
183 recv_config.rtp.remote_ssrc = 42;
184 recv_config.rtp.local_ssrc = 777;
185 recv_config.rtcp_send_transport = &rtcp_send_transport;
186 recv_config.decoder_factory =
187 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
188 AudioReceiveStream* recv_stream =
189 call->CreateAudioReceiveStream(recv_config);
190 EXPECT_NE(recv_stream, nullptr);
191
192 MockTransport send_transport;
193 AudioSendStream::Config send_config(&send_transport);
194 send_config.rtp.ssrc = 777;
195 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
196 EXPECT_NE(send_stream, nullptr);
197
198 internal::AudioReceiveStream* internal_recv_stream =
199 static_cast<internal::AudioReceiveStream*>(recv_stream);
200 EXPECT_EQ(send_stream,
201 internal_recv_stream->GetAssociatedSendStreamForTesting());
202
203 call->DestroyAudioSendStream(send_stream);
204 EXPECT_EQ(nullptr,
205 internal_recv_stream->GetAssociatedSendStreamForTesting());
206
207 call->DestroyAudioReceiveStream(recv_stream);
208 }
209 }
210
TEST(CallTest,CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst)211 TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
212 for (bool use_null_audio_processing : {false, true}) {
213 CallHelper call(use_null_audio_processing);
214 MockTransport send_transport;
215 AudioSendStream::Config send_config(&send_transport);
216 send_config.rtp.ssrc = 777;
217 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
218 EXPECT_NE(send_stream, nullptr);
219
220 AudioReceiveStream::Config recv_config;
221 MockTransport rtcp_send_transport;
222 recv_config.rtp.remote_ssrc = 42;
223 recv_config.rtp.local_ssrc = 777;
224 recv_config.rtcp_send_transport = &rtcp_send_transport;
225 recv_config.decoder_factory =
226 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
227 AudioReceiveStream* recv_stream =
228 call->CreateAudioReceiveStream(recv_config);
229 EXPECT_NE(recv_stream, nullptr);
230
231 internal::AudioReceiveStream* internal_recv_stream =
232 static_cast<internal::AudioReceiveStream*>(recv_stream);
233 EXPECT_EQ(send_stream,
234 internal_recv_stream->GetAssociatedSendStreamForTesting());
235
236 call->DestroyAudioReceiveStream(recv_stream);
237
238 call->DestroyAudioSendStream(send_stream);
239 }
240 }
241
TEST(CallTest,CreateDestroy_FlexfecReceiveStream)242 TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
243 for (bool use_null_audio_processing : {false, true}) {
244 CallHelper call(use_null_audio_processing);
245 MockTransport rtcp_send_transport;
246 FlexfecReceiveStream::Config config(&rtcp_send_transport);
247 config.payload_type = 118;
248 config.remote_ssrc = 38837212;
249 config.protected_media_ssrcs = {27273};
250
251 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
252 EXPECT_NE(stream, nullptr);
253 call->DestroyFlexfecReceiveStream(stream);
254 }
255 }
256
TEST(CallTest,CreateDestroy_FlexfecReceiveStreams)257 TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
258 for (bool use_null_audio_processing : {false, true}) {
259 CallHelper call(use_null_audio_processing);
260 MockTransport rtcp_send_transport;
261 FlexfecReceiveStream::Config config(&rtcp_send_transport);
262 config.payload_type = 118;
263 std::list<FlexfecReceiveStream*> streams;
264
265 for (int i = 0; i < 2; ++i) {
266 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
267 config.remote_ssrc = ssrc;
268 config.protected_media_ssrcs = {ssrc + 1};
269 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
270 EXPECT_NE(stream, nullptr);
271 if (ssrc & 1) {
272 streams.push_back(stream);
273 } else {
274 streams.push_front(stream);
275 }
276 }
277 for (auto s : streams) {
278 call->DestroyFlexfecReceiveStream(s);
279 }
280 streams.clear();
281 }
282 }
283 }
284
TEST(CallTest,MultipleFlexfecReceiveStreamsProtectingSingleVideoStream)285 TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
286 for (bool use_null_audio_processing : {false, true}) {
287 CallHelper call(use_null_audio_processing);
288 MockTransport rtcp_send_transport;
289 FlexfecReceiveStream::Config config(&rtcp_send_transport);
290 config.payload_type = 118;
291 config.protected_media_ssrcs = {1324234};
292 FlexfecReceiveStream* stream;
293 std::list<FlexfecReceiveStream*> streams;
294
295 config.remote_ssrc = 838383;
296 stream = call->CreateFlexfecReceiveStream(config);
297 EXPECT_NE(stream, nullptr);
298 streams.push_back(stream);
299
300 config.remote_ssrc = 424993;
301 stream = call->CreateFlexfecReceiveStream(config);
302 EXPECT_NE(stream, nullptr);
303 streams.push_back(stream);
304
305 config.remote_ssrc = 99383;
306 stream = call->CreateFlexfecReceiveStream(config);
307 EXPECT_NE(stream, nullptr);
308 streams.push_back(stream);
309
310 config.remote_ssrc = 5548;
311 stream = call->CreateFlexfecReceiveStream(config);
312 EXPECT_NE(stream, nullptr);
313 streams.push_back(stream);
314
315 for (auto s : streams) {
316 call->DestroyFlexfecReceiveStream(s);
317 }
318 }
319 }
320
TEST(CallTest,RecreatingAudioStreamWithSameSsrcReusesRtpState)321 TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
322 constexpr uint32_t kSSRC = 12345;
323 for (bool use_null_audio_processing : {false, true}) {
324 CallHelper call(use_null_audio_processing);
325
326 auto create_stream_and_get_rtp_state = [&](uint32_t ssrc) {
327 MockTransport send_transport;
328 AudioSendStream::Config config(&send_transport);
329 config.rtp.ssrc = ssrc;
330 AudioSendStream* stream = call->CreateAudioSendStream(config);
331 const RtpState rtp_state =
332 static_cast<internal::AudioSendStream*>(stream)->GetRtpState();
333 call->DestroyAudioSendStream(stream);
334 return rtp_state;
335 };
336
337 const RtpState rtp_state1 = create_stream_and_get_rtp_state(kSSRC);
338 const RtpState rtp_state2 = create_stream_and_get_rtp_state(kSSRC);
339
340 EXPECT_EQ(rtp_state1.sequence_number, rtp_state2.sequence_number);
341 EXPECT_EQ(rtp_state1.start_timestamp, rtp_state2.start_timestamp);
342 EXPECT_EQ(rtp_state1.timestamp, rtp_state2.timestamp);
343 EXPECT_EQ(rtp_state1.capture_time_ms, rtp_state2.capture_time_ms);
344 EXPECT_EQ(rtp_state1.last_timestamp_time_ms,
345 rtp_state2.last_timestamp_time_ms);
346 }
347 }
348
TEST(CallTest,AddAdaptationResourceAfterCreatingVideoSendStream)349 TEST(CallTest, AddAdaptationResourceAfterCreatingVideoSendStream) {
350 CallHelper call(true);
351 // Create a VideoSendStream.
352 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
353 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
354 });
355 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
356 MockTransport send_transport;
357 VideoSendStream::Config config(&send_transport);
358 config.rtp.payload_type = 110;
359 config.rtp.ssrcs = {42};
360 config.encoder_settings.encoder_factory = &fake_encoder_factory;
361 config.encoder_settings.bitrate_allocator_factory =
362 bitrate_allocator_factory.get();
363 VideoEncoderConfig encoder_config;
364 encoder_config.max_bitrate_bps = 1337;
365 VideoSendStream* stream1 =
366 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
367 EXPECT_NE(stream1, nullptr);
368 config.rtp.ssrcs = {43};
369 VideoSendStream* stream2 =
370 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
371 EXPECT_NE(stream2, nullptr);
372 // Add a fake resource.
373 auto fake_resource = FakeResource::Create("FakeResource");
374 call->AddAdaptationResource(fake_resource);
375 // An adapter resource mirroring the |fake_resource| should now be present on
376 // both streams.
377 auto injected_resource1 = FindResourceWhoseNameContains(
378 stream1->GetAdaptationResources(), fake_resource->Name());
379 EXPECT_TRUE(injected_resource1);
380 auto injected_resource2 = FindResourceWhoseNameContains(
381 stream2->GetAdaptationResources(), fake_resource->Name());
382 EXPECT_TRUE(injected_resource2);
383 // Overwrite the real resource listeners with mock ones to verify the signal
384 // gets through.
385 injected_resource1->SetResourceListener(nullptr);
386 StrictMock<MockResourceListener> resource_listener1;
387 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
388 .Times(1)
389 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
390 ResourceUsageState usage_state) {
391 EXPECT_EQ(injected_resource1, resource);
392 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
393 });
394 injected_resource1->SetResourceListener(&resource_listener1);
395 injected_resource2->SetResourceListener(nullptr);
396 StrictMock<MockResourceListener> resource_listener2;
397 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
398 .Times(1)
399 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
400 ResourceUsageState usage_state) {
401 EXPECT_EQ(injected_resource2, resource);
402 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
403 });
404 injected_resource2->SetResourceListener(&resource_listener2);
405 // The kOveruse signal should get to our resource listeners.
406 fake_resource->SetUsageState(ResourceUsageState::kOveruse);
407 call->DestroyVideoSendStream(stream1);
408 call->DestroyVideoSendStream(stream2);
409 }
410
TEST(CallTest,AddAdaptationResourceBeforeCreatingVideoSendStream)411 TEST(CallTest, AddAdaptationResourceBeforeCreatingVideoSendStream) {
412 CallHelper call(true);
413 // Add a fake resource.
414 auto fake_resource = FakeResource::Create("FakeResource");
415 call->AddAdaptationResource(fake_resource);
416 // Create a VideoSendStream.
417 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
418 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
419 });
420 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
421 MockTransport send_transport;
422 VideoSendStream::Config config(&send_transport);
423 config.rtp.payload_type = 110;
424 config.rtp.ssrcs = {42};
425 config.encoder_settings.encoder_factory = &fake_encoder_factory;
426 config.encoder_settings.bitrate_allocator_factory =
427 bitrate_allocator_factory.get();
428 VideoEncoderConfig encoder_config;
429 encoder_config.max_bitrate_bps = 1337;
430 VideoSendStream* stream1 =
431 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
432 EXPECT_NE(stream1, nullptr);
433 config.rtp.ssrcs = {43};
434 VideoSendStream* stream2 =
435 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
436 EXPECT_NE(stream2, nullptr);
437 // An adapter resource mirroring the |fake_resource| should be present on both
438 // streams.
439 auto injected_resource1 = FindResourceWhoseNameContains(
440 stream1->GetAdaptationResources(), fake_resource->Name());
441 EXPECT_TRUE(injected_resource1);
442 auto injected_resource2 = FindResourceWhoseNameContains(
443 stream2->GetAdaptationResources(), fake_resource->Name());
444 EXPECT_TRUE(injected_resource2);
445 // Overwrite the real resource listeners with mock ones to verify the signal
446 // gets through.
447 injected_resource1->SetResourceListener(nullptr);
448 StrictMock<MockResourceListener> resource_listener1;
449 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
450 .Times(1)
451 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
452 ResourceUsageState usage_state) {
453 EXPECT_EQ(injected_resource1, resource);
454 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
455 });
456 injected_resource1->SetResourceListener(&resource_listener1);
457 injected_resource2->SetResourceListener(nullptr);
458 StrictMock<MockResourceListener> resource_listener2;
459 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
460 .Times(1)
461 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
462 ResourceUsageState usage_state) {
463 EXPECT_EQ(injected_resource2, resource);
464 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
465 });
466 injected_resource2->SetResourceListener(&resource_listener2);
467 // The kUnderuse signal should get to our resource listeners.
468 fake_resource->SetUsageState(ResourceUsageState::kUnderuse);
469 call->DestroyVideoSendStream(stream1);
470 call->DestroyVideoSendStream(stream2);
471 }
472
TEST(CallTest,SharedModuleThread)473 TEST(CallTest, SharedModuleThread) {
474 class SharedModuleThreadUser : public Module {
475 public:
476 SharedModuleThreadUser(ProcessThread* expected_thread,
477 rtc::scoped_refptr<SharedModuleThread> thread)
478 : expected_thread_(expected_thread), thread_(std::move(thread)) {
479 thread_->EnsureStarted();
480 thread_->process_thread()->RegisterModule(this, RTC_FROM_HERE);
481 }
482
483 ~SharedModuleThreadUser() override {
484 thread_->process_thread()->DeRegisterModule(this);
485 EXPECT_TRUE(thread_was_checked_);
486 }
487
488 private:
489 int64_t TimeUntilNextProcess() override { return 1000; }
490 void Process() override {}
491 void ProcessThreadAttached(ProcessThread* process_thread) override {
492 if (!process_thread) {
493 // Being detached.
494 return;
495 }
496 EXPECT_EQ(process_thread, expected_thread_);
497 thread_was_checked_ = true;
498 }
499
500 bool thread_was_checked_ = false;
501 ProcessThread* const expected_thread_;
502 rtc::scoped_refptr<SharedModuleThread> thread_;
503 };
504
505 // Create our test instance and pass a lambda to it that gets executed when
506 // the reference count goes back to 1 - meaning |shared| again is the only
507 // reference, which means we can free the variable and deallocate the thread.
508 rtc::scoped_refptr<SharedModuleThread> shared;
509 shared =
510 SharedModuleThread::Create(ProcessThread::Create("MySharedProcessThread"),
511 [&shared]() { shared = nullptr; });
512 ProcessThread* process_thread = shared->process_thread();
513
514 ASSERT_TRUE(shared.get());
515
516 {
517 // Create a couple of users of the thread.
518 // These instances are in a separate scope to trigger the callback to our
519 // lambda, which will run when these go out of scope.
520 SharedModuleThreadUser user1(process_thread, shared);
521 SharedModuleThreadUser user2(process_thread, shared);
522 }
523
524 // The thread should now have been stopped and freed.
525 EXPECT_FALSE(shared);
526 }
527
528 } // namespace webrtc
529