blob: 4ce38dbd7fd35f1fa9c0d293297c8fa2dea44bbf [file] [log] [blame]
Jon Hjelleda99da82016-01-20 13:40:30 -08001/*
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
Mirko Bonadei317a1f02019-09-17 17:06:18 +020011#include <memory>
12
magjedb8853ca2017-08-29 03:57:22 -070013#import "RTCPeerConnectionFactory+Native.h"
tkchin9eeb6242016-04-27 01:54:20 -070014#import "RTCPeerConnectionFactory+Private.h"
Yura Yaroshevichbf567122018-01-02 13:33:16 +030015#import "RTCPeerConnectionFactoryOptions+Private.h"
Jon Hjelleda99da82016-01-20 13:40:30 -080016
tkchind4bfbfc2016-08-30 11:56:05 -070017#import "RTCAudioSource+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070018#import "RTCAudioTrack+Private.h"
tkchind4bfbfc2016-08-30 11:56:05 -070019#import "RTCMediaConstraints+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070020#import "RTCMediaStream+Private.h"
21#import "RTCPeerConnection+Private.h"
22#import "RTCVideoSource+Private.h"
23#import "RTCVideoTrack+Private.h"
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020024#import "base/RTCLogging.h"
25#import "base/RTCVideoDecoderFactory.h"
26#import "base/RTCVideoEncoderFactory.h"
27#import "helpers/NSString+StdString.h"
kthelgasonfb143122017-07-25 07:55:58 -070028#ifndef HAVE_NO_MEDIA
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020029#import "components/video_codec/RTCVideoDecoderFactoryH264.h"
30#import "components/video_codec/RTCVideoEncoderFactoryH264.h"
magjedb8853ca2017-08-29 03:57:22 -070031// The no-media version PeerConnectionFactory doesn't depend on these files, but the gn check tool
32// is not smart enough to take the #ifdef into account.
Anders Carlsson7e042812017-10-05 16:55:38 +020033#include "api/audio_codecs/builtin_audio_decoder_factory.h" // nogncheck
34#include "api/audio_codecs/builtin_audio_encoder_factory.h" // nogncheck
Danil Chapovalov4ba04b72019-06-26 15:49:47 +020035#include "api/rtc_event_log/rtc_event_log_factory.h"
Danil Chapovalovaaa11432019-05-17 13:20:14 +020036#include "api/task_queue/default_task_queue_factory.h"
Anders Carlsson7e042812017-10-05 16:55:38 +020037#include "modules/audio_device/include/audio_device.h" // nogncheck
38#include "modules/audio_processing/include/audio_processing.h" // nogncheck
Anders Carlsson3ff50fb2018-02-01 15:47:05 +010039
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020040#include "sdk/objc/native/api/video_decoder_factory.h"
41#include "sdk/objc/native/api/video_encoder_factory.h"
42#include "sdk/objc/native/src/objc_video_decoder_factory.h"
43#include "sdk/objc/native/src/objc_video_encoder_factory.h"
kthelgasonfb143122017-07-25 07:55:58 -070044#endif
kwibergbfefb032016-05-01 14:53:46 -070045
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020046#if defined(WEBRTC_IOS)
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020047#import "sdk/objc/native/api/audio_device_module.h"
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020048#endif
49
zhihuanga4c113a2017-06-28 14:05:44 -070050// Adding the nogncheck to disable the including header check.
51// The no-media version PeerConnectionFactory doesn't depend on media related
52// C++ target.
53// TODO(zhihuang): Remove nogncheck once MediaEngineInterface is moved to C++
54// API layer.
Steve Anton10542f22019-01-11 09:11:00 -080055#include "media/engine/webrtc_media_engine.h" // nogncheck
Kári Tristan Helgasoncbe74352016-11-09 10:43:26 +010056
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020057@implementation RTC_OBJC_TYPE (RTCPeerConnectionFactory) {
danilchape9021a32016-05-17 01:52:02 -070058 std::unique_ptr<rtc::Thread> _networkThread;
kwibergbfefb032016-05-01 14:53:46 -070059 std::unique_ptr<rtc::Thread> _workerThread;
danilchape9021a32016-05-17 01:52:02 -070060 std::unique_ptr<rtc::Thread> _signalingThread;
tkchinfce0e2c2016-08-30 12:58:11 -070061 BOOL _hasStartedAecDump;
Jon Hjelleda99da82016-01-20 13:40:30 -080062}
63
64@synthesize nativeFactory = _nativeFactory;
65
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020066- (rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule {
67#if defined(WEBRTC_IOS)
68 return webrtc::CreateAudioDeviceModule();
69#else
70 return nullptr;
71#endif
72}
73
Jon Hjelleda99da82016-01-20 13:40:30 -080074- (instancetype)init {
kthelgasonfb143122017-07-25 07:55:58 -070075#ifdef HAVE_NO_MEDIA
Anders Carlsson7e042812017-10-05 16:55:38 +020076 return [self initWithNoMedia];
Magnus Jedvert8b4e92d2018-04-13 15:36:43 +020077#else
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020078 return [self
79 initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
80 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
81 nativeVideoEncoderFactory:webrtc::ObjCToNativeVideoEncoderFactory([[RTC_OBJC_TYPE(
82 RTCVideoEncoderFactoryH264) alloc] init])
83 nativeVideoDecoderFactory:webrtc::ObjCToNativeVideoDecoderFactory([[RTC_OBJC_TYPE(
84 RTCVideoDecoderFactoryH264) alloc] init])
85 audioDeviceModule:[self audioDeviceModule]
Niels Möller938bc332020-06-10 17:36:17 +020086 audioProcessingModule:nullptr];
kthelgasonfb143122017-07-25 07:55:58 -070087#endif
88}
89
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020090- (instancetype)
91 initWithEncoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoEncoderFactory)>)encoderFactory
Niels Möller938bc332020-06-10 17:36:17 +020092 decoderFactory:(nullable id<RTC_OBJC_TYPE(RTCVideoDecoderFactory)>)decoderFactory {
magjedb8853ca2017-08-29 03:57:22 -070093#ifdef HAVE_NO_MEDIA
Anders Carlsson7e042812017-10-05 16:55:38 +020094 return [self initWithNoMedia];
magjedb8853ca2017-08-29 03:57:22 -070095#else
Anders Carlsson7e042812017-10-05 16:55:38 +020096 std::unique_ptr<webrtc::VideoEncoderFactory> native_encoder_factory;
97 std::unique_ptr<webrtc::VideoDecoderFactory> native_decoder_factory;
98 if (encoderFactory) {
Anders Carlsson3ff50fb2018-02-01 15:47:05 +010099 native_encoder_factory = webrtc::ObjCToNativeVideoEncoderFactory(encoderFactory);
Anders Carlsson7e042812017-10-05 16:55:38 +0200100 }
101 if (decoderFactory) {
Anders Carlsson3ff50fb2018-02-01 15:47:05 +0100102 native_decoder_factory = webrtc::ObjCToNativeVideoDecoderFactory(decoderFactory);
Anders Carlsson7e042812017-10-05 16:55:38 +0200103 }
magjedb8853ca2017-08-29 03:57:22 -0700104 return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
105 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
Anders Carlsson7e042812017-10-05 16:55:38 +0200106 nativeVideoEncoderFactory:std::move(native_encoder_factory)
Sean Rosenbaume5c42652017-10-30 07:50:17 -0700107 nativeVideoDecoderFactory:std::move(native_decoder_factory)
Peter Hanspers8d95e3b2018-05-15 10:22:36 +0200108 audioDeviceModule:[self audioDeviceModule]
Niels Möller938bc332020-06-10 17:36:17 +0200109 audioProcessingModule:nullptr];
magjedb8853ca2017-08-29 03:57:22 -0700110#endif
111}
Anders Carlsson7e042812017-10-05 16:55:38 +0200112- (instancetype)initNative {
kthelgasonfb143122017-07-25 07:55:58 -0700113 if (self = [super init]) {
danilchape9021a32016-05-17 01:52:02 -0700114 _networkThread = rtc::Thread::CreateWithSocketServer();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300115 _networkThread->SetName("network_thread", _networkThread.get());
danilchape9021a32016-05-17 01:52:02 -0700116 BOOL result = _networkThread->Start();
117 NSAssert(result, @"Failed to start network thread.");
118
119 _workerThread = rtc::Thread::Create();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300120 _workerThread->SetName("worker_thread", _workerThread.get());
Jon Hjelleda99da82016-01-20 13:40:30 -0800121 result = _workerThread->Start();
122 NSAssert(result, @"Failed to start worker thread.");
123
danilchape9021a32016-05-17 01:52:02 -0700124 _signalingThread = rtc::Thread::Create();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300125 _signalingThread->SetName("signaling_thread", _signalingThread.get());
danilchape9021a32016-05-17 01:52:02 -0700126 result = _signalingThread->Start();
127 NSAssert(result, @"Failed to start signaling thread.");
Anders Carlsson7e042812017-10-05 16:55:38 +0200128 }
129 return self;
130}
131
132- (instancetype)initWithNoMedia {
133 if (self = [self initNative]) {
Danil Chapovalovaaa11432019-05-17 13:20:14 +0200134 webrtc::PeerConnectionFactoryDependencies dependencies;
135 dependencies.network_thread = _networkThread.get();
136 dependencies.worker_thread = _workerThread.get();
137 dependencies.signaling_thread = _signalingThread.get();
138 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies));
Anders Carlsson7e042812017-10-05 16:55:38 +0200139 NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!");
140 }
141 return self;
142}
143
144- (instancetype)initWithNativeAudioEncoderFactory:
145 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
146 nativeAudioDecoderFactory:
147 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
148 nativeVideoEncoderFactory:
149 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory
150 nativeVideoDecoderFactory:
Sean Rosenbaume5c42652017-10-30 07:50:17 -0700151 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory
Sebastian Jansson77c0a622019-04-23 10:24:03 +0200152 audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule
Sam Zackrisson6124aac2017-11-13 14:56:02 +0100153 audioProcessingModule:
154 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule {
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700155 return [self initWithNativeAudioEncoderFactory:audioEncoderFactory
156 nativeAudioDecoderFactory:audioDecoderFactory
157 nativeVideoEncoderFactory:std::move(videoEncoderFactory)
158 nativeVideoDecoderFactory:std::move(videoDecoderFactory)
159 audioDeviceModule:audioDeviceModule
160 audioProcessingModule:audioProcessingModule
Niels Möller938bc332020-06-10 17:36:17 +0200161 networkControllerFactory:nullptr];
Sebastian Jansson77c0a622019-04-23 10:24:03 +0200162}
163- (instancetype)initWithNativeAudioEncoderFactory:
164 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
165 nativeAudioDecoderFactory:
166 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
167 nativeVideoEncoderFactory:
168 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory
169 nativeVideoDecoderFactory:
170 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory
171 audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule
172 audioProcessingModule:
173 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule
174 networkControllerFactory:
175 (std::unique_ptr<webrtc::NetworkControllerFactoryInterface>)
Niels Möller938bc332020-06-10 17:36:17 +0200176 networkControllerFactory {
Anders Carlsson7e042812017-10-05 16:55:38 +0200177 if (self = [self initNative]) {
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700178 webrtc::PeerConnectionFactoryDependencies dependencies;
179 dependencies.network_thread = _networkThread.get();
180 dependencies.worker_thread = _workerThread.get();
181 dependencies.signaling_thread = _signalingThread.get();
Danil Chapovalovaaa11432019-05-17 13:20:14 +0200182#ifndef HAVE_NO_MEDIA
183 dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
184 cricket::MediaEngineDependencies media_deps;
185 media_deps.adm = std::move(audioDeviceModule);
186 media_deps.task_queue_factory = dependencies.task_queue_factory.get();
187 media_deps.audio_encoder_factory = std::move(audioEncoderFactory);
188 media_deps.audio_decoder_factory = std::move(audioDecoderFactory);
189 media_deps.video_encoder_factory = std::move(videoEncoderFactory);
190 media_deps.video_decoder_factory = std::move(videoDecoderFactory);
191 if (audioProcessingModule) {
192 media_deps.audio_processing = std::move(audioProcessingModule);
193 } else {
194 media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create();
195 }
196 dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps));
197 dependencies.call_factory = webrtc::CreateCallFactory();
198 dependencies.event_log_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200199 std::make_unique<webrtc::RtcEventLogFactory>(dependencies.task_queue_factory.get());
Sebastian Jansson77c0a622019-04-23 10:24:03 +0200200 dependencies.network_controller_factory = std::move(networkControllerFactory);
Danil Chapovalovaaa11432019-05-17 13:20:14 +0200201#endif
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700202 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies));
Anders Carlsson7e042812017-10-05 16:55:38 +0200203 NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!");
204 }
205 return self;
Anders Carlsson7e042812017-10-05 16:55:38 +0200206}
207
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200208- (RTC_OBJC_TYPE(RTCAudioSource) *)audioSourceWithConstraints:
209 (nullable RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints {
tkchind4bfbfc2016-08-30 11:56:05 -0700210 std::unique_ptr<webrtc::MediaConstraints> nativeConstraints;
211 if (constraints) {
212 nativeConstraints = constraints.nativeConstraints;
213 }
Niels Möller2d02e082018-05-21 11:23:35 +0200214 cricket::AudioOptions options;
215 CopyConstraintsIntoAudioOptions(nativeConstraints.get(), &options);
216
tkchind4bfbfc2016-08-30 11:56:05 -0700217 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200218 _nativeFactory->CreateAudioSource(options);
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200219 return [[RTC_OBJC_TYPE(RTCAudioSource) alloc] initWithFactory:self nativeAudioSource:source];
tkchind4bfbfc2016-08-30 11:56:05 -0700220}
221
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200222- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithTrackId:(NSString *)trackId {
223 RTC_OBJC_TYPE(RTCAudioSource) *audioSource = [self audioSourceWithConstraints:nil];
tkchind4bfbfc2016-08-30 11:56:05 -0700224 return [self audioTrackWithSource:audioSource trackId:trackId];
225}
226
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200227- (RTC_OBJC_TYPE(RTCAudioTrack) *)audioTrackWithSource:(RTC_OBJC_TYPE(RTCAudioSource) *)source
228 trackId:(NSString *)trackId {
229 return [[RTC_OBJC_TYPE(RTCAudioTrack) alloc] initWithFactory:self source:source trackId:trackId];
tkchind4bfbfc2016-08-30 11:56:05 -0700230}
231
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200232- (RTC_OBJC_TYPE(RTCVideoSource) *)videoSource {
233 return [[RTC_OBJC_TYPE(RTCVideoSource) alloc] initWithFactory:self
234 signalingThread:_signalingThread.get()
235 workerThread:_workerThread.get()];
magjedabb84b82017-03-28 01:56:41 -0700236}
237
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200238- (RTC_OBJC_TYPE(RTCVideoTrack) *)videoTrackWithSource:(RTC_OBJC_TYPE(RTCVideoSource) *)source
239 trackId:(NSString *)trackId {
240 return [[RTC_OBJC_TYPE(RTCVideoTrack) alloc] initWithFactory:self source:source trackId:trackId];
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700241}
242
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200243- (RTC_OBJC_TYPE(RTCMediaStream) *)mediaStreamWithStreamId:(NSString *)streamId {
244 return [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:self streamId:streamId];
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700245}
246
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200247- (RTC_OBJC_TYPE(RTCPeerConnection) *)
248 peerConnectionWithConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
249 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
250 delegate:
251 (nullable id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
252 return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithFactory:self
253 configuration:configuration
254 constraints:constraints
255 delegate:delegate];
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700256}
257
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200258- (RTC_OBJC_TYPE(RTCPeerConnection) *)
259 peerConnectionWithDependencies:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
260 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Jonas Oreland285f83d2020-02-07 10:30:08 +0100261 dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200262 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
263 return [[RTC_OBJC_TYPE(RTCPeerConnection) alloc] initWithDependencies:self
264 configuration:configuration
265 constraints:constraints
266 dependencies:std::move(dependencies)
267 delegate:delegate];
Jonas Oreland285f83d2020-02-07 10:30:08 +0100268}
269
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200270- (void)setOptions:(nonnull RTC_OBJC_TYPE(RTCPeerConnectionFactoryOptions) *)options {
Yura Yaroshevichbf567122018-01-02 13:33:16 +0300271 RTC_DCHECK(options != nil);
272 _nativeFactory->SetOptions(options.nativeOptions);
273}
274
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000275- (BOOL)startAecDumpWithFilePath:(NSString *)filePath
276 maxSizeInBytes:(int64_t)maxSizeInBytes {
tkchinfce0e2c2016-08-30 12:58:11 -0700277 RTC_DCHECK(filePath.length);
278 RTC_DCHECK_GT(maxSizeInBytes, 0);
279
280 if (_hasStartedAecDump) {
281 RTCLogError(@"Aec dump already started.");
282 return NO;
283 }
Niels Möllere4ac7232019-06-24 09:39:56 +0200284 FILE *f = fopen(filePath.UTF8String, "wb");
285 if (!f) {
286 RTCLogError(@"Error opening file: %@. Error: %s", filePath, strerror(errno));
tkchinfce0e2c2016-08-30 12:58:11 -0700287 return NO;
288 }
Niels Möllere4ac7232019-06-24 09:39:56 +0200289 _hasStartedAecDump = _nativeFactory->StartAecDump(f, maxSizeInBytes);
tkchinfce0e2c2016-08-30 12:58:11 -0700290 return _hasStartedAecDump;
291}
292
293- (void)stopAecDump {
294 _nativeFactory->StopAecDump();
295 _hasStartedAecDump = NO;
296}
297
Jon Hjelleda99da82016-01-20 13:40:30 -0800298@end