blob: 26765d21097ff81a791b4ac54b64fa207eb0d48c [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2004--2011 Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004 *
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"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032#include "talk/app/webrtc/mediastreamproxy.h"
33#include "talk/app/webrtc/mediastreamtrackproxy.h"
34#include "talk/app/webrtc/peerconnection.h"
perkj@webrtc.org81134d02015-01-12 08:30:16 +000035#include "talk/app/webrtc/peerconnectionfactoryproxy.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036#include "talk/app/webrtc/peerconnectionproxy.h"
37#include "talk/app/webrtc/portallocatorfactory.h"
wu@webrtc.org967bfff2013-09-19 05:49:50 +000038#include "talk/app/webrtc/videosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/app/webrtc/videosourceproxy.h"
40#include "talk/app/webrtc/videotrack.h"
41#include "talk/media/devices/dummydevicemanager.h"
42#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:05 +000045#include "webrtc/base/bind.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046#include "webrtc/modules/audio_device/include/audio_device.h"
47
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048namespace webrtc {
49
Henrik Boström5e56c592015-08-11 10:33:13 +020050namespace {
51
52// Passes down the calls to |store_|. See usage in CreatePeerConnection.
53class DtlsIdentityStoreWrapper : public DtlsIdentityStoreInterface {
54 public:
55 DtlsIdentityStoreWrapper(
56 const rtc::scoped_refptr<RefCountedDtlsIdentityStore>& store)
57 : store_(store) {
58 DCHECK(store_);
59 }
60
61 void RequestIdentity(
62 rtc::KeyType key_type,
63 const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>&
64 observer) override {
65 store_->RequestIdentity(key_type, observer);
66 }
67
68 private:
69 rtc::scoped_refptr<RefCountedDtlsIdentityStore> store_;
70};
71
72} // anonymous namespace
73
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000074rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075CreatePeerConnectionFactory() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000076 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
77 new rtc::RefCountedObject<PeerConnectionFactory>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078
perkj@webrtc.org81134d02015-01-12 08:30:16 +000079
80 // Call Initialize synchronously but make sure its executed on
81 // |signaling_thread|.
82 MethodCall0<PeerConnectionFactory, bool> call(
83 pc_factory.get(),
84 &PeerConnectionFactory::Initialize);
85 bool result = call.Marshal(pc_factory->signaling_thread());
86
87 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088 return NULL;
89 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000090 return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(),
91 pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092}
93
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000094rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000095CreatePeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000096 rtc::Thread* worker_thread,
97 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000098 AudioDeviceModule* default_adm,
99 cricket::WebRtcVideoEncoderFactory* encoder_factory,
100 cricket::WebRtcVideoDecoderFactory* decoder_factory) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000101 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
102 new rtc::RefCountedObject<PeerConnectionFactory>(worker_thread,
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000103 signaling_thread,
104 default_adm,
105 encoder_factory,
106 decoder_factory));
107
108 // Call Initialize synchronously but make sure its executed on
109 // |signaling_thread|.
110 MethodCall0<PeerConnectionFactory, bool> call(
111 pc_factory.get(),
112 &PeerConnectionFactory::Initialize);
113 bool result = call.Marshal(signaling_thread);
114
115 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116 return NULL;
117 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000118 return PeerConnectionFactoryProxy::Create(signaling_thread, pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119}
120
121PeerConnectionFactory::PeerConnectionFactory()
122 : owns_ptrs_(true),
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000123 wraps_current_thread_(false),
124 signaling_thread_(rtc::ThreadManager::Instance()->CurrentThread()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000125 worker_thread_(new rtc::Thread) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000126 if (!signaling_thread_) {
127 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
128 wraps_current_thread_ = true;
129 }
130 worker_thread_->Start();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131}
132
133PeerConnectionFactory::PeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000134 rtc::Thread* worker_thread,
135 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136 AudioDeviceModule* default_adm,
137 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
138 cricket::WebRtcVideoDecoderFactory* video_decoder_factory)
139 : owns_ptrs_(false),
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000140 wraps_current_thread_(false),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000141 signaling_thread_(signaling_thread),
142 worker_thread_(worker_thread),
143 default_adm_(default_adm),
144 video_encoder_factory_(video_encoder_factory),
145 video_decoder_factory_(video_decoder_factory) {
146 ASSERT(worker_thread != NULL);
147 ASSERT(signaling_thread != NULL);
148 // TODO: Currently there is no way creating an external adm in
149 // libjingle source tree. So we can 't currently assert if this is NULL.
150 // ASSERT(default_adm != NULL);
151}
152
153PeerConnectionFactory::~PeerConnectionFactory() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000154 DCHECK(signaling_thread_->IsCurrent());
Henrik Boström5e56c592015-08-11 10:33:13 +0200155 channel_manager_.reset(nullptr);
156 default_allocator_factory_ = nullptr;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000157
158 // Make sure |worker_thread_| and |signaling_thread_| outlive
159 // |dtls_identity_store_|.
Henrik Boström5e56c592015-08-11 10:33:13 +0200160 dtls_identity_store_ = nullptr;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000161
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162 if (owns_ptrs_) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000163 if (wraps_current_thread_)
164 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
fischman@webrtc.org29540b12014-04-17 22:54:30 +0000165 delete worker_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 }
167}
168
169bool PeerConnectionFactory::Initialize() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000170 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000171 rtc::InitRandom(rtc::Time());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000173 default_allocator_factory_ = PortAllocatorFactory::Create(worker_thread_);
174 if (!default_allocator_factory_)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000175 return false;
176
177 cricket::DummyDeviceManager* device_manager(
178 new cricket::DummyDeviceManager());
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000179
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 // TODO: Need to make sure only one VoE is created inside
181 // WebRtcMediaEngine.
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000182 cricket::MediaEngineInterface* media_engine =
183 worker_thread_->Invoke<cricket::MediaEngineInterface*>(rtc::Bind(
184 &PeerConnectionFactory::CreateMediaEngine_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185
186 channel_manager_.reset(new cricket::ChannelManager(
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000187 media_engine, device_manager, worker_thread_));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000188
stefan@webrtc.org85d27942014-06-09 12:51:39 +0000189 channel_manager_->SetVideoRtxEnabled(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 if (!channel_manager_->Init()) {
191 return false;
192 }
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000193
Henrik Boström5e56c592015-08-11 10:33:13 +0200194 dtls_identity_store_ = new RefCountedDtlsIdentityStore(
195 signaling_thread_, worker_thread_);
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000196
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000197 return true;
198}
199
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000200rtc::scoped_refptr<AudioSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000201PeerConnectionFactory::CreateAudioSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000203 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000204 rtc::scoped_refptr<LocalAudioSource> source(
wu@webrtc.org97077a32013-10-25 21:18:33 +0000205 LocalAudioSource::Create(options_, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 return source;
207}
208
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000209rtc::scoped_refptr<VideoSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000210PeerConnectionFactory::CreateVideoSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211 cricket::VideoCapturer* capturer,
212 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000213 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000214 rtc::scoped_refptr<VideoSource> source(
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000215 VideoSource::Create(channel_manager_.get(), capturer, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216 return VideoSourceProxy::Create(signaling_thread_, source);
217}
218
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000219bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file) {
220 DCHECK(signaling_thread_->IsCurrent());
wu@webrtc.orga9890802013-12-13 00:21:03 +0000221 return channel_manager_->StartAecDump(file);
222}
223
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000224rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000225PeerConnectionFactory::CreatePeerConnection(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000226 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227 const MediaConstraintsInterface* constraints,
228 PortAllocatorFactoryInterface* allocator_factory,
Henrik Boström5e56c592015-08-11 10:33:13 +0200229 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230 PeerConnectionObserver* observer) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000231 DCHECK(signaling_thread_->IsCurrent());
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000232 DCHECK(allocator_factory || default_allocator_factory_);
233
Henrik Boström5e56c592015-08-11 10:33:13 +0200234 if (!dtls_identity_store.get()) {
235 // Because |pc|->Initialize takes ownership of the store we need a new
236 // wrapper object that can be deleted without deleting the underlying
237 // |dtls_identity_store_|, protecting it from being deleted multiple times.
238 dtls_identity_store.reset(
239 new DtlsIdentityStoreWrapper(dtls_identity_store_));
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000240 }
241
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000242 PortAllocatorFactoryInterface* chosen_allocator_factory =
243 allocator_factory ? allocator_factory : default_allocator_factory_.get();
244 chosen_allocator_factory->SetNetworkIgnoreMask(options_.network_ignore_mask);
245
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246 rtc::scoped_refptr<PeerConnection> pc(
247 new rtc::RefCountedObject<PeerConnection>(this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 if (!pc->Initialize(
249 configuration,
250 constraints,
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000251 chosen_allocator_factory,
Henrik Boström5e56c592015-08-11 10:33:13 +0200252 dtls_identity_store.Pass(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 observer)) {
254 return NULL;
255 }
256 return PeerConnectionProxy::Create(signaling_thread(), pc);
257}
258
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000259rtc::scoped_refptr<MediaStreamInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000261 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 return MediaStreamProxy::Create(signaling_thread_,
263 MediaStream::Create(label));
264}
265
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000266rtc::scoped_refptr<VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000267PeerConnectionFactory::CreateVideoTrack(
268 const std::string& id,
269 VideoSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000270 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000271 rtc::scoped_refptr<VideoTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 VideoTrack::Create(id, source));
273 return VideoTrackProxy::Create(signaling_thread_, track);
274}
275
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000276rtc::scoped_refptr<AudioTrackInterface>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000277PeerConnectionFactory::CreateAudioTrack(const std::string& id,
278 AudioSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000279 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000280 rtc::scoped_refptr<AudioTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 AudioTrack::Create(id, source));
282 return AudioTrackProxy::Create(signaling_thread_, track);
283}
284
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000286 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000287 return channel_manager_.get();
288}
289
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000290rtc::Thread* PeerConnectionFactory::signaling_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000291 // This method can be called on a different thread when the factory is
292 // created in CreatePeerConnectionFactory().
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293 return signaling_thread_;
294}
295
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000296rtc::Thread* PeerConnectionFactory::worker_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000297 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298 return worker_thread_;
299}
300
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000301cricket::MediaEngineInterface* PeerConnectionFactory::CreateMediaEngine_w() {
302 ASSERT(worker_thread_ == rtc::Thread::Current());
303 return cricket::WebRtcMediaEngineFactory::Create(
Fredrik Solenbergccb49e72015-05-19 11:37:56 +0200304 default_adm_.get(), video_encoder_factory_.get(),
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000305 video_decoder_factory_.get());
306}
307
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000308} // namespace webrtc