blob: bb695b57c0817d515e3063dd650bb585988753aa [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
magjedb8853ca2017-08-29 03:57:22 -070011#import "RTCPeerConnectionFactory+Native.h"
tkchin9eeb6242016-04-27 01:54:20 -070012#import "RTCPeerConnectionFactory+Private.h"
Yura Yaroshevichbf567122018-01-02 13:33:16 +030013#import "RTCPeerConnectionFactoryOptions+Private.h"
Jon Hjelleda99da82016-01-20 13:40:30 -080014
tkchind4bfbfc2016-08-30 11:56:05 -070015#import "RTCAudioSource+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070016#import "RTCAudioTrack+Private.h"
tkchind4bfbfc2016-08-30 11:56:05 -070017#import "RTCMediaConstraints+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070018#import "RTCMediaStream+Private.h"
19#import "RTCPeerConnection+Private.h"
20#import "RTCVideoSource+Private.h"
21#import "RTCVideoTrack+Private.h"
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020022#import "base/RTCLogging.h"
23#import "base/RTCVideoDecoderFactory.h"
24#import "base/RTCVideoEncoderFactory.h"
25#import "helpers/NSString+StdString.h"
kthelgasonfb143122017-07-25 07:55:58 -070026#ifndef HAVE_NO_MEDIA
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020027#import "components/video_codec/RTCVideoDecoderFactoryH264.h"
28#import "components/video_codec/RTCVideoEncoderFactoryH264.h"
magjedb8853ca2017-08-29 03:57:22 -070029// The no-media version PeerConnectionFactory doesn't depend on these files, but the gn check tool
30// is not smart enough to take the #ifdef into account.
Danil Chapovalovaaa11432019-05-17 13:20:14 +020031#include "absl/memory/memory.h"
Anders Carlsson7e042812017-10-05 16:55:38 +020032#include "api/audio_codecs/builtin_audio_decoder_factory.h" // nogncheck
33#include "api/audio_codecs/builtin_audio_encoder_factory.h" // nogncheck
Danil Chapovalov4ba04b72019-06-26 15:49:47 +020034#include "api/rtc_event_log/rtc_event_log_factory.h"
Danil Chapovalovaaa11432019-05-17 13:20:14 +020035#include "api/task_queue/default_task_queue_factory.h"
Anders Carlsson7e042812017-10-05 16:55:38 +020036#include "modules/audio_device/include/audio_device.h" // nogncheck
37#include "modules/audio_processing/include/audio_processing.h" // nogncheck
Anders Carlsson3ff50fb2018-02-01 15:47:05 +010038
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020039#include "sdk/objc/native/api/video_decoder_factory.h"
40#include "sdk/objc/native/api/video_encoder_factory.h"
41#include "sdk/objc/native/src/objc_video_decoder_factory.h"
42#include "sdk/objc/native/src/objc_video_encoder_factory.h"
kthelgasonfb143122017-07-25 07:55:58 -070043#endif
kwibergbfefb032016-05-01 14:53:46 -070044
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020045#if defined(WEBRTC_IOS)
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020046#import "sdk/objc/native/api/audio_device_module.h"
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020047#endif
48
zhihuanga4c113a2017-06-28 14:05:44 -070049// Adding the nogncheck to disable the including header check.
50// The no-media version PeerConnectionFactory doesn't depend on media related
51// C++ target.
52// TODO(zhihuang): Remove nogncheck once MediaEngineInterface is moved to C++
53// API layer.
Karl Wiberg918f50c2018-07-05 11:40:33 +020054#include "absl/memory/memory.h"
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070055#include "api/media_transport_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080056#include "media/engine/webrtc_media_engine.h" // nogncheck
Kári Tristan Helgasoncbe74352016-11-09 10:43:26 +010057
Jon Hjelleda99da82016-01-20 13:40:30 -080058@implementation RTCPeerConnectionFactory {
danilchape9021a32016-05-17 01:52:02 -070059 std::unique_ptr<rtc::Thread> _networkThread;
kwibergbfefb032016-05-01 14:53:46 -070060 std::unique_ptr<rtc::Thread> _workerThread;
danilchape9021a32016-05-17 01:52:02 -070061 std::unique_ptr<rtc::Thread> _signalingThread;
tkchinfce0e2c2016-08-30 12:58:11 -070062 BOOL _hasStartedAecDump;
Jon Hjelleda99da82016-01-20 13:40:30 -080063}
64
65@synthesize nativeFactory = _nativeFactory;
66
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020067- (rtc::scoped_refptr<webrtc::AudioDeviceModule>)audioDeviceModule {
68#if defined(WEBRTC_IOS)
69 return webrtc::CreateAudioDeviceModule();
70#else
71 return nullptr;
72#endif
73}
74
Jon Hjelleda99da82016-01-20 13:40:30 -080075- (instancetype)init {
kthelgasonfb143122017-07-25 07:55:58 -070076#ifdef HAVE_NO_MEDIA
Anders Carlsson7e042812017-10-05 16:55:38 +020077 return [self initWithNoMedia];
Magnus Jedvert8b4e92d2018-04-13 15:36:43 +020078#else
Anders Carlssondd8c1652018-01-30 10:32:13 +010079 return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
80 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
Anders Carlsson3ff50fb2018-02-01 15:47:05 +010081 nativeVideoEncoderFactory:webrtc::ObjCToNativeVideoEncoderFactory(
82 [[RTCVideoEncoderFactoryH264 alloc] init])
83 nativeVideoDecoderFactory:webrtc::ObjCToNativeVideoDecoderFactory(
84 [[RTCVideoDecoderFactoryH264 alloc] init])
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020085 audioDeviceModule:[self audioDeviceModule]
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070086 audioProcessingModule:nullptr
87 mediaTransportFactory:nullptr];
kthelgasonfb143122017-07-25 07:55:58 -070088#endif
89}
90
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +000091- (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070092 decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory
93 mediaTransportFactory:
94 (std::unique_ptr<webrtc::MediaTransportFactory>)mediaTransportFactory {
magjedb8853ca2017-08-29 03:57:22 -070095#ifdef HAVE_NO_MEDIA
Anders Carlsson7e042812017-10-05 16:55:38 +020096 return [self initWithNoMedia];
magjedb8853ca2017-08-29 03:57:22 -070097#else
Anders Carlsson7e042812017-10-05 16:55:38 +020098 std::unique_ptr<webrtc::VideoEncoderFactory> native_encoder_factory;
99 std::unique_ptr<webrtc::VideoDecoderFactory> native_decoder_factory;
100 if (encoderFactory) {
Anders Carlsson3ff50fb2018-02-01 15:47:05 +0100101 native_encoder_factory = webrtc::ObjCToNativeVideoEncoderFactory(encoderFactory);
Anders Carlsson7e042812017-10-05 16:55:38 +0200102 }
103 if (decoderFactory) {
Anders Carlsson3ff50fb2018-02-01 15:47:05 +0100104 native_decoder_factory = webrtc::ObjCToNativeVideoDecoderFactory(decoderFactory);
Anders Carlsson7e042812017-10-05 16:55:38 +0200105 }
magjedb8853ca2017-08-29 03:57:22 -0700106 return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
107 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
Anders Carlsson7e042812017-10-05 16:55:38 +0200108 nativeVideoEncoderFactory:std::move(native_encoder_factory)
Sean Rosenbaume5c42652017-10-30 07:50:17 -0700109 nativeVideoDecoderFactory:std::move(native_decoder_factory)
Peter Hanspers8d95e3b2018-05-15 10:22:36 +0200110 audioDeviceModule:[self audioDeviceModule]
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700111 audioProcessingModule:nullptr
112 mediaTransportFactory:std::move(mediaTransportFactory)];
magjedb8853ca2017-08-29 03:57:22 -0700113#endif
114}
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700115- (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
116 decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory {
117 return [self initWithEncoderFactory:encoderFactory
118 decoderFactory:decoderFactory
119 mediaTransportFactory:nullptr];
120}
magjedb8853ca2017-08-29 03:57:22 -0700121
Anders Carlsson7e042812017-10-05 16:55:38 +0200122- (instancetype)initNative {
kthelgasonfb143122017-07-25 07:55:58 -0700123 if (self = [super init]) {
danilchape9021a32016-05-17 01:52:02 -0700124 _networkThread = rtc::Thread::CreateWithSocketServer();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300125 _networkThread->SetName("network_thread", _networkThread.get());
danilchape9021a32016-05-17 01:52:02 -0700126 BOOL result = _networkThread->Start();
127 NSAssert(result, @"Failed to start network thread.");
128
129 _workerThread = rtc::Thread::Create();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300130 _workerThread->SetName("worker_thread", _workerThread.get());
Jon Hjelleda99da82016-01-20 13:40:30 -0800131 result = _workerThread->Start();
132 NSAssert(result, @"Failed to start worker thread.");
133
danilchape9021a32016-05-17 01:52:02 -0700134 _signalingThread = rtc::Thread::Create();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300135 _signalingThread->SetName("signaling_thread", _signalingThread.get());
danilchape9021a32016-05-17 01:52:02 -0700136 result = _signalingThread->Start();
137 NSAssert(result, @"Failed to start signaling thread.");
Anders Carlsson7e042812017-10-05 16:55:38 +0200138 }
139 return self;
140}
141
142- (instancetype)initWithNoMedia {
143 if (self = [self initNative]) {
Danil Chapovalovaaa11432019-05-17 13:20:14 +0200144 webrtc::PeerConnectionFactoryDependencies dependencies;
145 dependencies.network_thread = _networkThread.get();
146 dependencies.worker_thread = _workerThread.get();
147 dependencies.signaling_thread = _signalingThread.get();
148 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies));
Anders Carlsson7e042812017-10-05 16:55:38 +0200149 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:
Sean Rosenbaume5c42652017-10-30 07:50:17 -0700161 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory
Sebastian Jansson77c0a622019-04-23 10:24:03 +0200162 audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule
Sam Zackrisson6124aac2017-11-13 14:56:02 +0100163 audioProcessingModule:
164 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule {
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700165 return [self initWithNativeAudioEncoderFactory:audioEncoderFactory
166 nativeAudioDecoderFactory:audioDecoderFactory
167 nativeVideoEncoderFactory:std::move(videoEncoderFactory)
168 nativeVideoDecoderFactory:std::move(videoDecoderFactory)
169 audioDeviceModule:audioDeviceModule
170 audioProcessingModule:audioProcessingModule
171 mediaTransportFactory:nullptr];
172}
173
Sebastian Jansson77c0a622019-04-23 10:24:03 +0200174- (instancetype)initWithNativeAudioEncoderFactory:
175 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
176 nativeAudioDecoderFactory:
177 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
178 nativeVideoEncoderFactory:
179 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory
180 nativeVideoDecoderFactory:
181 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory
182 audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule
183 audioProcessingModule:
184 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule
185 mediaTransportFactory:(std::unique_ptr<webrtc::MediaTransportFactory>)
186 mediaTransportFactory {
187 return [self initWithNativeAudioEncoderFactory:audioEncoderFactory
188 nativeAudioDecoderFactory:audioDecoderFactory
189 nativeVideoEncoderFactory:std::move(videoEncoderFactory)
190 nativeVideoDecoderFactory:std::move(videoDecoderFactory)
191 audioDeviceModule:audioDeviceModule
192 audioProcessingModule:audioProcessingModule
193 networkControllerFactory:nullptr
194 mediaTransportFactory:std::move(mediaTransportFactory)];
195}
196- (instancetype)initWithNativeAudioEncoderFactory:
197 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
198 nativeAudioDecoderFactory:
199 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
200 nativeVideoEncoderFactory:
201 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory
202 nativeVideoDecoderFactory:
203 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory
204 audioDeviceModule:(webrtc::AudioDeviceModule *)audioDeviceModule
205 audioProcessingModule:
206 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule
207 networkControllerFactory:
208 (std::unique_ptr<webrtc::NetworkControllerFactoryInterface>)
209 networkControllerFactory
210 mediaTransportFactory:(std::unique_ptr<webrtc::MediaTransportFactory>)
211 mediaTransportFactory {
Anders Carlsson7e042812017-10-05 16:55:38 +0200212 if (self = [self initNative]) {
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700213 webrtc::PeerConnectionFactoryDependencies dependencies;
214 dependencies.network_thread = _networkThread.get();
215 dependencies.worker_thread = _workerThread.get();
216 dependencies.signaling_thread = _signalingThread.get();
Danil Chapovalovaaa11432019-05-17 13:20:14 +0200217#ifndef HAVE_NO_MEDIA
218 dependencies.task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
219 cricket::MediaEngineDependencies media_deps;
220 media_deps.adm = std::move(audioDeviceModule);
221 media_deps.task_queue_factory = dependencies.task_queue_factory.get();
222 media_deps.audio_encoder_factory = std::move(audioEncoderFactory);
223 media_deps.audio_decoder_factory = std::move(audioDecoderFactory);
224 media_deps.video_encoder_factory = std::move(videoEncoderFactory);
225 media_deps.video_decoder_factory = std::move(videoDecoderFactory);
226 if (audioProcessingModule) {
227 media_deps.audio_processing = std::move(audioProcessingModule);
228 } else {
229 media_deps.audio_processing = webrtc::AudioProcessingBuilder().Create();
230 }
231 dependencies.media_engine = cricket::CreateMediaEngine(std::move(media_deps));
232 dependencies.call_factory = webrtc::CreateCallFactory();
233 dependencies.event_log_factory =
234 absl::make_unique<webrtc::RtcEventLogFactory>(dependencies.task_queue_factory.get());
Sebastian Jansson77c0a622019-04-23 10:24:03 +0200235 dependencies.network_controller_factory = std::move(networkControllerFactory);
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700236 dependencies.media_transport_factory = std::move(mediaTransportFactory);
Danil Chapovalovaaa11432019-05-17 13:20:14 +0200237#endif
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700238 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies));
Anders Carlsson7e042812017-10-05 16:55:38 +0200239 NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!");
240 }
241 return self;
Anders Carlsson7e042812017-10-05 16:55:38 +0200242}
243
tkchind4bfbfc2016-08-30 11:56:05 -0700244- (RTCAudioSource *)audioSourceWithConstraints:(nullable RTCMediaConstraints *)constraints {
245 std::unique_ptr<webrtc::MediaConstraints> nativeConstraints;
246 if (constraints) {
247 nativeConstraints = constraints.nativeConstraints;
248 }
Niels Möller2d02e082018-05-21 11:23:35 +0200249 cricket::AudioOptions options;
250 CopyConstraintsIntoAudioOptions(nativeConstraints.get(), &options);
251
tkchind4bfbfc2016-08-30 11:56:05 -0700252 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200253 _nativeFactory->CreateAudioSource(options);
Yura Yaroshevich01cee072018-07-11 15:35:40 +0300254 return [[RTCAudioSource alloc] initWithFactory:self nativeAudioSource:source];
tkchind4bfbfc2016-08-30 11:56:05 -0700255}
256
257- (RTCAudioTrack *)audioTrackWithTrackId:(NSString *)trackId {
258 RTCAudioSource *audioSource = [self audioSourceWithConstraints:nil];
259 return [self audioTrackWithSource:audioSource trackId:trackId];
260}
261
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000262- (RTCAudioTrack *)audioTrackWithSource:(RTCAudioSource *)source
263 trackId:(NSString *)trackId {
264 return [[RTCAudioTrack alloc] initWithFactory:self
265 source:source
266 trackId:trackId];
tkchind4bfbfc2016-08-30 11:56:05 -0700267}
268
magjedabb84b82017-03-28 01:56:41 -0700269- (RTCVideoSource *)videoSource {
Yura Yaroshevich01cee072018-07-11 15:35:40 +0300270 return [[RTCVideoSource alloc] initWithFactory:self
271 signalingThread:_signalingThread.get()
272 workerThread:_workerThread.get()];
magjedabb84b82017-03-28 01:56:41 -0700273}
274
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000275- (RTCVideoTrack *)videoTrackWithSource:(RTCVideoSource *)source
276 trackId:(NSString *)trackId {
277 return [[RTCVideoTrack alloc] initWithFactory:self
278 source:source
279 trackId:trackId];
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700280}
281
282- (RTCMediaStream *)mediaStreamWithStreamId:(NSString *)streamId {
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000283 return [[RTCMediaStream alloc] initWithFactory:self
284 streamId:streamId];
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700285}
286
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000287- (RTCPeerConnection *)peerConnectionWithConfiguration:
288 (RTCConfiguration *)configuration
289 constraints:
290 (RTCMediaConstraints *)constraints
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700291 delegate:
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000292 (nullable id<RTCPeerConnectionDelegate>)delegate {
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700293 return [[RTCPeerConnection alloc] initWithFactory:self
294 configuration:configuration
295 constraints:constraints
296 delegate:delegate];
297}
298
Yura Yaroshevichbf567122018-01-02 13:33:16 +0300299- (void)setOptions:(nonnull RTCPeerConnectionFactoryOptions *)options {
300 RTC_DCHECK(options != nil);
301 _nativeFactory->SetOptions(options.nativeOptions);
302}
303
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000304- (BOOL)startAecDumpWithFilePath:(NSString *)filePath
305 maxSizeInBytes:(int64_t)maxSizeInBytes {
tkchinfce0e2c2016-08-30 12:58:11 -0700306 RTC_DCHECK(filePath.length);
307 RTC_DCHECK_GT(maxSizeInBytes, 0);
308
309 if (_hasStartedAecDump) {
310 RTCLogError(@"Aec dump already started.");
311 return NO;
312 }
Niels Möllere4ac7232019-06-24 09:39:56 +0200313 FILE *f = fopen(filePath.UTF8String, "wb");
314 if (!f) {
315 RTCLogError(@"Error opening file: %@. Error: %s", filePath, strerror(errno));
tkchinfce0e2c2016-08-30 12:58:11 -0700316 return NO;
317 }
Niels Möllere4ac7232019-06-24 09:39:56 +0200318 _hasStartedAecDump = _nativeFactory->StartAecDump(f, maxSizeInBytes);
tkchinfce0e2c2016-08-30 12:58:11 -0700319 return _hasStartedAecDump;
320}
321
322- (void)stopAecDump {
323 _nativeFactory->StopAecDump();
324 _hasStartedAecDump = NO;
325}
326
Jon Hjelleda99da82016-01-20 13:40:30 -0800327@end