blob: 3524af7932a4f92f60da84e552f742d1a2aaa7ac [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"
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +000031#include "talk/app/webrtc/dtlsidentityservice.h"
32#include "talk/app/webrtc/dtlsidentitystore.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033#include "talk/app/webrtc/localaudiosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include "talk/app/webrtc/mediastreamproxy.h"
35#include "talk/app/webrtc/mediastreamtrackproxy.h"
36#include "talk/app/webrtc/peerconnection.h"
perkj@webrtc.org81134d02015-01-12 08:30:16 +000037#include "talk/app/webrtc/peerconnectionfactoryproxy.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038#include "talk/app/webrtc/peerconnectionproxy.h"
39#include "talk/app/webrtc/portallocatorfactory.h"
wu@webrtc.org967bfff2013-09-19 05:49:50 +000040#include "talk/app/webrtc/videosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000041#include "talk/app/webrtc/videosourceproxy.h"
42#include "talk/app/webrtc/videotrack.h"
43#include "talk/media/devices/dummydevicemanager.h"
44#include "talk/media/webrtc/webrtcmediaengine.h"
45#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
46#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
jiayl@webrtc.org3987b6d2014-09-24 17:14:05 +000047#include "webrtc/base/bind.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048#include "webrtc/modules/audio_device/include/audio_device.h"
49
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050namespace webrtc {
51
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000052rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053CreatePeerConnectionFactory() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000054 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
55 new rtc::RefCountedObject<PeerConnectionFactory>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056
perkj@webrtc.org81134d02015-01-12 08:30:16 +000057
58 // Call Initialize synchronously but make sure its executed on
59 // |signaling_thread|.
60 MethodCall0<PeerConnectionFactory, bool> call(
61 pc_factory.get(),
62 &PeerConnectionFactory::Initialize);
63 bool result = call.Marshal(pc_factory->signaling_thread());
64
65 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 return NULL;
67 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000068 return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(),
69 pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070}
71
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000072rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073CreatePeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000074 rtc::Thread* worker_thread,
75 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076 AudioDeviceModule* default_adm,
77 cricket::WebRtcVideoEncoderFactory* encoder_factory,
78 cricket::WebRtcVideoDecoderFactory* decoder_factory) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000079 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
80 new rtc::RefCountedObject<PeerConnectionFactory>(worker_thread,
perkj@webrtc.org81134d02015-01-12 08:30:16 +000081 signaling_thread,
82 default_adm,
83 encoder_factory,
84 decoder_factory));
85
86 // Call Initialize synchronously but make sure its executed on
87 // |signaling_thread|.
88 MethodCall0<PeerConnectionFactory, bool> call(
89 pc_factory.get(),
90 &PeerConnectionFactory::Initialize);
91 bool result = call.Marshal(signaling_thread);
92
93 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094 return NULL;
95 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000096 return PeerConnectionFactoryProxy::Create(signaling_thread, pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000097}
98
99PeerConnectionFactory::PeerConnectionFactory()
100 : owns_ptrs_(true),
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000101 wraps_current_thread_(false),
102 signaling_thread_(rtc::ThreadManager::Instance()->CurrentThread()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000103 worker_thread_(new rtc::Thread) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000104 if (!signaling_thread_) {
105 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
106 wraps_current_thread_ = true;
107 }
108 worker_thread_->Start();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000109}
110
111PeerConnectionFactory::PeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000112 rtc::Thread* worker_thread,
113 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114 AudioDeviceModule* default_adm,
115 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
116 cricket::WebRtcVideoDecoderFactory* video_decoder_factory)
117 : owns_ptrs_(false),
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000118 wraps_current_thread_(false),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119 signaling_thread_(signaling_thread),
120 worker_thread_(worker_thread),
121 default_adm_(default_adm),
122 video_encoder_factory_(video_encoder_factory),
123 video_decoder_factory_(video_decoder_factory) {
124 ASSERT(worker_thread != NULL);
125 ASSERT(signaling_thread != NULL);
126 // TODO: Currently there is no way creating an external adm in
127 // libjingle source tree. So we can 't currently assert if this is NULL.
128 // ASSERT(default_adm != NULL);
129}
130
131PeerConnectionFactory::~PeerConnectionFactory() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000132 DCHECK(signaling_thread_->IsCurrent());
133 channel_manager_.reset(NULL);
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000134 default_allocator_factory_ = NULL;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000135
136 // Make sure |worker_thread_| and |signaling_thread_| outlive
137 // |dtls_identity_store_|.
138 dtls_identity_store_.reset(NULL);
139
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 if (owns_ptrs_) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000141 if (wraps_current_thread_)
142 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
fischman@webrtc.org29540b12014-04-17 22:54:30 +0000143 delete worker_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000144 }
145}
146
147bool PeerConnectionFactory::Initialize() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000148 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000149 rtc::InitRandom(rtc::Time());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000151 default_allocator_factory_ = PortAllocatorFactory::Create(worker_thread_);
152 if (!default_allocator_factory_)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153 return false;
154
155 cricket::DummyDeviceManager* device_manager(
156 new cricket::DummyDeviceManager());
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000157
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158 // TODO: Need to make sure only one VoE is created inside
159 // WebRtcMediaEngine.
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000160 cricket::MediaEngineInterface* media_engine =
161 worker_thread_->Invoke<cricket::MediaEngineInterface*>(rtc::Bind(
162 &PeerConnectionFactory::CreateMediaEngine_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163
164 channel_manager_.reset(new cricket::ChannelManager(
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000165 media_engine, device_manager, worker_thread_));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000166
stefan@webrtc.org85d27942014-06-09 12:51:39 +0000167 channel_manager_->SetVideoRtxEnabled(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168 if (!channel_manager_->Init()) {
169 return false;
170 }
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000171
172 dtls_identity_store_.reset(
173 new DtlsIdentityStore(signaling_thread_, worker_thread_));
174 dtls_identity_store_->Initialize();
175
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 return true;
177}
178
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000179rtc::scoped_refptr<AudioSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000180PeerConnectionFactory::CreateAudioSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000182 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000183 rtc::scoped_refptr<LocalAudioSource> source(
wu@webrtc.org97077a32013-10-25 21:18:33 +0000184 LocalAudioSource::Create(options_, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185 return source;
186}
187
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000188rtc::scoped_refptr<VideoSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000189PeerConnectionFactory::CreateVideoSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 cricket::VideoCapturer* capturer,
191 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000192 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000193 rtc::scoped_refptr<VideoSource> source(
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000194 VideoSource::Create(channel_manager_.get(), capturer, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195 return VideoSourceProxy::Create(signaling_thread_, source);
196}
197
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000198bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file) {
199 DCHECK(signaling_thread_->IsCurrent());
wu@webrtc.orga9890802013-12-13 00:21:03 +0000200 return channel_manager_->StartAecDump(file);
201}
202
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000203rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204PeerConnectionFactory::CreatePeerConnection(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000205 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 const MediaConstraintsInterface* constraints,
207 PortAllocatorFactoryInterface* allocator_factory,
208 DTLSIdentityServiceInterface* dtls_identity_service,
209 PeerConnectionObserver* observer) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000210 DCHECK(signaling_thread_->IsCurrent());
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000211 DCHECK(allocator_factory || default_allocator_factory_);
212
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000213 if (!dtls_identity_service) {
214 dtls_identity_service = new DtlsIdentityService(dtls_identity_store_.get());
215 }
216
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000217 PortAllocatorFactoryInterface* chosen_allocator_factory =
218 allocator_factory ? allocator_factory : default_allocator_factory_.get();
219 chosen_allocator_factory->SetNetworkIgnoreMask(options_.network_ignore_mask);
220
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000221 rtc::scoped_refptr<PeerConnection> pc(
222 new rtc::RefCountedObject<PeerConnection>(this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223 if (!pc->Initialize(
224 configuration,
225 constraints,
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000226 chosen_allocator_factory,
wu@webrtc.org91053e72013-08-10 07:18:04 +0000227 dtls_identity_service,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 observer)) {
229 return NULL;
230 }
231 return PeerConnectionProxy::Create(signaling_thread(), pc);
232}
233
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000234rtc::scoped_refptr<MediaStreamInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000236 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237 return MediaStreamProxy::Create(signaling_thread_,
238 MediaStream::Create(label));
239}
240
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000241rtc::scoped_refptr<VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242PeerConnectionFactory::CreateVideoTrack(
243 const std::string& id,
244 VideoSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000245 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246 rtc::scoped_refptr<VideoTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 VideoTrack::Create(id, source));
248 return VideoTrackProxy::Create(signaling_thread_, track);
249}
250
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000251rtc::scoped_refptr<AudioTrackInterface>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000252PeerConnectionFactory::CreateAudioTrack(const std::string& id,
253 AudioSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000254 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000255 rtc::scoped_refptr<AudioTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 AudioTrack::Create(id, source));
257 return AudioTrackProxy::Create(signaling_thread_, track);
258}
259
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000261 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 return channel_manager_.get();
263}
264
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000265rtc::Thread* PeerConnectionFactory::signaling_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000266 // This method can be called on a different thread when the factory is
267 // created in CreatePeerConnectionFactory().
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 return signaling_thread_;
269}
270
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000271rtc::Thread* PeerConnectionFactory::worker_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000272 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273 return worker_thread_;
274}
275
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000276cricket::MediaEngineInterface* PeerConnectionFactory::CreateMediaEngine_w() {
277 ASSERT(worker_thread_ == rtc::Thread::Current());
278 return cricket::WebRtcMediaEngineFactory::Create(
Fredrik Solenbergccb49e72015-05-19 11:37:56 +0200279 default_adm_.get(), video_encoder_factory_.get(),
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000280 video_decoder_factory_.get());
281}
282
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000283} // namespace webrtc