• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2004 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 
11 #include "pc/peer_connection_factory.h"
12 
13 #include <cstdio>
14 #include <memory>
15 #include <utility>
16 #include <vector>
17 
18 #include "absl/strings/match.h"
19 #include "api/fec_controller.h"
20 #include "api/media_stream_proxy.h"
21 #include "api/media_stream_track_proxy.h"
22 #include "api/network_state_predictor.h"
23 #include "api/peer_connection_factory_proxy.h"
24 #include "api/peer_connection_proxy.h"
25 #include "api/rtc_event_log/rtc_event_log.h"
26 #include "api/transport/field_trial_based_config.h"
27 #include "api/turn_customizer.h"
28 #include "api/units/data_rate.h"
29 #include "api/video_track_source_proxy.h"
30 #include "media/base/rtp_data_engine.h"
31 #include "media/sctp/sctp_transport.h"
32 #include "p2p/base/basic_async_resolver_factory.h"
33 #include "p2p/base/basic_packet_socket_factory.h"
34 #include "p2p/base/default_ice_transport_factory.h"
35 #include "p2p/client/basic_port_allocator.h"
36 #include "pc/audio_track.h"
37 #include "pc/local_audio_source.h"
38 #include "pc/media_stream.h"
39 #include "pc/peer_connection.h"
40 #include "pc/rtp_parameters_conversion.h"
41 #include "pc/video_track.h"
42 #include "rtc_base/bind.h"
43 #include "rtc_base/checks.h"
44 #include "rtc_base/experiments/field_trial_parser.h"
45 #include "rtc_base/experiments/field_trial_units.h"
46 #include "rtc_base/numerics/safe_conversions.h"
47 #include "rtc_base/system/file_wrapper.h"
48 
49 namespace webrtc {
50 
51 rtc::scoped_refptr<PeerConnectionFactoryInterface>
CreateModularPeerConnectionFactory(PeerConnectionFactoryDependencies dependencies)52 CreateModularPeerConnectionFactory(
53     PeerConnectionFactoryDependencies dependencies) {
54   rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
55       new rtc::RefCountedObject<PeerConnectionFactory>(
56           std::move(dependencies)));
57   // Call Initialize synchronously but make sure it is executed on
58   // |signaling_thread|.
59   MethodCall<PeerConnectionFactory, bool> call(
60       pc_factory.get(), &PeerConnectionFactory::Initialize);
61   bool result = call.Marshal(RTC_FROM_HERE, pc_factory->signaling_thread());
62 
63   if (!result) {
64     return nullptr;
65   }
66   return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(),
67                                             pc_factory);
68 }
69 
PeerConnectionFactory(PeerConnectionFactoryDependencies dependencies)70 PeerConnectionFactory::PeerConnectionFactory(
71     PeerConnectionFactoryDependencies dependencies)
72     : wraps_current_thread_(false),
73       network_thread_(dependencies.network_thread),
74       worker_thread_(dependencies.worker_thread),
75       signaling_thread_(dependencies.signaling_thread),
76       task_queue_factory_(std::move(dependencies.task_queue_factory)),
77       media_engine_(std::move(dependencies.media_engine)),
78       call_factory_(std::move(dependencies.call_factory)),
79       event_log_factory_(std::move(dependencies.event_log_factory)),
80       fec_controller_factory_(std::move(dependencies.fec_controller_factory)),
81       network_state_predictor_factory_(
82           std::move(dependencies.network_state_predictor_factory)),
83       injected_network_controller_factory_(
84           std::move(dependencies.network_controller_factory)),
85       neteq_factory_(std::move(dependencies.neteq_factory)),
86       trials_(dependencies.trials ? std::move(dependencies.trials)
87                                   : std::make_unique<FieldTrialBasedConfig>()) {
88   if (!network_thread_) {
89     owned_network_thread_ = rtc::Thread::CreateWithSocketServer();
90     owned_network_thread_->SetName("pc_network_thread", nullptr);
91     owned_network_thread_->Start();
92     network_thread_ = owned_network_thread_.get();
93   }
94 
95   if (!worker_thread_) {
96     owned_worker_thread_ = rtc::Thread::Create();
97     owned_worker_thread_->SetName("pc_worker_thread", nullptr);
98     owned_worker_thread_->Start();
99     worker_thread_ = owned_worker_thread_.get();
100   }
101 
102   if (!signaling_thread_) {
103     signaling_thread_ = rtc::Thread::Current();
104     if (!signaling_thread_) {
105       // If this thread isn't already wrapped by an rtc::Thread, create a
106       // wrapper and own it in this class.
107       signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
108       wraps_current_thread_ = true;
109     }
110   }
111   signaling_thread_->AllowInvokesToThread(worker_thread_);
112   signaling_thread_->AllowInvokesToThread(network_thread_);
113   worker_thread_->AllowInvokesToThread(network_thread_);
114   network_thread_->DisallowAllInvokes();
115 }
116 
~PeerConnectionFactory()117 PeerConnectionFactory::~PeerConnectionFactory() {
118   RTC_DCHECK(signaling_thread_->IsCurrent());
119   channel_manager_.reset(nullptr);
120 
121   // Make sure |worker_thread_| and |signaling_thread_| outlive
122   // |default_socket_factory_| and |default_network_manager_|.
123   default_socket_factory_ = nullptr;
124   default_network_manager_ = nullptr;
125 
126   if (wraps_current_thread_)
127     rtc::ThreadManager::Instance()->UnwrapCurrentThread();
128 }
129 
Initialize()130 bool PeerConnectionFactory::Initialize() {
131   RTC_DCHECK(signaling_thread_->IsCurrent());
132   rtc::InitRandom(rtc::Time32());
133 
134   default_network_manager_.reset(new rtc::BasicNetworkManager());
135   if (!default_network_manager_) {
136     return false;
137   }
138 
139   default_socket_factory_.reset(
140       new rtc::BasicPacketSocketFactory(network_thread_));
141   if (!default_socket_factory_) {
142     return false;
143   }
144 
145   channel_manager_ = std::make_unique<cricket::ChannelManager>(
146       std::move(media_engine_), std::make_unique<cricket::RtpDataEngine>(),
147       worker_thread_, network_thread_);
148 
149   channel_manager_->SetVideoRtxEnabled(true);
150   if (!channel_manager_->Init()) {
151     return false;
152   }
153 
154   return true;
155 }
156 
SetOptions(const Options & options)157 void PeerConnectionFactory::SetOptions(const Options& options) {
158   options_ = options;
159 }
160 
GetRtpSenderCapabilities(cricket::MediaType kind) const161 RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities(
162     cricket::MediaType kind) const {
163   RTC_DCHECK_RUN_ON(signaling_thread_);
164   switch (kind) {
165     case cricket::MEDIA_TYPE_AUDIO: {
166       cricket::AudioCodecs cricket_codecs;
167       channel_manager_->GetSupportedAudioSendCodecs(&cricket_codecs);
168       return ToRtpCapabilities(
169           cricket_codecs,
170           channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions());
171     }
172     case cricket::MEDIA_TYPE_VIDEO: {
173       cricket::VideoCodecs cricket_codecs;
174       channel_manager_->GetSupportedVideoSendCodecs(&cricket_codecs);
175       return ToRtpCapabilities(
176           cricket_codecs,
177           channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions());
178     }
179     case cricket::MEDIA_TYPE_DATA:
180       return RtpCapabilities();
181   }
182   // Not reached; avoids compile warning.
183   FATAL();
184 }
185 
GetRtpReceiverCapabilities(cricket::MediaType kind) const186 RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities(
187     cricket::MediaType kind) const {
188   RTC_DCHECK_RUN_ON(signaling_thread_);
189   switch (kind) {
190     case cricket::MEDIA_TYPE_AUDIO: {
191       cricket::AudioCodecs cricket_codecs;
192       channel_manager_->GetSupportedAudioReceiveCodecs(&cricket_codecs);
193       return ToRtpCapabilities(
194           cricket_codecs,
195           channel_manager_->GetDefaultEnabledAudioRtpHeaderExtensions());
196     }
197     case cricket::MEDIA_TYPE_VIDEO: {
198       cricket::VideoCodecs cricket_codecs;
199       channel_manager_->GetSupportedVideoReceiveCodecs(&cricket_codecs);
200       return ToRtpCapabilities(
201           cricket_codecs,
202           channel_manager_->GetDefaultEnabledVideoRtpHeaderExtensions());
203     }
204     case cricket::MEDIA_TYPE_DATA:
205       return RtpCapabilities();
206   }
207   // Not reached; avoids compile warning.
208   FATAL();
209 }
210 
211 rtc::scoped_refptr<AudioSourceInterface>
CreateAudioSource(const cricket::AudioOptions & options)212 PeerConnectionFactory::CreateAudioSource(const cricket::AudioOptions& options) {
213   RTC_DCHECK(signaling_thread_->IsCurrent());
214   rtc::scoped_refptr<LocalAudioSource> source(
215       LocalAudioSource::Create(&options));
216   return source;
217 }
218 
StartAecDump(FILE * file,int64_t max_size_bytes)219 bool PeerConnectionFactory::StartAecDump(FILE* file, int64_t max_size_bytes) {
220   RTC_DCHECK(signaling_thread_->IsCurrent());
221   return channel_manager_->StartAecDump(FileWrapper(file), max_size_bytes);
222 }
223 
StopAecDump()224 void PeerConnectionFactory::StopAecDump() {
225   RTC_DCHECK(signaling_thread_->IsCurrent());
226   channel_manager_->StopAecDump();
227 }
228 
229 rtc::scoped_refptr<PeerConnectionInterface>
CreatePeerConnection(const PeerConnectionInterface::RTCConfiguration & configuration,std::unique_ptr<cricket::PortAllocator> allocator,std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,PeerConnectionObserver * observer)230 PeerConnectionFactory::CreatePeerConnection(
231     const PeerConnectionInterface::RTCConfiguration& configuration,
232     std::unique_ptr<cricket::PortAllocator> allocator,
233     std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
234     PeerConnectionObserver* observer) {
235   // Convert the legacy API into the new dependency structure.
236   PeerConnectionDependencies dependencies(observer);
237   dependencies.allocator = std::move(allocator);
238   dependencies.cert_generator = std::move(cert_generator);
239   // Pass that into the new API.
240   return CreatePeerConnection(configuration, std::move(dependencies));
241 }
242 
243 rtc::scoped_refptr<PeerConnectionInterface>
CreatePeerConnection(const PeerConnectionInterface::RTCConfiguration & configuration,PeerConnectionDependencies dependencies)244 PeerConnectionFactory::CreatePeerConnection(
245     const PeerConnectionInterface::RTCConfiguration& configuration,
246     PeerConnectionDependencies dependencies) {
247   RTC_DCHECK(signaling_thread_->IsCurrent());
248   RTC_DCHECK(!(dependencies.allocator && dependencies.packet_socket_factory))
249       << "You can't set both allocator and packet_socket_factory; "
250          "the former is going away (see bugs.webrtc.org/7447";
251 
252   // Set internal defaults if optional dependencies are not set.
253   if (!dependencies.cert_generator) {
254     dependencies.cert_generator =
255         std::make_unique<rtc::RTCCertificateGenerator>(signaling_thread_,
256                                                        network_thread_);
257   }
258   if (!dependencies.allocator) {
259     rtc::PacketSocketFactory* packet_socket_factory;
260     if (dependencies.packet_socket_factory)
261       packet_socket_factory = dependencies.packet_socket_factory.get();
262     else
263       packet_socket_factory = default_socket_factory_.get();
264 
265     network_thread_->Invoke<void>(RTC_FROM_HERE, [this, &configuration,
266                                                   &dependencies,
267                                                   &packet_socket_factory]() {
268       dependencies.allocator = std::make_unique<cricket::BasicPortAllocator>(
269           default_network_manager_.get(), packet_socket_factory,
270           configuration.turn_customizer);
271     });
272   }
273 
274   if (!dependencies.async_resolver_factory) {
275     dependencies.async_resolver_factory =
276         std::make_unique<webrtc::BasicAsyncResolverFactory>();
277   }
278 
279   if (!dependencies.ice_transport_factory) {
280     dependencies.ice_transport_factory =
281         std::make_unique<DefaultIceTransportFactory>();
282   }
283 
284   network_thread_->Invoke<void>(
285       RTC_FROM_HERE,
286       rtc::Bind(&cricket::PortAllocator::SetNetworkIgnoreMask,
287                 dependencies.allocator.get(), options_.network_ignore_mask));
288 
289   std::unique_ptr<RtcEventLog> event_log =
290       worker_thread_->Invoke<std::unique_ptr<RtcEventLog>>(
291           RTC_FROM_HERE,
292           rtc::Bind(&PeerConnectionFactory::CreateRtcEventLog_w, this));
293 
294   std::unique_ptr<Call> call = worker_thread_->Invoke<std::unique_ptr<Call>>(
295       RTC_FROM_HERE,
296       rtc::Bind(&PeerConnectionFactory::CreateCall_w, this, event_log.get()));
297 
298   rtc::scoped_refptr<PeerConnection> pc(
299       new rtc::RefCountedObject<PeerConnection>(this, std::move(event_log),
300                                                 std::move(call)));
301   ActionsBeforeInitializeForTesting(pc);
302   if (!pc->Initialize(configuration, std::move(dependencies))) {
303     return nullptr;
304   }
305   return PeerConnectionProxy::Create(signaling_thread(), pc);
306 }
307 
308 rtc::scoped_refptr<MediaStreamInterface>
CreateLocalMediaStream(const std::string & stream_id)309 PeerConnectionFactory::CreateLocalMediaStream(const std::string& stream_id) {
310   RTC_DCHECK(signaling_thread_->IsCurrent());
311   return MediaStreamProxy::Create(signaling_thread_,
312                                   MediaStream::Create(stream_id));
313 }
314 
CreateVideoTrack(const std::string & id,VideoTrackSourceInterface * source)315 rtc::scoped_refptr<VideoTrackInterface> PeerConnectionFactory::CreateVideoTrack(
316     const std::string& id,
317     VideoTrackSourceInterface* source) {
318   RTC_DCHECK(signaling_thread_->IsCurrent());
319   rtc::scoped_refptr<VideoTrackInterface> track(
320       VideoTrack::Create(id, source, worker_thread_));
321   return VideoTrackProxy::Create(signaling_thread_, worker_thread_, track);
322 }
323 
CreateAudioTrack(const std::string & id,AudioSourceInterface * source)324 rtc::scoped_refptr<AudioTrackInterface> PeerConnectionFactory::CreateAudioTrack(
325     const std::string& id,
326     AudioSourceInterface* source) {
327   RTC_DCHECK(signaling_thread_->IsCurrent());
328   rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source));
329   return AudioTrackProxy::Create(signaling_thread_, track);
330 }
331 
332 std::unique_ptr<cricket::SctpTransportInternalFactory>
CreateSctpTransportInternalFactory()333 PeerConnectionFactory::CreateSctpTransportInternalFactory() {
334 #ifdef HAVE_SCTP
335   return std::make_unique<cricket::SctpTransportFactory>(network_thread());
336 #else
337   return nullptr;
338 #endif
339 }
340 
channel_manager()341 cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
342   return channel_manager_.get();
343 }
344 
CreateRtcEventLog_w()345 std::unique_ptr<RtcEventLog> PeerConnectionFactory::CreateRtcEventLog_w() {
346   RTC_DCHECK_RUN_ON(worker_thread_);
347 
348   auto encoding_type = RtcEventLog::EncodingType::Legacy;
349   if (IsTrialEnabled("WebRTC-RtcEventLogNewFormat"))
350     encoding_type = RtcEventLog::EncodingType::NewFormat;
351   return event_log_factory_
352              ? event_log_factory_->CreateRtcEventLog(encoding_type)
353              : std::make_unique<RtcEventLogNull>();
354 }
355 
CreateCall_w(RtcEventLog * event_log)356 std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
357     RtcEventLog* event_log) {
358   RTC_DCHECK_RUN_ON(worker_thread_);
359 
360   webrtc::Call::Config call_config(event_log);
361   if (!channel_manager_->media_engine() || !call_factory_) {
362     return nullptr;
363   }
364   call_config.audio_state =
365       channel_manager_->media_engine()->voice().GetAudioState();
366 
367   FieldTrialParameter<DataRate> min_bandwidth("min",
368                                               DataRate::KilobitsPerSec(30));
369   FieldTrialParameter<DataRate> start_bandwidth("start",
370                                                 DataRate::KilobitsPerSec(300));
371   FieldTrialParameter<DataRate> max_bandwidth("max",
372                                               DataRate::KilobitsPerSec(2000));
373   ParseFieldTrial({&min_bandwidth, &start_bandwidth, &max_bandwidth},
374                   trials_->Lookup("WebRTC-PcFactoryDefaultBitrates"));
375 
376   call_config.bitrate_config.min_bitrate_bps =
377       rtc::saturated_cast<int>(min_bandwidth->bps());
378   call_config.bitrate_config.start_bitrate_bps =
379       rtc::saturated_cast<int>(start_bandwidth->bps());
380   call_config.bitrate_config.max_bitrate_bps =
381       rtc::saturated_cast<int>(max_bandwidth->bps());
382 
383   call_config.fec_controller_factory = fec_controller_factory_.get();
384   call_config.task_queue_factory = task_queue_factory_.get();
385   call_config.network_state_predictor_factory =
386       network_state_predictor_factory_.get();
387   call_config.neteq_factory = neteq_factory_.get();
388 
389   if (IsTrialEnabled("WebRTC-Bwe-InjectedCongestionController")) {
390     RTC_LOG(LS_INFO) << "Using injected network controller factory";
391     call_config.network_controller_factory =
392         injected_network_controller_factory_.get();
393   } else {
394     RTC_LOG(LS_INFO) << "Using default network controller factory";
395   }
396 
397   call_config.trials = trials_.get();
398 
399   return std::unique_ptr<Call>(call_factory_->CreateCall(call_config));
400 }
401 
IsTrialEnabled(absl::string_view key) const402 bool PeerConnectionFactory::IsTrialEnabled(absl::string_view key) const {
403   RTC_DCHECK(trials_);
404   return absl::StartsWith(trials_->Lookup(key), "Enabled");
405 }
406 
407 }  // namespace webrtc
408