blob: 3c306675a3c1ead3c19a20ce9082c43d51b83064 [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
Christoffer Rodbro8649e492020-12-15 20:20:54 +010012#include <iostream>
13#include <memory>
Sebastian Jansson98b07e92018-09-27 13:47:01 +020014#include <utility>
15
Danil Chapovalovb32f2c72019-05-22 13:39:25 +020016#include "api/rtc_event_log/rtc_event_log.h"
17#include "api/rtc_event_log/rtc_event_log_factory.h"
Christoffer Rodbro8649e492020-12-15 20:20:54 +010018#include "api/transport/network_types.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020019#include "modules/audio_mixer/audio_mixer_impl.h"
Danil Chapovalov00ca0042021-07-05 19:06:17 +020020#include "modules/rtp_rtcp/source/rtp_util.h"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020021
22namespace webrtc {
23namespace test {
24namespace {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010025static constexpr size_t kNumSsrcs = 6;
26const uint32_t kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE, 0xBADCAFF,
27 0xBADCB00, 0xBADCB01, 0xBADCB02};
28const uint32_t kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE, 0xC0FFEF,
29 0xC0FFF0, 0xC0FFF1, 0xC0FFF2};
30const uint32_t kVideoRecvLocalSsrcs[kNumSsrcs] = {0xDAB001, 0xDAB002, 0xDAB003,
31 0xDAB004, 0xDAB005, 0xDAB006};
32const uint32_t kAudioSendSsrc = 0xDEADBEEF;
33const uint32_t kReceiverLocalAudioSsrc = 0x1234567;
34
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020035constexpr int kEventLogOutputIntervalMs = 5000;
36
Sebastian Jansson105a10a2019-04-01 09:18:14 +020037CallClientFakeAudio InitAudio(TimeController* time_controller) {
Sebastian Jansson800e1212018-10-22 11:49:03 +020038 CallClientFakeAudio setup;
39 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
40 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
Sebastian Jansson105a10a2019-04-01 09:18:14 +020041 setup.fake_audio_device = TestAudioDeviceModule::Create(
42 time_controller->GetTaskQueueFactory(), std::move(capturer),
43 std::move(renderer), 1.f);
Sebastian Jansson800e1212018-10-22 11:49:03 +020044 setup.apm = AudioProcessingBuilder().Create();
45 setup.fake_audio_device->Init();
46 AudioState::Config audio_state_config;
47 audio_state_config.audio_mixer = AudioMixerImpl::Create();
48 audio_state_config.audio_processing = setup.apm;
49 audio_state_config.audio_device_module = setup.fake_audio_device;
50 setup.audio_state = AudioState::Create(audio_state_config);
51 setup.fake_audio_device->RegisterAudioCallback(
52 setup.audio_state->audio_transport());
53 return setup;
54}
55
Sebastian Jansson105a10a2019-04-01 09:18:14 +020056Call* CreateCall(TimeController* time_controller,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020057 RtcEventLog* event_log,
Sebastian Jansson105a10a2019-04-01 09:18:14 +020058 CallClientConfig config,
59 LoggingNetworkControllerFactory* network_controller_factory,
Tommi25c77c12020-05-25 17:44:55 +020060 rtc::scoped_refptr<AudioState> audio_state,
61 rtc::scoped_refptr<SharedModuleThread> call_thread) {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020062 CallConfig call_config(event_log);
Sebastian Jansson800e1212018-10-22 11:49:03 +020063 call_config.bitrate_config.max_bitrate_bps =
64 config.transport.rates.max_rate.bps_or(-1);
65 call_config.bitrate_config.min_bitrate_bps =
66 config.transport.rates.min_rate.bps();
67 call_config.bitrate_config.start_bitrate_bps =
68 config.transport.rates.start_rate.bps();
Danil Chapovalov359fe332019-04-01 10:46:36 +020069 call_config.task_queue_factory = time_controller->GetTaskQueueFactory();
Sebastian Jansson105a10a2019-04-01 09:18:14 +020070 call_config.network_controller_factory = network_controller_factory;
Sebastian Jansson800e1212018-10-22 11:49:03 +020071 call_config.audio_state = audio_state;
Erik Språng014dd3c2019-11-28 13:44:25 +010072 call_config.trials = config.field_trials;
Sebastian Jansson105a10a2019-04-01 09:18:14 +020073 return Call::Create(call_config, time_controller->GetClock(),
Tommi25c77c12020-05-25 17:44:55 +020074 std::move(call_thread),
Danil Chapovalov359fe332019-04-01 10:46:36 +020075 time_controller->CreateProcessThread("Pacer"));
Sebastian Jansson800e1212018-10-22 11:49:03 +020076}
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020077
78std::unique_ptr<RtcEventLog> CreateEventLog(
79 TaskQueueFactory* task_queue_factory,
80 LogWriterFactoryInterface* log_writer_factory) {
81 if (!log_writer_factory) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +020082 return std::make_unique<RtcEventLogNull>();
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020083 }
Danil Chapovalovb32f2c72019-05-22 13:39:25 +020084 auto event_log = RtcEventLogFactory(task_queue_factory)
85 .CreateRtcEventLog(RtcEventLog::EncodingType::NewFormat);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +020086 bool success = event_log->StartLogging(log_writer_factory->Create(".rtc.dat"),
87 kEventLogOutputIntervalMs);
88 RTC_CHECK(success);
89 return event_log;
90}
Jonas Olssona4d87372019-07-05 19:08:33 +020091} // namespace
Sebastian Janssona7d70ab2019-06-11 10:21:32 +020092NetworkControleUpdateCache::NetworkControleUpdateCache(
93 std::unique_ptr<NetworkControllerInterface> controller)
94 : controller_(std::move(controller)) {}
95NetworkControlUpdate NetworkControleUpdateCache::OnNetworkAvailability(
96 NetworkAvailability msg) {
97 return Update(controller_->OnNetworkAvailability(msg));
98}
99NetworkControlUpdate NetworkControleUpdateCache::OnNetworkRouteChange(
100 NetworkRouteChange msg) {
101 return Update(controller_->OnNetworkRouteChange(msg));
102}
103NetworkControlUpdate NetworkControleUpdateCache::OnProcessInterval(
104 ProcessInterval msg) {
105 return Update(controller_->OnProcessInterval(msg));
106}
107NetworkControlUpdate NetworkControleUpdateCache::OnRemoteBitrateReport(
108 RemoteBitrateReport msg) {
109 return Update(controller_->OnRemoteBitrateReport(msg));
110}
111NetworkControlUpdate NetworkControleUpdateCache::OnRoundTripTimeUpdate(
112 RoundTripTimeUpdate msg) {
113 return Update(controller_->OnRoundTripTimeUpdate(msg));
114}
115NetworkControlUpdate NetworkControleUpdateCache::OnSentPacket(SentPacket msg) {
116 return Update(controller_->OnSentPacket(msg));
117}
118NetworkControlUpdate NetworkControleUpdateCache::OnReceivedPacket(
119 ReceivedPacket msg) {
120 return Update(controller_->OnReceivedPacket(msg));
121}
122NetworkControlUpdate NetworkControleUpdateCache::OnStreamsConfig(
123 StreamsConfig msg) {
124 return Update(controller_->OnStreamsConfig(msg));
125}
126NetworkControlUpdate NetworkControleUpdateCache::OnTargetRateConstraints(
127 TargetRateConstraints msg) {
128 return Update(controller_->OnTargetRateConstraints(msg));
129}
130NetworkControlUpdate NetworkControleUpdateCache::OnTransportLossReport(
131 TransportLossReport msg) {
132 return Update(controller_->OnTransportLossReport(msg));
133}
134NetworkControlUpdate NetworkControleUpdateCache::OnTransportPacketsFeedback(
135 TransportPacketsFeedback msg) {
136 return Update(controller_->OnTransportPacketsFeedback(msg));
137}
Sebastian Jansson49167de2019-06-27 15:59:03 +0200138NetworkControlUpdate NetworkControleUpdateCache::OnNetworkStateEstimate(
139 NetworkStateEstimate msg) {
140 return Update(controller_->OnNetworkStateEstimate(msg));
141}
142
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200143NetworkControlUpdate NetworkControleUpdateCache::update_state() const {
144 return update_state_;
145}
146NetworkControlUpdate NetworkControleUpdateCache::Update(
147 NetworkControlUpdate update) {
148 if (update.target_rate)
149 update_state_.target_rate = update.target_rate;
150 if (update.pacer_config)
151 update_state_.pacer_config = update.pacer_config;
152 if (update.congestion_window)
153 update_state_.congestion_window = update.congestion_window;
154 if (!update.probe_cluster_configs.empty())
155 update_state_.probe_cluster_configs = update.probe_cluster_configs;
156 return update;
157}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200158
159LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100160 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200161 TransportControllerConfig config) {
162 if (config.cc_factory) {
163 cc_factory_ = config.cc_factory;
164 if (log_writer_factory)
165 RTC_LOG(LS_WARNING)
166 << "Can't log controller state for injected network controllers";
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200167 } else {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200168 if (log_writer_factory) {
Sebastian Jansson871ac422019-05-17 17:53:44 +0200169 goog_cc_factory_.AttachWriter(
170 log_writer_factory->Create(".cc_state.txt"));
171 print_cc_state_ = true;
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200172 }
Sebastian Jansson871ac422019-05-17 17:53:44 +0200173 cc_factory_ = &goog_cc_factory_;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200174 }
175}
176
Jonas Olssona4d87372019-07-05 19:08:33 +0200177LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200178
179void LoggingNetworkControllerFactory::LogCongestionControllerStats(
180 Timestamp at_time) {
Sebastian Jansson871ac422019-05-17 17:53:44 +0200181 if (print_cc_state_)
182 goog_cc_factory_.PrintState(at_time);
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200183}
184
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200185NetworkControlUpdate LoggingNetworkControllerFactory::GetUpdate() const {
186 if (last_controller_)
187 return last_controller_->update_state();
188 return NetworkControlUpdate();
189}
190
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200191std::unique_ptr<NetworkControllerInterface>
192LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200193 auto controller =
194 std::make_unique<NetworkControleUpdateCache>(cc_factory_->Create(config));
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200195 last_controller_ = controller.get();
196 return controller;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200197}
198
199TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
200 return cc_factory_->GetProcessInterval();
201}
202
Christoffer Rodbro8649e492020-12-15 20:20:54 +0100203void LoggingNetworkControllerFactory::SetRemoteBitrateEstimate(
204 RemoteBitrateReport msg) {
205 if (last_controller_)
206 last_controller_->OnRemoteBitrateReport(msg);
207}
208
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100209CallClient::CallClient(
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200210 TimeController* time_controller,
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100211 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
212 CallClientConfig config)
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200213 : time_controller_(time_controller),
214 clock_(time_controller->GetClock()),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100215 log_writer_factory_(std::move(log_writer_factory)),
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200216 network_controller_factory_(log_writer_factory_.get(), config.transport),
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200217 task_queue_(time_controller->GetTaskQueueFactory()->CreateTaskQueue(
218 "CallClient",
219 TaskQueueFactory::Priority::NORMAL)) {
Erik Språng014dd3c2019-11-28 13:44:25 +0100220 config.field_trials = &field_trials_;
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200221 SendTask([this, config] {
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200222 event_log_ = CreateEventLog(time_controller_->GetTaskQueueFactory(),
223 log_writer_factory_.get());
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200224 fake_audio_setup_ = InitAudio(time_controller_);
Tommi25c77c12020-05-25 17:44:55 +0200225 RTC_DCHECK(!module_thread_);
226 module_thread_ = SharedModuleThread::Create(
227 time_controller_->CreateProcessThread("CallThread"),
228 [this]() { module_thread_ = nullptr; });
229
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200230 call_.reset(CreateCall(time_controller_, event_log_.get(), config,
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200231 &network_controller_factory_,
Tommi25c77c12020-05-25 17:44:55 +0200232 fake_audio_setup_.audio_state, module_thread_));
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200233 transport_ = std::make_unique<NetworkNodeTransport>(clock_, call_.get());
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200234 });
235}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200236
Sebastian Jansson800e1212018-10-22 11:49:03 +0200237CallClient::~CallClient() {
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200238 SendTask([&] {
239 call_.reset();
Tommi25c77c12020-05-25 17:44:55 +0200240 RTC_DCHECK(!module_thread_); // Should be set to null in the lambda above.
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200241 fake_audio_setup_ = {};
Sebastian Jansson58c71db2019-05-22 16:20:56 +0200242 rtc::Event done;
243 event_log_->StopLogging([&done] { done.Set(); });
244 done.Wait(rtc::Event::kForever);
Sebastian Jansson7ccaf892019-04-24 15:13:26 +0200245 event_log_.reset();
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200246 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200247}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200248
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200249ColumnPrinter CallClient::StatsPrinter() {
250 return ColumnPrinter::Lambda(
251 "pacer_delay call_send_bw",
252 [this](rtc::SimpleStringBuilder& sb) {
253 Call::Stats call_stats = call_->GetStats();
254 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
255 call_stats.send_bandwidth_bps / 8.0);
256 },
257 64);
258}
259
260Call::Stats CallClient::GetStats() {
Artem Titov1ee563d2021-07-27 12:46:29 +0200261 // This call needs to be made on the thread that `call_` was constructed on.
Tommie6b7b662019-08-06 12:44:35 +0200262 Call::Stats stats;
263 SendTask([this, &stats] { stats = call_->GetStats(); });
264 return stats;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200265}
266
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200267DataRate CallClient::target_rate() const {
268 return network_controller_factory_.GetUpdate().target_rate->target_rate;
269}
270
Florent Castelli4e615d52019-08-22 16:09:06 +0200271DataRate CallClient::stable_target_rate() const {
272 return network_controller_factory_.GetUpdate()
273 .target_rate->stable_target_rate;
274}
275
Sebastian Janssona7d70ab2019-06-11 10:21:32 +0200276DataRate CallClient::padding_rate() const {
277 return network_controller_factory_.GetUpdate().pacer_config->pad_rate();
278}
279
Christoffer Rodbro8649e492020-12-15 20:20:54 +0100280void CallClient::SetRemoteBitrate(DataRate bitrate) {
281 RemoteBitrateReport msg;
282 msg.bandwidth = bitrate;
283 msg.receive_time = clock_->CurrentTime();
284 network_controller_factory_.SetRemoteBitrateEstimate(msg);
285}
286
Erik Språng3e3e1662020-10-06 21:51:21 +0200287void CallClient::UpdateBitrateConstraints(
288 const BitrateConstraints& constraints) {
289 SendTask([this, &constraints]() {
290 call_->GetTransportControllerSend()->SetSdpBitrateParameters(constraints);
291 });
292}
293
Artem Titov40f51152019-01-04 15:45:01 +0100294void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200295 MediaType media_type = MediaType::ANY;
Danil Chapovalov00ca0042021-07-05 19:06:17 +0200296 if (IsRtpPacket(packet.data)) {
Danil Chapovalov623146c2021-07-19 15:43:18 +0000297 media_type = ssrc_media_types_[ParseRtpSsrc(packet.data)];
Sebastian Jansson800e1212018-10-22 11:49:03 +0200298 }
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +0200299 task_queue_.PostTask(
300 [call = call_.get(), media_type, packet = std::move(packet)]() mutable {
301 call->Receiver()->DeliverPacket(media_type, packet.data,
302 packet.arrival_time.us());
303 });
Sebastian Jansson800e1212018-10-22 11:49:03 +0200304}
305
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100306std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
307 if (!log_writer_factory_ || name.empty())
308 return nullptr;
309 return log_writer_factory_->Create(name);
310}
311
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200312uint32_t CallClient::GetNextVideoSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100313 RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
314 return kVideoSendSsrcs[next_video_ssrc_index_++];
315}
316
317uint32_t CallClient::GetNextVideoLocalSsrc() {
318 RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
319 return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200320}
321
322uint32_t CallClient::GetNextAudioSsrc() {
323 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
324 next_audio_ssrc_index_++;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100325 return kAudioSendSsrc;
326}
327
328uint32_t CallClient::GetNextAudioLocalSsrc() {
329 RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
330 next_audio_local_ssrc_index_++;
331 return kReceiverLocalAudioSsrc;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200332}
333
334uint32_t CallClient::GetNextRtxSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100335 RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
336 return kSendRtxSsrcs[next_rtx_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200337}
338
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200339void CallClient::SendTask(std::function<void()> task) {
Sebastian Jansson340af972019-12-04 10:07:48 +0100340 task_queue_.SendTask(std::move(task), RTC_FROM_HERE);
Sebastian Jansson105a10a2019-04-01 09:18:14 +0200341}
342
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100343int16_t CallClient::Bind(EmulatedEndpoint* endpoint) {
344 uint16_t port = endpoint->BindReceiver(0, this).value();
345 endpoints_.push_back({endpoint, port});
346 return port;
347}
348
349void CallClient::UnBind() {
350 for (auto ep_port : endpoints_)
351 ep_port.first->UnbindReceiver(ep_port.second);
352}
353
Sebastian Jansson800e1212018-10-22 11:49:03 +0200354CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200355
356} // namespace test
357} // namespace webrtc