blob: a768afdb83d54e13a4a81ed1ddf1ee98b8920356 [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
14#include "logging/rtc_event_log/output/rtc_event_log_output_file.h"
15#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(
59 std::string filename,
60 TransportControllerConfig config) {
61 if (filename.empty()) {
62 event_log_ = RtcEventLog::CreateNull();
63 } else {
64 event_log_ = RtcEventLog::Create(RtcEventLog::EncodingType::Legacy);
65 bool success = event_log_->StartLogging(
66 absl::make_unique<RtcEventLogOutputFile>(filename + ".rtc.dat",
67 RtcEventLog::kUnlimitedOutput),
68 RtcEventLog::kImmediateOutput);
69 RTC_CHECK(success);
70 cc_out_ = fopen((filename + ".cc_state.txt").c_str(), "w");
Sebastian Janssonf0d03122018-12-18 15:53:04 +010071 }
72 switch (config.cc) {
73 case TransportControllerConfig::CongestionController::kGoogCc:
74 if (cc_out_) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020075 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +010076 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020077 new GoogCcDebugFactory(event_log_.get(), goog_printer.get()));
78 cc_printer_.reset(
79 new ControlStatePrinter(cc_out_, std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010080 } else {
81 owned_cc_factory_.reset(
82 new GoogCcNetworkControllerFactory(event_log_.get()));
Sebastian Jansson98b07e92018-09-27 13:47:01 +020083 }
Sebastian Janssonf0d03122018-12-18 15:53:04 +010084 break;
85 case TransportControllerConfig::CongestionController::kGoogCcFeedback:
86 if (cc_out_) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020087 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +010088 owned_cc_factory_.reset(new GoogCcFeedbackDebugFactory(
89 event_log_.get(), goog_printer.get()));
Sebastian Jansson98b07e92018-09-27 13:47:01 +020090 cc_printer_.reset(
91 new ControlStatePrinter(cc_out_, std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010092 } else {
93 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020094 new GoogCcFeedbackNetworkControllerFactory(event_log_.get()));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010095 }
96 break;
97 case TransportControllerConfig::CongestionController::kInjected:
98 cc_factory_ = config.cc_factory;
99 if (cc_out_)
100 RTC_LOG(LS_WARNING)
101 << "Can't log controller state for injected network controllers";
102 break;
103 }
104 if (cc_printer_)
105 cc_printer_->PrintHeaders();
106 if (owned_cc_factory_) {
107 RTC_DCHECK(!cc_factory_);
108 cc_factory_ = owned_cc_factory_.get();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200109 }
110}
111
112LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
113 if (cc_out_)
114 fclose(cc_out_);
115}
116
117void LoggingNetworkControllerFactory::LogCongestionControllerStats(
118 Timestamp at_time) {
119 if (cc_printer_)
120 cc_printer_->PrintState(at_time);
121}
122
123RtcEventLog* LoggingNetworkControllerFactory::GetEventLog() const {
124 return event_log_.get();
125}
126
127std::unique_ptr<NetworkControllerInterface>
128LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
129 return cc_factory_->Create(config);
130}
131
132TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
133 return cc_factory_->GetProcessInterval();
134}
135
136CallClient::CallClient(Clock* clock,
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +0100137 std::string name,
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200138 std::string log_filename,
139 CallClientConfig config)
140 : clock_(clock),
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +0100141 name_(name),
Sebastian Jansson800e1212018-10-22 11:49:03 +0200142 network_controller_factory_(log_filename, config.transport),
143 fake_audio_setup_(InitAudio()),
144 call_(CreateCall(config,
145 &network_controller_factory_,
146 fake_audio_setup_.audio_state)),
147 transport_(clock_, call_.get()),
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +0100148 header_parser_(RtpHeaderParser::Create()) {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200149
Sebastian Jansson800e1212018-10-22 11:49:03 +0200150CallClient::~CallClient() {
151 delete header_parser_;
152}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200153
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200154ColumnPrinter CallClient::StatsPrinter() {
155 return ColumnPrinter::Lambda(
156 "pacer_delay call_send_bw",
157 [this](rtc::SimpleStringBuilder& sb) {
158 Call::Stats call_stats = call_->GetStats();
159 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
160 call_stats.send_bandwidth_bps / 8.0);
161 },
162 64);
163}
164
165Call::Stats CallClient::GetStats() {
166 return call_->GetStats();
167}
168
Artem Titov40f51152019-01-04 15:45:01 +0100169void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200170 // Removes added overhead before delivering packet to sender.
Artem Titov40f51152019-01-04 15:45:01 +0100171 RTC_DCHECK_GE(packet.data.size(),
172 route_overhead_.at(packet.dest_endpoint_id).bytes());
173 packet.data.SetSize(packet.data.size() -
174 route_overhead_.at(packet.dest_endpoint_id).bytes());
Sebastian Jansson800e1212018-10-22 11:49:03 +0200175
176 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100177 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200178 RTPHeader header;
179 bool success =
Artem Titov40f51152019-01-04 15:45:01 +0100180 header_parser_->Parse(packet.cdata(), packet.data.size(), &header);
Sebastian Janssonf65309c2018-12-20 10:26:00 +0100181 if (!success) {
182 RTC_DLOG(LS_ERROR) << "Failed to parse RTP header of packet";
183 return;
184 }
Sebastian Jansson800e1212018-10-22 11:49:03 +0200185 media_type = ssrc_media_types_[header.ssrc];
186 }
Artem Titov40f51152019-01-04 15:45:01 +0100187 call_->Receiver()->DeliverPacket(media_type, packet.data,
188 packet.arrival_time.us());
Sebastian Jansson800e1212018-10-22 11:49:03 +0200189}
190
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200191uint32_t CallClient::GetNextVideoSsrc() {
192 RTC_CHECK_LT(next_video_ssrc_index_, CallTest::kNumSsrcs);
193 return CallTest::kVideoSendSsrcs[next_video_ssrc_index_++];
194}
195
196uint32_t CallClient::GetNextAudioSsrc() {
197 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
198 next_audio_ssrc_index_++;
199 return CallTest::kAudioSendSsrc;
200}
201
202uint32_t CallClient::GetNextRtxSsrc() {
203 RTC_CHECK_LT(next_rtx_ssrc_index_, CallTest::kNumSsrcs);
204 return CallTest::kSendRtxSsrcs[next_rtx_ssrc_index_++];
205}
206
207std::string CallClient::GetNextPriorityId() {
208 RTC_CHECK_LT(next_priority_index_++, 1);
209 return kPriorityStreamId;
210}
211
Sebastian Janssonfd201712018-11-12 16:44:16 +0100212void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
213 for (const auto& extension : extensions)
214 header_parser_->RegisterRtpHeaderExtension(extension);
215}
216
Sebastian Jansson800e1212018-10-22 11:49:03 +0200217CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200218
219} // namespace test
220} // namespace webrtc