blob: 7258bd7d33a74b951aaae3c8a8d23d3072867a2f [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#include "modules/congestion_controller/goog_cc/test/goog_cc_printer.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020017
18namespace webrtc {
19namespace test {
20namespace {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010021static constexpr size_t kNumSsrcs = 6;
22const uint32_t kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE, 0xBADCAFF,
23 0xBADCB00, 0xBADCB01, 0xBADCB02};
24const uint32_t kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE, 0xC0FFEF,
25 0xC0FFF0, 0xC0FFF1, 0xC0FFF2};
26const uint32_t kVideoRecvLocalSsrcs[kNumSsrcs] = {0xDAB001, 0xDAB002, 0xDAB003,
27 0xDAB004, 0xDAB005, 0xDAB006};
28const uint32_t kAudioSendSsrc = 0xDEADBEEF;
29const uint32_t kReceiverLocalAudioSsrc = 0x1234567;
30
Sebastian Jansson98b07e92018-09-27 13:47:01 +020031const char* kPriorityStreamId = "priority-track";
Sebastian Jansson800e1212018-10-22 11:49:03 +020032
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020033constexpr int kEventLogOutputIntervalMs = 5000;
34
Sebastian Jansson105a10a2019-04-01 09:18:14 +020035CallClientFakeAudio InitAudio(TimeController* time_controller) {
Sebastian Jansson800e1212018-10-22 11:49:03 +020036 CallClientFakeAudio setup;
37 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
38 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
Sebastian Jansson105a10a2019-04-01 09:18:14 +020039 setup.fake_audio_device = TestAudioDeviceModule::Create(
40 time_controller->GetTaskQueueFactory(), std::move(capturer),
41 std::move(renderer), 1.f);
Sebastian Jansson800e1212018-10-22 11:49:03 +020042 setup.apm = AudioProcessingBuilder().Create();
43 setup.fake_audio_device->Init();
44 AudioState::Config audio_state_config;
45 audio_state_config.audio_mixer = AudioMixerImpl::Create();
46 audio_state_config.audio_processing = setup.apm;
47 audio_state_config.audio_device_module = setup.fake_audio_device;
48 setup.audio_state = AudioState::Create(audio_state_config);
49 setup.fake_audio_device->RegisterAudioCallback(
50 setup.audio_state->audio_transport());
51 return setup;
52}
53
Sebastian Jansson105a10a2019-04-01 09:18:14 +020054Call* CreateCall(TimeController* time_controller,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020055 RtcEventLog* event_log,
Sebastian Jansson105a10a2019-04-01 09:18:14 +020056 CallClientConfig config,
57 LoggingNetworkControllerFactory* network_controller_factory,
Sebastian Jansson800e1212018-10-22 11:49:03 +020058 rtc::scoped_refptr<AudioState> audio_state) {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020059 CallConfig call_config(event_log);
Sebastian Jansson800e1212018-10-22 11:49:03 +020060 call_config.bitrate_config.max_bitrate_bps =
61 config.transport.rates.max_rate.bps_or(-1);
62 call_config.bitrate_config.min_bitrate_bps =
63 config.transport.rates.min_rate.bps();
64 call_config.bitrate_config.start_bitrate_bps =
65 config.transport.rates.start_rate.bps();
Danil Chapovalov359fe332019-04-01 10:46:36 +020066 call_config.task_queue_factory = time_controller->GetTaskQueueFactory();
Sebastian Jansson105a10a2019-04-01 09:18:14 +020067 call_config.network_controller_factory = network_controller_factory;
Sebastian Jansson800e1212018-10-22 11:49:03 +020068 call_config.audio_state = audio_state;
Sebastian Jansson105a10a2019-04-01 09:18:14 +020069 return Call::Create(call_config, time_controller->GetClock(),
70 time_controller->CreateProcessThread("CallModules"),
Danil Chapovalov359fe332019-04-01 10:46:36 +020071 time_controller->CreateProcessThread("Pacer"));
Sebastian Jansson800e1212018-10-22 11:49:03 +020072}
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020073
74std::unique_ptr<RtcEventLog> CreateEventLog(
75 TaskQueueFactory* task_queue_factory,
76 LogWriterFactoryInterface* log_writer_factory) {
77 if (!log_writer_factory) {
78 return RtcEventLog::CreateNull();
79 }
80 auto event_log = RtcEventLog::Create(RtcEventLog::EncodingType::NewFormat,
81 task_queue_factory);
82 bool success = event_log->StartLogging(log_writer_factory->Create(".rtc.dat"),
83 kEventLogOutputIntervalMs);
84 RTC_CHECK(success);
85 return event_log;
86}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020087}
88
89LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010090 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020091 TransportControllerConfig config) {
92 if (config.cc_factory) {
93 cc_factory_ = config.cc_factory;
94 if (log_writer_factory)
95 RTC_LOG(LS_WARNING)
96 << "Can't log controller state for injected network controllers";
Sebastian Jansson98b07e92018-09-27 13:47:01 +020097 } else {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020098 if (log_writer_factory) {
99 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
100 owned_cc_factory_.reset(new GoogCcDebugFactory(goog_printer.get()));
101 cc_factory_ = owned_cc_factory_.get();
102 cc_printer_.reset(
103 new ControlStatePrinter(log_writer_factory->Create(".cc_state.txt"),
104 std::move(goog_printer)));
105 cc_printer_->PrintHeaders();
106 } else {
107 owned_cc_factory_.reset(
108 new GoogCcNetworkControllerFactory(GoogCcFactoryConfig()));
109 cc_factory_ = owned_cc_factory_.get();
110 }
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200111 }
112}
113
114LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200115}
116
117void LoggingNetworkControllerFactory::LogCongestionControllerStats(
118 Timestamp at_time) {
119 if (cc_printer_)
120 cc_printer_->PrintState(at_time);
121}
122
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200123std::unique_ptr<NetworkControllerInterface>
124LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
125 return cc_factory_->Create(config);
126}
127
128TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
129 return cc_factory_->GetProcessInterval();
130}
131
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100132CallClient::CallClient(
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200133 TimeController* time_controller,
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100134 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
135 CallClientConfig config)
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200136 : time_controller_(time_controller),
137 clock_(time_controller->GetClock()),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100138 log_writer_factory_(std::move(log_writer_factory)),
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200139 network_controller_factory_(log_writer_factory_.get(), config.transport),
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200140 header_parser_(RtpHeaderParser::Create()),
141 task_queue_(time_controller->GetTaskQueueFactory()->CreateTaskQueue(
142 "CallClient",
143 TaskQueueFactory::Priority::NORMAL)) {
144 SendTask([this, config] {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200145 event_log_ = CreateEventLog(time_controller_->GetTaskQueueFactory(),
146 log_writer_factory_.get());
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200147 fake_audio_setup_ = InitAudio(time_controller_);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200148 call_.reset(CreateCall(time_controller_, event_log_.get(), config,
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200149 &network_controller_factory_,
150 fake_audio_setup_.audio_state));
151 transport_ = absl::make_unique<NetworkNodeTransport>(clock_, call_.get());
152 });
153}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200154
Sebastian Jansson800e1212018-10-22 11:49:03 +0200155CallClient::~CallClient() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200156 SendTask([&] {
157 call_.reset();
158 fake_audio_setup_ = {};
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200159 event_log_.reset();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200160 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200161}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200162
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200163ColumnPrinter CallClient::StatsPrinter() {
164 return ColumnPrinter::Lambda(
165 "pacer_delay call_send_bw",
166 [this](rtc::SimpleStringBuilder& sb) {
167 Call::Stats call_stats = call_->GetStats();
168 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
169 call_stats.send_bandwidth_bps / 8.0);
170 },
171 64);
172}
173
174Call::Stats CallClient::GetStats() {
175 return call_->GetStats();
176}
177
Artem Titov40f51152019-01-04 15:45:01 +0100178void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200179 // Removes added overhead before delivering packet to sender.
Artem Titov4cd433e2019-04-01 11:01:16 +0200180 size_t size =
181 packet.data.size() - route_overhead_.at(packet.to.ipaddr()).bytes();
182 RTC_DCHECK_GE(size, 0);
183 packet.data.SetSize(size);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200184
185 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100186 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson1e427612019-03-05 14:25:03 +0100187 auto ssrc = RtpHeaderParser::GetSsrc(packet.cdata(), packet.data.size());
188 RTC_CHECK(ssrc.has_value());
189 media_type = ssrc_media_types_[*ssrc];
Sebastian Jansson800e1212018-10-22 11:49:03 +0200190 }
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200191 struct Closure {
192 void operator()() {
193 call->Receiver()->DeliverPacket(media_type, packet.data,
194 packet.arrival_time.us());
195 }
196 Call* call;
197 MediaType media_type;
198 EmulatedIpPacket packet;
199 };
200 task_queue_.PostTask(Closure{call_.get(), media_type, std::move(packet)});
Sebastian Jansson800e1212018-10-22 11:49:03 +0200201}
202
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100203std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
204 if (!log_writer_factory_ || name.empty())
205 return nullptr;
206 return log_writer_factory_->Create(name);
207}
208
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200209uint32_t CallClient::GetNextVideoSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100210 RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
211 return kVideoSendSsrcs[next_video_ssrc_index_++];
212}
213
214uint32_t CallClient::GetNextVideoLocalSsrc() {
215 RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
216 return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200217}
218
219uint32_t CallClient::GetNextAudioSsrc() {
220 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
221 next_audio_ssrc_index_++;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100222 return kAudioSendSsrc;
223}
224
225uint32_t CallClient::GetNextAudioLocalSsrc() {
226 RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
227 next_audio_local_ssrc_index_++;
228 return kReceiverLocalAudioSsrc;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200229}
230
231uint32_t CallClient::GetNextRtxSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100232 RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
233 return kSendRtxSsrcs[next_rtx_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200234}
235
236std::string CallClient::GetNextPriorityId() {
237 RTC_CHECK_LT(next_priority_index_++, 1);
238 return kPriorityStreamId;
239}
240
Sebastian Janssonfd201712018-11-12 16:44:16 +0100241void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
242 for (const auto& extension : extensions)
243 header_parser_->RegisterRtpHeaderExtension(extension);
244}
245
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200246void CallClient::SendTask(std::function<void()> task) {
247 time_controller_->InvokeWithControlledYield(
248 [&] { task_queue_.SendTask(std::move(task)); });
249}
250
Sebastian Jansson800e1212018-10-22 11:49:03 +0200251CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200252
253} // namespace test
254} // namespace webrtc