blob: 3a8ce11b0ff5425f7a363a9e0a5376804004ac5d [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"
Sebastian Jansson98b07e92018-09-27 13:47:01 +020017
18namespace webrtc {
19namespace test {
20namespace {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +010021static constexpr size_t kNumSsrcs = 6;
22const uint32_t kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE, 0xBADCAFF,
23 0xBADCB00, 0xBADCB01, 0xBADCB02};
24const uint32_t kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE, 0xC0FFEF,
25 0xC0FFF0, 0xC0FFF1, 0xC0FFF2};
26const uint32_t kVideoRecvLocalSsrcs[kNumSsrcs] = {0xDAB001, 0xDAB002, 0xDAB003,
27 0xDAB004, 0xDAB005, 0xDAB006};
28const uint32_t kAudioSendSsrc = 0xDEADBEEF;
29const uint32_t kReceiverLocalAudioSsrc = 0x1234567;
30
Sebastian Jansson98b07e92018-09-27 13:47:01 +020031const char* kPriorityStreamId = "priority-track";
Sebastian Jansson800e1212018-10-22 11:49:03 +020032
33CallClientFakeAudio InitAudio() {
34 CallClientFakeAudio setup;
35 auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
36 auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
37 setup.fake_audio_device = TestAudioDeviceModule::CreateTestAudioDeviceModule(
38 std::move(capturer), std::move(renderer), 1.f);
39 setup.apm = AudioProcessingBuilder().Create();
40 setup.fake_audio_device->Init();
41 AudioState::Config audio_state_config;
42 audio_state_config.audio_mixer = AudioMixerImpl::Create();
43 audio_state_config.audio_processing = setup.apm;
44 audio_state_config.audio_device_module = setup.fake_audio_device;
45 setup.audio_state = AudioState::Create(audio_state_config);
46 setup.fake_audio_device->RegisterAudioCallback(
47 setup.audio_state->audio_transport());
48 return setup;
49}
50
51Call* CreateCall(CallClientConfig config,
52 LoggingNetworkControllerFactory* network_controller_factory_,
53 rtc::scoped_refptr<AudioState> audio_state) {
54 CallConfig call_config(network_controller_factory_->GetEventLog());
55 call_config.bitrate_config.max_bitrate_bps =
56 config.transport.rates.max_rate.bps_or(-1);
57 call_config.bitrate_config.min_bitrate_bps =
58 config.transport.rates.min_rate.bps();
59 call_config.bitrate_config.start_bitrate_bps =
60 config.transport.rates.start_rate.bps();
61 call_config.network_controller_factory = network_controller_factory_;
62 call_config.audio_state = audio_state;
63 return Call::Create(call_config);
64}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020065}
66
67LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010068 LogWriterFactoryInterface* log_writer_factory,
Sebastian Jansson98b07e92018-09-27 13:47:01 +020069 TransportControllerConfig config) {
Sebastian Jansson52de8b02019-01-16 17:25:44 +010070 std::unique_ptr<RtcEventLogOutput> cc_out;
71 if (!log_writer_factory) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020072 event_log_ = RtcEventLog::CreateNull();
73 } else {
74 event_log_ = RtcEventLog::Create(RtcEventLog::EncodingType::Legacy);
75 bool success = event_log_->StartLogging(
Sebastian Jansson52de8b02019-01-16 17:25:44 +010076 log_writer_factory->Create(".rtc.dat"), RtcEventLog::kImmediateOutput);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020077 RTC_CHECK(success);
Sebastian Jansson52de8b02019-01-16 17:25:44 +010078 cc_out = log_writer_factory->Create(".cc_state.txt");
Sebastian Janssonf0d03122018-12-18 15:53:04 +010079 }
80 switch (config.cc) {
81 case TransportControllerConfig::CongestionController::kGoogCc:
Sebastian Jansson52de8b02019-01-16 17:25:44 +010082 if (cc_out) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020083 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +010084 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +020085 new GoogCcDebugFactory(event_log_.get(), goog_printer.get()));
Sebastian Jansson52de8b02019-01-16 17:25:44 +010086 cc_printer_.reset(new ControlStatePrinter(std::move(cc_out),
87 std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +010088 } else {
89 owned_cc_factory_.reset(
90 new GoogCcNetworkControllerFactory(event_log_.get()));
Sebastian Jansson98b07e92018-09-27 13:47:01 +020091 }
Sebastian Janssonf0d03122018-12-18 15:53:04 +010092 break;
93 case TransportControllerConfig::CongestionController::kGoogCcFeedback:
Sebastian Jansson52de8b02019-01-16 17:25:44 +010094 if (cc_out) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020095 auto goog_printer = absl::make_unique<GoogCcStatePrinter>();
Sebastian Janssonf0d03122018-12-18 15:53:04 +010096 owned_cc_factory_.reset(new GoogCcFeedbackDebugFactory(
97 event_log_.get(), goog_printer.get()));
Sebastian Jansson52de8b02019-01-16 17:25:44 +010098 cc_printer_.reset(new ControlStatePrinter(std::move(cc_out),
99 std::move(goog_printer)));
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100100 } else {
101 owned_cc_factory_.reset(
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200102 new GoogCcFeedbackNetworkControllerFactory(event_log_.get()));
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100103 }
104 break;
105 case TransportControllerConfig::CongestionController::kInjected:
106 cc_factory_ = config.cc_factory;
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100107 if (cc_out)
Sebastian Janssonf0d03122018-12-18 15:53:04 +0100108 RTC_LOG(LS_WARNING)
109 << "Can't log controller state for injected network controllers";
110 break;
111 }
112 if (cc_printer_)
113 cc_printer_->PrintHeaders();
114 if (owned_cc_factory_) {
115 RTC_DCHECK(!cc_factory_);
116 cc_factory_ = owned_cc_factory_.get();
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200117 }
118}
119
120LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200121}
122
123void LoggingNetworkControllerFactory::LogCongestionControllerStats(
124 Timestamp at_time) {
125 if (cc_printer_)
126 cc_printer_->PrintState(at_time);
127}
128
129RtcEventLog* LoggingNetworkControllerFactory::GetEventLog() const {
130 return event_log_.get();
131}
132
133std::unique_ptr<NetworkControllerInterface>
134LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
135 return cc_factory_->Create(config);
136}
137
138TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
139 return cc_factory_->GetProcessInterval();
140}
141
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100142CallClient::CallClient(
143 Clock* clock,
144 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
145 CallClientConfig config)
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200146 : clock_(clock),
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100147 log_writer_factory_(std::move(log_writer_factory)),
148 network_controller_factory_(log_writer_factory_.get(), config.transport),
Sebastian Jansson800e1212018-10-22 11:49:03 +0200149 fake_audio_setup_(InitAudio()),
150 call_(CreateCall(config,
151 &network_controller_factory_,
152 fake_audio_setup_.audio_state)),
153 transport_(clock_, call_.get()),
Sebastian Jansson9a4f38e2018-12-19 13:14:41 +0100154 header_parser_(RtpHeaderParser::Create()) {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200155
Sebastian Jansson800e1212018-10-22 11:49:03 +0200156CallClient::~CallClient() {
157 delete header_parser_;
158}
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200159
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200160ColumnPrinter CallClient::StatsPrinter() {
161 return ColumnPrinter::Lambda(
162 "pacer_delay call_send_bw",
163 [this](rtc::SimpleStringBuilder& sb) {
164 Call::Stats call_stats = call_->GetStats();
165 sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
166 call_stats.send_bandwidth_bps / 8.0);
167 },
168 64);
169}
170
171Call::Stats CallClient::GetStats() {
172 return call_->GetStats();
173}
174
Artem Titov40f51152019-01-04 15:45:01 +0100175void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200176 // Removes added overhead before delivering packet to sender.
Artem Titov40f51152019-01-04 15:45:01 +0100177 RTC_DCHECK_GE(packet.data.size(),
178 route_overhead_.at(packet.dest_endpoint_id).bytes());
179 packet.data.SetSize(packet.data.size() -
180 route_overhead_.at(packet.dest_endpoint_id).bytes());
Sebastian Jansson800e1212018-10-22 11:49:03 +0200181
182 MediaType media_type = MediaType::ANY;
Artem Titov40f51152019-01-04 15:45:01 +0100183 if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
Sebastian Jansson1e427612019-03-05 14:25:03 +0100184 auto ssrc = RtpHeaderParser::GetSsrc(packet.cdata(), packet.data.size());
185 RTC_CHECK(ssrc.has_value());
186 media_type = ssrc_media_types_[*ssrc];
Sebastian Jansson800e1212018-10-22 11:49:03 +0200187 }
Artem Titov40f51152019-01-04 15:45:01 +0100188 call_->Receiver()->DeliverPacket(media_type, packet.data,
189 packet.arrival_time.us());
Sebastian Jansson800e1212018-10-22 11:49:03 +0200190}
191
Sebastian Jansson52de8b02019-01-16 17:25:44 +0100192std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
193 if (!log_writer_factory_ || name.empty())
194 return nullptr;
195 return log_writer_factory_->Create(name);
196}
197
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200198uint32_t CallClient::GetNextVideoSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100199 RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
200 return kVideoSendSsrcs[next_video_ssrc_index_++];
201}
202
203uint32_t CallClient::GetNextVideoLocalSsrc() {
204 RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
205 return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200206}
207
208uint32_t CallClient::GetNextAudioSsrc() {
209 RTC_CHECK_LT(next_audio_ssrc_index_, 1);
210 next_audio_ssrc_index_++;
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100211 return kAudioSendSsrc;
212}
213
214uint32_t CallClient::GetNextAudioLocalSsrc() {
215 RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
216 next_audio_local_ssrc_index_++;
217 return kReceiverLocalAudioSsrc;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200218}
219
220uint32_t CallClient::GetNextRtxSsrc() {
Sebastian Jansson5fbebd52019-02-20 11:16:19 +0100221 RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
222 return kSendRtxSsrcs[next_rtx_ssrc_index_++];
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200223}
224
225std::string CallClient::GetNextPriorityId() {
226 RTC_CHECK_LT(next_priority_index_++, 1);
227 return kPriorityStreamId;
228}
229
Sebastian Janssonfd201712018-11-12 16:44:16 +0100230void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
231 for (const auto& extension : extensions)
232 header_parser_->RegisterRtpHeaderExtension(extension);
233}
234
Sebastian Jansson800e1212018-10-22 11:49:03 +0200235CallClientPair::~CallClientPair() = default;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200236
237} // namespace test
238} // namespace webrtc