blob: d01f5428265a8088e710462f73247abc7adb7173 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:361/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:133 * Copyright 2004--2011 Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:364 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "talk/app/webrtc/peerconnectionfactory.h"
29
30#include "talk/app/webrtc/audiotrack.h"
31#include "talk/app/webrtc/localaudiosource.h"
deadbeefab9b2d12015-10-14 18:33:1132#include "talk/app/webrtc/mediastream.h"
henrike@webrtc.org28e20752013-07-10 00:45:3633#include "talk/app/webrtc/mediastreamproxy.h"
34#include "talk/app/webrtc/mediastreamtrackproxy.h"
35#include "talk/app/webrtc/peerconnection.h"
perkj@webrtc.org81134d02015-01-12 08:30:1636#include "talk/app/webrtc/peerconnectionfactoryproxy.h"
henrike@webrtc.org28e20752013-07-10 00:45:3637#include "talk/app/webrtc/peerconnectionproxy.h"
38#include "talk/app/webrtc/portallocatorfactory.h"
wu@webrtc.org967bfff2013-09-19 05:49:5039#include "talk/app/webrtc/videosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:3640#include "talk/app/webrtc/videosourceproxy.h"
41#include "talk/app/webrtc/videotrack.h"
henrike@webrtc.org28e20752013-07-10 00:45:3642#include "talk/media/webrtc/webrtcmediaengine.h"
43#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
44#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
jiayl@webrtc.org3987b6d2014-09-24 17:14:0545#include "webrtc/base/bind.h"
henrike@webrtc.org28e20752013-07-10 00:45:3646#include "webrtc/modules/audio_device/include/audio_device.h"
deadbeef41b07982015-12-01 23:01:2447#include "webrtc/p2p/base/basicpacketsocketfactory.h"
48#include "webrtc/p2p/client/basicportallocator.h"
henrike@webrtc.org28e20752013-07-10 00:45:3649
henrike@webrtc.org28e20752013-07-10 00:45:3650namespace webrtc {
51
Henrik Boström5e56c592015-08-11 08:33:1352namespace {
53
54// Passes down the calls to |store_|. See usage in CreatePeerConnection.
55class DtlsIdentityStoreWrapper : public DtlsIdentityStoreInterface {
56 public:
57 DtlsIdentityStoreWrapper(
58 const rtc::scoped_refptr<RefCountedDtlsIdentityStore>& store)
59 : store_(store) {
henrikg91d6ede2015-09-17 07:24:3460 RTC_DCHECK(store_);
Henrik Boström5e56c592015-08-11 08:33:1361 }
62
63 void RequestIdentity(
64 rtc::KeyType key_type,
65 const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>&
66 observer) override {
67 store_->RequestIdentity(key_type, observer);
68 }
69
70 private:
71 rtc::scoped_refptr<RefCountedDtlsIdentityStore> store_;
72};
73
74} // anonymous namespace
75
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5276rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:3677CreatePeerConnectionFactory() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5278 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
79 new rtc::RefCountedObject<PeerConnectionFactory>());
henrike@webrtc.org28e20752013-07-10 00:45:3680
perkj@webrtc.org81134d02015-01-12 08:30:1681
82 // Call Initialize synchronously but make sure its executed on
83 // |signaling_thread|.
84 MethodCall0<PeerConnectionFactory, bool> call(
85 pc_factory.get(),
86 &PeerConnectionFactory::Initialize);
87 bool result = call.Marshal(pc_factory->signaling_thread());
88
89 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:3690 return NULL;
91 }
perkj@webrtc.org81134d02015-01-12 08:30:1692 return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(),
93 pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:3694}
95
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5296rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:3697CreatePeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:5298 rtc::Thread* worker_thread,
99 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36100 AudioDeviceModule* default_adm,
101 cricket::WebRtcVideoEncoderFactory* encoder_factory,
102 cricket::WebRtcVideoDecoderFactory* decoder_factory) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52103 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
104 new rtc::RefCountedObject<PeerConnectionFactory>(worker_thread,
perkj@webrtc.org81134d02015-01-12 08:30:16105 signaling_thread,
106 default_adm,
107 encoder_factory,
108 decoder_factory));
109
110 // Call Initialize synchronously but make sure its executed on
111 // |signaling_thread|.
112 MethodCall0<PeerConnectionFactory, bool> call(
113 pc_factory.get(),
114 &PeerConnectionFactory::Initialize);
115 bool result = call.Marshal(signaling_thread);
116
117 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36118 return NULL;
119 }
perkj@webrtc.org81134d02015-01-12 08:30:16120 return PeerConnectionFactoryProxy::Create(signaling_thread, pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36121}
122
123PeerConnectionFactory::PeerConnectionFactory()
124 : owns_ptrs_(true),
perkj@webrtc.org81134d02015-01-12 08:30:16125 wraps_current_thread_(false),
126 signaling_thread_(rtc::ThreadManager::Instance()->CurrentThread()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52127 worker_thread_(new rtc::Thread) {
perkj@webrtc.org81134d02015-01-12 08:30:16128 if (!signaling_thread_) {
129 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
130 wraps_current_thread_ = true;
131 }
132 worker_thread_->Start();
henrike@webrtc.org28e20752013-07-10 00:45:36133}
134
135PeerConnectionFactory::PeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52136 rtc::Thread* worker_thread,
137 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36138 AudioDeviceModule* default_adm,
139 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
140 cricket::WebRtcVideoDecoderFactory* video_decoder_factory)
141 : owns_ptrs_(false),
perkj@webrtc.org81134d02015-01-12 08:30:16142 wraps_current_thread_(false),
henrike@webrtc.org28e20752013-07-10 00:45:36143 signaling_thread_(signaling_thread),
144 worker_thread_(worker_thread),
145 default_adm_(default_adm),
146 video_encoder_factory_(video_encoder_factory),
147 video_decoder_factory_(video_decoder_factory) {
148 ASSERT(worker_thread != NULL);
149 ASSERT(signaling_thread != NULL);
150 // TODO: Currently there is no way creating an external adm in
151 // libjingle source tree. So we can 't currently assert if this is NULL.
152 // ASSERT(default_adm != NULL);
153}
154
155PeerConnectionFactory::~PeerConnectionFactory() {
henrikg91d6ede2015-09-17 07:24:34156 RTC_DCHECK(signaling_thread_->IsCurrent());
Henrik Boström5e56c592015-08-11 08:33:13157 channel_manager_.reset(nullptr);
158 default_allocator_factory_ = nullptr;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12159
160 // Make sure |worker_thread_| and |signaling_thread_| outlive
deadbeef41b07982015-12-01 23:01:24161 // |dtls_identity_store_|, |default_socket_factory_| and
162 // |default_network_manager_|.
Henrik Boström5e56c592015-08-11 08:33:13163 dtls_identity_store_ = nullptr;
deadbeef41b07982015-12-01 23:01:24164 default_socket_factory_ = nullptr;
165 default_network_manager_ = nullptr;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12166
henrike@webrtc.org28e20752013-07-10 00:45:36167 if (owns_ptrs_) {
perkj@webrtc.org81134d02015-01-12 08:30:16168 if (wraps_current_thread_)
169 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
fischman@webrtc.org29540b12014-04-17 22:54:30170 delete worker_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36171 }
172}
173
174bool PeerConnectionFactory::Initialize() {
henrikg91d6ede2015-09-17 07:24:34175 RTC_DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52176 rtc::InitRandom(rtc::Time());
henrike@webrtc.org28e20752013-07-10 00:45:36177
phoglund@webrtc.org006521d2015-02-12 09:23:59178 default_allocator_factory_ = PortAllocatorFactory::Create(worker_thread_);
deadbeef41b07982015-12-01 23:01:24179 if (!default_allocator_factory_) {
henrike@webrtc.org28e20752013-07-10 00:45:36180 return false;
deadbeef41b07982015-12-01 23:01:24181 }
182
183 default_network_manager_.reset(new rtc::BasicNetworkManager());
184 if (!default_network_manager_) {
185 return false;
186 }
187
188 default_socket_factory_.reset(
189 new rtc::BasicPacketSocketFactory(worker_thread_));
190 if (!default_socket_factory_) {
191 return false;
192 }
henrike@webrtc.org28e20752013-07-10 00:45:36193
henrike@webrtc.org28e20752013-07-10 00:45:36194 // TODO: Need to make sure only one VoE is created inside
195 // WebRtcMediaEngine.
henrika@webrtc.org62f6e752015-02-11 08:38:35196 cricket::MediaEngineInterface* media_engine =
197 worker_thread_->Invoke<cricket::MediaEngineInterface*>(rtc::Bind(
198 &PeerConnectionFactory::CreateMediaEngine_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36199
solenbergfacbbec2015-09-24 07:41:50200 channel_manager_.reset(
201 new cricket::ChannelManager(media_engine, worker_thread_));
henrika@webrtc.org62f6e752015-02-11 08:38:35202
stefan@webrtc.org85d27942014-06-09 12:51:39203 channel_manager_->SetVideoRtxEnabled(true);
henrike@webrtc.org28e20752013-07-10 00:45:36204 if (!channel_manager_->Init()) {
205 return false;
206 }
jiayl@webrtc.org61e00b02015-03-04 22:17:38207
Henrik Boström5e56c592015-08-11 08:33:13208 dtls_identity_store_ = new RefCountedDtlsIdentityStore(
209 signaling_thread_, worker_thread_);
jiayl@webrtc.org61e00b02015-03-04 22:17:38210
henrike@webrtc.org28e20752013-07-10 00:45:36211 return true;
212}
213
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52214rtc::scoped_refptr<AudioSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16215PeerConnectionFactory::CreateAudioSource(
henrike@webrtc.org28e20752013-07-10 00:45:36216 const MediaConstraintsInterface* constraints) {
henrikg91d6ede2015-09-17 07:24:34217 RTC_DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52218 rtc::scoped_refptr<LocalAudioSource> source(
wu@webrtc.org97077a32013-10-25 21:18:33219 LocalAudioSource::Create(options_, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36220 return source;
221}
222
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52223rtc::scoped_refptr<VideoSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16224PeerConnectionFactory::CreateVideoSource(
henrike@webrtc.org28e20752013-07-10 00:45:36225 cricket::VideoCapturer* capturer,
226 const MediaConstraintsInterface* constraints) {
henrikg91d6ede2015-09-17 07:24:34227 RTC_DCHECK(signaling_thread_->IsCurrent());
tommi6eca7e32015-12-15 12:27:11228 rtc::scoped_refptr<VideoSource> source(VideoSource::Create(
229 channel_manager_.get(), capturer, constraints, false));
henrike@webrtc.org28e20752013-07-10 00:45:36230 return VideoSourceProxy::Create(signaling_thread_, source);
231}
232
perkj@webrtc.org81134d02015-01-12 08:30:16233bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file) {
henrikg91d6ede2015-09-17 07:24:34234 RTC_DCHECK(signaling_thread_->IsCurrent());
wu@webrtc.orga9890802013-12-13 00:21:03235 return channel_manager_->StartAecDump(file);
236}
237
ivoc797ef122015-10-22 10:25:41238void PeerConnectionFactory::StopAecDump() {
239 RTC_DCHECK(signaling_thread_->IsCurrent());
240 channel_manager_->StopAecDump();
241}
242
ivoc112a3d82015-10-16 09:22:18243bool PeerConnectionFactory::StartRtcEventLog(rtc::PlatformFile file) {
244 RTC_DCHECK(signaling_thread_->IsCurrent());
245 return channel_manager_->StartRtcEventLog(file);
246}
247
248void PeerConnectionFactory::StopRtcEventLog() {
249 RTC_DCHECK(signaling_thread_->IsCurrent());
250 channel_manager_->StopRtcEventLog();
251}
252
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52253rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36254PeerConnectionFactory::CreatePeerConnection(
buildbot@webrtc.org41451d42014-05-03 05:39:45255 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36256 const MediaConstraintsInterface* constraints,
257 PortAllocatorFactoryInterface* allocator_factory,
Henrik Boström5e56c592015-08-11 08:33:13258 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
henrike@webrtc.org28e20752013-07-10 00:45:36259 PeerConnectionObserver* observer) {
henrikg91d6ede2015-09-17 07:24:34260 RTC_DCHECK(signaling_thread_->IsCurrent());
261 RTC_DCHECK(allocator_factory || default_allocator_factory_);
phoglund@webrtc.org006521d2015-02-12 09:23:59262
Henrik Boström5e56c592015-08-11 08:33:13263 if (!dtls_identity_store.get()) {
264 // Because |pc|->Initialize takes ownership of the store we need a new
265 // wrapper object that can be deleted without deleting the underlying
266 // |dtls_identity_store_|, protecting it from being deleted multiple times.
267 dtls_identity_store.reset(
268 new DtlsIdentityStoreWrapper(dtls_identity_store_));
jiayl@webrtc.org61e00b02015-03-04 22:17:38269 }
270
phoglund@webrtc.org006521d2015-02-12 09:23:59271 PortAllocatorFactoryInterface* chosen_allocator_factory =
272 allocator_factory ? allocator_factory : default_allocator_factory_.get();
273 chosen_allocator_factory->SetNetworkIgnoreMask(options_.network_ignore_mask);
274
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52275 rtc::scoped_refptr<PeerConnection> pc(
276 new rtc::RefCountedObject<PeerConnection>(this));
henrike@webrtc.org28e20752013-07-10 00:45:36277 if (!pc->Initialize(
278 configuration,
279 constraints,
phoglund@webrtc.org006521d2015-02-12 09:23:59280 chosen_allocator_factory,
Henrik Boström5e56c592015-08-11 08:33:13281 dtls_identity_store.Pass(),
henrike@webrtc.org28e20752013-07-10 00:45:36282 observer)) {
283 return NULL;
284 }
285 return PeerConnectionProxy::Create(signaling_thread(), pc);
286}
287
deadbeef41b07982015-12-01 23:01:24288rtc::scoped_refptr<PeerConnectionInterface>
289PeerConnectionFactory::CreatePeerConnection(
290 const PeerConnectionInterface::RTCConfiguration& configuration,
291 const MediaConstraintsInterface* constraints,
292 rtc::scoped_ptr<cricket::PortAllocator> allocator,
293 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
294 PeerConnectionObserver* observer) {
295 RTC_DCHECK(signaling_thread_->IsCurrent());
296
297 if (!dtls_identity_store.get()) {
298 // Because |pc|->Initialize takes ownership of the store we need a new
299 // wrapper object that can be deleted without deleting the underlying
300 // |dtls_identity_store_|, protecting it from being deleted multiple times.
301 dtls_identity_store.reset(
302 new DtlsIdentityStoreWrapper(dtls_identity_store_));
303 }
304
305 if (!allocator) {
306 allocator.reset(new cricket::BasicPortAllocator(
307 default_network_manager_.get(), default_socket_factory_.get()));
308 }
309 default_network_manager_->set_network_ignore_mask(
310 options_.network_ignore_mask);
311
312 rtc::scoped_refptr<PeerConnection> pc(
313 new rtc::RefCountedObject<PeerConnection>(this));
314 if (!pc->Initialize(configuration, constraints, std::move(allocator),
315 std::move(dtls_identity_store), observer)) {
316 return nullptr;
317 }
318 return PeerConnectionProxy::Create(signaling_thread(), pc);
319}
320
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52321rtc::scoped_refptr<MediaStreamInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36322PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
henrikg91d6ede2015-09-17 07:24:34323 RTC_DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36324 return MediaStreamProxy::Create(signaling_thread_,
325 MediaStream::Create(label));
326}
327
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52328rtc::scoped_refptr<VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36329PeerConnectionFactory::CreateVideoTrack(
330 const std::string& id,
331 VideoSourceInterface* source) {
henrikg91d6ede2015-09-17 07:24:34332 RTC_DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52333 rtc::scoped_refptr<VideoTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36334 VideoTrack::Create(id, source));
335 return VideoTrackProxy::Create(signaling_thread_, track);
336}
337
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52338rtc::scoped_refptr<AudioTrackInterface>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01339PeerConnectionFactory::CreateAudioTrack(const std::string& id,
340 AudioSourceInterface* source) {
henrikg91d6ede2015-09-17 07:24:34341 RTC_DCHECK(signaling_thread_->IsCurrent());
tommi6eca7e32015-12-15 12:27:11342 rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source));
henrike@webrtc.org28e20752013-07-10 00:45:36343 return AudioTrackProxy::Create(signaling_thread_, track);
344}
345
stefanc1aeaf02015-10-15 14:26:07346webrtc::MediaControllerInterface* PeerConnectionFactory::CreateMediaController()
347 const {
henrikg91d6ede2015-09-17 07:24:34348 RTC_DCHECK(signaling_thread_->IsCurrent());
stefanc1aeaf02015-10-15 14:26:07349 return MediaControllerInterface::Create(worker_thread_,
350 channel_manager_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36351}
352
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52353rtc::Thread* PeerConnectionFactory::signaling_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16354 // This method can be called on a different thread when the factory is
355 // created in CreatePeerConnectionFactory().
henrike@webrtc.org28e20752013-07-10 00:45:36356 return signaling_thread_;
357}
358
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52359rtc::Thread* PeerConnectionFactory::worker_thread() {
henrikg91d6ede2015-09-17 07:24:34360 RTC_DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36361 return worker_thread_;
362}
363
henrika@webrtc.org62f6e752015-02-11 08:38:35364cricket::MediaEngineInterface* PeerConnectionFactory::CreateMediaEngine_w() {
365 ASSERT(worker_thread_ == rtc::Thread::Current());
366 return cricket::WebRtcMediaEngineFactory::Create(
Fredrik Solenbergccb49e72015-05-19 09:37:56367 default_adm_.get(), video_encoder_factory_.get(),
henrika@webrtc.org62f6e752015-02-11 08:38:35368 video_decoder_factory_.get());
369}
370
henrike@webrtc.org28e20752013-07-10 00:45:36371} // namespace webrtc