blob: 0fbd2bc8f260f0e86cb71e987c8cf8f3acc4650e [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"
16#include "modules/congestion_controller/bbr/test/bbr_printer.h"
17#include "modules/congestion_controller/goog_cc/test/goog_cc_printer.h"
18#include "test/call_test.h"
19
20namespace webrtc {
21namespace test {
22namespace {
23const char* kPriorityStreamId = "priority-track";
Sebastian Jansson800e1212018-10-22 11:49:03 +020024
25CallClientFakeAudio InitAudio() {
26 CallClientFakeAudio setup;
27 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
28 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
29 setup.fake_audio_device = TestAudioDeviceModule::CreateTestAudioDeviceModule(
30 std::move(capturer), std::move(renderer), 1.f);
31 setup.apm = AudioProcessingBuilder().Create();
32 setup.fake_audio_device->Init();
33 AudioState::Config audio_state_config;
34 audio_state_config.audio_mixer = AudioMixerImpl::Create();
35 audio_state_config.audio_processing = setup.apm;
36 audio_state_config.audio_device_module = setup.fake_audio_device;
37 setup.audio_state = AudioState::Create(audio_state_config);
38 setup.fake_audio_device->RegisterAudioCallback(
39 setup.audio_state->audio_transport());
40 return setup;
41}
42
43Call* CreateCall(CallClientConfig config,
44 LoggingNetworkControllerFactory* network_controller_factory_,
45 rtc::scoped_refptr<AudioState> audio_state) {
46 CallConfig call_config(network_controller_factory_->GetEventLog());
47 call_config.bitrate_config.max_bitrate_bps =
48 config.transport.rates.max_rate.bps_or(-1);
49 call_config.bitrate_config.min_bitrate_bps =
50 config.transport.rates.min_rate.bps();
51 call_config.bitrate_config.start_bitrate_bps =
52 config.transport.rates.start_rate.bps();
53 call_config.network_controller_factory = network_controller_factory_;
54 call_config.audio_state = audio_state;
55 return Call::Create(call_config);
56}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020057}
58
59LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
60 std::string filename,
61 TransportControllerConfig config) {
62 if (filename.empty()) {
63 event_log_ = RtcEventLog::CreateNull();
64 } else {
65 event_log_ = RtcEventLog::Create(RtcEventLog::EncodingType::Legacy);
66 bool success = event_log_->StartLogging(
67 absl::make_unique<RtcEventLogOutputFile>(filename + ".rtc.dat",
68 RtcEventLog::kUnlimitedOutput),
69 RtcEventLog::kImmediateOutput);
70 RTC_CHECK(success);
71 cc_out_ = fopen((filename + ".cc_state.txt").c_str(), "w");
72 switch (config.cc) {
73 case TransportControllerConfig::CongestionController::kBbr: {
74 auto bbr_printer = absl::make_unique<BbrStatePrinter>();
75 cc_factory_.reset(new BbrDebugFactory(bbr_printer.get()));
76 cc_printer_.reset(
77 new ControlStatePrinter(cc_out_, std::move(bbr_printer)));
78 break;
79 }
80 case TransportControllerConfig::CongestionController::kGoogCc: {
81 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
82 cc_factory_.reset(
83 new GoogCcDebugFactory(event_log_.get(), goog_printer.get()));
84 cc_printer_.reset(
85 new ControlStatePrinter(cc_out_, std::move(goog_printer)));
86 break;
87 }
88 case TransportControllerConfig::CongestionController::kGoogCcFeedback: {
89 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
90 cc_factory_.reset(new GoogCcFeedbackDebugFactory(event_log_.get(),
91 goog_printer.get()));
92 cc_printer_.reset(
93 new ControlStatePrinter(cc_out_, std::move(goog_printer)));
94 break;
95 }
96 }
97 cc_printer_->PrintHeaders();
98 }
99 if (!cc_factory_) {
100 switch (config.cc) {
101 case TransportControllerConfig::CongestionController::kBbr:
102 cc_factory_.reset(new BbrNetworkControllerFactory());
103 break;
104 case TransportControllerConfig::CongestionController::kGoogCcFeedback:
105 cc_factory_.reset(
106 new GoogCcFeedbackNetworkControllerFactory(event_log_.get()));
107 break;
108 case TransportControllerConfig::CongestionController::kGoogCc:
109 cc_factory_.reset(new GoogCcNetworkControllerFactory(event_log_.get()));
110 break;
111 }
112 }
113}
114
115LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
116 if (cc_out_)
117 fclose(cc_out_);
118}
119
120void LoggingNetworkControllerFactory::LogCongestionControllerStats(
121 Timestamp at_time) {
122 if (cc_printer_)
123 cc_printer_->PrintState(at_time);
124}
125
126RtcEventLog* LoggingNetworkControllerFactory::GetEventLog() const {
127 return event_log_.get();
128}
129
130std::unique_ptr<NetworkControllerInterface>
131LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
132 return cc_factory_->Create(config);
133}
134
135TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
136 return cc_factory_->GetProcessInterval();
137}
138
139CallClient::CallClient(Clock* clock,
140 std::string log_filename,
141 CallClientConfig config)
142 : clock_(clock),
Sebastian Jansson800e1212018-10-22 11:49:03 +0200143 network_controller_factory_(log_filename, config.transport),
144 fake_audio_setup_(InitAudio()),
145 call_(CreateCall(config,
146 &network_controller_factory_,
147 fake_audio_setup_.audio_state)),
148 transport_(clock_, call_.get()),
149 header_parser_(RtpHeaderParser::Create()) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200150} // namespace test
151
Sebastian Jansson800e1212018-10-22 11:49:03 +0200152CallClient::~CallClient() {
153 delete header_parser_;
154}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200155
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200156ColumnPrinter CallClient::StatsPrinter() {
157 return ColumnPrinter::Lambda(
158 "pacer_delay call_send_bw",
159 [this](rtc::SimpleStringBuilder& sb) {
160 Call::Stats call_stats = call_->GetStats();
161 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
162 call_stats.send_bandwidth_bps / 8.0);
163 },
164 64);
165}
166
167Call::Stats CallClient::GetStats() {
168 return call_->GetStats();
169}
170
Sebastian Jansson800e1212018-10-22 11:49:03 +0200171bool CallClient::TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
172 uint64_t receiver,
173 Timestamp at_time) {
174 // Removes added overhead before delivering packet to sender.
175 RTC_DCHECK_GE(packet.size(), route_overhead_.at(receiver).bytes());
176 packet.SetSize(packet.size() - route_overhead_.at(receiver).bytes());
177
178 MediaType media_type = MediaType::ANY;
179 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.size())) {
180 RTPHeader header;
181 bool success =
182 header_parser_->Parse(packet.cdata(), packet.size(), &header);
183 if (!success)
184 return false;
185 media_type = ssrc_media_types_[header.ssrc];
186 }
187 call_->Receiver()->DeliverPacket(media_type, packet, at_time.us());
188 return true;
189}
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 Jansson800e1212018-10-22 11:49:03 +0200212CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200213
214} // namespace test
215} // namespace webrtc