blob: bc93a490f046ebb695b258f3220fc28e94908f08 [file] [log] [blame]
Sebastian Jansson98b07e92018-09-27 13:47:01 +02001/*
2 * Copyright 2018 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#include "test/scenario/call_client.h"
11
12#include <utility>
13
Steve Anton40d55332019-01-07 10:21:47 -080014#include "absl/memory/memory.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020015#include "modules/audio_mixer/audio_mixer_impl.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020016
17namespace webrtc {
18namespace test {
19namespace {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010020static constexpr size_t kNumSsrcs = 6;
21const uint32_t kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE, 0xBADCAFF,
22 0xBADCB00, 0xBADCB01, 0xBADCB02};
23const uint32_t kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE, 0xC0FFEF,
24 0xC0FFF0, 0xC0FFF1, 0xC0FFF2};
25const uint32_t kVideoRecvLocalSsrcs[kNumSsrcs] = {0xDAB001, 0xDAB002, 0xDAB003,
26 0xDAB004, 0xDAB005, 0xDAB006};
27const uint32_t kAudioSendSsrc = 0xDEADBEEF;
28const uint32_t kReceiverLocalAudioSsrc = 0x1234567;
29
Sebastian Jansson98b07e92018-09-27 13:47:01 +020030const char* kPriorityStreamId = "priority-track";
Sebastian Jansson800e1212018-10-22 11:49:03 +020031
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020032constexpr int kEventLogOutputIntervalMs = 5000;
33
Sebastian Jansson105a10a2019-04-01 09:18:14 +020034CallClientFakeAudio InitAudio(TimeController* time_controller) {
Sebastian Jansson800e1212018-10-22 11:49:03 +020035 CallClientFakeAudio setup;
36 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
37 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
Sebastian Jansson105a10a2019-04-01 09:18:14 +020038 setup.fake_audio_device = TestAudioDeviceModule::Create(
39 time_controller->GetTaskQueueFactory(), std::move(capturer),
40 std::move(renderer), 1.f);
Sebastian Jansson800e1212018-10-22 11:49:03 +020041 setup.apm = AudioProcessingBuilder().Create();
42 setup.fake_audio_device->Init();
43 AudioState::Config audio_state_config;
44 audio_state_config.audio_mixer = AudioMixerImpl::Create();
45 audio_state_config.audio_processing = setup.apm;
46 audio_state_config.audio_device_module = setup.fake_audio_device;
47 setup.audio_state = AudioState::Create(audio_state_config);
48 setup.fake_audio_device->RegisterAudioCallback(
49 setup.audio_state->audio_transport());
50 return setup;
51}
52
Sebastian Jansson105a10a2019-04-01 09:18:14 +020053Call* CreateCall(TimeController* time_controller,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020054 RtcEventLog* event_log,
Sebastian Jansson105a10a2019-04-01 09:18:14 +020055 CallClientConfig config,
56 LoggingNetworkControllerFactory* network_controller_factory,
Sebastian Jansson800e1212018-10-22 11:49:03 +020057 rtc::scoped_refptr<AudioState> audio_state) {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020058 CallConfig call_config(event_log);
Sebastian Jansson800e1212018-10-22 11:49:03 +020059 call_config.bitrate_config.max_bitrate_bps =
60 config.transport.rates.max_rate.bps_or(-1);
61 call_config.bitrate_config.min_bitrate_bps =
62 config.transport.rates.min_rate.bps();
63 call_config.bitrate_config.start_bitrate_bps =
64 config.transport.rates.start_rate.bps();
Danil Chapovalov359fe332019-04-01 10:46:36 +020065 call_config.task_queue_factory = time_controller->GetTaskQueueFactory();
Sebastian Jansson105a10a2019-04-01 09:18:14 +020066 call_config.network_controller_factory = network_controller_factory;
Sebastian Jansson800e1212018-10-22 11:49:03 +020067 call_config.audio_state = audio_state;
Sebastian Jansson105a10a2019-04-01 09:18:14 +020068 return Call::Create(call_config, time_controller->GetClock(),
69 time_controller->CreateProcessThread("CallModules"),
Danil Chapovalov359fe332019-04-01 10:46:36 +020070 time_controller->CreateProcessThread("Pacer"));
Sebastian Jansson800e1212018-10-22 11:49:03 +020071}
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020072
73std::unique_ptr<RtcEventLog> CreateEventLog(
74 TaskQueueFactory* task_queue_factory,
75 LogWriterFactoryInterface* log_writer_factory) {
76 if (!log_writer_factory) {
77 return RtcEventLog::CreateNull();
78 }
79 auto event_log = RtcEventLog::Create(RtcEventLog::EncodingType::NewFormat,
80 task_queue_factory);
81 bool success = event_log->StartLogging(log_writer_factory->Create(".rtc.dat"),
82 kEventLogOutputIntervalMs);
83 RTC_CHECK(success);
84 return event_log;
85}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020086}
87
88LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010089 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020090 TransportControllerConfig config) {
91 if (config.cc_factory) {
92 cc_factory_ = config.cc_factory;
93 if (log_writer_factory)
94 RTC_LOG(LS_WARNING)
95 << "Can't log controller state for injected network controllers";
Sebastian Jansson98b07e92018-09-27 13:47:01 +020096 } else {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020097 if (log_writer_factory) {
Sebastian Jansson871ac422019-05-17 17:53:44 +020098 goog_cc_factory_.AttachWriter(
99 log_writer_factory->Create(".cc_state.txt"));
100 print_cc_state_ = true;
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200101 }
Sebastian Jansson871ac422019-05-17 17:53:44 +0200102 cc_factory_ = &goog_cc_factory_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200103 }
104}
105
106LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200107}
108
109void LoggingNetworkControllerFactory::LogCongestionControllerStats(
110 Timestamp at_time) {
Sebastian Jansson871ac422019-05-17 17:53:44 +0200111 if (print_cc_state_)
112 goog_cc_factory_.PrintState(at_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200113}
114
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200115std::unique_ptr<NetworkControllerInterface>
116LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
117 return cc_factory_->Create(config);
118}
119
120TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
121 return cc_factory_->GetProcessInterval();
122}
123
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100124CallClient::CallClient(
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200125 TimeController* time_controller,
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100126 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
127 CallClientConfig config)
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200128 : time_controller_(time_controller),
129 clock_(time_controller->GetClock()),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100130 log_writer_factory_(std::move(log_writer_factory)),
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200131 network_controller_factory_(log_writer_factory_.get(), config.transport),
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200132 header_parser_(RtpHeaderParser::Create()),
133 task_queue_(time_controller->GetTaskQueueFactory()->CreateTaskQueue(
134 "CallClient",
135 TaskQueueFactory::Priority::NORMAL)) {
136 SendTask([this, config] {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200137 event_log_ = CreateEventLog(time_controller_->GetTaskQueueFactory(),
138 log_writer_factory_.get());
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200139 fake_audio_setup_ = InitAudio(time_controller_);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200140 call_.reset(CreateCall(time_controller_, event_log_.get(), config,
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200141 &network_controller_factory_,
142 fake_audio_setup_.audio_state));
143 transport_ = absl::make_unique<NetworkNodeTransport>(clock_, call_.get());
144 });
145}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200146
Sebastian Jansson800e1212018-10-22 11:49:03 +0200147CallClient::~CallClient() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200148 SendTask([&] {
149 call_.reset();
150 fake_audio_setup_ = {};
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200151 event_log_.reset();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200152 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200153}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200154
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200155ColumnPrinter CallClient::StatsPrinter() {
156 return ColumnPrinter::Lambda(
157 "pacer_delay call_send_bw",
158 [this](rtc::SimpleStringBuilder& sb) {
159 Call::Stats call_stats = call_->GetStats();
160 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
161 call_stats.send_bandwidth_bps / 8.0);
162 },
163 64);
164}
165
166Call::Stats CallClient::GetStats() {
167 return call_->GetStats();
168}
169
Artem Titov40f51152019-01-04 15:45:01 +0100170void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200171 // Removes added overhead before delivering packet to sender.
Artem Titov4cd433e2019-04-01 11:01:16 +0200172 size_t size =
173 packet.data.size() - route_overhead_.at(packet.to.ipaddr()).bytes();
174 RTC_DCHECK_GE(size, 0);
175 packet.data.SetSize(size);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200176
177 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100178 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson1e427612019-03-05 14:25:03 +0100179 auto ssrc = RtpHeaderParser::GetSsrc(packet.cdata(), packet.data.size());
180 RTC_CHECK(ssrc.has_value());
181 media_type = ssrc_media_types_[*ssrc];
Sebastian Jansson800e1212018-10-22 11:49:03 +0200182 }
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200183 struct Closure {
184 void operator()() {
185 call->Receiver()->DeliverPacket(media_type, packet.data,
186 packet.arrival_time.us());
187 }
188 Call* call;
189 MediaType media_type;
190 EmulatedIpPacket packet;
191 };
192 task_queue_.PostTask(Closure{call_.get(), media_type, std::move(packet)});
Sebastian Jansson800e1212018-10-22 11:49:03 +0200193}
194
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100195std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
196 if (!log_writer_factory_ || name.empty())
197 return nullptr;
198 return log_writer_factory_->Create(name);
199}
200
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200201uint32_t CallClient::GetNextVideoSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100202 RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
203 return kVideoSendSsrcs[next_video_ssrc_index_++];
204}
205
206uint32_t CallClient::GetNextVideoLocalSsrc() {
207 RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
208 return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200209}
210
211uint32_t CallClient::GetNextAudioSsrc() {
212 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
213 next_audio_ssrc_index_++;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100214 return kAudioSendSsrc;
215}
216
217uint32_t CallClient::GetNextAudioLocalSsrc() {
218 RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
219 next_audio_local_ssrc_index_++;
220 return kReceiverLocalAudioSsrc;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200221}
222
223uint32_t CallClient::GetNextRtxSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100224 RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
225 return kSendRtxSsrcs[next_rtx_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200226}
227
228std::string CallClient::GetNextPriorityId() {
229 RTC_CHECK_LT(next_priority_index_++, 1);
230 return kPriorityStreamId;
231}
232
Sebastian Janssonfd201712018-11-12 16:44:16 +0100233void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
234 for (const auto& extension : extensions)
235 header_parser_->RegisterRtpHeaderExtension(extension);
236}
237
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200238void CallClient::SendTask(std::function<void()> task) {
239 time_controller_->InvokeWithControlledYield(
240 [&] { task_queue_.SendTask(std::move(task)); });
241}
242
Sebastian Jansson800e1212018-10-22 11:49:03 +0200243CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200244
245} // namespace test
246} // namespace webrtc