blob: 47cc3bc57b82d2536e22fcde9e62c37ba43d260e [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";
24}
25
26LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
27 std::string filename,
28 TransportControllerConfig config) {
29 if (filename.empty()) {
30 event_log_ = RtcEventLog::CreateNull();
31 } else {
32 event_log_ = RtcEventLog::Create(RtcEventLog::EncodingType::Legacy);
33 bool success = event_log_->StartLogging(
34 absl::make_unique<RtcEventLogOutputFile>(filename + ".rtc.dat",
35 RtcEventLog::kUnlimitedOutput),
36 RtcEventLog::kImmediateOutput);
37 RTC_CHECK(success);
38 cc_out_ = fopen((filename + ".cc_state.txt").c_str(), "w");
39 switch (config.cc) {
40 case TransportControllerConfig::CongestionController::kBbr: {
41 auto bbr_printer = absl::make_unique<BbrStatePrinter>();
42 cc_factory_.reset(new BbrDebugFactory(bbr_printer.get()));
43 cc_printer_.reset(
44 new ControlStatePrinter(cc_out_, std::move(bbr_printer)));
45 break;
46 }
47 case TransportControllerConfig::CongestionController::kGoogCc: {
48 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
49 cc_factory_.reset(
50 new GoogCcDebugFactory(event_log_.get(), goog_printer.get()));
51 cc_printer_.reset(
52 new ControlStatePrinter(cc_out_, std::move(goog_printer)));
53 break;
54 }
55 case TransportControllerConfig::CongestionController::kGoogCcFeedback: {
56 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
57 cc_factory_.reset(new GoogCcFeedbackDebugFactory(event_log_.get(),
58 goog_printer.get()));
59 cc_printer_.reset(
60 new ControlStatePrinter(cc_out_, std::move(goog_printer)));
61 break;
62 }
63 }
64 cc_printer_->PrintHeaders();
65 }
66 if (!cc_factory_) {
67 switch (config.cc) {
68 case TransportControllerConfig::CongestionController::kBbr:
69 cc_factory_.reset(new BbrNetworkControllerFactory());
70 break;
71 case TransportControllerConfig::CongestionController::kGoogCcFeedback:
72 cc_factory_.reset(
73 new GoogCcFeedbackNetworkControllerFactory(event_log_.get()));
74 break;
75 case TransportControllerConfig::CongestionController::kGoogCc:
76 cc_factory_.reset(new GoogCcNetworkControllerFactory(event_log_.get()));
77 break;
78 }
79 }
80}
81
82LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
83 if (cc_out_)
84 fclose(cc_out_);
85}
86
87void LoggingNetworkControllerFactory::LogCongestionControllerStats(
88 Timestamp at_time) {
89 if (cc_printer_)
90 cc_printer_->PrintState(at_time);
91}
92
93RtcEventLog* LoggingNetworkControllerFactory::GetEventLog() const {
94 return event_log_.get();
95}
96
97std::unique_ptr<NetworkControllerInterface>
98LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
99 return cc_factory_->Create(config);
100}
101
102TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
103 return cc_factory_->GetProcessInterval();
104}
105
106CallClient::CallClient(Clock* clock,
107 std::string log_filename,
108 CallClientConfig config)
109 : clock_(clock),
110 network_controller_factory_(log_filename, config.transport) {
111 CallConfig call_config(network_controller_factory_.GetEventLog());
112 call_config.bitrate_config.max_bitrate_bps =
113 config.transport.rates.max_rate.bps_or(-1);
114 call_config.bitrate_config.min_bitrate_bps =
115 config.transport.rates.min_rate.bps();
116 call_config.bitrate_config.start_bitrate_bps =
117 config.transport.rates.start_rate.bps();
118 call_config.network_controller_factory = &network_controller_factory_;
119 call_config.audio_state = InitAudio();
120 call_.reset(Call::Create(call_config));
121 if (!config.priority_target_rate.IsZero() &&
122 config.priority_target_rate.IsFinite()) {
123 call_->SetBitrateAllocationStrategy(
124 absl::make_unique<rtc::AudioPriorityBitrateAllocationStrategy>(
125 kPriorityStreamId, config.priority_target_rate.bps()));
126 }
127} // namespace test
128
129CallClient::~CallClient() {}
130
131void CallClient::DeliverPacket(MediaType media_type,
132 rtc::CopyOnWriteBuffer packet,
133 Timestamp at_time) {
134 call_->Receiver()->DeliverPacket(media_type, packet, at_time.us());
135}
136
137ColumnPrinter CallClient::StatsPrinter() {
138 return ColumnPrinter::Lambda(
139 "pacer_delay call_send_bw",
140 [this](rtc::SimpleStringBuilder& sb) {
141 Call::Stats call_stats = call_->GetStats();
142 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
143 call_stats.send_bandwidth_bps / 8.0);
144 },
145 64);
146}
147
148Call::Stats CallClient::GetStats() {
149 return call_->GetStats();
150}
151
152uint32_t CallClient::GetNextVideoSsrc() {
153 RTC_CHECK_LT(next_video_ssrc_index_, CallTest::kNumSsrcs);
154 return CallTest::kVideoSendSsrcs[next_video_ssrc_index_++];
155}
156
157uint32_t CallClient::GetNextAudioSsrc() {
158 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
159 next_audio_ssrc_index_++;
160 return CallTest::kAudioSendSsrc;
161}
162
163uint32_t CallClient::GetNextRtxSsrc() {
164 RTC_CHECK_LT(next_rtx_ssrc_index_, CallTest::kNumSsrcs);
165 return CallTest::kSendRtxSsrcs[next_rtx_ssrc_index_++];
166}
167
168std::string CallClient::GetNextPriorityId() {
169 RTC_CHECK_LT(next_priority_index_++, 1);
170 return kPriorityStreamId;
171}
172
173rtc::scoped_refptr<AudioState> CallClient::InitAudio() {
174 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
175 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
176 fake_audio_device_ = TestAudioDeviceModule::CreateTestAudioDeviceModule(
177 std::move(capturer), std::move(renderer), 1.f);
178 apm_ = AudioProcessingBuilder().Create();
179 fake_audio_device_->Init();
180 AudioState::Config audio_state_config;
181 audio_state_config.audio_mixer = AudioMixerImpl::Create();
182 audio_state_config.audio_processing = apm_;
183 audio_state_config.audio_device_module = fake_audio_device_;
184 auto audio_state = AudioState::Create(audio_state_config);
185 fake_audio_device_->RegisterAudioCallback(audio_state->audio_transport());
186 return audio_state;
187}
188
189} // namespace test
190} // namespace webrtc