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