blob: b6be941e53a71f485927d9df029581aba37a7c85 [file] [log] [blame]
solenbergc7a8b082015-10-16 14:35:07 -07001/*
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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "call/call.h"
12
solenbergc7a8b082015-10-16 14:35:07 -070013#include <list>
kwiberg1c07c702017-03-27 07:15:49 -070014#include <map>
kwibergb25345e2016-03-12 06:10:44 -080015#include <memory>
zstein7cb69d52017-05-08 11:52:38 -070016#include <utility>
solenbergc7a8b082015-10-16 14:35:07 -070017
Karl Wiberg918f50c2018-07-05 11:40:33 +020018#include "absl/memory/memory.h"
Karl Wibergf3850f62017-11-02 13:04:41 +010019#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020020#include "api/rtc_event_log/rtc_event_log.h"
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020021#include "api/task_queue/default_task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020022#include "api/test/mock_audio_mixer.h"
Henrik Boströmf4a99912020-06-11 12:07:14 +020023#include "api/test/video/function_video_encoder_factory.h"
Erik Språng014dd3c2019-11-28 13:44:25 +010024#include "api/transport/field_trial_based_config.h"
Henrik Boströmf4a99912020-06-11 12:07:14 +020025#include "api/video/builtin_video_bitrate_allocator_factory.h"
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +010026#include "audio/audio_receive_stream.h"
Yves Gerey665174f2018-06-19 15:03:05 +020027#include "audio/audio_send_stream.h"
Henrik Boströmf4a99912020-06-11 12:07:14 +020028#include "call/adaptation/test/fake_resource.h"
Henrik Boström29444c62020-07-01 15:48:46 +020029#include "call/adaptation/test/mock_resource_listener.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020030#include "call/audio_state.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "modules/audio_device/include/mock_audio_device.h"
Fredrik Solenberg2a877972017-12-15 16:42:15 +010032#include "modules/audio_processing/include/mock_audio_processing.h"
Tomas Gunnarssonf25761d2020-06-03 22:55:33 +020033#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "test/fake_encoder.h"
35#include "test/gtest.h"
36#include "test/mock_audio_decoder_factory.h"
37#include "test/mock_transport.h"
Tommi553c8692020-05-05 15:35:45 +020038#include "test/run_loop.h"
solenbergc7a8b082015-10-16 14:35:07 -070039
40namespace {
41
Henrik Boström29444c62020-07-01 15:48:46 +020042using ::testing::_;
Henrik Boströmf4a99912020-06-11 12:07:14 +020043using ::testing::Contains;
Alex Konradic20baf62020-12-03 11:30:34 -050044using ::testing::NiceMock;
Henrik Boström29444c62020-07-01 15:48:46 +020045using ::testing::StrictMock;
Henrik Boströmf4a99912020-06-11 12:07:14 +020046
solenbergc7a8b082015-10-16 14:35:07 -070047struct CallHelper {
Per Åhgrencc73ed32020-04-26 23:56:17 +020048 explicit CallHelper(bool use_null_audio_processing) {
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020049 task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
solenberg566ef242015-11-06 15:34:49 -080050 webrtc::AudioState::Config audio_state_config;
Fredrik Solenberg2a877972017-12-15 16:42:15 +010051 audio_state_config.audio_mixer =
52 new rtc::RefCountedObject<webrtc::test::MockAudioMixer>();
53 audio_state_config.audio_processing =
Per Åhgrencc73ed32020-04-26 23:56:17 +020054 use_null_audio_processing
55 ? nullptr
Alex Konradic20baf62020-12-03 11:30:34 -050056 : new rtc::RefCountedObject<
57 NiceMock<webrtc::test::MockAudioProcessing>>();
Fredrik Solenberg2a877972017-12-15 16:42:15 +010058 audio_state_config.audio_device_module =
59 new rtc::RefCountedObject<webrtc::test::MockAudioDeviceModule>();
skvlad11a9cbf2016-10-07 11:53:05 -070060 webrtc::Call::Config config(&event_log_);
solenberg566ef242015-11-06 15:34:49 -080061 config.audio_state = webrtc::AudioState::Create(audio_state_config);
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020062 config.task_queue_factory = task_queue_factory_.get();
Erik Språng014dd3c2019-11-28 13:44:25 +010063 config.trials = &field_trials_;
solenbergc7a8b082015-10-16 14:35:07 -070064 call_.reset(webrtc::Call::Create(config));
65 }
66
67 webrtc::Call* operator->() { return call_.get(); }
68
69 private:
Tommi553c8692020-05-05 15:35:45 +020070 webrtc::test::RunLoop loop_;
Danil Chapovalov83bbe912019-08-07 12:24:53 +020071 webrtc::RtcEventLogNull event_log_;
Erik Språng014dd3c2019-11-28 13:44:25 +010072 webrtc::FieldTrialBasedConfig field_trials_;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020073 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
kwibergb25345e2016-03-12 06:10:44 -080074 std::unique_ptr<webrtc::Call> call_;
solenbergc7a8b082015-10-16 14:35:07 -070075};
76} // namespace
77
78namespace webrtc {
79
Henrik Boström29444c62020-07-01 15:48:46 +020080namespace {
81
82rtc::scoped_refptr<Resource> FindResourceWhoseNameContains(
83 const std::vector<rtc::scoped_refptr<Resource>>& resources,
84 const std::string& name_contains) {
85 for (const auto& resource : resources) {
86 if (resource->Name().find(name_contains) != std::string::npos)
87 return resource;
88 }
89 return nullptr;
90}
91
92} // namespace
93
solenbergc7a8b082015-10-16 14:35:07 -070094TEST(CallTest, ConstructDestruct) {
Per Åhgrencc73ed32020-04-26 23:56:17 +020095 for (bool use_null_audio_processing : {false, true}) {
96 CallHelper call(use_null_audio_processing);
97 }
solenbergc7a8b082015-10-16 14:35:07 -070098}
99
100TEST(CallTest, CreateDestroy_AudioSendStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200101 for (bool use_null_audio_processing : {false, true}) {
102 CallHelper call(use_null_audio_processing);
103 MockTransport send_transport;
104 AudioSendStream::Config config(&send_transport);
105 config.rtp.ssrc = 42;
106 AudioSendStream* stream = call->CreateAudioSendStream(config);
107 EXPECT_NE(stream, nullptr);
108 call->DestroyAudioSendStream(stream);
109 }
solenbergc7a8b082015-10-16 14:35:07 -0700110}
111
112TEST(CallTest, CreateDestroy_AudioReceiveStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200113 for (bool use_null_audio_processing : {false, true}) {
114 CallHelper call(use_null_audio_processing);
115 AudioReceiveStream::Config config;
116 MockTransport rtcp_send_transport;
117 config.rtp.remote_ssrc = 42;
118 config.rtcp_send_transport = &rtcp_send_transport;
119 config.decoder_factory =
120 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
121 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
122 EXPECT_NE(stream, nullptr);
123 call->DestroyAudioReceiveStream(stream);
124 }
solenbergc7a8b082015-10-16 14:35:07 -0700125}
126
127TEST(CallTest, CreateDestroy_AudioSendStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200128 for (bool use_null_audio_processing : {false, true}) {
129 CallHelper call(use_null_audio_processing);
130 MockTransport send_transport;
131 AudioSendStream::Config config(&send_transport);
132 std::list<AudioSendStream*> streams;
133 for (int i = 0; i < 2; ++i) {
134 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
135 config.rtp.ssrc = ssrc;
136 AudioSendStream* stream = call->CreateAudioSendStream(config);
137 EXPECT_NE(stream, nullptr);
138 if (ssrc & 1) {
139 streams.push_back(stream);
140 } else {
141 streams.push_front(stream);
142 }
solenbergc7a8b082015-10-16 14:35:07 -0700143 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200144 for (auto s : streams) {
145 call->DestroyAudioSendStream(s);
146 }
147 streams.clear();
solenbergc7a8b082015-10-16 14:35:07 -0700148 }
solenbergc7a8b082015-10-16 14:35:07 -0700149 }
150}
151
152TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200153 for (bool use_null_audio_processing : {false, true}) {
154 CallHelper call(use_null_audio_processing);
155 AudioReceiveStream::Config config;
156 MockTransport rtcp_send_transport;
157 config.rtcp_send_transport = &rtcp_send_transport;
158 config.decoder_factory =
159 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
160 std::list<AudioReceiveStream*> streams;
161 for (int i = 0; i < 2; ++i) {
162 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
163 config.rtp.remote_ssrc = ssrc;
164 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
165 EXPECT_NE(stream, nullptr);
166 if (ssrc & 1) {
167 streams.push_back(stream);
168 } else {
169 streams.push_front(stream);
170 }
solenbergc7a8b082015-10-16 14:35:07 -0700171 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200172 for (auto s : streams) {
173 call->DestroyAudioReceiveStream(s);
174 }
175 streams.clear();
solenbergc7a8b082015-10-16 14:35:07 -0700176 }
solenbergc7a8b082015-10-16 14:35:07 -0700177 }
178}
brandtr25445d32016-10-23 23:37:14 -0700179
solenberg7602aab2016-11-14 11:30:07 -0800180TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200181 for (bool use_null_audio_processing : {false, true}) {
182 CallHelper call(use_null_audio_processing);
183 AudioReceiveStream::Config recv_config;
184 MockTransport rtcp_send_transport;
185 recv_config.rtp.remote_ssrc = 42;
186 recv_config.rtp.local_ssrc = 777;
187 recv_config.rtcp_send_transport = &rtcp_send_transport;
188 recv_config.decoder_factory =
189 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
190 AudioReceiveStream* recv_stream =
191 call->CreateAudioReceiveStream(recv_config);
192 EXPECT_NE(recv_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800193
Per Åhgrencc73ed32020-04-26 23:56:17 +0200194 MockTransport send_transport;
195 AudioSendStream::Config send_config(&send_transport);
196 send_config.rtp.ssrc = 777;
197 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
198 EXPECT_NE(send_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800199
Per Åhgrencc73ed32020-04-26 23:56:17 +0200200 internal::AudioReceiveStream* internal_recv_stream =
201 static_cast<internal::AudioReceiveStream*>(recv_stream);
202 EXPECT_EQ(send_stream,
203 internal_recv_stream->GetAssociatedSendStreamForTesting());
solenberg7602aab2016-11-14 11:30:07 -0800204
Per Åhgrencc73ed32020-04-26 23:56:17 +0200205 call->DestroyAudioSendStream(send_stream);
206 EXPECT_EQ(nullptr,
207 internal_recv_stream->GetAssociatedSendStreamForTesting());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100208
Per Åhgrencc73ed32020-04-26 23:56:17 +0200209 call->DestroyAudioReceiveStream(recv_stream);
210 }
solenberg7602aab2016-11-14 11:30:07 -0800211}
212
213TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200214 for (bool use_null_audio_processing : {false, true}) {
215 CallHelper call(use_null_audio_processing);
216 MockTransport send_transport;
217 AudioSendStream::Config send_config(&send_transport);
218 send_config.rtp.ssrc = 777;
219 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
220 EXPECT_NE(send_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800221
Per Åhgrencc73ed32020-04-26 23:56:17 +0200222 AudioReceiveStream::Config recv_config;
223 MockTransport rtcp_send_transport;
224 recv_config.rtp.remote_ssrc = 42;
225 recv_config.rtp.local_ssrc = 777;
226 recv_config.rtcp_send_transport = &rtcp_send_transport;
227 recv_config.decoder_factory =
228 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
229 AudioReceiveStream* recv_stream =
230 call->CreateAudioReceiveStream(recv_config);
231 EXPECT_NE(recv_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800232
Per Åhgrencc73ed32020-04-26 23:56:17 +0200233 internal::AudioReceiveStream* internal_recv_stream =
234 static_cast<internal::AudioReceiveStream*>(recv_stream);
235 EXPECT_EQ(send_stream,
236 internal_recv_stream->GetAssociatedSendStreamForTesting());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100237
Per Åhgrencc73ed32020-04-26 23:56:17 +0200238 call->DestroyAudioReceiveStream(recv_stream);
solenberg7602aab2016-11-14 11:30:07 -0800239
Per Åhgrencc73ed32020-04-26 23:56:17 +0200240 call->DestroyAudioSendStream(send_stream);
241 }
solenberg7602aab2016-11-14 11:30:07 -0800242}
243
brandtr25445d32016-10-23 23:37:14 -0700244TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200245 for (bool use_null_audio_processing : {false, true}) {
246 CallHelper call(use_null_audio_processing);
247 MockTransport rtcp_send_transport;
248 FlexfecReceiveStream::Config config(&rtcp_send_transport);
249 config.payload_type = 118;
250 config.remote_ssrc = 38837212;
251 config.protected_media_ssrcs = {27273};
brandtr25445d32016-10-23 23:37:14 -0700252
Per Åhgrencc73ed32020-04-26 23:56:17 +0200253 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
254 EXPECT_NE(stream, nullptr);
255 call->DestroyFlexfecReceiveStream(stream);
256 }
brandtr25445d32016-10-23 23:37:14 -0700257}
258
259TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200260 for (bool use_null_audio_processing : {false, true}) {
261 CallHelper call(use_null_audio_processing);
262 MockTransport rtcp_send_transport;
263 FlexfecReceiveStream::Config config(&rtcp_send_transport);
264 config.payload_type = 118;
265 std::list<FlexfecReceiveStream*> streams;
brandtr25445d32016-10-23 23:37:14 -0700266
Per Åhgrencc73ed32020-04-26 23:56:17 +0200267 for (int i = 0; i < 2; ++i) {
268 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
269 config.remote_ssrc = ssrc;
270 config.protected_media_ssrcs = {ssrc + 1};
271 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
272 EXPECT_NE(stream, nullptr);
273 if (ssrc & 1) {
274 streams.push_back(stream);
275 } else {
276 streams.push_front(stream);
277 }
brandtr25445d32016-10-23 23:37:14 -0700278 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200279 for (auto s : streams) {
280 call->DestroyFlexfecReceiveStream(s);
281 }
282 streams.clear();
brandtr25445d32016-10-23 23:37:14 -0700283 }
brandtr25445d32016-10-23 23:37:14 -0700284 }
285}
286
287TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200288 for (bool use_null_audio_processing : {false, true}) {
289 CallHelper call(use_null_audio_processing);
290 MockTransport rtcp_send_transport;
291 FlexfecReceiveStream::Config config(&rtcp_send_transport);
292 config.payload_type = 118;
293 config.protected_media_ssrcs = {1324234};
294 FlexfecReceiveStream* stream;
295 std::list<FlexfecReceiveStream*> streams;
brandtr25445d32016-10-23 23:37:14 -0700296
Per Åhgrencc73ed32020-04-26 23:56:17 +0200297 config.remote_ssrc = 838383;
298 stream = call->CreateFlexfecReceiveStream(config);
299 EXPECT_NE(stream, nullptr);
300 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700301
Per Åhgrencc73ed32020-04-26 23:56:17 +0200302 config.remote_ssrc = 424993;
303 stream = call->CreateFlexfecReceiveStream(config);
304 EXPECT_NE(stream, nullptr);
305 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700306
Per Åhgrencc73ed32020-04-26 23:56:17 +0200307 config.remote_ssrc = 99383;
308 stream = call->CreateFlexfecReceiveStream(config);
309 EXPECT_NE(stream, nullptr);
310 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700311
Per Åhgrencc73ed32020-04-26 23:56:17 +0200312 config.remote_ssrc = 5548;
313 stream = call->CreateFlexfecReceiveStream(config);
314 EXPECT_NE(stream, nullptr);
315 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700316
Per Åhgrencc73ed32020-04-26 23:56:17 +0200317 for (auto s : streams) {
318 call->DestroyFlexfecReceiveStream(s);
319 }
brandtr25445d32016-10-23 23:37:14 -0700320 }
321}
322
ossuc3d4b482017-05-23 06:07:11 -0700323TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
324 constexpr uint32_t kSSRC = 12345;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200325 for (bool use_null_audio_processing : {false, true}) {
326 CallHelper call(use_null_audio_processing);
ossuc3d4b482017-05-23 06:07:11 -0700327
Per Åhgrencc73ed32020-04-26 23:56:17 +0200328 auto create_stream_and_get_rtp_state = [&](uint32_t ssrc) {
329 MockTransport send_transport;
330 AudioSendStream::Config config(&send_transport);
331 config.rtp.ssrc = ssrc;
332 AudioSendStream* stream = call->CreateAudioSendStream(config);
333 const RtpState rtp_state =
334 static_cast<internal::AudioSendStream*>(stream)->GetRtpState();
335 call->DestroyAudioSendStream(stream);
336 return rtp_state;
337 };
ossuc3d4b482017-05-23 06:07:11 -0700338
Per Åhgrencc73ed32020-04-26 23:56:17 +0200339 const RtpState rtp_state1 = create_stream_and_get_rtp_state(kSSRC);
340 const RtpState rtp_state2 = create_stream_and_get_rtp_state(kSSRC);
ossuc3d4b482017-05-23 06:07:11 -0700341
Per Åhgrencc73ed32020-04-26 23:56:17 +0200342 EXPECT_EQ(rtp_state1.sequence_number, rtp_state2.sequence_number);
343 EXPECT_EQ(rtp_state1.start_timestamp, rtp_state2.start_timestamp);
344 EXPECT_EQ(rtp_state1.timestamp, rtp_state2.timestamp);
345 EXPECT_EQ(rtp_state1.capture_time_ms, rtp_state2.capture_time_ms);
346 EXPECT_EQ(rtp_state1.last_timestamp_time_ms,
347 rtp_state2.last_timestamp_time_ms);
Per Åhgrencc73ed32020-04-26 23:56:17 +0200348 }
ossuc3d4b482017-05-23 06:07:11 -0700349}
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100350
Henrik Boströmf4a99912020-06-11 12:07:14 +0200351TEST(CallTest, AddAdaptationResourceAfterCreatingVideoSendStream) {
352 CallHelper call(true);
353 // Create a VideoSendStream.
354 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
355 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
356 });
357 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
358 MockTransport send_transport;
359 VideoSendStream::Config config(&send_transport);
360 config.rtp.payload_type = 110;
361 config.rtp.ssrcs = {42};
362 config.encoder_settings.encoder_factory = &fake_encoder_factory;
363 config.encoder_settings.bitrate_allocator_factory =
364 bitrate_allocator_factory.get();
365 VideoEncoderConfig encoder_config;
366 encoder_config.max_bitrate_bps = 1337;
Henrik Boström29444c62020-07-01 15:48:46 +0200367 VideoSendStream* stream1 =
368 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
369 EXPECT_NE(stream1, nullptr);
370 config.rtp.ssrcs = {43};
371 VideoSendStream* stream2 =
372 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
373 EXPECT_NE(stream2, nullptr);
374 // Add a fake resource.
Henrik Boströmf4a99912020-06-11 12:07:14 +0200375 auto fake_resource = FakeResource::Create("FakeResource");
376 call->AddAdaptationResource(fake_resource);
Henrik Boström29444c62020-07-01 15:48:46 +0200377 // An adapter resource mirroring the |fake_resource| should now be present on
378 // both streams.
379 auto injected_resource1 = FindResourceWhoseNameContains(
380 stream1->GetAdaptationResources(), fake_resource->Name());
381 EXPECT_TRUE(injected_resource1);
382 auto injected_resource2 = FindResourceWhoseNameContains(
383 stream2->GetAdaptationResources(), fake_resource->Name());
384 EXPECT_TRUE(injected_resource2);
385 // Overwrite the real resource listeners with mock ones to verify the signal
386 // gets through.
387 injected_resource1->SetResourceListener(nullptr);
388 StrictMock<MockResourceListener> resource_listener1;
389 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
390 .Times(1)
391 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
392 ResourceUsageState usage_state) {
393 EXPECT_EQ(injected_resource1, resource);
394 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
395 });
396 injected_resource1->SetResourceListener(&resource_listener1);
397 injected_resource2->SetResourceListener(nullptr);
398 StrictMock<MockResourceListener> resource_listener2;
399 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
400 .Times(1)
401 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
402 ResourceUsageState usage_state) {
403 EXPECT_EQ(injected_resource2, resource);
404 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
405 });
406 injected_resource2->SetResourceListener(&resource_listener2);
407 // The kOveruse signal should get to our resource listeners.
408 fake_resource->SetUsageState(ResourceUsageState::kOveruse);
409 call->DestroyVideoSendStream(stream1);
410 call->DestroyVideoSendStream(stream2);
Henrik Boströmf4a99912020-06-11 12:07:14 +0200411}
412
413TEST(CallTest, AddAdaptationResourceBeforeCreatingVideoSendStream) {
414 CallHelper call(true);
415 // Add a fake resource.
416 auto fake_resource = FakeResource::Create("FakeResource");
417 call->AddAdaptationResource(fake_resource);
418 // Create a VideoSendStream.
419 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
420 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
421 });
422 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
423 MockTransport send_transport;
424 VideoSendStream::Config config(&send_transport);
425 config.rtp.payload_type = 110;
426 config.rtp.ssrcs = {42};
427 config.encoder_settings.encoder_factory = &fake_encoder_factory;
428 config.encoder_settings.bitrate_allocator_factory =
429 bitrate_allocator_factory.get();
430 VideoEncoderConfig encoder_config;
431 encoder_config.max_bitrate_bps = 1337;
Henrik Boström29444c62020-07-01 15:48:46 +0200432 VideoSendStream* stream1 =
433 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
434 EXPECT_NE(stream1, nullptr);
435 config.rtp.ssrcs = {43};
436 VideoSendStream* stream2 =
437 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
438 EXPECT_NE(stream2, nullptr);
439 // An adapter resource mirroring the |fake_resource| should be present on both
440 // streams.
441 auto injected_resource1 = FindResourceWhoseNameContains(
442 stream1->GetAdaptationResources(), fake_resource->Name());
443 EXPECT_TRUE(injected_resource1);
444 auto injected_resource2 = FindResourceWhoseNameContains(
445 stream2->GetAdaptationResources(), fake_resource->Name());
446 EXPECT_TRUE(injected_resource2);
447 // Overwrite the real resource listeners with mock ones to verify the signal
448 // gets through.
449 injected_resource1->SetResourceListener(nullptr);
450 StrictMock<MockResourceListener> resource_listener1;
451 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
452 .Times(1)
453 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
454 ResourceUsageState usage_state) {
455 EXPECT_EQ(injected_resource1, resource);
456 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
457 });
458 injected_resource1->SetResourceListener(&resource_listener1);
459 injected_resource2->SetResourceListener(nullptr);
460 StrictMock<MockResourceListener> resource_listener2;
461 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
462 .Times(1)
463 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
464 ResourceUsageState usage_state) {
465 EXPECT_EQ(injected_resource2, resource);
466 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
467 });
468 injected_resource2->SetResourceListener(&resource_listener2);
469 // The kUnderuse signal should get to our resource listeners.
470 fake_resource->SetUsageState(ResourceUsageState::kUnderuse);
471 call->DestroyVideoSendStream(stream1);
472 call->DestroyVideoSendStream(stream2);
Henrik Boströmf4a99912020-06-11 12:07:14 +0200473}
474
Tommi25c77c12020-05-25 17:44:55 +0200475TEST(CallTest, SharedModuleThread) {
476 class SharedModuleThreadUser : public Module {
477 public:
478 SharedModuleThreadUser(ProcessThread* expected_thread,
479 rtc::scoped_refptr<SharedModuleThread> thread)
480 : expected_thread_(expected_thread), thread_(std::move(thread)) {
481 thread_->EnsureStarted();
482 thread_->process_thread()->RegisterModule(this, RTC_FROM_HERE);
483 }
484
485 ~SharedModuleThreadUser() override {
486 thread_->process_thread()->DeRegisterModule(this);
487 EXPECT_TRUE(thread_was_checked_);
488 }
489
490 private:
491 int64_t TimeUntilNextProcess() override { return 1000; }
492 void Process() override {}
493 void ProcessThreadAttached(ProcessThread* process_thread) override {
494 if (!process_thread) {
495 // Being detached.
496 return;
497 }
498 EXPECT_EQ(process_thread, expected_thread_);
499 thread_was_checked_ = true;
500 }
501
502 bool thread_was_checked_ = false;
503 ProcessThread* const expected_thread_;
504 rtc::scoped_refptr<SharedModuleThread> thread_;
505 };
506
507 // Create our test instance and pass a lambda to it that gets executed when
508 // the reference count goes back to 1 - meaning |shared| again is the only
509 // reference, which means we can free the variable and deallocate the thread.
510 rtc::scoped_refptr<SharedModuleThread> shared;
Per Kjellander4c50e702020-06-30 14:39:43 +0200511 shared =
512 SharedModuleThread::Create(ProcessThread::Create("MySharedProcessThread"),
513 [&shared]() { shared = nullptr; });
Tommi25c77c12020-05-25 17:44:55 +0200514 ProcessThread* process_thread = shared->process_thread();
515
516 ASSERT_TRUE(shared.get());
517
518 {
519 // Create a couple of users of the thread.
520 // These instances are in a separate scope to trigger the callback to our
521 // lambda, which will run when these go out of scope.
522 SharedModuleThreadUser user1(process_thread, shared);
523 SharedModuleThreadUser user2(process_thread, shared);
524 }
525
526 // The thread should now have been stopped and freed.
527 EXPECT_FALSE(shared);
528}
529
solenbergc7a8b082015-10-16 14:35:07 -0700530} // namespace webrtc