• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 <memory>
15 #include "api/rtc_event_log/rtc_event_log.h"
16 #include "api/rtc_event_log/rtc_event_log_factory.h"
17 #include "modules/audio_mixer/audio_mixer_impl.h"
18 
19 namespace webrtc {
20 namespace test {
21 namespace {
22 static constexpr size_t kNumSsrcs = 6;
23 const uint32_t kSendRtxSsrcs[kNumSsrcs] = {0xBADCAFD, 0xBADCAFE, 0xBADCAFF,
24                                            0xBADCB00, 0xBADCB01, 0xBADCB02};
25 const uint32_t kVideoSendSsrcs[kNumSsrcs] = {0xC0FFED, 0xC0FFEE, 0xC0FFEF,
26                                              0xC0FFF0, 0xC0FFF1, 0xC0FFF2};
27 const uint32_t kVideoRecvLocalSsrcs[kNumSsrcs] = {0xDAB001, 0xDAB002, 0xDAB003,
28                                                   0xDAB004, 0xDAB005, 0xDAB006};
29 const uint32_t kAudioSendSsrc = 0xDEADBEEF;
30 const uint32_t kReceiverLocalAudioSsrc = 0x1234567;
31 
32 constexpr int kEventLogOutputIntervalMs = 5000;
33 
InitAudio(TimeController * time_controller)34 CallClientFakeAudio InitAudio(TimeController* time_controller) {
35   CallClientFakeAudio setup;
36   auto capturer = TestAudioDeviceModule::CreatePulsedNoiseCapturer(256, 48000);
37   auto renderer = TestAudioDeviceModule::CreateDiscardRenderer(48000);
38   setup.fake_audio_device = TestAudioDeviceModule::Create(
39       time_controller->GetTaskQueueFactory(), std::move(capturer),
40       std::move(renderer), 1.f);
41   setup.apm = AudioProcessingBuilder().Create();
42   setup.fake_audio_device->Init();
43   AudioState::Config audio_state_config;
44   audio_state_config.audio_mixer = AudioMixerImpl::Create();
45   audio_state_config.audio_processing = setup.apm;
46   audio_state_config.audio_device_module = setup.fake_audio_device;
47   setup.audio_state = AudioState::Create(audio_state_config);
48   setup.fake_audio_device->RegisterAudioCallback(
49       setup.audio_state->audio_transport());
50   return setup;
51 }
52 
CreateCall(TimeController * time_controller,RtcEventLog * event_log,CallClientConfig config,LoggingNetworkControllerFactory * network_controller_factory,rtc::scoped_refptr<AudioState> audio_state,rtc::scoped_refptr<SharedModuleThread> call_thread)53 Call* CreateCall(TimeController* time_controller,
54                  RtcEventLog* event_log,
55                  CallClientConfig config,
56                  LoggingNetworkControllerFactory* network_controller_factory,
57                  rtc::scoped_refptr<AudioState> audio_state,
58                  rtc::scoped_refptr<SharedModuleThread> call_thread) {
59   CallConfig call_config(event_log);
60   call_config.bitrate_config.max_bitrate_bps =
61       config.transport.rates.max_rate.bps_or(-1);
62   call_config.bitrate_config.min_bitrate_bps =
63       config.transport.rates.min_rate.bps();
64   call_config.bitrate_config.start_bitrate_bps =
65       config.transport.rates.start_rate.bps();
66   call_config.task_queue_factory = time_controller->GetTaskQueueFactory();
67   call_config.network_controller_factory = network_controller_factory;
68   call_config.audio_state = audio_state;
69   call_config.trials = config.field_trials;
70   return Call::Create(call_config, time_controller->GetClock(),
71                       std::move(call_thread),
72                       time_controller->CreateProcessThread("Pacer"));
73 }
74 
CreateEventLog(TaskQueueFactory * task_queue_factory,LogWriterFactoryInterface * log_writer_factory)75 std::unique_ptr<RtcEventLog> CreateEventLog(
76     TaskQueueFactory* task_queue_factory,
77     LogWriterFactoryInterface* log_writer_factory) {
78   if (!log_writer_factory) {
79     return std::make_unique<RtcEventLogNull>();
80   }
81   auto event_log = RtcEventLogFactory(task_queue_factory)
82                        .CreateRtcEventLog(RtcEventLog::EncodingType::NewFormat);
83   bool success = event_log->StartLogging(log_writer_factory->Create(".rtc.dat"),
84                                          kEventLogOutputIntervalMs);
85   RTC_CHECK(success);
86   return event_log;
87 }
88 }  // namespace
NetworkControleUpdateCache(std::unique_ptr<NetworkControllerInterface> controller)89 NetworkControleUpdateCache::NetworkControleUpdateCache(
90     std::unique_ptr<NetworkControllerInterface> controller)
91     : controller_(std::move(controller)) {}
OnNetworkAvailability(NetworkAvailability msg)92 NetworkControlUpdate NetworkControleUpdateCache::OnNetworkAvailability(
93     NetworkAvailability msg) {
94   return Update(controller_->OnNetworkAvailability(msg));
95 }
OnNetworkRouteChange(NetworkRouteChange msg)96 NetworkControlUpdate NetworkControleUpdateCache::OnNetworkRouteChange(
97     NetworkRouteChange msg) {
98   return Update(controller_->OnNetworkRouteChange(msg));
99 }
OnProcessInterval(ProcessInterval msg)100 NetworkControlUpdate NetworkControleUpdateCache::OnProcessInterval(
101     ProcessInterval msg) {
102   return Update(controller_->OnProcessInterval(msg));
103 }
OnRemoteBitrateReport(RemoteBitrateReport msg)104 NetworkControlUpdate NetworkControleUpdateCache::OnRemoteBitrateReport(
105     RemoteBitrateReport msg) {
106   return Update(controller_->OnRemoteBitrateReport(msg));
107 }
OnRoundTripTimeUpdate(RoundTripTimeUpdate msg)108 NetworkControlUpdate NetworkControleUpdateCache::OnRoundTripTimeUpdate(
109     RoundTripTimeUpdate msg) {
110   return Update(controller_->OnRoundTripTimeUpdate(msg));
111 }
OnSentPacket(SentPacket msg)112 NetworkControlUpdate NetworkControleUpdateCache::OnSentPacket(SentPacket msg) {
113   return Update(controller_->OnSentPacket(msg));
114 }
OnReceivedPacket(ReceivedPacket msg)115 NetworkControlUpdate NetworkControleUpdateCache::OnReceivedPacket(
116     ReceivedPacket msg) {
117   return Update(controller_->OnReceivedPacket(msg));
118 }
OnStreamsConfig(StreamsConfig msg)119 NetworkControlUpdate NetworkControleUpdateCache::OnStreamsConfig(
120     StreamsConfig msg) {
121   return Update(controller_->OnStreamsConfig(msg));
122 }
OnTargetRateConstraints(TargetRateConstraints msg)123 NetworkControlUpdate NetworkControleUpdateCache::OnTargetRateConstraints(
124     TargetRateConstraints msg) {
125   return Update(controller_->OnTargetRateConstraints(msg));
126 }
OnTransportLossReport(TransportLossReport msg)127 NetworkControlUpdate NetworkControleUpdateCache::OnTransportLossReport(
128     TransportLossReport msg) {
129   return Update(controller_->OnTransportLossReport(msg));
130 }
OnTransportPacketsFeedback(TransportPacketsFeedback msg)131 NetworkControlUpdate NetworkControleUpdateCache::OnTransportPacketsFeedback(
132     TransportPacketsFeedback msg) {
133   return Update(controller_->OnTransportPacketsFeedback(msg));
134 }
OnNetworkStateEstimate(NetworkStateEstimate msg)135 NetworkControlUpdate NetworkControleUpdateCache::OnNetworkStateEstimate(
136     NetworkStateEstimate msg) {
137   return Update(controller_->OnNetworkStateEstimate(msg));
138 }
139 
update_state() const140 NetworkControlUpdate NetworkControleUpdateCache::update_state() const {
141   return update_state_;
142 }
Update(NetworkControlUpdate update)143 NetworkControlUpdate NetworkControleUpdateCache::Update(
144     NetworkControlUpdate update) {
145   if (update.target_rate)
146     update_state_.target_rate = update.target_rate;
147   if (update.pacer_config)
148     update_state_.pacer_config = update.pacer_config;
149   if (update.congestion_window)
150     update_state_.congestion_window = update.congestion_window;
151   if (!update.probe_cluster_configs.empty())
152     update_state_.probe_cluster_configs = update.probe_cluster_configs;
153   return update;
154 }
155 
LoggingNetworkControllerFactory(LogWriterFactoryInterface * log_writer_factory,TransportControllerConfig config)156 LoggingNetworkControllerFactory::LoggingNetworkControllerFactory(
157     LogWriterFactoryInterface* log_writer_factory,
158     TransportControllerConfig config) {
159   if (config.cc_factory) {
160     cc_factory_ = config.cc_factory;
161     if (log_writer_factory)
162       RTC_LOG(LS_WARNING)
163           << "Can't log controller state for injected network controllers";
164   } else {
165     if (log_writer_factory) {
166       goog_cc_factory_.AttachWriter(
167           log_writer_factory->Create(".cc_state.txt"));
168       print_cc_state_ = true;
169     }
170     cc_factory_ = &goog_cc_factory_;
171   }
172 }
173 
~LoggingNetworkControllerFactory()174 LoggingNetworkControllerFactory::~LoggingNetworkControllerFactory() {}
175 
LogCongestionControllerStats(Timestamp at_time)176 void LoggingNetworkControllerFactory::LogCongestionControllerStats(
177     Timestamp at_time) {
178   if (print_cc_state_)
179     goog_cc_factory_.PrintState(at_time);
180 }
181 
GetUpdate() const182 NetworkControlUpdate LoggingNetworkControllerFactory::GetUpdate() const {
183   if (last_controller_)
184     return last_controller_->update_state();
185   return NetworkControlUpdate();
186 }
187 
188 std::unique_ptr<NetworkControllerInterface>
Create(NetworkControllerConfig config)189 LoggingNetworkControllerFactory::Create(NetworkControllerConfig config) {
190   auto controller =
191       std::make_unique<NetworkControleUpdateCache>(cc_factory_->Create(config));
192   last_controller_ = controller.get();
193   return controller;
194 }
195 
GetProcessInterval() const196 TimeDelta LoggingNetworkControllerFactory::GetProcessInterval() const {
197   return cc_factory_->GetProcessInterval();
198 }
199 
CallClient(TimeController * time_controller,std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,CallClientConfig config)200 CallClient::CallClient(
201     TimeController* time_controller,
202     std::unique_ptr<LogWriterFactoryInterface> log_writer_factory,
203     CallClientConfig config)
204     : time_controller_(time_controller),
205       clock_(time_controller->GetClock()),
206       log_writer_factory_(std::move(log_writer_factory)),
207       network_controller_factory_(log_writer_factory_.get(), config.transport),
208       header_parser_(RtpHeaderParser::CreateForTest()),
209       task_queue_(time_controller->GetTaskQueueFactory()->CreateTaskQueue(
210           "CallClient",
211           TaskQueueFactory::Priority::NORMAL)) {
212   config.field_trials = &field_trials_;
213   SendTask([this, config] {
214     event_log_ = CreateEventLog(time_controller_->GetTaskQueueFactory(),
215                                 log_writer_factory_.get());
216     fake_audio_setup_ = InitAudio(time_controller_);
217     RTC_DCHECK(!module_thread_);
218     module_thread_ = SharedModuleThread::Create(
219         time_controller_->CreateProcessThread("CallThread"),
220         [this]() { module_thread_ = nullptr; });
221 
222     call_.reset(CreateCall(time_controller_, event_log_.get(), config,
223                            &network_controller_factory_,
224                            fake_audio_setup_.audio_state, module_thread_));
225     transport_ = std::make_unique<NetworkNodeTransport>(clock_, call_.get());
226   });
227 }
228 
~CallClient()229 CallClient::~CallClient() {
230   SendTask([&] {
231     call_.reset();
232     RTC_DCHECK(!module_thread_);  // Should be set to null in the lambda above.
233     fake_audio_setup_ = {};
234     rtc::Event done;
235     event_log_->StopLogging([&done] { done.Set(); });
236     done.Wait(rtc::Event::kForever);
237     event_log_.reset();
238   });
239 }
240 
StatsPrinter()241 ColumnPrinter CallClient::StatsPrinter() {
242   return ColumnPrinter::Lambda(
243       "pacer_delay call_send_bw",
244       [this](rtc::SimpleStringBuilder& sb) {
245         Call::Stats call_stats = call_->GetStats();
246         sb.AppendFormat("%.3lf %.0lf", call_stats.pacer_delay_ms / 1000.0,
247                         call_stats.send_bandwidth_bps / 8.0);
248       },
249       64);
250 }
251 
GetStats()252 Call::Stats CallClient::GetStats() {
253   // This call needs to be made on the thread that |call_| was constructed on.
254   Call::Stats stats;
255   SendTask([this, &stats] { stats = call_->GetStats(); });
256   return stats;
257 }
258 
target_rate() const259 DataRate CallClient::target_rate() const {
260   return network_controller_factory_.GetUpdate().target_rate->target_rate;
261 }
262 
stable_target_rate() const263 DataRate CallClient::stable_target_rate() const {
264   return network_controller_factory_.GetUpdate()
265       .target_rate->stable_target_rate;
266 }
267 
padding_rate() const268 DataRate CallClient::padding_rate() const {
269   return network_controller_factory_.GetUpdate().pacer_config->pad_rate();
270 }
271 
OnPacketReceived(EmulatedIpPacket packet)272 void CallClient::OnPacketReceived(EmulatedIpPacket packet) {
273   MediaType media_type = MediaType::ANY;
274   if (!RtpHeaderParser::IsRtcp(packet.cdata(), packet.data.size())) {
275     auto ssrc = RtpHeaderParser::GetSsrc(packet.cdata(), packet.data.size());
276     RTC_CHECK(ssrc.has_value());
277     media_type = ssrc_media_types_[*ssrc];
278   }
279   task_queue_.PostTask(
280       [call = call_.get(), media_type, packet = std::move(packet)]() mutable {
281         call->Receiver()->DeliverPacket(media_type, packet.data,
282                                         packet.arrival_time.us());
283       });
284 }
285 
GetLogWriter(std::string name)286 std::unique_ptr<RtcEventLogOutput> CallClient::GetLogWriter(std::string name) {
287   if (!log_writer_factory_ || name.empty())
288     return nullptr;
289   return log_writer_factory_->Create(name);
290 }
291 
GetNextVideoSsrc()292 uint32_t CallClient::GetNextVideoSsrc() {
293   RTC_CHECK_LT(next_video_ssrc_index_, kNumSsrcs);
294   return kVideoSendSsrcs[next_video_ssrc_index_++];
295 }
296 
GetNextVideoLocalSsrc()297 uint32_t CallClient::GetNextVideoLocalSsrc() {
298   RTC_CHECK_LT(next_video_local_ssrc_index_, kNumSsrcs);
299   return kVideoRecvLocalSsrcs[next_video_local_ssrc_index_++];
300 }
301 
GetNextAudioSsrc()302 uint32_t CallClient::GetNextAudioSsrc() {
303   RTC_CHECK_LT(next_audio_ssrc_index_, 1);
304   next_audio_ssrc_index_++;
305   return kAudioSendSsrc;
306 }
307 
GetNextAudioLocalSsrc()308 uint32_t CallClient::GetNextAudioLocalSsrc() {
309   RTC_CHECK_LT(next_audio_local_ssrc_index_, 1);
310   next_audio_local_ssrc_index_++;
311   return kReceiverLocalAudioSsrc;
312 }
313 
GetNextRtxSsrc()314 uint32_t CallClient::GetNextRtxSsrc() {
315   RTC_CHECK_LT(next_rtx_ssrc_index_, kNumSsrcs);
316   return kSendRtxSsrcs[next_rtx_ssrc_index_++];
317 }
318 
AddExtensions(std::vector<RtpExtension> extensions)319 void CallClient::AddExtensions(std::vector<RtpExtension> extensions) {
320   for (const auto& extension : extensions)
321     header_parser_->RegisterRtpHeaderExtension(extension);
322 }
323 
SendTask(std::function<void ()> task)324 void CallClient::SendTask(std::function<void()> task) {
325   task_queue_.SendTask(std::move(task), RTC_FROM_HERE);
326 }
327 
Bind(EmulatedEndpoint * endpoint)328 int16_t CallClient::Bind(EmulatedEndpoint* endpoint) {
329   uint16_t port = endpoint->BindReceiver(0, this).value();
330   endpoints_.push_back({endpoint, port});
331   return port;
332 }
333 
UnBind()334 void CallClient::UnBind() {
335   for (auto ep_port : endpoints_)
336     ep_port.first->UnbindReceiver(ep_port.second);
337 }
338 
339 CallClientPair::~CallClientPair() = default;
340 
341 }  // namespace test
342 }  // namespace webrtc
343