blob: e07e447a0f66128414b37f91590238715d26680f [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"
Ali Tofigh641a1b12022-05-17 11:48:46 +020019#include "absl/strings/string_view.h"
Karl Wibergf3850f62017-11-02 13:04:41 +010020#include "api/audio_codecs/builtin_audio_decoder_factory.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020021#include "api/rtc_event_log/rtc_event_log.h"
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020022#include "api/task_queue/default_task_queue_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "api/test/mock_audio_mixer.h"
Henrik Boströmf4a99912020-06-11 12:07:14 +020024#include "api/test/video/function_video_encoder_factory.h"
Erik Språng014dd3c2019-11-28 13:44:25 +010025#include "api/transport/field_trial_based_config.h"
Henrik Boströmf4a99912020-06-11 12:07:14 +020026#include "api/video/builtin_video_bitrate_allocator_factory.h"
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +010027#include "audio/audio_receive_stream.h"
Yves Gerey665174f2018-06-19 15:03:05 +020028#include "audio/audio_send_stream.h"
Henrik Boströmf4a99912020-06-11 12:07:14 +020029#include "call/adaptation/test/fake_resource.h"
Henrik Boström29444c62020-07-01 15:48:46 +020030#include "call/adaptation/test/mock_resource_listener.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "call/audio_state.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "modules/audio_device/include/mock_audio_device.h"
Fredrik Solenberg2a877972017-12-15 16:42:15 +010033#include "modules/audio_processing/include/mock_audio_processing.h"
Niels Möller3e9cb2c2021-01-14 12:00:57 +010034#include "modules/include/module.h"
Tomas Gunnarssonf25761d2020-06-03 22:55:33 +020035#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020036#include "test/fake_encoder.h"
37#include "test/gtest.h"
38#include "test/mock_audio_decoder_factory.h"
39#include "test/mock_transport.h"
Tommi553c8692020-05-05 15:35:45 +020040#include "test/run_loop.h"
solenbergc7a8b082015-10-16 14:35:07 -070041
42namespace {
43
Henrik Boström29444c62020-07-01 15:48:46 +020044using ::testing::_;
Henrik Boströmf4a99912020-06-11 12:07:14 +020045using ::testing::Contains;
Alex Konradic20baf62020-12-03 11:30:34 -050046using ::testing::NiceMock;
Henrik Boström29444c62020-07-01 15:48:46 +020047using ::testing::StrictMock;
Henrik Boströmf4a99912020-06-11 12:07:14 +020048
solenbergc7a8b082015-10-16 14:35:07 -070049struct CallHelper {
Per Åhgrencc73ed32020-04-26 23:56:17 +020050 explicit CallHelper(bool use_null_audio_processing) {
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020051 task_queue_factory_ = webrtc::CreateDefaultTaskQueueFactory();
solenberg566ef242015-11-06 15:34:49 -080052 webrtc::AudioState::Config audio_state_config;
Fredrik Solenberg2a877972017-12-15 16:42:15 +010053 audio_state_config.audio_mixer =
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +020054 rtc::make_ref_counted<webrtc::test::MockAudioMixer>();
Fredrik Solenberg2a877972017-12-15 16:42:15 +010055 audio_state_config.audio_processing =
Per Åhgrencc73ed32020-04-26 23:56:17 +020056 use_null_audio_processing
57 ? nullptr
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +020058 : rtc::make_ref_counted<
Alex Konradic20baf62020-12-03 11:30:34 -050059 NiceMock<webrtc::test::MockAudioProcessing>>();
Fredrik Solenberg2a877972017-12-15 16:42:15 +010060 audio_state_config.audio_device_module =
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +020061 rtc::make_ref_counted<webrtc::test::MockAudioDeviceModule>();
skvlad11a9cbf2016-10-07 11:53:05 -070062 webrtc::Call::Config config(&event_log_);
solenberg566ef242015-11-06 15:34:49 -080063 config.audio_state = webrtc::AudioState::Create(audio_state_config);
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020064 config.task_queue_factory = task_queue_factory_.get();
Erik Språng014dd3c2019-11-28 13:44:25 +010065 config.trials = &field_trials_;
solenbergc7a8b082015-10-16 14:35:07 -070066 call_.reset(webrtc::Call::Create(config));
67 }
68
69 webrtc::Call* operator->() { return call_.get(); }
70
71 private:
Tommi553c8692020-05-05 15:35:45 +020072 webrtc::test::RunLoop loop_;
Danil Chapovalov83bbe912019-08-07 12:24:53 +020073 webrtc::RtcEventLogNull event_log_;
Erik Språng014dd3c2019-11-28 13:44:25 +010074 webrtc::FieldTrialBasedConfig field_trials_;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020075 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
kwibergb25345e2016-03-12 06:10:44 -080076 std::unique_ptr<webrtc::Call> call_;
solenbergc7a8b082015-10-16 14:35:07 -070077};
78} // namespace
79
80namespace webrtc {
81
Henrik Boström29444c62020-07-01 15:48:46 +020082namespace {
83
84rtc::scoped_refptr<Resource> FindResourceWhoseNameContains(
85 const std::vector<rtc::scoped_refptr<Resource>>& resources,
Ali Tofigh641a1b12022-05-17 11:48:46 +020086 absl::string_view name_contains) {
Henrik Boström29444c62020-07-01 15:48:46 +020087 for (const auto& resource : resources) {
Ali Tofigh641a1b12022-05-17 11:48:46 +020088 if (resource->Name().find(std::string(name_contains)) != std::string::npos)
Henrik Boström29444c62020-07-01 15:48:46 +020089 return resource;
90 }
91 return nullptr;
92}
93
94} // namespace
95
solenbergc7a8b082015-10-16 14:35:07 -070096TEST(CallTest, ConstructDestruct) {
Per Åhgrencc73ed32020-04-26 23:56:17 +020097 for (bool use_null_audio_processing : {false, true}) {
98 CallHelper call(use_null_audio_processing);
99 }
solenbergc7a8b082015-10-16 14:35:07 -0700100}
101
102TEST(CallTest, CreateDestroy_AudioSendStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200103 for (bool use_null_audio_processing : {false, true}) {
104 CallHelper call(use_null_audio_processing);
105 MockTransport send_transport;
106 AudioSendStream::Config config(&send_transport);
107 config.rtp.ssrc = 42;
108 AudioSendStream* stream = call->CreateAudioSendStream(config);
109 EXPECT_NE(stream, nullptr);
110 call->DestroyAudioSendStream(stream);
111 }
solenbergc7a8b082015-10-16 14:35:07 -0700112}
113
114TEST(CallTest, CreateDestroy_AudioReceiveStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200115 for (bool use_null_audio_processing : {false, true}) {
116 CallHelper call(use_null_audio_processing);
117 AudioReceiveStream::Config config;
118 MockTransport rtcp_send_transport;
119 config.rtp.remote_ssrc = 42;
120 config.rtcp_send_transport = &rtcp_send_transport;
121 config.decoder_factory =
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200122 rtc::make_ref_counted<webrtc::MockAudioDecoderFactory>();
Per Åhgrencc73ed32020-04-26 23:56:17 +0200123 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
124 EXPECT_NE(stream, nullptr);
125 call->DestroyAudioReceiveStream(stream);
126 }
solenbergc7a8b082015-10-16 14:35:07 -0700127}
128
129TEST(CallTest, CreateDestroy_AudioSendStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200130 for (bool use_null_audio_processing : {false, true}) {
131 CallHelper call(use_null_audio_processing);
132 MockTransport send_transport;
133 AudioSendStream::Config config(&send_transport);
134 std::list<AudioSendStream*> streams;
135 for (int i = 0; i < 2; ++i) {
136 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
137 config.rtp.ssrc = ssrc;
138 AudioSendStream* stream = call->CreateAudioSendStream(config);
139 EXPECT_NE(stream, nullptr);
140 if (ssrc & 1) {
141 streams.push_back(stream);
142 } else {
143 streams.push_front(stream);
144 }
solenbergc7a8b082015-10-16 14:35:07 -0700145 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200146 for (auto s : streams) {
147 call->DestroyAudioSendStream(s);
148 }
149 streams.clear();
solenbergc7a8b082015-10-16 14:35:07 -0700150 }
solenbergc7a8b082015-10-16 14:35:07 -0700151 }
152}
153
154TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200155 for (bool use_null_audio_processing : {false, true}) {
156 CallHelper call(use_null_audio_processing);
157 AudioReceiveStream::Config config;
158 MockTransport rtcp_send_transport;
159 config.rtcp_send_transport = &rtcp_send_transport;
160 config.decoder_factory =
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200161 rtc::make_ref_counted<webrtc::MockAudioDecoderFactory>();
Per Åhgrencc73ed32020-04-26 23:56:17 +0200162 std::list<AudioReceiveStream*> streams;
163 for (int i = 0; i < 2; ++i) {
164 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
165 config.rtp.remote_ssrc = ssrc;
166 AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
167 EXPECT_NE(stream, nullptr);
168 if (ssrc & 1) {
169 streams.push_back(stream);
170 } else {
171 streams.push_front(stream);
172 }
solenbergc7a8b082015-10-16 14:35:07 -0700173 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200174 for (auto s : streams) {
175 call->DestroyAudioReceiveStream(s);
176 }
177 streams.clear();
solenbergc7a8b082015-10-16 14:35:07 -0700178 }
solenbergc7a8b082015-10-16 14:35:07 -0700179 }
180}
brandtr25445d32016-10-23 23:37:14 -0700181
solenberg7602aab2016-11-14 11:30:07 -0800182TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200183 for (bool use_null_audio_processing : {false, true}) {
184 CallHelper call(use_null_audio_processing);
185 AudioReceiveStream::Config recv_config;
186 MockTransport rtcp_send_transport;
187 recv_config.rtp.remote_ssrc = 42;
188 recv_config.rtp.local_ssrc = 777;
189 recv_config.rtcp_send_transport = &rtcp_send_transport;
190 recv_config.decoder_factory =
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200191 rtc::make_ref_counted<webrtc::MockAudioDecoderFactory>();
Per Åhgrencc73ed32020-04-26 23:56:17 +0200192 AudioReceiveStream* recv_stream =
193 call->CreateAudioReceiveStream(recv_config);
194 EXPECT_NE(recv_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800195
Per Åhgrencc73ed32020-04-26 23:56:17 +0200196 MockTransport send_transport;
197 AudioSendStream::Config send_config(&send_transport);
198 send_config.rtp.ssrc = 777;
199 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
200 EXPECT_NE(send_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800201
Per Åhgrencc73ed32020-04-26 23:56:17 +0200202 internal::AudioReceiveStream* internal_recv_stream =
203 static_cast<internal::AudioReceiveStream*>(recv_stream);
204 EXPECT_EQ(send_stream,
205 internal_recv_stream->GetAssociatedSendStreamForTesting());
solenberg7602aab2016-11-14 11:30:07 -0800206
Per Åhgrencc73ed32020-04-26 23:56:17 +0200207 call->DestroyAudioSendStream(send_stream);
208 EXPECT_EQ(nullptr,
209 internal_recv_stream->GetAssociatedSendStreamForTesting());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100210
Per Åhgrencc73ed32020-04-26 23:56:17 +0200211 call->DestroyAudioReceiveStream(recv_stream);
212 }
solenberg7602aab2016-11-14 11:30:07 -0800213}
214
215TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200216 for (bool use_null_audio_processing : {false, true}) {
217 CallHelper call(use_null_audio_processing);
218 MockTransport send_transport;
219 AudioSendStream::Config send_config(&send_transport);
220 send_config.rtp.ssrc = 777;
221 AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
222 EXPECT_NE(send_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800223
Per Åhgrencc73ed32020-04-26 23:56:17 +0200224 AudioReceiveStream::Config recv_config;
225 MockTransport rtcp_send_transport;
226 recv_config.rtp.remote_ssrc = 42;
227 recv_config.rtp.local_ssrc = 777;
228 recv_config.rtcp_send_transport = &rtcp_send_transport;
229 recv_config.decoder_factory =
Tomas Gunnarssonc1d58912021-04-22 19:21:43 +0200230 rtc::make_ref_counted<webrtc::MockAudioDecoderFactory>();
Per Åhgrencc73ed32020-04-26 23:56:17 +0200231 AudioReceiveStream* recv_stream =
232 call->CreateAudioReceiveStream(recv_config);
233 EXPECT_NE(recv_stream, nullptr);
solenberg7602aab2016-11-14 11:30:07 -0800234
Per Åhgrencc73ed32020-04-26 23:56:17 +0200235 internal::AudioReceiveStream* internal_recv_stream =
236 static_cast<internal::AudioReceiveStream*>(recv_stream);
237 EXPECT_EQ(send_stream,
238 internal_recv_stream->GetAssociatedSendStreamForTesting());
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100239
Per Åhgrencc73ed32020-04-26 23:56:17 +0200240 call->DestroyAudioReceiveStream(recv_stream);
solenberg7602aab2016-11-14 11:30:07 -0800241
Per Åhgrencc73ed32020-04-26 23:56:17 +0200242 call->DestroyAudioSendStream(send_stream);
243 }
solenberg7602aab2016-11-14 11:30:07 -0800244}
245
brandtr25445d32016-10-23 23:37:14 -0700246TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200247 for (bool use_null_audio_processing : {false, true}) {
248 CallHelper call(use_null_audio_processing);
249 MockTransport rtcp_send_transport;
250 FlexfecReceiveStream::Config config(&rtcp_send_transport);
251 config.payload_type = 118;
Tommi1c1f5402021-06-14 10:54:20 +0200252 config.rtp.remote_ssrc = 38837212;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200253 config.protected_media_ssrcs = {27273};
brandtr25445d32016-10-23 23:37:14 -0700254
Per Åhgrencc73ed32020-04-26 23:56:17 +0200255 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
256 EXPECT_NE(stream, nullptr);
257 call->DestroyFlexfecReceiveStream(stream);
258 }
brandtr25445d32016-10-23 23:37:14 -0700259}
260
261TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200262 for (bool use_null_audio_processing : {false, true}) {
263 CallHelper call(use_null_audio_processing);
264 MockTransport rtcp_send_transport;
265 FlexfecReceiveStream::Config config(&rtcp_send_transport);
266 config.payload_type = 118;
267 std::list<FlexfecReceiveStream*> streams;
brandtr25445d32016-10-23 23:37:14 -0700268
Per Åhgrencc73ed32020-04-26 23:56:17 +0200269 for (int i = 0; i < 2; ++i) {
270 for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
Tommi1c1f5402021-06-14 10:54:20 +0200271 config.rtp.remote_ssrc = ssrc;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200272 config.protected_media_ssrcs = {ssrc + 1};
273 FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
274 EXPECT_NE(stream, nullptr);
275 if (ssrc & 1) {
276 streams.push_back(stream);
277 } else {
278 streams.push_front(stream);
279 }
brandtr25445d32016-10-23 23:37:14 -0700280 }
Per Åhgrencc73ed32020-04-26 23:56:17 +0200281 for (auto s : streams) {
282 call->DestroyFlexfecReceiveStream(s);
283 }
284 streams.clear();
brandtr25445d32016-10-23 23:37:14 -0700285 }
brandtr25445d32016-10-23 23:37:14 -0700286 }
287}
288
289TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
Per Åhgrencc73ed32020-04-26 23:56:17 +0200290 for (bool use_null_audio_processing : {false, true}) {
291 CallHelper call(use_null_audio_processing);
292 MockTransport rtcp_send_transport;
293 FlexfecReceiveStream::Config config(&rtcp_send_transport);
294 config.payload_type = 118;
295 config.protected_media_ssrcs = {1324234};
296 FlexfecReceiveStream* stream;
297 std::list<FlexfecReceiveStream*> streams;
brandtr25445d32016-10-23 23:37:14 -0700298
Tommi1c1f5402021-06-14 10:54:20 +0200299 config.rtp.remote_ssrc = 838383;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200300 stream = call->CreateFlexfecReceiveStream(config);
301 EXPECT_NE(stream, nullptr);
302 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700303
Tommi1c1f5402021-06-14 10:54:20 +0200304 config.rtp.remote_ssrc = 424993;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200305 stream = call->CreateFlexfecReceiveStream(config);
306 EXPECT_NE(stream, nullptr);
307 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700308
Tommi1c1f5402021-06-14 10:54:20 +0200309 config.rtp.remote_ssrc = 99383;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200310 stream = call->CreateFlexfecReceiveStream(config);
311 EXPECT_NE(stream, nullptr);
312 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700313
Tommi1c1f5402021-06-14 10:54:20 +0200314 config.rtp.remote_ssrc = 5548;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200315 stream = call->CreateFlexfecReceiveStream(config);
316 EXPECT_NE(stream, nullptr);
317 streams.push_back(stream);
brandtr25445d32016-10-23 23:37:14 -0700318
Per Åhgrencc73ed32020-04-26 23:56:17 +0200319 for (auto s : streams) {
320 call->DestroyFlexfecReceiveStream(s);
321 }
brandtr25445d32016-10-23 23:37:14 -0700322 }
323}
324
ossuc3d4b482017-05-23 06:07:11 -0700325TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
326 constexpr uint32_t kSSRC = 12345;
Per Åhgrencc73ed32020-04-26 23:56:17 +0200327 for (bool use_null_audio_processing : {false, true}) {
328 CallHelper call(use_null_audio_processing);
ossuc3d4b482017-05-23 06:07:11 -0700329
Per Åhgrencc73ed32020-04-26 23:56:17 +0200330 auto create_stream_and_get_rtp_state = [&](uint32_t ssrc) {
331 MockTransport send_transport;
332 AudioSendStream::Config config(&send_transport);
333 config.rtp.ssrc = ssrc;
334 AudioSendStream* stream = call->CreateAudioSendStream(config);
335 const RtpState rtp_state =
336 static_cast<internal::AudioSendStream*>(stream)->GetRtpState();
337 call->DestroyAudioSendStream(stream);
338 return rtp_state;
339 };
ossuc3d4b482017-05-23 06:07:11 -0700340
Per Åhgrencc73ed32020-04-26 23:56:17 +0200341 const RtpState rtp_state1 = create_stream_and_get_rtp_state(kSSRC);
342 const RtpState rtp_state2 = create_stream_and_get_rtp_state(kSSRC);
ossuc3d4b482017-05-23 06:07:11 -0700343
Per Åhgrencc73ed32020-04-26 23:56:17 +0200344 EXPECT_EQ(rtp_state1.sequence_number, rtp_state2.sequence_number);
345 EXPECT_EQ(rtp_state1.start_timestamp, rtp_state2.start_timestamp);
346 EXPECT_EQ(rtp_state1.timestamp, rtp_state2.timestamp);
347 EXPECT_EQ(rtp_state1.capture_time_ms, rtp_state2.capture_time_ms);
348 EXPECT_EQ(rtp_state1.last_timestamp_time_ms,
349 rtp_state2.last_timestamp_time_ms);
Per Åhgrencc73ed32020-04-26 23:56:17 +0200350 }
ossuc3d4b482017-05-23 06:07:11 -0700351}
Fredrik Solenberg8f5787a2018-01-11 13:52:30 +0100352
Henrik Boströmf4a99912020-06-11 12:07:14 +0200353TEST(CallTest, AddAdaptationResourceAfterCreatingVideoSendStream) {
354 CallHelper call(true);
355 // Create a VideoSendStream.
356 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
357 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
358 });
359 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
360 MockTransport send_transport;
361 VideoSendStream::Config config(&send_transport);
362 config.rtp.payload_type = 110;
363 config.rtp.ssrcs = {42};
364 config.encoder_settings.encoder_factory = &fake_encoder_factory;
365 config.encoder_settings.bitrate_allocator_factory =
366 bitrate_allocator_factory.get();
367 VideoEncoderConfig encoder_config;
368 encoder_config.max_bitrate_bps = 1337;
Henrik Boström29444c62020-07-01 15:48:46 +0200369 VideoSendStream* stream1 =
370 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
371 EXPECT_NE(stream1, nullptr);
372 config.rtp.ssrcs = {43};
373 VideoSendStream* stream2 =
374 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
375 EXPECT_NE(stream2, nullptr);
376 // Add a fake resource.
Henrik Boströmf4a99912020-06-11 12:07:14 +0200377 auto fake_resource = FakeResource::Create("FakeResource");
378 call->AddAdaptationResource(fake_resource);
Artem Titovea240272021-07-26 12:40:21 +0200379 // An adapter resource mirroring the `fake_resource` should now be present on
Henrik Boström29444c62020-07-01 15:48:46 +0200380 // both streams.
381 auto injected_resource1 = FindResourceWhoseNameContains(
382 stream1->GetAdaptationResources(), fake_resource->Name());
383 EXPECT_TRUE(injected_resource1);
384 auto injected_resource2 = FindResourceWhoseNameContains(
385 stream2->GetAdaptationResources(), fake_resource->Name());
386 EXPECT_TRUE(injected_resource2);
387 // Overwrite the real resource listeners with mock ones to verify the signal
388 // gets through.
389 injected_resource1->SetResourceListener(nullptr);
390 StrictMock<MockResourceListener> resource_listener1;
391 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
392 .Times(1)
393 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
394 ResourceUsageState usage_state) {
395 EXPECT_EQ(injected_resource1, resource);
396 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
397 });
398 injected_resource1->SetResourceListener(&resource_listener1);
399 injected_resource2->SetResourceListener(nullptr);
400 StrictMock<MockResourceListener> resource_listener2;
401 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
402 .Times(1)
403 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
404 ResourceUsageState usage_state) {
405 EXPECT_EQ(injected_resource2, resource);
406 EXPECT_EQ(ResourceUsageState::kOveruse, usage_state);
407 });
408 injected_resource2->SetResourceListener(&resource_listener2);
409 // The kOveruse signal should get to our resource listeners.
410 fake_resource->SetUsageState(ResourceUsageState::kOveruse);
411 call->DestroyVideoSendStream(stream1);
412 call->DestroyVideoSendStream(stream2);
Henrik Boströmf4a99912020-06-11 12:07:14 +0200413}
414
415TEST(CallTest, AddAdaptationResourceBeforeCreatingVideoSendStream) {
416 CallHelper call(true);
417 // Add a fake resource.
418 auto fake_resource = FakeResource::Create("FakeResource");
419 call->AddAdaptationResource(fake_resource);
420 // Create a VideoSendStream.
421 test::FunctionVideoEncoderFactory fake_encoder_factory([]() {
422 return std::make_unique<test::FakeEncoder>(Clock::GetRealTimeClock());
423 });
424 auto bitrate_allocator_factory = CreateBuiltinVideoBitrateAllocatorFactory();
425 MockTransport send_transport;
426 VideoSendStream::Config config(&send_transport);
427 config.rtp.payload_type = 110;
428 config.rtp.ssrcs = {42};
429 config.encoder_settings.encoder_factory = &fake_encoder_factory;
430 config.encoder_settings.bitrate_allocator_factory =
431 bitrate_allocator_factory.get();
432 VideoEncoderConfig encoder_config;
433 encoder_config.max_bitrate_bps = 1337;
Henrik Boström29444c62020-07-01 15:48:46 +0200434 VideoSendStream* stream1 =
435 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
436 EXPECT_NE(stream1, nullptr);
437 config.rtp.ssrcs = {43};
438 VideoSendStream* stream2 =
439 call->CreateVideoSendStream(config.Copy(), encoder_config.Copy());
440 EXPECT_NE(stream2, nullptr);
Artem Titovea240272021-07-26 12:40:21 +0200441 // An adapter resource mirroring the `fake_resource` should be present on both
Henrik Boström29444c62020-07-01 15:48:46 +0200442 // streams.
443 auto injected_resource1 = FindResourceWhoseNameContains(
444 stream1->GetAdaptationResources(), fake_resource->Name());
445 EXPECT_TRUE(injected_resource1);
446 auto injected_resource2 = FindResourceWhoseNameContains(
447 stream2->GetAdaptationResources(), fake_resource->Name());
448 EXPECT_TRUE(injected_resource2);
449 // Overwrite the real resource listeners with mock ones to verify the signal
450 // gets through.
451 injected_resource1->SetResourceListener(nullptr);
452 StrictMock<MockResourceListener> resource_listener1;
453 EXPECT_CALL(resource_listener1, OnResourceUsageStateMeasured(_, _))
454 .Times(1)
455 .WillOnce([injected_resource1](rtc::scoped_refptr<Resource> resource,
456 ResourceUsageState usage_state) {
457 EXPECT_EQ(injected_resource1, resource);
458 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
459 });
460 injected_resource1->SetResourceListener(&resource_listener1);
461 injected_resource2->SetResourceListener(nullptr);
462 StrictMock<MockResourceListener> resource_listener2;
463 EXPECT_CALL(resource_listener2, OnResourceUsageStateMeasured(_, _))
464 .Times(1)
465 .WillOnce([injected_resource2](rtc::scoped_refptr<Resource> resource,
466 ResourceUsageState usage_state) {
467 EXPECT_EQ(injected_resource2, resource);
468 EXPECT_EQ(ResourceUsageState::kUnderuse, usage_state);
469 });
470 injected_resource2->SetResourceListener(&resource_listener2);
471 // The kUnderuse signal should get to our resource listeners.
472 fake_resource->SetUsageState(ResourceUsageState::kUnderuse);
473 call->DestroyVideoSendStream(stream1);
474 call->DestroyVideoSendStream(stream2);
Henrik Boströmf4a99912020-06-11 12:07:14 +0200475}
476
Tommi25c77c12020-05-25 17:44:55 +0200477TEST(CallTest, SharedModuleThread) {
478 class SharedModuleThreadUser : public Module {
479 public:
480 SharedModuleThreadUser(ProcessThread* expected_thread,
481 rtc::scoped_refptr<SharedModuleThread> thread)
482 : expected_thread_(expected_thread), thread_(std::move(thread)) {
483 thread_->EnsureStarted();
484 thread_->process_thread()->RegisterModule(this, RTC_FROM_HERE);
485 }
486
487 ~SharedModuleThreadUser() override {
488 thread_->process_thread()->DeRegisterModule(this);
489 EXPECT_TRUE(thread_was_checked_);
490 }
491
492 private:
493 int64_t TimeUntilNextProcess() override { return 1000; }
494 void Process() override {}
495 void ProcessThreadAttached(ProcessThread* process_thread) override {
496 if (!process_thread) {
497 // Being detached.
498 return;
499 }
500 EXPECT_EQ(process_thread, expected_thread_);
501 thread_was_checked_ = true;
502 }
503
504 bool thread_was_checked_ = false;
505 ProcessThread* const expected_thread_;
506 rtc::scoped_refptr<SharedModuleThread> thread_;
507 };
508
509 // Create our test instance and pass a lambda to it that gets executed when
Artem Titovea240272021-07-26 12:40:21 +0200510 // the reference count goes back to 1 - meaning `shared` again is the only
Tommi25c77c12020-05-25 17:44:55 +0200511 // reference, which means we can free the variable and deallocate the thread.
512 rtc::scoped_refptr<SharedModuleThread> shared;
Per Kjellander4c50e702020-06-30 14:39:43 +0200513 shared =
514 SharedModuleThread::Create(ProcessThread::Create("MySharedProcessThread"),
515 [&shared]() { shared = nullptr; });
Tommi25c77c12020-05-25 17:44:55 +0200516 ProcessThread* process_thread = shared->process_thread();
517
518 ASSERT_TRUE(shared.get());
519
520 {
521 // Create a couple of users of the thread.
522 // These instances are in a separate scope to trigger the callback to our
523 // lambda, which will run when these go out of scope.
524 SharedModuleThreadUser user1(process_thread, shared);
525 SharedModuleThreadUser user2(process_thread, shared);
526 }
527
528 // The thread should now have been stopped and freed.
529 EXPECT_FALSE(shared);
530}
531
solenbergc7a8b082015-10-16 14:35:07 -0700532} // namespace webrtc