blob: 7df4e030de677bd40408ed266abf702fe8d3996c [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 Jansson105a10a2019-04-01 09:18:14 +020033CallClientFakeAudio InitAudio(TimeController* time_controller) {
Sebastian Jansson800e1212018-10-22 11:49:03 +020034 CallClientFakeAudio setup;
35 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
36 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
Sebastian Jansson105a10a2019-04-01 09:18:14 +020037 setup.fake_audio_device = TestAudioDeviceModule::Create(
38 time_controller->GetTaskQueueFactory(), std::move(capturer),
39 std::move(renderer), 1.f);
Sebastian Jansson800e1212018-10-22 11:49:03 +020040 setup.apm = AudioProcessingBuilder().Create();
41 setup.fake_audio_device->Init();
42 AudioState::Config audio_state_config;
43 audio_state_config.audio_mixer = AudioMixerImpl::Create();
44 audio_state_config.audio_processing = setup.apm;
45 audio_state_config.audio_device_module = setup.fake_audio_device;
46 setup.audio_state = AudioState::Create(audio_state_config);
47 setup.fake_audio_device->RegisterAudioCallback(
48 setup.audio_state->audio_transport());
49 return setup;
50}
51
Sebastian Jansson105a10a2019-04-01 09:18:14 +020052Call* CreateCall(TimeController* time_controller,
53 CallClientConfig config,
54 LoggingNetworkControllerFactory* network_controller_factory,
Sebastian Jansson800e1212018-10-22 11:49:03 +020055 rtc::scoped_refptr<AudioState> audio_state) {
Sebastian Jansson105a10a2019-04-01 09:18:14 +020056 CallConfig call_config(network_controller_factory->GetEventLog());
Sebastian Jansson800e1212018-10-22 11:49:03 +020057 call_config.bitrate_config.max_bitrate_bps =
58 config.transport.rates.max_rate.bps_or(-1);
59 call_config.bitrate_config.min_bitrate_bps =
60 config.transport.rates.min_rate.bps();
61 call_config.bitrate_config.start_bitrate_bps =
62 config.transport.rates.start_rate.bps();
Sebastian Jansson105a10a2019-04-01 09:18:14 +020063 call_config.network_controller_factory = network_controller_factory;
Sebastian Jansson800e1212018-10-22 11:49:03 +020064 call_config.audio_state = audio_state;
Sebastian Jansson105a10a2019-04-01 09:18:14 +020065 return Call::Create(call_config, time_controller->GetClock(),
66 time_controller->CreateProcessThread("CallModules"),
67 time_controller->CreateProcessThread("Pacer"),
68 time_controller->GetTaskQueueFactory());
Sebastian Jansson800e1212018-10-22 11:49:03 +020069}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020070}
71
72LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson105a10a2019-04-01 09:18:14 +020073 TimeController* time_controller,
Sebastian Jansson52de8b02019-01-16 17:25:44 +010074 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson105a10a2019-04-01 09:18:14 +020075 TransportControllerConfig config)
76 : time_controller_(time_controller) {
Sebastian Jansson52de8b02019-01-16 17:25:44 +010077 std::unique_ptr<RtcEventLogOutput> cc_out;
78 if (!log_writer_factory) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020079 event_log_ = RtcEventLog::CreateNull();
80 } else {
Sebastian Jansson105a10a2019-04-01 09:18:14 +020081 event_log_ = RtcEventLog::Create(RtcEventLog::EncodingType::Legacy,
82 time_controller->GetTaskQueueFactory());
Sebastian Jansson98b07e92018-09-27 13:47:01 +020083 bool success = event_log_->StartLogging(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010084 log_writer_factory->Create(".rtc.dat"), RtcEventLog::kImmediateOutput);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020085 RTC_CHECK(success);
Sebastian Jansson52de8b02019-01-16 17:25:44 +010086 cc_out = log_writer_factory->Create(".cc_state.txt");
Sebastian Janssonf0d03122018-12-18 15:53:04 +010087 }
88 switch (config.cc) {
89 case TransportControllerConfig::CongestionController::kGoogCc:
Sebastian Jansson52de8b02019-01-16 17:25:44 +010090 if (cc_out) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020091 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +010092 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020093 new GoogCcDebugFactory(event_log_.get(), goog_printer.get()));
Sebastian Jansson52de8b02019-01-16 17:25:44 +010094 cc_printer_.reset(new ControlStatePrinter(std::move(cc_out),
95 std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010096 } else {
97 owned_cc_factory_.reset(
98 new GoogCcNetworkControllerFactory(event_log_.get()));
Sebastian Jansson98b07e92018-09-27 13:47:01 +020099 }
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100100 break;
101 case TransportControllerConfig::CongestionController::kGoogCcFeedback:
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100102 if (cc_out) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200103 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100104 owned_cc_factory_.reset(new GoogCcFeedbackDebugFactory(
105 event_log_.get(), goog_printer.get()));
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100106 cc_printer_.reset(new ControlStatePrinter(std::move(cc_out),
107 std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100108 } else {
109 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200110 new GoogCcFeedbackNetworkControllerFactory(event_log_.get()));
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100111 }
112 break;
113 case TransportControllerConfig::CongestionController::kInjected:
114 cc_factory_ = config.cc_factory;
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100115 if (cc_out)
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100116 RTC_LOG(LS_WARNING)
117 << "Can't log controller state for injected network controllers";
118 break;
119 }
120 if (cc_printer_)
121 cc_printer_->PrintHeaders();
122 if (owned_cc_factory_) {
123 RTC_DCHECK(!cc_factory_);
124 cc_factory_ = owned_cc_factory_.get();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200125 }
126}
127
128LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200129 time_controller_->InvokeWithControlledYield([this]() { event_log_.reset(); });
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200130}
131
132void LoggingNetworkControllerFactory::LogCongestionControllerStats(
133 Timestamp at_time) {
134 if (cc_printer_)
135 cc_printer_->PrintState(at_time);
136}
137
138RtcEventLog* LoggingNetworkControllerFactory::GetEventLog() const {
139 return event_log_.get();
140}
141
142std::unique_ptr<NetworkControllerInterface>
143LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
144 return cc_factory_->Create(config);
145}
146
147TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
148 return cc_factory_->GetProcessInterval();
149}
150
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100151CallClient::CallClient(
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200152 TimeController* time_controller,
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100153 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
154 CallClientConfig config)
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200155 : time_controller_(time_controller),
156 clock_(time_controller->GetClock()),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100157 log_writer_factory_(std::move(log_writer_factory)),
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200158 network_controller_factory_(time_controller,
159 log_writer_factory_.get(),
160 config.transport),
161 header_parser_(RtpHeaderParser::Create()),
162 task_queue_(time_controller->GetTaskQueueFactory()->CreateTaskQueue(
163 "CallClient",
164 TaskQueueFactory::Priority::NORMAL)) {
165 SendTask([this, config] {
166 fake_audio_setup_ = InitAudio(time_controller_);
167 call_.reset(CreateCall(time_controller_, config,
168 &network_controller_factory_,
169 fake_audio_setup_.audio_state));
170 transport_ = absl::make_unique<NetworkNodeTransport>(clock_, call_.get());
171 });
172}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200173
Sebastian Jansson800e1212018-10-22 11:49:03 +0200174CallClient::~CallClient() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200175 SendTask([&] {
176 call_.reset();
177 fake_audio_setup_ = {};
178 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200179}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200180
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200181ColumnPrinter CallClient::StatsPrinter() {
182 return ColumnPrinter::Lambda(
183 "pacer_delay call_send_bw",
184 [this](rtc::SimpleStringBuilder& sb) {
185 Call::Stats call_stats = call_->GetStats();
186 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
187 call_stats.send_bandwidth_bps / 8.0);
188 },
189 64);
190}
191
192Call::Stats CallClient::GetStats() {
193 return call_->GetStats();
194}
195
Artem Titov40f51152019-01-04 15:45:01 +0100196void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200197 // Removes added overhead before delivering packet to sender.
Artem Titov40f51152019-01-04 15:45:01 +0100198 RTC_DCHECK_GE(packet.data.size(),
199 route_overhead_.at(packet.dest_endpoint_id).bytes());
200 packet.data.SetSize(packet.data.size() -
201 route_overhead_.at(packet.dest_endpoint_id).bytes());
Sebastian Jansson800e1212018-10-22 11:49:03 +0200202
203 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100204 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson1e427612019-03-05 14:25:03 +0100205 auto ssrc = RtpHeaderParser::GetSsrc(packet.cdata(), packet.data.size());
206 RTC_CHECK(ssrc.has_value());
207 media_type = ssrc_media_types_[*ssrc];
Sebastian Jansson800e1212018-10-22 11:49:03 +0200208 }
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200209 struct Closure {
210 void operator()() {
211 call->Receiver()->DeliverPacket(media_type, packet.data,
212 packet.arrival_time.us());
213 }
214 Call* call;
215 MediaType media_type;
216 EmulatedIpPacket packet;
217 };
218 task_queue_.PostTask(Closure{call_.get(), media_type, std::move(packet)});
Sebastian Jansson800e1212018-10-22 11:49:03 +0200219}
220
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100221std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
222 if (!log_writer_factory_ || name.empty())
223 return nullptr;
224 return log_writer_factory_->Create(name);
225}
226
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200227uint32_t CallClient::GetNextVideoSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100228 RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
229 return kVideoSendSsrcs[next_video_ssrc_index_++];
230}
231
232uint32_t CallClient::GetNextVideoLocalSsrc() {
233 RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
234 return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200235}
236
237uint32_t CallClient::GetNextAudioSsrc() {
238 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
239 next_audio_ssrc_index_++;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100240 return kAudioSendSsrc;
241}
242
243uint32_t CallClient::GetNextAudioLocalSsrc() {
244 RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
245 next_audio_local_ssrc_index_++;
246 return kReceiverLocalAudioSsrc;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200247}
248
249uint32_t CallClient::GetNextRtxSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100250 RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
251 return kSendRtxSsrcs[next_rtx_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200252}
253
254std::string CallClient::GetNextPriorityId() {
255 RTC_CHECK_LT(next_priority_index_++, 1);
256 return kPriorityStreamId;
257}
258
Sebastian Janssonfd201712018-11-12 16:44:16 +0100259void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
260 for (const auto& extension : extensions)
261 header_parser_->RegisterRtpHeaderExtension(extension);
262}
263
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200264void CallClient::SendTask(std::function<void()> task) {
265 time_controller_->InvokeWithControlledYield(
266 [&] { task_queue_.SendTask(std::move(task)); });
267}
268
Sebastian Jansson800e1212018-10-22 11:49:03 +0200269CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200270
271} // namespace test
272} // namespace webrtc