blob: a4607bc5868f2f27c22cc00ef3d109bfd46f9edc [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"
Danil Chapovalovb32f2c72019-05-22 13:39:25 +020015#include "api/rtc_event_log/rtc_event_log.h"
16#include "api/rtc_event_log/rtc_event_log_factory.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020017#include "modules/audio_mixer/audio_mixer_impl.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020018
19namespace webrtc {
20namespace test {
21namespace {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010022static constexpr size_t kNumSsrcs = 6;
23const uint32_t kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE, 0xBADCAFF,
24 0xBADCB00, 0xBADCB01, 0xBADCB02};
25const uint32_t kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE, 0xC0FFEF,
26 0xC0FFF0, 0xC0FFF1, 0xC0FFF2};
27const uint32_t kVideoRecvLocalSsrcs[kNumSsrcs] = {0xDAB001, 0xDAB002, 0xDAB003,
28 0xDAB004, 0xDAB005, 0xDAB006};
29const uint32_t kAudioSendSsrc = 0xDEADBEEF;
30const uint32_t kReceiverLocalAudioSsrc = 0x1234567;
31
Sebastian Jansson98b07e92018-09-27 13:47:01 +020032const char* kPriorityStreamId = "priority-track";
Sebastian Jansson800e1212018-10-22 11:49:03 +020033
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020034constexpr int kEventLogOutputIntervalMs = 5000;
35
Sebastian Jansson105a10a2019-04-01 09:18:14 +020036CallClientFakeAudio InitAudio(TimeController* time_controller) {
Sebastian Jansson800e1212018-10-22 11:49:03 +020037 CallClientFakeAudio setup;
38 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
39 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
Sebastian Jansson105a10a2019-04-01 09:18:14 +020040 setup.fake_audio_device = TestAudioDeviceModule::Create(
41 time_controller->GetTaskQueueFactory(), std::move(capturer),
42 std::move(renderer), 1.f);
Sebastian Jansson800e1212018-10-22 11:49:03 +020043 setup.apm = AudioProcessingBuilder().Create();
44 setup.fake_audio_device->Init();
45 AudioState::Config audio_state_config;
46 audio_state_config.audio_mixer = AudioMixerImpl::Create();
47 audio_state_config.audio_processing = setup.apm;
48 audio_state_config.audio_device_module = setup.fake_audio_device;
49 setup.audio_state = AudioState::Create(audio_state_config);
50 setup.fake_audio_device->RegisterAudioCallback(
51 setup.audio_state->audio_transport());
52 return setup;
53}
54
Sebastian Jansson105a10a2019-04-01 09:18:14 +020055Call* CreateCall(TimeController* time_controller,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020056 RtcEventLog* event_log,
Sebastian Jansson105a10a2019-04-01 09:18:14 +020057 CallClientConfig config,
58 LoggingNetworkControllerFactory* network_controller_factory,
Sebastian Jansson800e1212018-10-22 11:49:03 +020059 rtc::scoped_refptr<AudioState> audio_state) {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020060 CallConfig call_config(event_log);
Sebastian Jansson800e1212018-10-22 11:49:03 +020061 call_config.bitrate_config.max_bitrate_bps =
62 config.transport.rates.max_rate.bps_or(-1);
63 call_config.bitrate_config.min_bitrate_bps =
64 config.transport.rates.min_rate.bps();
65 call_config.bitrate_config.start_bitrate_bps =
66 config.transport.rates.start_rate.bps();
Danil Chapovalov359fe332019-04-01 10:46:36 +020067 call_config.task_queue_factory = time_controller->GetTaskQueueFactory();
Sebastian Jansson105a10a2019-04-01 09:18:14 +020068 call_config.network_controller_factory = network_controller_factory;
Sebastian Jansson800e1212018-10-22 11:49:03 +020069 call_config.audio_state = audio_state;
Sebastian Jansson105a10a2019-04-01 09:18:14 +020070 return Call::Create(call_config, time_controller->GetClock(),
71 time_controller->CreateProcessThread("CallModules"),
Danil Chapovalov359fe332019-04-01 10:46:36 +020072 time_controller->CreateProcessThread("Pacer"));
Sebastian Jansson800e1212018-10-22 11:49:03 +020073}
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020074
75std::unique_ptr<RtcEventLog> CreateEventLog(
76 TaskQueueFactory* task_queue_factory,
77 LogWriterFactoryInterface* log_writer_factory) {
78 if (!log_writer_factory) {
Danil Chapovalovb32f2c72019-05-22 13:39:25 +020079 return absl::make_unique<RtcEventLogNull>();
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020080 }
Danil Chapovalovb32f2c72019-05-22 13:39:25 +020081 auto event_log = RtcEventLogFactory(task_queue_factory)
82 .CreateRtcEventLog(RtcEventLog::EncodingType::NewFormat);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020083 bool success = event_log->StartLogging(log_writer_factory->Create(".rtc.dat"),
84 kEventLogOutputIntervalMs);
85 RTC_CHECK(success);
86 return event_log;
87}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020088}
89
90LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010091 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020092 TransportControllerConfig config) {
93 if (config.cc_factory) {
94 cc_factory_ = config.cc_factory;
95 if (log_writer_factory)
96 RTC_LOG(LS_WARNING)
97 << "Can't log controller state for injected network controllers";
Sebastian Jansson98b07e92018-09-27 13:47:01 +020098 } else {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020099 if (log_writer_factory) {
Sebastian Jansson871ac422019-05-17 17:53:44 +0200100 goog_cc_factory_.AttachWriter(
101 log_writer_factory->Create(".cc_state.txt"));
102 print_cc_state_ = true;
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200103 }
Sebastian Jansson871ac422019-05-17 17:53:44 +0200104 cc_factory_ = &goog_cc_factory_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200105 }
106}
107
108LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200109}
110
111void LoggingNetworkControllerFactory::LogCongestionControllerStats(
112 Timestamp at_time) {
Sebastian Jansson871ac422019-05-17 17:53:44 +0200113 if (print_cc_state_)
114 goog_cc_factory_.PrintState(at_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200115}
116
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200117std::unique_ptr<NetworkControllerInterface>
118LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
119 return cc_factory_->Create(config);
120}
121
122TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
123 return cc_factory_->GetProcessInterval();
124}
125
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100126CallClient::CallClient(
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200127 TimeController* time_controller,
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100128 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
129 CallClientConfig config)
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200130 : time_controller_(time_controller),
131 clock_(time_controller->GetClock()),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100132 log_writer_factory_(std::move(log_writer_factory)),
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200133 network_controller_factory_(log_writer_factory_.get(), config.transport),
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200134 header_parser_(RtpHeaderParser::Create()),
135 task_queue_(time_controller->GetTaskQueueFactory()->CreateTaskQueue(
136 "CallClient",
137 TaskQueueFactory::Priority::NORMAL)) {
138 SendTask([this, config] {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200139 event_log_ = CreateEventLog(time_controller_->GetTaskQueueFactory(),
140 log_writer_factory_.get());
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200141 fake_audio_setup_ = InitAudio(time_controller_);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200142 call_.reset(CreateCall(time_controller_, event_log_.get(), config,
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200143 &network_controller_factory_,
144 fake_audio_setup_.audio_state));
145 transport_ = absl::make_unique<NetworkNodeTransport>(clock_, call_.get());
146 });
147}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200148
Sebastian Jansson800e1212018-10-22 11:49:03 +0200149CallClient::~CallClient() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200150 SendTask([&] {
151 call_.reset();
152 fake_audio_setup_ = {};
Sebastian Jansson58c71db2019-05-22 16:20:56 +0200153 rtc::Event done;
154 event_log_->StopLogging([&done] { done.Set(); });
155 done.Wait(rtc::Event::kForever);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200156 event_log_.reset();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200157 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200158}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200159
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200160ColumnPrinter CallClient::StatsPrinter() {
161 return ColumnPrinter::Lambda(
162 "pacer_delay call_send_bw",
163 [this](rtc::SimpleStringBuilder& sb) {
164 Call::Stats call_stats = call_->GetStats();
165 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
166 call_stats.send_bandwidth_bps / 8.0);
167 },
168 64);
169}
170
171Call::Stats CallClient::GetStats() {
172 return call_->GetStats();
173}
174
Artem Titov40f51152019-01-04 15:45:01 +0100175void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200176 // Removes added overhead before delivering packet to sender.
Artem Titov4cd433e2019-04-01 11:01:16 +0200177 size_t size =
178 packet.data.size() - route_overhead_.at(packet.to.ipaddr()).bytes();
179 RTC_DCHECK_GE(size, 0);
180 packet.data.SetSize(size);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200181
182 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100183 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson1e427612019-03-05 14:25:03 +0100184 auto ssrc = RtpHeaderParser::GetSsrc(packet.cdata(), packet.data.size());
185 RTC_CHECK(ssrc.has_value());
186 media_type = ssrc_media_types_[*ssrc];
Sebastian Jansson800e1212018-10-22 11:49:03 +0200187 }
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200188 struct Closure {
189 void operator()() {
190 call->Receiver()->DeliverPacket(media_type, packet.data,
191 packet.arrival_time.us());
192 }
193 Call* call;
194 MediaType media_type;
195 EmulatedIpPacket packet;
196 };
197 task_queue_.PostTask(Closure{call_.get(), media_type, std::move(packet)});
Sebastian Jansson800e1212018-10-22 11:49:03 +0200198}
199
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100200std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
201 if (!log_writer_factory_ || name.empty())
202 return nullptr;
203 return log_writer_factory_->Create(name);
204}
205
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200206uint32_t CallClient::GetNextVideoSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100207 RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
208 return kVideoSendSsrcs[next_video_ssrc_index_++];
209}
210
211uint32_t CallClient::GetNextVideoLocalSsrc() {
212 RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
213 return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200214}
215
216uint32_t CallClient::GetNextAudioSsrc() {
217 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
218 next_audio_ssrc_index_++;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100219 return kAudioSendSsrc;
220}
221
222uint32_t CallClient::GetNextAudioLocalSsrc() {
223 RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
224 next_audio_local_ssrc_index_++;
225 return kReceiverLocalAudioSsrc;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200226}
227
228uint32_t CallClient::GetNextRtxSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100229 RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
230 return kSendRtxSsrcs[next_rtx_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200231}
232
233std::string CallClient::GetNextPriorityId() {
234 RTC_CHECK_LT(next_priority_index_++, 1);
235 return kPriorityStreamId;
236}
237
Sebastian Janssonfd201712018-11-12 16:44:16 +0100238void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
239 for (const auto& extension : extensions)
240 header_parser_->RegisterRtpHeaderExtension(extension);
241}
242
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200243void CallClient::SendTask(std::function<void()> task) {
244 time_controller_->InvokeWithControlledYield(
245 [&] { task_queue_.SendTask(std::move(task)); });
246}
247
Sebastian Jansson800e1212018-10-22 11:49:03 +0200248CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200249
250} // namespace test
251} // namespace webrtc