blob: dfe035af773aa1ea7a3f601ea50e8938eb3815d3 [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.
Anders Carlsson7e042812017-10-05 16:55:38 +020031#include "api/audio_codecs/builtin_audio_decoder_factory.h" // nogncheck
32#include "api/audio_codecs/builtin_audio_encoder_factory.h" // nogncheck
Jiawei Oube142172018-10-10 01:16:20 -070033#include "api/video/builtin_video_bitrate_allocator_factory.h" // nogncheck
Anders Carlsson565e3e02018-01-19 11:36:48 +010034#include "media/engine/convert_legacy_video_factory.h" // nogncheck
Anders Carlsson7e042812017-10-05 16:55:38 +020035#include "modules/audio_device/include/audio_device.h" // nogncheck
36#include "modules/audio_processing/include/audio_processing.h" // nogncheck
Anders Carlsson3ff50fb2018-02-01 15:47:05 +010037
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020038#include "sdk/objc/native/api/video_decoder_factory.h"
39#include "sdk/objc/native/api/video_encoder_factory.h"
40#include "sdk/objc/native/src/objc_video_decoder_factory.h"
41#include "sdk/objc/native/src/objc_video_encoder_factory.h"
kthelgasonfb143122017-07-25 07:55:58 -070042#endif
kwibergbfefb032016-05-01 14:53:46 -070043
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020044#if defined(WEBRTC_IOS)
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020045#import "sdk/objc/native/api/audio_device_module.h"
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020046#endif
47
zhihuanga4c113a2017-06-28 14:05:44 -070048// Adding the nogncheck to disable the including header check.
49// The no-media version PeerConnectionFactory doesn't depend on media related
50// C++ target.
51// TODO(zhihuang): Remove nogncheck once MediaEngineInterface is moved to C++
52// API layer.
Karl Wiberg918f50c2018-07-05 11:40:33 +020053#include "absl/memory/memory.h"
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070054#include "api/media_transport_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "media/engine/webrtcmediaengine.h" // nogncheck
Kári Tristan Helgasoncbe74352016-11-09 10:43:26 +010056
Jon Hjelleda99da82016-01-20 13:40:30 -080057@implementation 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
Anders Carlssondd8c1652018-01-30 10:32:13 +010078 return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
79 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
Anders Carlsson3ff50fb2018-02-01 15:47:05 +010080 nativeVideoEncoderFactory:webrtc::ObjCToNativeVideoEncoderFactory(
81 [[RTCVideoEncoderFactoryH264 alloc] init])
82 nativeVideoDecoderFactory:webrtc::ObjCToNativeVideoDecoderFactory(
83 [[RTCVideoDecoderFactoryH264 alloc] init])
Peter Hanspers8d95e3b2018-05-15 10:22:36 +020084 audioDeviceModule:[self audioDeviceModule]
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070085 audioProcessingModule:nullptr
86 mediaTransportFactory:nullptr];
kthelgasonfb143122017-07-25 07:55:58 -070087#endif
88}
89
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +000090- (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -070091 decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory
92 mediaTransportFactory:
93 (std::unique_ptr<webrtc::MediaTransportFactory>)mediaTransportFactory {
magjedb8853ca2017-08-29 03:57:22 -070094#ifdef HAVE_NO_MEDIA
Anders Carlsson7e042812017-10-05 16:55:38 +020095 return [self initWithNoMedia];
magjedb8853ca2017-08-29 03:57:22 -070096#else
Anders Carlsson7e042812017-10-05 16:55:38 +020097 std::unique_ptr<webrtc::VideoEncoderFactory> native_encoder_factory;
98 std::unique_ptr<webrtc::VideoDecoderFactory> native_decoder_factory;
99 if (encoderFactory) {
Anders Carlsson3ff50fb2018-02-01 15:47:05 +0100100 native_encoder_factory = webrtc::ObjCToNativeVideoEncoderFactory(encoderFactory);
Anders Carlsson7e042812017-10-05 16:55:38 +0200101 }
102 if (decoderFactory) {
Anders Carlsson3ff50fb2018-02-01 15:47:05 +0100103 native_decoder_factory = webrtc::ObjCToNativeVideoDecoderFactory(decoderFactory);
Anders Carlsson7e042812017-10-05 16:55:38 +0200104 }
magjedb8853ca2017-08-29 03:57:22 -0700105 return [self initWithNativeAudioEncoderFactory:webrtc::CreateBuiltinAudioEncoderFactory()
106 nativeAudioDecoderFactory:webrtc::CreateBuiltinAudioDecoderFactory()
Anders Carlsson7e042812017-10-05 16:55:38 +0200107 nativeVideoEncoderFactory:std::move(native_encoder_factory)
Sean Rosenbaume5c42652017-10-30 07:50:17 -0700108 nativeVideoDecoderFactory:std::move(native_decoder_factory)
Peter Hanspers8d95e3b2018-05-15 10:22:36 +0200109 audioDeviceModule:[self audioDeviceModule]
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700110 audioProcessingModule:nullptr
111 mediaTransportFactory:std::move(mediaTransportFactory)];
magjedb8853ca2017-08-29 03:57:22 -0700112#endif
113}
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700114- (instancetype)initWithEncoderFactory:(nullable id<RTCVideoEncoderFactory>)encoderFactory
115 decoderFactory:(nullable id<RTCVideoDecoderFactory>)decoderFactory {
116 return [self initWithEncoderFactory:encoderFactory
117 decoderFactory:decoderFactory
118 mediaTransportFactory:nullptr];
119}
magjedb8853ca2017-08-29 03:57:22 -0700120
Anders Carlsson7e042812017-10-05 16:55:38 +0200121- (instancetype)initNative {
kthelgasonfb143122017-07-25 07:55:58 -0700122 if (self = [super init]) {
danilchape9021a32016-05-17 01:52:02 -0700123 _networkThread = rtc::Thread::CreateWithSocketServer();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300124 _networkThread->SetName("network_thread", _networkThread.get());
danilchape9021a32016-05-17 01:52:02 -0700125 BOOL result = _networkThread->Start();
126 NSAssert(result, @"Failed to start network thread.");
127
128 _workerThread = rtc::Thread::Create();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300129 _workerThread->SetName("worker_thread", _workerThread.get());
Jon Hjelleda99da82016-01-20 13:40:30 -0800130 result = _workerThread->Start();
131 NSAssert(result, @"Failed to start worker thread.");
132
danilchape9021a32016-05-17 01:52:02 -0700133 _signalingThread = rtc::Thread::Create();
Yura Yaroshevichcef06502018-05-01 00:58:43 +0300134 _signalingThread->SetName("signaling_thread", _signalingThread.get());
danilchape9021a32016-05-17 01:52:02 -0700135 result = _signalingThread->Start();
136 NSAssert(result, @"Failed to start signaling thread.");
Anders Carlsson7e042812017-10-05 16:55:38 +0200137 }
138 return self;
139}
140
141- (instancetype)initWithNoMedia {
142 if (self = [self initNative]) {
zhihuanga4c113a2017-06-28 14:05:44 -0700143 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(
144 _networkThread.get(),
145 _workerThread.get(),
146 _signalingThread.get(),
zhihuanga4c113a2017-06-28 14:05:44 -0700147 std::unique_ptr<cricket::MediaEngineInterface>(),
148 std::unique_ptr<webrtc::CallFactoryInterface>(),
149 std::unique_ptr<webrtc::RtcEventLogFactoryInterface>());
Anders Carlsson7e042812017-10-05 16:55:38 +0200150 NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!");
151 }
152 return self;
153}
154
155- (instancetype)initWithNativeAudioEncoderFactory:
156 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
157 nativeAudioDecoderFactory:
158 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
159 nativeVideoEncoderFactory:
160 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory
161 nativeVideoDecoderFactory:
Sean Rosenbaume5c42652017-10-30 07:50:17 -0700162 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory
163 audioDeviceModule:
Sam Zackrisson6124aac2017-11-13 14:56:02 +0100164 (nullable webrtc::AudioDeviceModule *)audioDeviceModule
165 audioProcessingModule:
166 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule {
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700167 return [self initWithNativeAudioEncoderFactory:audioEncoderFactory
168 nativeAudioDecoderFactory:audioDecoderFactory
169 nativeVideoEncoderFactory:std::move(videoEncoderFactory)
170 nativeVideoDecoderFactory:std::move(videoDecoderFactory)
171 audioDeviceModule:audioDeviceModule
172 audioProcessingModule:audioProcessingModule
173 mediaTransportFactory:nullptr];
174}
175
176- (instancetype)
177 initWithNativeAudioEncoderFactory:
178 (rtc::scoped_refptr<webrtc::AudioEncoderFactory>)audioEncoderFactory
179 nativeAudioDecoderFactory:
180 (rtc::scoped_refptr<webrtc::AudioDecoderFactory>)audioDecoderFactory
181 nativeVideoEncoderFactory:
182 (std::unique_ptr<webrtc::VideoEncoderFactory>)videoEncoderFactory
183 nativeVideoDecoderFactory:
184 (std::unique_ptr<webrtc::VideoDecoderFactory>)videoDecoderFactory
185 audioDeviceModule:(nullable webrtc::AudioDeviceModule *)audioDeviceModule
186 audioProcessingModule:
187 (rtc::scoped_refptr<webrtc::AudioProcessing>)audioProcessingModule
188 mediaTransportFactory:
189 (std::unique_ptr<webrtc::MediaTransportFactory>)mediaTransportFactory {
Anders Carlsson7e042812017-10-05 16:55:38 +0200190#ifdef HAVE_NO_MEDIA
191 return [self initWithNoMedia];
zhihuanga4c113a2017-06-28 14:05:44 -0700192#else
Anders Carlsson7e042812017-10-05 16:55:38 +0200193 if (self = [self initNative]) {
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700194 if (!audioProcessingModule) audioProcessingModule = webrtc::AudioProcessingBuilder().Create();
195
196 std::unique_ptr<cricket::MediaEngineInterface> media_engine =
Jiawei Oube142172018-10-10 01:16:20 -0700197 cricket::WebRtcMediaEngineFactory::Create(
198 audioDeviceModule,
199 audioEncoderFactory,
200 audioDecoderFactory,
201 std::move(videoEncoderFactory),
202 std::move(videoDecoderFactory),
203 webrtc::CreateBuiltinVideoBitrateAllocatorFactory(),
204 nullptr, // audio mixer
205 audioProcessingModule);
Piotr (Peter) Slatalae0c2e972018-10-08 09:43:21 -0700206
207 std::unique_ptr<webrtc::CallFactoryInterface> call_factory = webrtc::CreateCallFactory();
208
209 std::unique_ptr<webrtc::RtcEventLogFactoryInterface> event_log_factory =
210 webrtc::CreateRtcEventLogFactory();
211 webrtc::PeerConnectionFactoryDependencies dependencies;
212 dependencies.network_thread = _networkThread.get();
213 dependencies.worker_thread = _workerThread.get();
214 dependencies.signaling_thread = _signalingThread.get();
215 dependencies.media_engine = std::move(media_engine);
216 dependencies.call_factory = std::move(call_factory);
217 dependencies.event_log_factory = std::move(event_log_factory);
218 dependencies.media_transport_factory = std::move(mediaTransportFactory);
219 _nativeFactory = webrtc::CreateModularPeerConnectionFactory(std::move(dependencies));
Anders Carlsson7e042812017-10-05 16:55:38 +0200220 NSAssert(_nativeFactory, @"Failed to initialize PeerConnectionFactory!");
221 }
222 return self;
223#endif
224}
225
tkchind4bfbfc2016-08-30 11:56:05 -0700226- (RTCAudioSource *)audioSourceWithConstraints:(nullable RTCMediaConstraints *)constraints {
227 std::unique_ptr<webrtc::MediaConstraints> nativeConstraints;
228 if (constraints) {
229 nativeConstraints = constraints.nativeConstraints;
230 }
Niels Möller2d02e082018-05-21 11:23:35 +0200231 cricket::AudioOptions options;
232 CopyConstraintsIntoAudioOptions(nativeConstraints.get(), &options);
233
tkchind4bfbfc2016-08-30 11:56:05 -0700234 rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
Niels Möller2d02e082018-05-21 11:23:35 +0200235 _nativeFactory->CreateAudioSource(options);
Yura Yaroshevich01cee072018-07-11 15:35:40 +0300236 return [[RTCAudioSource alloc] initWithFactory:self nativeAudioSource:source];
tkchind4bfbfc2016-08-30 11:56:05 -0700237}
238
239- (RTCAudioTrack *)audioTrackWithTrackId:(NSString *)trackId {
240 RTCAudioSource *audioSource = [self audioSourceWithConstraints:nil];
241 return [self audioTrackWithSource:audioSource trackId:trackId];
242}
243
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000244- (RTCAudioTrack *)audioTrackWithSource:(RTCAudioSource *)source
245 trackId:(NSString *)trackId {
246 return [[RTCAudioTrack alloc] initWithFactory:self
247 source:source
248 trackId:trackId];
tkchind4bfbfc2016-08-30 11:56:05 -0700249}
250
magjedabb84b82017-03-28 01:56:41 -0700251- (RTCVideoSource *)videoSource {
Yura Yaroshevich01cee072018-07-11 15:35:40 +0300252 return [[RTCVideoSource alloc] initWithFactory:self
253 signalingThread:_signalingThread.get()
254 workerThread:_workerThread.get()];
magjedabb84b82017-03-28 01:56:41 -0700255}
256
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000257- (RTCVideoTrack *)videoTrackWithSource:(RTCVideoSource *)source
258 trackId:(NSString *)trackId {
259 return [[RTCVideoTrack alloc] initWithFactory:self
260 source:source
261 trackId:trackId];
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700262}
263
264- (RTCMediaStream *)mediaStreamWithStreamId:(NSString *)streamId {
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000265 return [[RTCMediaStream alloc] initWithFactory:self
266 streamId:streamId];
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700267}
268
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000269- (RTCPeerConnection *)peerConnectionWithConfiguration:
270 (RTCConfiguration *)configuration
271 constraints:
272 (RTCMediaConstraints *)constraints
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700273 delegate:
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000274 (nullable id<RTCPeerConnectionDelegate>)delegate {
Tze Kwang Chinf3cb49f2016-03-22 10:57:40 -0700275 return [[RTCPeerConnection alloc] initWithFactory:self
276 configuration:configuration
277 constraints:constraints
278 delegate:delegate];
279}
280
Yura Yaroshevichbf567122018-01-02 13:33:16 +0300281- (void)setOptions:(nonnull RTCPeerConnectionFactoryOptions *)options {
282 RTC_DCHECK(options != nil);
283 _nativeFactory->SetOptions(options.nativeOptions);
284}
285
Magnus Jedvertf83dc8b2017-08-29 09:49:43 +0000286- (BOOL)startAecDumpWithFilePath:(NSString *)filePath
287 maxSizeInBytes:(int64_t)maxSizeInBytes {
tkchinfce0e2c2016-08-30 12:58:11 -0700288 RTC_DCHECK(filePath.length);
289 RTC_DCHECK_GT(maxSizeInBytes, 0);
290
291 if (_hasStartedAecDump) {
292 RTCLogError(@"Aec dump already started.");
293 return NO;
294 }
295 int fd = open(filePath.UTF8String, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
296 if (fd < 0) {
297 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
298 return NO;
299 }
300 _hasStartedAecDump = _nativeFactory->StartAecDump(fd, maxSizeInBytes);
301 return _hasStartedAecDump;
302}
303
304- (void)stopAecDump {
305 _nativeFactory->StopAecDump();
306 _hasStartedAecDump = NO;
307}
308
Jon Hjelleda99da82016-01-20 13:40:30 -0800309@end