blob: cb29ff6d4541471e581858bafd950831a5014878 [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
Mirko Bonadei317a1f02019-09-17 17:06:18 +020014#include <memory>
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 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) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020077 return std::make_unique<RtcEventLogNull>();
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020078 }
Danil Chapovalovb32f2c72019-05-22 13:39:25 +020079 auto event_log = RtcEventLogFactory(task_queue_factory)
80 .CreateRtcEventLog(RtcEventLog::EncodingType::NewFormat);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020081 bool success = event_log->StartLogging(log_writer_factory->Create(".rtc.dat"),
82 kEventLogOutputIntervalMs);
83 RTC_CHECK(success);
84 return event_log;
85}
Jonas Olssona4d87372019-07-05 19:08:33 +020086} // namespace
Sebastian Janssona7d70ab2019-06-11 10:21:32 +020087NetworkControleUpdateCache::NetworkControleUpdateCache(
88 std::unique_ptr<NetworkControllerInterface> controller)
89 : controller_(std::move(controller)) {}
90NetworkControlUpdate NetworkControleUpdateCache::OnNetworkAvailability(
91 NetworkAvailability msg) {
92 return Update(controller_->OnNetworkAvailability(msg));
93}
94NetworkControlUpdate NetworkControleUpdateCache::OnNetworkRouteChange(
95 NetworkRouteChange msg) {
96 return Update(controller_->OnNetworkRouteChange(msg));
97}
98NetworkControlUpdate NetworkControleUpdateCache::OnProcessInterval(
99 ProcessInterval msg) {
100 return Update(controller_->OnProcessInterval(msg));
101}
102NetworkControlUpdate NetworkControleUpdateCache::OnRemoteBitrateReport(
103 RemoteBitrateReport msg) {
104 return Update(controller_->OnRemoteBitrateReport(msg));
105}
106NetworkControlUpdate NetworkControleUpdateCache::OnRoundTripTimeUpdate(
107 RoundTripTimeUpdate msg) {
108 return Update(controller_->OnRoundTripTimeUpdate(msg));
109}
110NetworkControlUpdate NetworkControleUpdateCache::OnSentPacket(SentPacket msg) {
111 return Update(controller_->OnSentPacket(msg));
112}
113NetworkControlUpdate NetworkControleUpdateCache::OnReceivedPacket(
114 ReceivedPacket msg) {
115 return Update(controller_->OnReceivedPacket(msg));
116}
117NetworkControlUpdate NetworkControleUpdateCache::OnStreamsConfig(
118 StreamsConfig msg) {
119 return Update(controller_->OnStreamsConfig(msg));
120}
121NetworkControlUpdate NetworkControleUpdateCache::OnTargetRateConstraints(
122 TargetRateConstraints msg) {
123 return Update(controller_->OnTargetRateConstraints(msg));
124}
125NetworkControlUpdate NetworkControleUpdateCache::OnTransportLossReport(
126 TransportLossReport msg) {
127 return Update(controller_->OnTransportLossReport(msg));
128}
129NetworkControlUpdate NetworkControleUpdateCache::OnTransportPacketsFeedback(
130 TransportPacketsFeedback msg) {
131 return Update(controller_->OnTransportPacketsFeedback(msg));
132}
Sebastian Jansson49167de2019-06-27 15:59:03 +0200133NetworkControlUpdate NetworkControleUpdateCache::OnNetworkStateEstimate(
134 NetworkStateEstimate msg) {
135 return Update(controller_->OnNetworkStateEstimate(msg));
136}
137
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200138NetworkControlUpdate NetworkControleUpdateCache::update_state() const {
139 return update_state_;
140}
141NetworkControlUpdate NetworkControleUpdateCache::Update(
142 NetworkControlUpdate update) {
143 if (update.target_rate)
144 update_state_.target_rate = update.target_rate;
145 if (update.pacer_config)
146 update_state_.pacer_config = update.pacer_config;
147 if (update.congestion_window)
148 update_state_.congestion_window = update.congestion_window;
149 if (!update.probe_cluster_configs.empty())
150 update_state_.probe_cluster_configs = update.probe_cluster_configs;
151 return update;
152}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200153
154LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100155 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200156 TransportControllerConfig config) {
157 if (config.cc_factory) {
158 cc_factory_ = config.cc_factory;
159 if (log_writer_factory)
160 RTC_LOG(LS_WARNING)
161 << "Can't log controller state for injected network controllers";
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200162 } else {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200163 if (log_writer_factory) {
Sebastian Jansson871ac422019-05-17 17:53:44 +0200164 goog_cc_factory_.AttachWriter(
165 log_writer_factory->Create(".cc_state.txt"));
166 print_cc_state_ = true;
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200167 }
Sebastian Jansson871ac422019-05-17 17:53:44 +0200168 cc_factory_ = &goog_cc_factory_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200169 }
170}
171
Jonas Olssona4d87372019-07-05 19:08:33 +0200172LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200173
174void LoggingNetworkControllerFactory::LogCongestionControllerStats(
175 Timestamp at_time) {
Sebastian Jansson871ac422019-05-17 17:53:44 +0200176 if (print_cc_state_)
177 goog_cc_factory_.PrintState(at_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200178}
179
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200180NetworkControlUpdate LoggingNetworkControllerFactory::GetUpdate() const {
181 if (last_controller_)
182 return last_controller_->update_state();
183 return NetworkControlUpdate();
184}
185
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200186std::unique_ptr<NetworkControllerInterface>
187LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200188 auto controller =
189 std::make_unique<NetworkControleUpdateCache>(cc_factory_->Create(config));
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200190 last_controller_ = controller.get();
191 return controller;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200192}
193
194TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
195 return cc_factory_->GetProcessInterval();
196}
197
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100198CallClient::CallClient(
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200199 TimeController* time_controller,
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100200 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
201 CallClientConfig config)
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200202 : time_controller_(time_controller),
203 clock_(time_controller->GetClock()),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100204 log_writer_factory_(std::move(log_writer_factory)),
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200205 network_controller_factory_(log_writer_factory_.get(), config.transport),
Tommi25eb47c2019-08-29 16:39:05 +0200206 header_parser_(RtpHeaderParser::CreateForTest()),
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200207 task_queue_(time_controller->GetTaskQueueFactory()->CreateTaskQueue(
208 "CallClient",
209 TaskQueueFactory::Priority::NORMAL)) {
210 SendTask([this, config] {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200211 event_log_ = CreateEventLog(time_controller_->GetTaskQueueFactory(),
212 log_writer_factory_.get());
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200213 fake_audio_setup_ = InitAudio(time_controller_);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200214 call_.reset(CreateCall(time_controller_, event_log_.get(), config,
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200215 &network_controller_factory_,
216 fake_audio_setup_.audio_state));
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200217 transport_ = std::make_unique<NetworkNodeTransport>(clock_, call_.get());
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200218 });
219}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200220
Sebastian Jansson800e1212018-10-22 11:49:03 +0200221CallClient::~CallClient() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200222 SendTask([&] {
223 call_.reset();
224 fake_audio_setup_ = {};
Sebastian Jansson58c71db2019-05-22 16:20:56 +0200225 rtc::Event done;
226 event_log_->StopLogging([&done] { done.Set(); });
227 done.Wait(rtc::Event::kForever);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200228 event_log_.reset();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200229 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200230}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200231
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200232ColumnPrinter CallClient::StatsPrinter() {
233 return ColumnPrinter::Lambda(
234 "pacer_delay call_send_bw",
235 [this](rtc::SimpleStringBuilder& sb) {
236 Call::Stats call_stats = call_->GetStats();
237 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
238 call_stats.send_bandwidth_bps / 8.0);
239 },
240 64);
241}
242
243Call::Stats CallClient::GetStats() {
Tommie6b7b662019-08-06 12:44:35 +0200244 // This call needs to be made on the thread that |call_| was constructed on.
245 Call::Stats stats;
246 SendTask([this, &stats] { stats = call_->GetStats(); });
247 return stats;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200248}
249
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200250DataRate CallClient::target_rate() const {
251 return network_controller_factory_.GetUpdate().target_rate->target_rate;
252}
253
Florent Castelli4e615d52019-08-22 16:09:06 +0200254DataRate CallClient::stable_target_rate() const {
255 return network_controller_factory_.GetUpdate()
256 .target_rate->stable_target_rate;
257}
258
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200259DataRate CallClient::padding_rate() const {
260 return network_controller_factory_.GetUpdate().pacer_config->pad_rate();
261}
262
Artem Titov40f51152019-01-04 15:45:01 +0100263void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200264 // Removes added overhead before delivering packet to sender.
Artem Titov4cd433e2019-04-01 11:01:16 +0200265 size_t size =
266 packet.data.size() - route_overhead_.at(packet.to.ipaddr()).bytes();
267 RTC_DCHECK_GE(size, 0);
268 packet.data.SetSize(size);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200269
270 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100271 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson1e427612019-03-05 14:25:03 +0100272 auto ssrc = RtpHeaderParser::GetSsrc(packet.cdata(), packet.data.size());
273 RTC_CHECK(ssrc.has_value());
274 media_type = ssrc_media_types_[*ssrc];
Sebastian Jansson800e1212018-10-22 11:49:03 +0200275 }
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +0200276 task_queue_.PostTask(
277 [call = call_.get(), media_type, packet = std::move(packet)]() mutable {
278 call->Receiver()->DeliverPacket(media_type, packet.data,
279 packet.arrival_time.us());
280 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200281}
282
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100283std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
284 if (!log_writer_factory_ || name.empty())
285 return nullptr;
286 return log_writer_factory_->Create(name);
287}
288
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200289uint32_t CallClient::GetNextVideoSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100290 RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
291 return kVideoSendSsrcs[next_video_ssrc_index_++];
292}
293
294uint32_t CallClient::GetNextVideoLocalSsrc() {
295 RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
296 return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200297}
298
299uint32_t CallClient::GetNextAudioSsrc() {
300 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
301 next_audio_ssrc_index_++;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100302 return kAudioSendSsrc;
303}
304
305uint32_t CallClient::GetNextAudioLocalSsrc() {
306 RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
307 next_audio_local_ssrc_index_++;
308 return kReceiverLocalAudioSsrc;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200309}
310
311uint32_t CallClient::GetNextRtxSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100312 RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
313 return kSendRtxSsrcs[next_rtx_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200314}
315
Sebastian Janssonfd201712018-11-12 16:44:16 +0100316void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
317 for (const auto& extension : extensions)
318 header_parser_->RegisterRtpHeaderExtension(extension);
319}
320
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200321void CallClient::SendTask(std::function<void()> task) {
322 time_controller_->InvokeWithControlledYield(
Danil Chapovaloveb90e6f2019-10-15 10:04:57 +0200323 [&] { task_queue_.SendTask(std::move(task), RTC_FROM_HERE); });
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200324}
325
Sebastian Jansson800e1212018-10-22 11:49:03 +0200326CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200327
328} // namespace test
329} // namespace webrtc