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 <memory>
14 #include <utility>
15 
16 #include "absl/strings/match.h"
17 #include "api/async_resolver_factory.h"
18 #include "api/call/call_factory_interface.h"
19 #include "api/fec_controller.h"
20 #include "api/ice_transport_interface.h"
21 #include "api/media_stream_proxy.h"
22 #include "api/media_stream_track_proxy.h"
23 #include "api/network_state_predictor.h"
24 #include "api/packet_socket_factory.h"
25 #include "api/peer_connection_factory_proxy.h"
26 #include "api/peer_connection_proxy.h"
27 #include "api/rtc_event_log/rtc_event_log.h"
28 #include "api/sequence_checker.h"
29 #include "api/transport/bitrate_settings.h"
30 #include "api/units/data_rate.h"
31 #include "call/audio_state.h"
32 #include "media/base/media_engine.h"
33 #include "p2p/base/basic_async_resolver_factory.h"
34 #include "p2p/base/basic_packet_socket_factory.h"
35 #include "p2p/base/default_ice_transport_factory.h"
36 #include "p2p/client/basic_port_allocator.h"
37 #include "pc/audio_track.h"
38 #include "pc/local_audio_source.h"
39 #include "pc/media_stream.h"
40 #include "pc/peer_connection.h"
41 #include "pc/rtp_parameters_conversion.h"
42 #include "pc/session_description.h"
43 #include "pc/video_track.h"
44 #include "rtc_base/checks.h"
45 #include "rtc_base/experiments/field_trial_parser.h"
46 #include "rtc_base/experiments/field_trial_units.h"
47 #include "rtc_base/location.h"
48 #include "rtc_base/logging.h"
49 #include "rtc_base/numerics/safe_conversions.h"
50 #include "rtc_base/ref_counted_object.h"
51 #include "rtc_base/system/file_wrapper.h"
52 
53 namespace webrtc {
54 
55 rtc::scoped_refptr<PeerConnectionFactoryInterface>
CreateModularPeerConnectionFactory(PeerConnectionFactoryDependencies dependencies)56 CreateModularPeerConnectionFactory(
57     PeerConnectionFactoryDependencies dependencies) {
58   // The PeerConnectionFactory must be created on the signaling thread.
59   if (dependencies.signaling_thread &&
60       !dependencies.signaling_thread->IsCurrent()) {
61     return dependencies.signaling_thread
62         ->Invoke<rtc::scoped_refptr<PeerConnectionFactoryInterface>>(
63             RTC_FROM_HERE, [&dependencies] {
64               return CreateModularPeerConnectionFactory(
65                   std::move(dependencies));
66             });
67   }
68 
69   auto pc_factory = PeerConnectionFactory::Create(std::move(dependencies));
70   if (!pc_factory) {
71     return nullptr;
72   }
73   // Verify that the invocation and the initialization ended up agreeing on the
74   // thread.
75   RTC_DCHECK_RUN_ON(pc_factory->signaling_thread());
76   return PeerConnectionFactoryProxy::Create(
77       pc_factory->signaling_thread(), pc_factory->worker_thread(), pc_factory);
78 }
79 
80 // Static
Create(PeerConnectionFactoryDependencies dependencies)81 rtc::scoped_refptr<PeerConnectionFactory> PeerConnectionFactory::Create(
82     PeerConnectionFactoryDependencies dependencies) {
83   auto context = ConnectionContext::Create(&dependencies);
84   if (!context) {
85     return nullptr;
86   }
87   return new rtc::RefCountedObject<PeerConnectionFactory>(context,
88                                                           &dependencies);
89 }
90 
PeerConnectionFactory(rtc::scoped_refptr<ConnectionContext> context,PeerConnectionFactoryDependencies * dependencies)91 PeerConnectionFactory::PeerConnectionFactory(
92     rtc::scoped_refptr<ConnectionContext> context,
93     PeerConnectionFactoryDependencies* dependencies)
94     : context_(context),
95       task_queue_factory_(std::move(dependencies->task_queue_factory)),
96       event_log_factory_(std::move(dependencies->event_log_factory)),
97       fec_controller_factory_(std::move(dependencies->fec_controller_factory)),
98       network_state_predictor_factory_(
99           std::move(dependencies->network_state_predictor_factory)),
100       injected_network_controller_factory_(
101           std::move(dependencies->network_controller_factory)),
102       neteq_factory_(std::move(dependencies->neteq_factory)) {}
103 
PeerConnectionFactory(PeerConnectionFactoryDependencies dependencies)104 PeerConnectionFactory::PeerConnectionFactory(
105     PeerConnectionFactoryDependencies dependencies)
106     : PeerConnectionFactory(ConnectionContext::Create(&dependencies),
107                             &dependencies) {}
108 
~PeerConnectionFactory()109 PeerConnectionFactory::~PeerConnectionFactory() {
110   RTC_DCHECK_RUN_ON(signaling_thread());
111 }
112 
SetOptions(const Options & options)113 void PeerConnectionFactory::SetOptions(const Options& options) {
114   RTC_DCHECK_RUN_ON(signaling_thread());
115   options_ = options;
116 }
117 
GetRtpSenderCapabilities(cricket::MediaType kind) const118 RtpCapabilities PeerConnectionFactory::GetRtpSenderCapabilities(
119     cricket::MediaType kind) const {
120   RTC_DCHECK_RUN_ON(signaling_thread());
121   switch (kind) {
122     case cricket::MEDIA_TYPE_AUDIO: {
123       cricket::AudioCodecs cricket_codecs;
124       channel_manager()->GetSupportedAudioSendCodecs(&cricket_codecs);
125       return ToRtpCapabilities(
126           cricket_codecs,
127           channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions());
128     }
129     case cricket::MEDIA_TYPE_VIDEO: {
130       cricket::VideoCodecs cricket_codecs;
131       channel_manager()->GetSupportedVideoSendCodecs(&cricket_codecs);
132       return ToRtpCapabilities(
133           cricket_codecs,
134           channel_manager()->GetDefaultEnabledVideoRtpHeaderExtensions());
135     }
136     case cricket::MEDIA_TYPE_DATA:
137       return RtpCapabilities();
138     case cricket::MEDIA_TYPE_UNSUPPORTED:
139       return RtpCapabilities();
140   }
141   RTC_CHECK_NOTREACHED();
142 }
143 
GetRtpReceiverCapabilities(cricket::MediaType kind) const144 RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities(
145     cricket::MediaType kind) const {
146   RTC_DCHECK_RUN_ON(signaling_thread());
147   switch (kind) {
148     case cricket::MEDIA_TYPE_AUDIO: {
149       cricket::AudioCodecs cricket_codecs;
150       channel_manager()->GetSupportedAudioReceiveCodecs(&cricket_codecs);
151       return ToRtpCapabilities(
152           cricket_codecs,
153           channel_manager()->GetDefaultEnabledAudioRtpHeaderExtensions());
154     }
155     case cricket::MEDIA_TYPE_VIDEO: {
156       cricket::VideoCodecs cricket_codecs;
157       channel_manager()->GetSupportedVideoReceiveCodecs(&cricket_codecs);
158       return ToRtpCapabilities(
159           cricket_codecs,
160           channel_manager()->GetDefaultEnabledVideoRtpHeaderExtensions());
161     }
162     case cricket::MEDIA_TYPE_DATA:
163       return RtpCapabilities();
164     case cricket::MEDIA_TYPE_UNSUPPORTED:
165       return RtpCapabilities();
166   }
167   RTC_CHECK_NOTREACHED();
168 }
169 
170 rtc::scoped_refptr<AudioSourceInterface>
CreateAudioSource(const cricket::AudioOptions & options)171 PeerConnectionFactory::CreateAudioSource(const cricket::AudioOptions& options) {
172   RTC_DCHECK(signaling_thread()->IsCurrent());
173   rtc::scoped_refptr<LocalAudioSource> source(
174       LocalAudioSource::Create(&options));
175   return source;
176 }
177 
StartAecDump(FILE * file,int64_t max_size_bytes)178 bool PeerConnectionFactory::StartAecDump(FILE* file, int64_t max_size_bytes) {
179   RTC_DCHECK_RUN_ON(worker_thread());
180   return channel_manager()->StartAecDump(FileWrapper(file), max_size_bytes);
181 }
182 
StopAecDump()183 void PeerConnectionFactory::StopAecDump() {
184   RTC_DCHECK_RUN_ON(worker_thread());
185   channel_manager()->StopAecDump();
186 }
187 
188 rtc::scoped_refptr<PeerConnectionInterface>
CreatePeerConnection(const PeerConnectionInterface::RTCConfiguration & configuration,std::unique_ptr<cricket::PortAllocator> allocator,std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,PeerConnectionObserver * observer)189 PeerConnectionFactory::CreatePeerConnection(
190     const PeerConnectionInterface::RTCConfiguration& configuration,
191     std::unique_ptr<cricket::PortAllocator> allocator,
192     std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
193     PeerConnectionObserver* observer) {
194   // Convert the legacy API into the new dependency structure.
195   PeerConnectionDependencies dependencies(observer);
196   dependencies.allocator = std::move(allocator);
197   dependencies.cert_generator = std::move(cert_generator);
198   // Pass that into the new API.
199   return CreatePeerConnection(configuration, std::move(dependencies));
200 }
201 
202 rtc::scoped_refptr<PeerConnectionInterface>
CreatePeerConnection(const PeerConnectionInterface::RTCConfiguration & configuration,PeerConnectionDependencies dependencies)203 PeerConnectionFactory::CreatePeerConnection(
204     const PeerConnectionInterface::RTCConfiguration& configuration,
205     PeerConnectionDependencies dependencies) {
206   auto result =
207       CreatePeerConnectionOrError(configuration, std::move(dependencies));
208   if (result.ok()) {
209     return result.MoveValue();
210   } else {
211     return nullptr;
212   }
213 }
214 
215 RTCErrorOr<rtc::scoped_refptr<PeerConnectionInterface>>
CreatePeerConnectionOrError(const PeerConnectionInterface::RTCConfiguration & configuration,PeerConnectionDependencies dependencies)216 PeerConnectionFactory::CreatePeerConnectionOrError(
217     const PeerConnectionInterface::RTCConfiguration& configuration,
218     PeerConnectionDependencies dependencies) {
219   RTC_DCHECK_RUN_ON(signaling_thread());
220   RTC_DCHECK(!(dependencies.allocator && dependencies.packet_socket_factory))
221       << "You can't set both allocator and packet_socket_factory; "
222          "the former is going away (see bugs.webrtc.org/7447";
223 
224   // Set internal defaults if optional dependencies are not set.
225   if (!dependencies.cert_generator) {
226     dependencies.cert_generator =
227         std::make_unique<rtc::RTCCertificateGenerator>(signaling_thread(),
228                                                        network_thread());
229   }
230   if (!dependencies.allocator) {
231     rtc::PacketSocketFactory* packet_socket_factory;
232     if (dependencies.packet_socket_factory)
233       packet_socket_factory = dependencies.packet_socket_factory.get();
234     else
235       packet_socket_factory = context_->default_socket_factory();
236 
237     dependencies.allocator = std::make_unique<cricket::BasicPortAllocator>(
238         context_->default_network_manager(), packet_socket_factory,
239         configuration.turn_customizer);
240   }
241 
242   if (!dependencies.async_resolver_factory) {
243     dependencies.async_resolver_factory =
244         std::make_unique<webrtc::BasicAsyncResolverFactory>();
245   }
246 
247   if (!dependencies.ice_transport_factory) {
248     dependencies.ice_transport_factory =
249         std::make_unique<DefaultIceTransportFactory>();
250   }
251 
252   dependencies.allocator->SetNetworkIgnoreMask(options().network_ignore_mask);
253 
254   std::unique_ptr<RtcEventLog> event_log =
255       worker_thread()->Invoke<std::unique_ptr<RtcEventLog>>(
256           RTC_FROM_HERE, [this] { return CreateRtcEventLog_w(); });
257 
258   std::unique_ptr<Call> call = worker_thread()->Invoke<std::unique_ptr<Call>>(
259       RTC_FROM_HERE,
260       [this, &event_log] { return CreateCall_w(event_log.get()); });
261 
262   auto result = PeerConnection::Create(context_, options_, std::move(event_log),
263                                        std::move(call), configuration,
264                                        std::move(dependencies));
265   if (!result.ok()) {
266     return result.MoveError();
267   }
268   // We configure the proxy with a pointer to the network thread for methods
269   // that need to be invoked there rather than on the signaling thread.
270   // Internally, the proxy object has a member variable named |worker_thread_|
271   // which will point to the network thread (and not the factory's
272   // worker_thread()).  All such methods have thread checks though, so the code
273   // should still be clear (outside of macro expansion).
274   rtc::scoped_refptr<PeerConnectionInterface> result_proxy =
275       PeerConnectionProxy::Create(signaling_thread(), network_thread(),
276                                   result.MoveValue());
277   return result_proxy;
278 }
279 
280 rtc::scoped_refptr<MediaStreamInterface>
CreateLocalMediaStream(const std::string & stream_id)281 PeerConnectionFactory::CreateLocalMediaStream(const std::string& stream_id) {
282   RTC_DCHECK(signaling_thread()->IsCurrent());
283   return MediaStreamProxy::Create(signaling_thread(),
284                                   MediaStream::Create(stream_id));
285 }
286 
CreateVideoTrack(const std::string & id,VideoTrackSourceInterface * source)287 rtc::scoped_refptr<VideoTrackInterface> PeerConnectionFactory::CreateVideoTrack(
288     const std::string& id,
289     VideoTrackSourceInterface* source) {
290   RTC_DCHECK(signaling_thread()->IsCurrent());
291   rtc::scoped_refptr<VideoTrackInterface> track(
292       VideoTrack::Create(id, source, worker_thread()));
293   return VideoTrackProxy::Create(signaling_thread(), worker_thread(), track);
294 }
295 
CreateAudioTrack(const std::string & id,AudioSourceInterface * source)296 rtc::scoped_refptr<AudioTrackInterface> PeerConnectionFactory::CreateAudioTrack(
297     const std::string& id,
298     AudioSourceInterface* source) {
299   RTC_DCHECK(signaling_thread()->IsCurrent());
300   rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source));
301   return AudioTrackProxy::Create(signaling_thread(), track);
302 }
303 
channel_manager()304 cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
305   return context_->channel_manager();
306 }
307 
CreateRtcEventLog_w()308 std::unique_ptr<RtcEventLog> PeerConnectionFactory::CreateRtcEventLog_w() {
309   RTC_DCHECK_RUN_ON(worker_thread());
310 
311   auto encoding_type = RtcEventLog::EncodingType::Legacy;
312   if (IsTrialEnabled("WebRTC-RtcEventLogNewFormat"))
313     encoding_type = RtcEventLog::EncodingType::NewFormat;
314   return event_log_factory_
315              ? event_log_factory_->CreateRtcEventLog(encoding_type)
316              : std::make_unique<RtcEventLogNull>();
317 }
318 
CreateCall_w(RtcEventLog * event_log)319 std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
320     RtcEventLog* event_log) {
321   RTC_DCHECK_RUN_ON(worker_thread());
322 
323   webrtc::Call::Config call_config(event_log, network_thread());
324   if (!channel_manager()->media_engine() || !context_->call_factory()) {
325     return nullptr;
326   }
327   call_config.audio_state =
328       channel_manager()->media_engine()->voice().GetAudioState();
329 
330   FieldTrialParameter<DataRate> min_bandwidth("min",
331                                               DataRate::KilobitsPerSec(30));
332   FieldTrialParameter<DataRate> start_bandwidth("start",
333                                                 DataRate::KilobitsPerSec(300));
334   FieldTrialParameter<DataRate> max_bandwidth("max",
335                                               DataRate::KilobitsPerSec(2000));
336   ParseFieldTrial({&min_bandwidth, &start_bandwidth, &max_bandwidth},
337                   trials().Lookup("WebRTC-PcFactoryDefaultBitrates"));
338 
339   call_config.bitrate_config.min_bitrate_bps =
340       rtc::saturated_cast<int>(min_bandwidth->bps());
341   call_config.bitrate_config.start_bitrate_bps =
342       rtc::saturated_cast<int>(start_bandwidth->bps());
343   call_config.bitrate_config.max_bitrate_bps =
344       rtc::saturated_cast<int>(max_bandwidth->bps());
345 
346   call_config.fec_controller_factory = fec_controller_factory_.get();
347   call_config.task_queue_factory = task_queue_factory_.get();
348   call_config.network_state_predictor_factory =
349       network_state_predictor_factory_.get();
350   call_config.neteq_factory = neteq_factory_.get();
351 
352   if (IsTrialEnabled("WebRTC-Bwe-InjectedCongestionController")) {
353     RTC_LOG(LS_INFO) << "Using injected network controller factory";
354     call_config.network_controller_factory =
355         injected_network_controller_factory_.get();
356   } else {
357     RTC_LOG(LS_INFO) << "Using default network controller factory";
358   }
359 
360   call_config.trials = &trials();
361 
362   return std::unique_ptr<Call>(
363       context_->call_factory()->CreateCall(call_config));
364 }
365 
IsTrialEnabled(absl::string_view key) const366 bool PeerConnectionFactory::IsTrialEnabled(absl::string_view key) const {
367   return absl::StartsWith(trials().Lookup(key), "Enabled");
368 }
369 
370 }  // namespace webrtc
371