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