blob: e165107d9877cfb005ffa45a5d72aac3af7e9d5b [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;
Henrik Boström29444c62020-07-01 15:48:46 +020044using ::testing::StrictMock;
Henrik Boströmf4a99912020-06-11 12:07:14 +020045
solenbergc7a8b082015-10-16 14:35:07 -070046struct CallHelper {
Per Åhgrencc73ed32020-04-26 23:56:17 +020047 explicit CallHelper(bool use_null_audio_processing) {
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020048 task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
solenberg566ef242015-11-06 15:34:49 -080049 webrtc::AudioState::Config audio_state_config;
Fredrik Solenberg2a877972017-12-15 16:42:15 +010050 audio_state_config.audio_mixer =
51 new rtc::RefCountedObject<webrtc::test::MockAudioMixer>();
52 audio_state_config.audio_processing =
Per Åhgrencc73ed32020-04-26 23:56:17 +020053 use_null_audio_processing
54 ? nullptr
55 : new rtc::RefCountedObject<webrtc::test::MockAudioProcessing>();
Fredrik Solenberg2a877972017-12-15 16:42:15 +010056 audio_state_config.audio_device_module =
57 new rtc::RefCountedObject<webrtc::test::MockAudioDeviceModule>();
skvlad11a9cbf2016-10-07 11:53:05 -070058 webrtc::Call::Config config(&event_log_);
solenberg566ef242015-11-06 15:34:49 -080059 config.audio_state = webrtc::AudioState::Create(audio_state_config);
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020060 config.task_queue_factory = task_queue_factory_.get();
Erik Språng014dd3c2019-11-28 13:44:25 +010061 config.trials = &field_trials_;
solenbergc7a8b082015-10-16 14:35:07 -070062 call_.reset(webrtc::Call::Create(config));
63 }
64
65 webrtc::Call* operator->() { return call_.get(); }
66
67 private:
Tommi553c8692020-05-05 15:35:45 +020068 webrtc::test::RunLoop loop_;
Danil Chapovalov83bbe912019-08-07 12:24:53 +020069 webrtc::RtcEventLogNull event_log_;
Erik Språng014dd3c2019-11-28 13:44:25 +010070 webrtc::FieldTrialBasedConfig field_trials_;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020071 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
kwibergb25345e2016-03-12 06:10:44 -080072 std::unique_ptr<webrtc::Call> call_;
solenbergc7a8b082015-10-16 14:35:07 -070073};
74} // namespace
75
76namespace webrtc {
77
Henrik Boström29444c62020-07-01 15:48:46 +020078namespace {
79
80rtc::scoped_refptr<Resource> FindResourceWhoseNameContains(
81 const std::vector<rtc::scoped_refptr<Resource>>& resources,
82 const std::string& name_contains) {
83 for (const auto& resource : resources) {
84 if (resource->Name().find(name_contains) != std::string::npos)
85 return resource;
86 }
87 return nullptr;
88}
89
90} // namespace
91
solenbergc7a8b082015-10-16 14:35:07 -070092TEST(CallTest, ConstructDestruct) {
Per Åhgrencc73ed32020-04-26 23:56:17 +020093 for (bool use_null_audio_processing : {false, true}) {
94 CallHelper call(use_null_audio_processing);
95 }
solenbergc7a8b082015-10-16 14:35:07 -070096}
97
98TEST(CallTest, CreateDestroy_AudioSendStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +020099 for (bool use_null_audio_processing : {false, true}) {
100 CallHelper call(use_null_audio_processing);
101 MockTransport send_transport;
102 AudioSendStream::Config config(&send_transport);
103 config.rtp.ssrc = 42;
104 AudioSendStream* stream = call->CreateAudioSendStream(config);
105 EXPECT_NE(stream, nullptr);
106 call->DestroyAudioSendStream(stream);
107 }
solenbergc7a8b082015-10-16 14:35:07 -0700108}
109
110TEST(CallTest, CreateDestroy_AudioReceiveStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200111 for (bool use_null_audio_processing : {false, true}) {
112 CallHelper call(use_null_audio_processing);
113 AudioReceiveStream::Config config;
114 MockTransport rtcp_send_transport;
115 config.rtp.remote_ssrc = 42;
116 config.rtcp_send_transport = &rtcp_send_transport;
117 config.decoder_factory =
118 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
119 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
120 EXPECT_NE(stream, nullptr);
121 call->DestroyAudioReceiveStream(stream);
122 }
solenbergc7a8b082015-10-16 14:35:07 -0700123}
124
125TEST(CallTest, CreateDestroy_AudioSendStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200126 for (bool use_null_audio_processing : {false, true}) {
127 CallHelper call(use_null_audio_processing);
128 MockTransport send_transport;
129 AudioSendStream::Config config(&send_transport);
130 std::list<AudioSendStream*> streams;
131 for (int i = 0; i < 2; ++i) {
132 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
133 config.rtp.ssrc = ssrc;
134 AudioSendStream* stream = call->CreateAudioSendStream(config);
135 EXPECT_NE(stream, nullptr);
136 if (ssrc & 1) {
137 streams.push_back(stream);
138 } else {
139 streams.push_front(stream);
140 }
solenbergc7a8b082015-10-16 14:35:07 -0700141 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200142 for (auto s : streams) {
143 call->DestroyAudioSendStream(s);
144 }
145 streams.clear();
solenbergc7a8b082015-10-16 14:35:07 -0700146 }
solenbergc7a8b082015-10-16 14:35:07 -0700147 }
148}
149
150TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200151 for (bool use_null_audio_processing : {false, true}) {
152 CallHelper call(use_null_audio_processing);
153 AudioReceiveStream::Config config;
154 MockTransport rtcp_send_transport;
155 config.rtcp_send_transport = &rtcp_send_transport;
156 config.decoder_factory =
157 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
158 std::list<AudioReceiveStream*> streams;
159 for (int i = 0; i < 2; ++i) {
160 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
161 config.rtp.remote_ssrc = ssrc;
162 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
163 EXPECT_NE(stream, nullptr);
164 if (ssrc & 1) {
165 streams.push_back(stream);
166 } else {
167 streams.push_front(stream);
168 }
solenbergc7a8b082015-10-16 14:35:07 -0700169 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200170 for (auto s : streams) {
171 call->DestroyAudioReceiveStream(s);
172 }
173 streams.clear();
solenbergc7a8b082015-10-16 14:35:07 -0700174 }
solenbergc7a8b082015-10-16 14:35:07 -0700175 }
176}
brandtr25445d32016-10-23 23:37:14 -0700177
solenberg7602aab2016-11-14 11:30:07 -0800178TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200179 for (bool use_null_audio_processing : {false, true}) {
180 CallHelper call(use_null_audio_processing);
181 AudioReceiveStream::Config recv_config;
182 MockTransport rtcp_send_transport;
183 recv_config.rtp.remote_ssrc = 42;
184 recv_config.rtp.local_ssrc = 777;
185 recv_config.rtcp_send_transport = &rtcp_send_transport;
186 recv_config.decoder_factory =
187 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
188 AudioReceiveStream* recv_stream =
189 call->CreateAudioReceiveStream(recv_config);
190 EXPECT_NE(recv_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800191
Per Åhgrencc73ed32020-04-26 23:56:17 +0200192 MockTransport send_transport;
193 AudioSendStream::Config send_config(&send_transport);
194 send_config.rtp.ssrc = 777;
195 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
196 EXPECT_NE(send_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800197
Per Åhgrencc73ed32020-04-26 23:56:17 +0200198 internal::AudioReceiveStream* internal_recv_stream =
199 static_cast<internal::AudioReceiveStream*>(recv_stream);
200 EXPECT_EQ(send_stream,
201 internal_recv_stream->GetAssociatedSendStreamForTesting());
solenberg7602aab2016-11-14 11:30:07 -0800202
Per Åhgrencc73ed32020-04-26 23:56:17 +0200203 call->DestroyAudioSendStream(send_stream);
204 EXPECT_EQ(nullptr,
205 internal_recv_stream->GetAssociatedSendStreamForTesting());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100206
Per Åhgrencc73ed32020-04-26 23:56:17 +0200207 call->DestroyAudioReceiveStream(recv_stream);
208 }
solenberg7602aab2016-11-14 11:30:07 -0800209}
210
211TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200212 for (bool use_null_audio_processing : {false, true}) {
213 CallHelper call(use_null_audio_processing);
214 MockTransport send_transport;
215 AudioSendStream::Config send_config(&send_transport);
216 send_config.rtp.ssrc = 777;
217 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
218 EXPECT_NE(send_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800219
Per Åhgrencc73ed32020-04-26 23:56:17 +0200220 AudioReceiveStream::Config recv_config;
221 MockTransport rtcp_send_transport;
222 recv_config.rtp.remote_ssrc = 42;
223 recv_config.rtp.local_ssrc = 777;
224 recv_config.rtcp_send_transport = &rtcp_send_transport;
225 recv_config.decoder_factory =
226 new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>();
227 AudioReceiveStream* recv_stream =
228 call->CreateAudioReceiveStream(recv_config);
229 EXPECT_NE(recv_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800230
Per Åhgrencc73ed32020-04-26 23:56:17 +0200231 internal::AudioReceiveStream* internal_recv_stream =
232 static_cast<internal::AudioReceiveStream*>(recv_stream);
233 EXPECT_EQ(send_stream,
234 internal_recv_stream->GetAssociatedSendStreamForTesting());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100235
Per Åhgrencc73ed32020-04-26 23:56:17 +0200236 call->DestroyAudioReceiveStream(recv_stream);
solenberg7602aab2016-11-14 11:30:07 -0800237
Per Åhgrencc73ed32020-04-26 23:56:17 +0200238 call->DestroyAudioSendStream(send_stream);
239 }
solenberg7602aab2016-11-14 11:30:07 -0800240}
241
brandtr25445d32016-10-23 23:37:14 -0700242TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200243 for (bool use_null_audio_processing : {false, true}) {
244 CallHelper call(use_null_audio_processing);
245 MockTransport rtcp_send_transport;
246 FlexfecReceiveStream::Config config(&rtcp_send_transport);
247 config.payload_type = 118;
248 config.remote_ssrc = 38837212;
249 config.protected_media_ssrcs = {27273};
brandtr25445d32016-10-23 23:37:14 -0700250
Per Åhgrencc73ed32020-04-26 23:56:17 +0200251 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
252 EXPECT_NE(stream, nullptr);
253 call->DestroyFlexfecReceiveStream(stream);
254 }
brandtr25445d32016-10-23 23:37:14 -0700255}
256
257TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200258 for (bool use_null_audio_processing : {false, true}) {
259 CallHelper call(use_null_audio_processing);
260 MockTransport rtcp_send_transport;
261 FlexfecReceiveStream::Config config(&rtcp_send_transport);
262 config.payload_type = 118;
263 std::list<FlexfecReceiveStream*> streams;
brandtr25445d32016-10-23 23:37:14 -0700264
Per Åhgrencc73ed32020-04-26 23:56:17 +0200265 for (int i = 0; i < 2; ++i) {
266 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
267 config.remote_ssrc = ssrc;
268 config.protected_media_ssrcs = {ssrc + 1};
269 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
270 EXPECT_NE(stream, nullptr);
271 if (ssrc & 1) {
272 streams.push_back(stream);
273 } else {
274 streams.push_front(stream);
275 }
brandtr25445d32016-10-23 23:37:14 -0700276 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200277 for (auto s : streams) {
278 call->DestroyFlexfecReceiveStream(s);
279 }
280 streams.clear();
brandtr25445d32016-10-23 23:37:14 -0700281 }
brandtr25445d32016-10-23 23:37:14 -0700282 }
283}
284
285TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200286 for (bool use_null_audio_processing : {false, true}) {
287 CallHelper call(use_null_audio_processing);
288 MockTransport rtcp_send_transport;
289 FlexfecReceiveStream::Config config(&rtcp_send_transport);
290 config.payload_type = 118;
291 config.protected_media_ssrcs = {1324234};
292 FlexfecReceiveStream* stream;
293 std::list<FlexfecReceiveStream*> streams;
brandtr25445d32016-10-23 23:37:14 -0700294
Per Åhgrencc73ed32020-04-26 23:56:17 +0200295 config.remote_ssrc = 838383;
296 stream = call->CreateFlexfecReceiveStream(config);
297 EXPECT_NE(stream, nullptr);
298 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700299
Per Åhgrencc73ed32020-04-26 23:56:17 +0200300 config.remote_ssrc = 424993;
301 stream = call->CreateFlexfecReceiveStream(config);
302 EXPECT_NE(stream, nullptr);
303 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700304
Per Åhgrencc73ed32020-04-26 23:56:17 +0200305 config.remote_ssrc = 99383;
306 stream = call->CreateFlexfecReceiveStream(config);
307 EXPECT_NE(stream, nullptr);
308 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700309
Per Åhgrencc73ed32020-04-26 23:56:17 +0200310 config.remote_ssrc = 5548;
311 stream = call->CreateFlexfecReceiveStream(config);
312 EXPECT_NE(stream, nullptr);
313 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700314
Per Åhgrencc73ed32020-04-26 23:56:17 +0200315 for (auto s : streams) {
316 call->DestroyFlexfecReceiveStream(s);
317 }
brandtr25445d32016-10-23 23:37:14 -0700318 }
319}
320
ossuc3d4b482017-05-23 06:07:11 -0700321TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
322 constexpr uint32_t kSSRC = 12345;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200323 for (bool use_null_audio_processing : {false, true}) {
324 CallHelper call(use_null_audio_processing);
ossuc3d4b482017-05-23 06:07:11 -0700325
Per Åhgrencc73ed32020-04-26 23:56:17 +0200326 auto create_stream_and_get_rtp_state = [&](uint32_t ssrc) {
327 MockTransport send_transport;
328 AudioSendStream::Config config(&send_transport);
329 config.rtp.ssrc = ssrc;
330 AudioSendStream* stream = call->CreateAudioSendStream(config);
331 const RtpState rtp_state =
332 static_cast<internal::AudioSendStream*>(stream)->GetRtpState();
333 call->DestroyAudioSendStream(stream);
334 return rtp_state;
335 };
ossuc3d4b482017-05-23 06:07:11 -0700336
Per Åhgrencc73ed32020-04-26 23:56:17 +0200337 const RtpState rtp_state1 = create_stream_and_get_rtp_state(kSSRC);
338 const RtpState rtp_state2 = create_stream_and_get_rtp_state(kSSRC);
ossuc3d4b482017-05-23 06:07:11 -0700339
Per Åhgrencc73ed32020-04-26 23:56:17 +0200340 EXPECT_EQ(rtp_state1.sequence_number, rtp_state2.sequence_number);
341 EXPECT_EQ(rtp_state1.start_timestamp, rtp_state2.start_timestamp);
342 EXPECT_EQ(rtp_state1.timestamp, rtp_state2.timestamp);
343 EXPECT_EQ(rtp_state1.capture_time_ms, rtp_state2.capture_time_ms);
344 EXPECT_EQ(rtp_state1.last_timestamp_time_ms,
345 rtp_state2.last_timestamp_time_ms);
Per Åhgrencc73ed32020-04-26 23:56:17 +0200346 }
ossuc3d4b482017-05-23 06:07:11 -0700347}
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100348
Henrik Boströmf4a99912020-06-11 12:07:14 +0200349TEST(CallTest, AddAdaptationResourceAfterCreatingVideoSendStream) {
350 CallHelper call(true);
351 // Create a VideoSendStream.
352 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
353 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
354 });
355 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
356 MockTransport send_transport;
357 VideoSendStream::Config config(&send_transport);
358 config.rtp.payload_type = 110;
359 config.rtp.ssrcs = {42};
360 config.encoder_settings.encoder_factory = &fake_encoder_factory;
361 config.encoder_settings.bitrate_allocator_factory =
362 bitrate_allocator_factory.get();
363 VideoEncoderConfig encoder_config;
364 encoder_config.max_bitrate_bps = 1337;
Henrik Boström29444c62020-07-01 15:48:46 +0200365 VideoSendStream* stream1 =
366 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
367 EXPECT_NE(stream1, nullptr);
368 config.rtp.ssrcs = {43};
369 VideoSendStream* stream2 =
370 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
371 EXPECT_NE(stream2, nullptr);
372 // Add a fake resource.
Henrik Boströmf4a99912020-06-11 12:07:14 +0200373 auto fake_resource = FakeResource::Create("FakeResource");
374 call->AddAdaptationResource(fake_resource);
Henrik Boström29444c62020-07-01 15:48:46 +0200375 // An adapter resource mirroring the |fake_resource| should now be present on
376 // both streams.
377 auto injected_resource1 = FindResourceWhoseNameContains(
378 stream1->GetAdaptationResources(), fake_resource->Name());
379 EXPECT_TRUE(injected_resource1);
380 auto injected_resource2 = FindResourceWhoseNameContains(
381 stream2->GetAdaptationResources(), fake_resource->Name());
382 EXPECT_TRUE(injected_resource2);
383 // Overwrite the real resource listeners with mock ones to verify the signal
384 // gets through.
385 injected_resource1->SetResourceListener(nullptr);
386 StrictMock<MockResourceListener> resource_listener1;
387 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
388 .Times(1)
389 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
390 ResourceUsageState usage_state) {
391 EXPECT_EQ(injected_resource1, resource);
392 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
393 });
394 injected_resource1->SetResourceListener(&resource_listener1);
395 injected_resource2->SetResourceListener(nullptr);
396 StrictMock<MockResourceListener> resource_listener2;
397 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
398 .Times(1)
399 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
400 ResourceUsageState usage_state) {
401 EXPECT_EQ(injected_resource2, resource);
402 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
403 });
404 injected_resource2->SetResourceListener(&resource_listener2);
405 // The kOveruse signal should get to our resource listeners.
406 fake_resource->SetUsageState(ResourceUsageState::kOveruse);
407 call->DestroyVideoSendStream(stream1);
408 call->DestroyVideoSendStream(stream2);
Henrik Boströmf4a99912020-06-11 12:07:14 +0200409}
410
411TEST(CallTest, AddAdaptationResourceBeforeCreatingVideoSendStream) {
412 CallHelper call(true);
413 // Add a fake resource.
414 auto fake_resource = FakeResource::Create("FakeResource");
415 call->AddAdaptationResource(fake_resource);
416 // Create a VideoSendStream.
417 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
418 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
419 });
420 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
421 MockTransport send_transport;
422 VideoSendStream::Config config(&send_transport);
423 config.rtp.payload_type = 110;
424 config.rtp.ssrcs = {42};
425 config.encoder_settings.encoder_factory = &fake_encoder_factory;
426 config.encoder_settings.bitrate_allocator_factory =
427 bitrate_allocator_factory.get();
428 VideoEncoderConfig encoder_config;
429 encoder_config.max_bitrate_bps = 1337;
Henrik Boström29444c62020-07-01 15:48:46 +0200430 VideoSendStream* stream1 =
431 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
432 EXPECT_NE(stream1, nullptr);
433 config.rtp.ssrcs = {43};
434 VideoSendStream* stream2 =
435 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
436 EXPECT_NE(stream2, nullptr);
437 // An adapter resource mirroring the |fake_resource| should be present on both
438 // streams.
439 auto injected_resource1 = FindResourceWhoseNameContains(
440 stream1->GetAdaptationResources(), fake_resource->Name());
441 EXPECT_TRUE(injected_resource1);
442 auto injected_resource2 = FindResourceWhoseNameContains(
443 stream2->GetAdaptationResources(), fake_resource->Name());
444 EXPECT_TRUE(injected_resource2);
445 // Overwrite the real resource listeners with mock ones to verify the signal
446 // gets through.
447 injected_resource1->SetResourceListener(nullptr);
448 StrictMock<MockResourceListener> resource_listener1;
449 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
450 .Times(1)
451 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
452 ResourceUsageState usage_state) {
453 EXPECT_EQ(injected_resource1, resource);
454 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
455 });
456 injected_resource1->SetResourceListener(&resource_listener1);
457 injected_resource2->SetResourceListener(nullptr);
458 StrictMock<MockResourceListener> resource_listener2;
459 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
460 .Times(1)
461 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
462 ResourceUsageState usage_state) {
463 EXPECT_EQ(injected_resource2, resource);
464 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
465 });
466 injected_resource2->SetResourceListener(&resource_listener2);
467 // The kUnderuse signal should get to our resource listeners.
468 fake_resource->SetUsageState(ResourceUsageState::kUnderuse);
469 call->DestroyVideoSendStream(stream1);
470 call->DestroyVideoSendStream(stream2);
Henrik Boströmf4a99912020-06-11 12:07:14 +0200471}
472
Tommi25c77c12020-05-25 17:44:55 +0200473TEST(CallTest, SharedModuleThread) {
474 class SharedModuleThreadUser : public Module {
475 public:
476 SharedModuleThreadUser(ProcessThread* expected_thread,
477 rtc::scoped_refptr<SharedModuleThread> thread)
478 : expected_thread_(expected_thread), thread_(std::move(thread)) {
479 thread_->EnsureStarted();
480 thread_->process_thread()->RegisterModule(this, RTC_FROM_HERE);
481 }
482
483 ~SharedModuleThreadUser() override {
484 thread_->process_thread()->DeRegisterModule(this);
485 EXPECT_TRUE(thread_was_checked_);
486 }
487
488 private:
489 int64_t TimeUntilNextProcess() override { return 1000; }
490 void Process() override {}
491 void ProcessThreadAttached(ProcessThread* process_thread) override {
492 if (!process_thread) {
493 // Being detached.
494 return;
495 }
496 EXPECT_EQ(process_thread, expected_thread_);
497 thread_was_checked_ = true;
498 }
499
500 bool thread_was_checked_ = false;
501 ProcessThread* const expected_thread_;
502 rtc::scoped_refptr<SharedModuleThread> thread_;
503 };
504
505 // Create our test instance and pass a lambda to it that gets executed when
506 // the reference count goes back to 1 - meaning |shared| again is the only
507 // reference, which means we can free the variable and deallocate the thread.
508 rtc::scoped_refptr<SharedModuleThread> shared;
Per Kjellander4c50e702020-06-30 14:39:43 +0200509 shared =
510 SharedModuleThread::Create(ProcessThread::Create("MySharedProcessThread"),
511 [&shared]() { shared = nullptr; });
Tommi25c77c12020-05-25 17:44:55 +0200512 ProcessThread* process_thread = shared->process_thread();
513
514 ASSERT_TRUE(shared.get());
515
516 {
517 // Create a couple of users of the thread.
518 // These instances are in a separate scope to trigger the callback to our
519 // lambda, which will run when these go out of scope.
520 SharedModuleThreadUser user1(process_thread, shared);
521 SharedModuleThreadUser user2(process_thread, shared);
522 }
523
524 // The thread should now have been stopped and freed.
525 EXPECT_FALSE(shared);
526}
527
solenbergc7a8b082015-10-16 14:35:07 -0700528} // namespace webrtc