blob: feb50b0ea8fe486df34b47b6b0e97a3d9fe5e2de [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"
17#include "test/call_test.h"
18
19namespace webrtc {
20namespace test {
21namespace {
22const char* kPriorityStreamId = "priority-track";
Sebastian Jansson800e1212018-10-22 11:49:03 +020023
24CallClientFakeAudio InitAudio() {
25 CallClientFakeAudio setup;
26 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
27 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
28 setup.fake_audio_device = TestAudioDeviceModule::CreateTestAudioDeviceModule(
29 std::move(capturer), std::move(renderer), 1.f);
30 setup.apm = AudioProcessingBuilder().Create();
31 setup.fake_audio_device->Init();
32 AudioState::Config audio_state_config;
33 audio_state_config.audio_mixer = AudioMixerImpl::Create();
34 audio_state_config.audio_processing = setup.apm;
35 audio_state_config.audio_device_module = setup.fake_audio_device;
36 setup.audio_state = AudioState::Create(audio_state_config);
37 setup.fake_audio_device->RegisterAudioCallback(
38 setup.audio_state->audio_transport());
39 return setup;
40}
41
42Call* CreateCall(CallClientConfig config,
43 LoggingNetworkControllerFactory* network_controller_factory_,
44 rtc::scoped_refptr<AudioState> audio_state) {
45 CallConfig call_config(network_controller_factory_->GetEventLog());
46 call_config.bitrate_config.max_bitrate_bps =
47 config.transport.rates.max_rate.bps_or(-1);
48 call_config.bitrate_config.min_bitrate_bps =
49 config.transport.rates.min_rate.bps();
50 call_config.bitrate_config.start_bitrate_bps =
51 config.transport.rates.start_rate.bps();
52 call_config.network_controller_factory = network_controller_factory_;
53 call_config.audio_state = audio_state;
54 return Call::Create(call_config);
55}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020056}
57
58LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010059 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020060 TransportControllerConfig config) {
Sebastian Jansson52de8b02019-01-16 17:25:44 +010061 std::unique_ptr<RtcEventLogOutput> cc_out;
62 if (!log_writer_factory) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020063 event_log_ = RtcEventLog::CreateNull();
64 } else {
65 event_log_ = RtcEventLog::Create(RtcEventLog::EncodingType::Legacy);
66 bool success = event_log_->StartLogging(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010067 log_writer_factory->Create(".rtc.dat"), RtcEventLog::kImmediateOutput);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020068 RTC_CHECK(success);
Sebastian Jansson52de8b02019-01-16 17:25:44 +010069 cc_out = log_writer_factory->Create(".cc_state.txt");
Sebastian Janssonf0d03122018-12-18 15:53:04 +010070 }
71 switch (config.cc) {
72 case TransportControllerConfig::CongestionController::kGoogCc:
Sebastian Jansson52de8b02019-01-16 17:25:44 +010073 if (cc_out) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020074 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +010075 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020076 new GoogCcDebugFactory(event_log_.get(), goog_printer.get()));
Sebastian Jansson52de8b02019-01-16 17:25:44 +010077 cc_printer_.reset(new ControlStatePrinter(std::move(cc_out),
78 std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010079 } else {
80 owned_cc_factory_.reset(
81 new GoogCcNetworkControllerFactory(event_log_.get()));
Sebastian Jansson98b07e92018-09-27 13:47:01 +020082 }
Sebastian Janssonf0d03122018-12-18 15:53:04 +010083 break;
84 case TransportControllerConfig::CongestionController::kGoogCcFeedback:
Sebastian Jansson52de8b02019-01-16 17:25:44 +010085 if (cc_out) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020086 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +010087 owned_cc_factory_.reset(new GoogCcFeedbackDebugFactory(
88 event_log_.get(), goog_printer.get()));
Sebastian Jansson52de8b02019-01-16 17:25:44 +010089 cc_printer_.reset(new ControlStatePrinter(std::move(cc_out),
90 std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010091 } else {
92 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020093 new GoogCcFeedbackNetworkControllerFactory(event_log_.get()));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010094 }
95 break;
96 case TransportControllerConfig::CongestionController::kInjected:
97 cc_factory_ = config.cc_factory;
Sebastian Jansson52de8b02019-01-16 17:25:44 +010098 if (cc_out)
Sebastian Janssonf0d03122018-12-18 15:53:04 +010099 RTC_LOG(LS_WARNING)
100 << "Can't log controller state for injected network controllers";
101 break;
102 }
103 if (cc_printer_)
104 cc_printer_->PrintHeaders();
105 if (owned_cc_factory_) {
106 RTC_DCHECK(!cc_factory_);
107 cc_factory_ = owned_cc_factory_.get();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200108 }
109}
110
111LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200112}
113
114void LoggingNetworkControllerFactory::LogCongestionControllerStats(
115 Timestamp at_time) {
116 if (cc_printer_)
117 cc_printer_->PrintState(at_time);
118}
119
120RtcEventLog* LoggingNetworkControllerFactory::GetEventLog() const {
121 return event_log_.get();
122}
123
124std::unique_ptr<NetworkControllerInterface>
125LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
126 return cc_factory_->Create(config);
127}
128
129TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
130 return cc_factory_->GetProcessInterval();
131}
132
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100133CallClient::CallClient(
134 Clock* clock,
135 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
136 CallClientConfig config)
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200137 : clock_(clock),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100138 log_writer_factory_(std::move(log_writer_factory)),
139 network_controller_factory_(log_writer_factory_.get(), config.transport),
Sebastian Jansson800e1212018-10-22 11:49:03 +0200140 fake_audio_setup_(InitAudio()),
141 call_(CreateCall(config,
142 &network_controller_factory_,
143 fake_audio_setup_.audio_state)),
144 transport_(clock_, call_.get()),
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +0100145 header_parser_(RtpHeaderParser::Create()) {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200146
Sebastian Jansson800e1212018-10-22 11:49:03 +0200147CallClient::~CallClient() {
148 delete header_parser_;
149}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200150
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200151ColumnPrinter CallClient::StatsPrinter() {
152 return ColumnPrinter::Lambda(
153 "pacer_delay call_send_bw",
154 [this](rtc::SimpleStringBuilder& sb) {
155 Call::Stats call_stats = call_->GetStats();
156 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
157 call_stats.send_bandwidth_bps / 8.0);
158 },
159 64);
160}
161
162Call::Stats CallClient::GetStats() {
163 return call_->GetStats();
164}
165
Artem Titov40f51152019-01-04 15:45:01 +0100166void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200167 // Removes added overhead before delivering packet to sender.
Artem Titov40f51152019-01-04 15:45:01 +0100168 RTC_DCHECK_GE(packet.data.size(),
169 route_overhead_.at(packet.dest_endpoint_id).bytes());
170 packet.data.SetSize(packet.data.size() -
171 route_overhead_.at(packet.dest_endpoint_id).bytes());
Sebastian Jansson800e1212018-10-22 11:49:03 +0200172
173 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100174 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200175 RTPHeader header;
176 bool success =
Artem Titov40f51152019-01-04 15:45:01 +0100177 header_parser_->Parse(packet.cdata(), packet.data.size(), &header);
Sebastian Janssonf65309c2018-12-20 10:26:00 +0100178 if (!success) {
179 RTC_DLOG(LS_ERROR) << "Failed to parse RTP header of packet";
180 return;
181 }
Sebastian Jansson800e1212018-10-22 11:49:03 +0200182 media_type = ssrc_media_types_[header.ssrc];
183 }
Artem Titov40f51152019-01-04 15:45:01 +0100184 call_->Receiver()->DeliverPacket(media_type, packet.data,
185 packet.arrival_time.us());
Sebastian Jansson800e1212018-10-22 11:49:03 +0200186}
187
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100188std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
189 if (!log_writer_factory_ || name.empty())
190 return nullptr;
191 return log_writer_factory_->Create(name);
192}
193
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200194uint32_t CallClient::GetNextVideoSsrc() {
195 RTC_CHECK_LT(next_video_ssrc_index_, CallTest::kNumSsrcs);
196 return CallTest::kVideoSendSsrcs[next_video_ssrc_index_++];
197}
198
199uint32_t CallClient::GetNextAudioSsrc() {
200 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
201 next_audio_ssrc_index_++;
202 return CallTest::kAudioSendSsrc;
203}
204
205uint32_t CallClient::GetNextRtxSsrc() {
206 RTC_CHECK_LT(next_rtx_ssrc_index_, CallTest::kNumSsrcs);
207 return CallTest::kSendRtxSsrcs[next_rtx_ssrc_index_++];
208}
209
210std::string CallClient::GetNextPriorityId() {
211 RTC_CHECK_LT(next_priority_index_++, 1);
212 return kPriorityStreamId;
213}
214
Sebastian Janssonfd201712018-11-12 16:44:16 +0100215void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
216 for (const auto& extension : extensions)
217 header_parser_->RegisterRtpHeaderExtension(extension);
218}
219
Sebastian Jansson800e1212018-10-22 11:49:03 +0200220CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200221
222} // namespace test
223} // namespace webrtc