xref: /aosp_15_r20/external/webrtc/pc/peer_connection_factory.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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