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