• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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