1/* 2 * Copyright 2015 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 <memory> 12 13#import "RTCPeerConnectionFactory+Native.h" 14#import "RTCPeerConnectionFactory+Private.h" 15#import "RTCPeerConnectionFactoryOptions+Private.h" 16 17#import "RTCAudioSource+Private.h" 18#import "RTCAudioTrack+Private.h" 19#import "RTCMediaConstraints+Private.h" 20#import "RTCMediaStream+Private.h" 21#import "RTCPeerConnection+Private.h" 22#import "RTCVideoSource+Private.h" 23#import "RTCVideoTrack+Private.h" 24#import "base/RTCLogging.h" 25#import "base/RTCVideoDecoderFactory.h" 26#import "base/RTCVideoEncoderFactory.h" 27#import "helpers/NSString+StdString.h" 28#include "rtc_base/checks.h" 29#include "sdk/objc/native/api/network_monitor_factory.h" 30#include "sdk/objc/native/api/ssl_certificate_verifier.h" 31#include "system_wrappers/include/field_trial.h" 32 33#include "api/audio_codecs/builtin_audio_decoder_factory.h" 34#include "api/audio_codecs/builtin_audio_encoder_factory.h" 35#include "api/rtc_event_log/rtc_event_log_factory.h" 36#include "api/task_queue/default_task_queue_factory.h" 37#include "api/transport/field_trial_based_config.h" 38#import "components/video_codec/RTCVideoDecoderFactoryH264.h" 39#import "components/video_codec/RTCVideoEncoderFactoryH264.h" 40#include "media/engine/webrtc_media_engine.h" 41#include "modules/audio_device/include/audio_device.h" 42#include "modules/audio_processing/include/audio_processing.h" 43 44#include "sdk/objc/native/api/objc_audio_device_module.h" 45#include "sdk/objc/native/api/video_decoder_factory.h" 46#include "sdk/objc/native/api/video_encoder_factory.h" 47#include "sdk/objc/native/src/objc_video_decoder_factory.h" 48#include "sdk/objc/native/src/objc_video_encoder_factory.h" 49 50#if defined(WEBRTC_IOS) 51#import "sdk/objc/native/api/audio_device_module.h" 52#endif 53 54@implementation RTC_OBJC_TYPE (RTCPeerConnectionFactory) { 55 std::unique_ptr<rtc::Thread> _networkThread; 56 std::unique_ptr<rtc::Thread> _workerThread; 57 std::unique_ptr<rtc::Thread> _signalingThread; 58 BOOL _hasStartedAecDump; 59} 60 61@synthesize nativeFactory = _nativeFactory; 62 63- (rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule { 64#if defined(WEBRTC_IOS) 65 return webrtc::CreateAudioDeviceModule(); 66#else 67 return nullptr; 68#endif 69} 70 71- (instancetype)init { 72 return [self 73 initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory() 74 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory() 75 nativeVideoEncoderFactory:webrtc::ObjCToNativeVideoEncoderFactory([[RTC_OBJC_TYPE( 76 RTCVideoEncoderFactoryH264) alloc] init]) 77 nativeVideoDecoderFactory:webrtc::ObjCToNativeVideoDecoderFactory([[RTC_OBJC_TYPE( 78 RTCVideoDecoderFactoryH264) alloc] init]) 79 audioDeviceModule:[self audioDeviceModule].get() 80 audioProcessingModule:nullptr]; 81} 82 83- (instancetype) 84 initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory 85 decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory { 86 return [self initWithEncoderFactory:encoderFactory decoderFactory:decoderFactory audioDevice:nil]; 87} 88 89- (instancetype) 90 initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory 91 decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory 92 audioDevice:(nullable id<RTC_OBJC_TYPE(RTCAudioDevice)>)audioDevice { 93#ifdef HAVE_NO_MEDIA 94 return [self initWithNoMedia]; 95#else 96 std::unique_ptr<webrtc::VideoEncoderFactory> native_encoder_factory; 97 std::unique_ptr<webrtc::VideoDecoderFactory> native_decoder_factory; 98 if (encoderFactory) { 99 native_encoder_factory = webrtc::ObjCToNativeVideoEncoderFactory(encoderFactory); 100 } 101 if (decoderFactory) { 102 native_decoder_factory = webrtc::ObjCToNativeVideoDecoderFactory(decoderFactory); 103 } 104 rtc::scoped_refptr<webrtc::AudioDeviceModule> audio_device_module; 105 if (audioDevice) { 106 audio_device_module = webrtc::CreateAudioDeviceModule(audioDevice); 107 } else { 108 audio_device_module = [self audioDeviceModule]; 109 } 110 return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory() 111 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory() 112 nativeVideoEncoderFactory:std::move(native_encoder_factory) 113 nativeVideoDecoderFactory:std::move(native_decoder_factory) 114 audioDeviceModule:audio_device_module.get() 115 audioProcessingModule:nullptr]; 116#endif 117} 118 119- (instancetype)initNative { 120 if (self = [super init]) { 121 _networkThread = rtc::Thread::CreateWithSocketServer(); 122 _networkThread->SetName("network_thread", _networkThread.get()); 123 BOOL result = _networkThread->Start(); 124 RTC_DCHECK(result) << "Failed to start network thread."; 125 126 _workerThread = rtc::Thread::Create(); 127 _workerThread->SetName("worker_thread", _workerThread.get()); 128 result = _workerThread->Start(); 129 RTC_DCHECK(result) << "Failed to start worker thread."; 130 131 _signalingThread = rtc::Thread::Create(); 132 _signalingThread->SetName("signaling_thread", _signalingThread.get()); 133 result = _signalingThread->Start(); 134 RTC_DCHECK(result) << "Failed to start signaling thread."; 135 } 136 return self; 137} 138 139- (instancetype)initWithNoMedia { 140 if (self = [self initNative]) { 141 webrtc::PeerConnectionFactoryDependencies dependencies; 142 dependencies.network_thread = _networkThread.get(); 143 dependencies.worker_thread = _workerThread.get(); 144 dependencies.signaling_thread = _signalingThread.get(); 145 if (webrtc::field_trial::IsEnabled("WebRTC-Network-UseNWPathMonitor")) { 146 dependencies.network_monitor_factory = webrtc::CreateNetworkMonitorFactory(); 147 } 148 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies)); 149 NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!"); 150 } 151 return self; 152} 153 154- (instancetype)initWithNativeAudioEncoderFactory: 155 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory 156 nativeAudioDecoderFactory: 157 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory 158 nativeVideoEncoderFactory: 159 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory 160 nativeVideoDecoderFactory: 161 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory 162 audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule 163 audioProcessingModule: 164 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule { 165 return [self initWithNativeAudioEncoderFactory:audioEncoderFactory 166 nativeAudioDecoderFactory:audioDecoderFactory 167 nativeVideoEncoderFactory:std::move(videoEncoderFactory) 168 nativeVideoDecoderFactory:std::move(videoDecoderFactory) 169 audioDeviceModule:audioDeviceModule 170 audioProcessingModule:audioProcessingModule 171 networkControllerFactory:nullptr]; 172} 173- (instancetype)initWithNativeAudioEncoderFactory: 174 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory 175 nativeAudioDecoderFactory: 176 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory 177 nativeVideoEncoderFactory: 178 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory 179 nativeVideoDecoderFactory: 180 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory 181 audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule 182 audioProcessingModule: 183 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule 184 networkControllerFactory: 185 (std::unique_ptr<webrtc::NetworkControllerFactoryInterface>) 186 networkControllerFactory { 187 if (self = [self initNative]) { 188 webrtc::PeerConnectionFactoryDependencies dependencies; 189 dependencies.network_thread = _networkThread.get(); 190 dependencies.worker_thread = _workerThread.get(); 191 dependencies.signaling_thread = _signalingThread.get(); 192 if (webrtc::field_trial::IsEnabled("WebRTC-Network-UseNWPathMonitor")) { 193 dependencies.network_monitor_factory = webrtc::CreateNetworkMonitorFactory(); 194 } 195 dependencies.trials = std::make_unique<webrtc::FieldTrialBasedConfig>(); 196 dependencies.task_queue_factory = 197 webrtc::CreateDefaultTaskQueueFactory(dependencies.trials.get()); 198 cricket::MediaEngineDependencies media_deps; 199 media_deps.adm = std::move(audioDeviceModule); 200 media_deps.task_queue_factory = dependencies.task_queue_factory.get(); 201 media_deps.audio_encoder_factory = std::move(audioEncoderFactory); 202 media_deps.audio_decoder_factory = std::move(audioDecoderFactory); 203 media_deps.video_encoder_factory = std::move(videoEncoderFactory); 204 media_deps.video_decoder_factory = std::move(videoDecoderFactory); 205 if (audioProcessingModule) { 206 media_deps.audio_processing = std::move(audioProcessingModule); 207 } else { 208 media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create(); 209 } 210 media_deps.trials = dependencies.trials.get(); 211 dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps)); 212 dependencies.call_factory = webrtc::CreateCallFactory(); 213 dependencies.event_log_factory = 214 std::make_unique<webrtc::RtcEventLogFactory>(dependencies.task_queue_factory.get()); 215 dependencies.network_controller_factory = std::move(networkControllerFactory); 216 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies)); 217 NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!"); 218 } 219 return self; 220} 221 222- (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints: 223 (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints { 224 std::unique_ptr<webrtc::MediaConstraints> nativeConstraints; 225 if (constraints) { 226 nativeConstraints = constraints.nativeConstraints; 227 } 228 cricket::AudioOptions options; 229 CopyConstraintsIntoAudioOptions(nativeConstraints.get(), &options); 230 231 rtc::scoped_refptr<webrtc::AudioSourceInterface> source = 232 _nativeFactory->CreateAudioSource(options); 233 return [[RTC_OBJC_TYPE(RTCAudioSource) alloc] initWithFactory:self nativeAudioSource:source]; 234} 235 236- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithTrackId:(NSString *)trackId { 237 RTC_OBJC_TYPE(RTCAudioSource) *audioSource = [self audioSourceWithConstraints:nil]; 238 return [self audioTrackWithSource:audioSource trackId:trackId]; 239} 240 241- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithSource:(RTC_OBJC_TYPE(RTCAudioSource) *)source 242 trackId:(NSString *)trackId { 243 return [[RTC_OBJC_TYPE(RTCAudioTrack) alloc] initWithFactory:self source:source trackId:trackId]; 244} 245 246- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSource { 247 return [[RTC_OBJC_TYPE(RTCVideoSource) alloc] initWithFactory:self 248 signalingThread:_signalingThread.get() 249 workerThread:_workerThread.get()]; 250} 251 252- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSourceForScreenCast:(BOOL)forScreenCast { 253 return [[RTC_OBJC_TYPE(RTCVideoSource) alloc] initWithFactory:self 254 signalingThread:_signalingThread.get() 255 workerThread:_workerThread.get() 256 isScreenCast:forScreenCast]; 257} 258 259- (RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrackWithSource:(RTC_OBJC_TYPE(RTCVideoSource) *)source 260 trackId:(NSString *)trackId { 261 return [[RTC_OBJC_TYPE(RTCVideoTrack) alloc] initWithFactory:self source:source trackId:trackId]; 262} 263 264- (RTC_OBJC_TYPE(RTCMediaStream) *)mediaStreamWithStreamId:(NSString *)streamId { 265 return [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:self streamId:streamId]; 266} 267 268- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) 269 peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration 270 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints 271 delegate: 272 (nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { 273 return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithFactory:self 274 configuration:configuration 275 constraints:constraints 276 certificateVerifier:nil 277 delegate:delegate]; 278} 279 280- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) 281 peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration 282 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints 283 certificateVerifier: 284 (id<RTC_OBJC_TYPE(RTCSSLCertificateVerifier)>)certificateVerifier 285 delegate: 286 (nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { 287 return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithFactory:self 288 configuration:configuration 289 constraints:constraints 290 certificateVerifier:certificateVerifier 291 delegate:delegate]; 292} 293 294- (nullable RTC_OBJC_TYPE(RTCPeerConnection) *) 295 peerConnectionWithDependencies:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration 296 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints 297 dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies 298 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate { 299 return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithDependencies:self 300 configuration:configuration 301 constraints:constraints 302 dependencies:std::move(dependencies) 303 delegate:delegate]; 304} 305 306- (void)setOptions:(nonnull RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions) *)options { 307 RTC_DCHECK(options != nil); 308 _nativeFactory->SetOptions(options.nativeOptions); 309} 310 311- (BOOL)startAecDumpWithFilePath:(NSString *)filePath 312 maxSizeInBytes:(int64_t)maxSizeInBytes { 313 RTC_DCHECK(filePath.length); 314 RTC_DCHECK_GT(maxSizeInBytes, 0); 315 316 if (_hasStartedAecDump) { 317 RTCLogError(@"Aec dump already started."); 318 return NO; 319 } 320 FILE *f = fopen(filePath.UTF8String, "wb"); 321 if (!f) { 322 RTCLogError(@"Error opening file: %@. Error: %s", filePath, strerror(errno)); 323 return NO; 324 } 325 _hasStartedAecDump = _nativeFactory->StartAecDump(f, maxSizeInBytes); 326 return _hasStartedAecDump; 327} 328 329- (void)stopAecDump { 330 _nativeFactory->StopAecDump(); 331 _hasStartedAecDump = NO; 332} 333 334- (rtc::Thread *)signalingThread { 335 return _signalingThread.get(); 336} 337 338- (rtc::Thread *)workerThread { 339 return _workerThread.get(); 340} 341 342@end 343