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