blob: 9f1e8588e7fbf05c82fb8d348c659a81f9eefc5d [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;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000135 if (owns_ptrs_) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000136 if (wraps_current_thread_)
137 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
fischman@webrtc.org29540b12014-04-17 22:54:30 +0000138 delete worker_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000139 }
140}
141
142bool PeerConnectionFactory::Initialize() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000143 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000144 rtc::InitRandom(rtc::Time());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000146 default_allocator_factory_ = PortAllocatorFactory::Create(worker_thread_);
147 if (!default_allocator_factory_)
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148 return false;
149
150 cricket::DummyDeviceManager* device_manager(
151 new cricket::DummyDeviceManager());
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000152
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153 // TODO: Need to make sure only one VoE is created inside
154 // WebRtcMediaEngine.
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000155 cricket::MediaEngineInterface* media_engine =
156 worker_thread_->Invoke<cricket::MediaEngineInterface*>(rtc::Bind(
157 &PeerConnectionFactory::CreateMediaEngine_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158
159 channel_manager_.reset(new cricket::ChannelManager(
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000160 media_engine, device_manager, worker_thread_));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000161
stefan@webrtc.org85d27942014-06-09 12:51:39 +0000162 channel_manager_->SetVideoRtxEnabled(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000163 if (!channel_manager_->Init()) {
164 return false;
165 }
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000166
167 dtls_identity_store_.reset(
168 new DtlsIdentityStore(signaling_thread_, worker_thread_));
169 dtls_identity_store_->Initialize();
170
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 return true;
172}
173
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000174rtc::scoped_refptr<AudioSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000175PeerConnectionFactory::CreateAudioSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000177 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000178 rtc::scoped_refptr<LocalAudioSource> source(
wu@webrtc.org97077a32013-10-25 21:18:33 +0000179 LocalAudioSource::Create(options_, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 return source;
181}
182
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000183rtc::scoped_refptr<VideoSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000184PeerConnectionFactory::CreateVideoSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000185 cricket::VideoCapturer* capturer,
186 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000187 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000188 rtc::scoped_refptr<VideoSource> source(
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000189 VideoSource::Create(channel_manager_.get(), capturer, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 return VideoSourceProxy::Create(signaling_thread_, source);
191}
192
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000193bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file) {
194 DCHECK(signaling_thread_->IsCurrent());
wu@webrtc.orga9890802013-12-13 00:21:03 +0000195 return channel_manager_->StartAecDump(file);
196}
197
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000198rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199PeerConnectionFactory::CreatePeerConnection(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000200 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000201 const MediaConstraintsInterface* constraints,
202 PortAllocatorFactoryInterface* allocator_factory,
203 DTLSIdentityServiceInterface* dtls_identity_service,
204 PeerConnectionObserver* observer) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000205 DCHECK(signaling_thread_->IsCurrent());
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000206 DCHECK(allocator_factory || default_allocator_factory_);
207
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000208 if (!dtls_identity_service) {
209 dtls_identity_service = new DtlsIdentityService(dtls_identity_store_.get());
210 }
211
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000212 PortAllocatorFactoryInterface* chosen_allocator_factory =
213 allocator_factory ? allocator_factory : default_allocator_factory_.get();
214 chosen_allocator_factory->SetNetworkIgnoreMask(options_.network_ignore_mask);
215
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000216 rtc::scoped_refptr<PeerConnection> pc(
217 new rtc::RefCountedObject<PeerConnection>(this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218 if (!pc->Initialize(
219 configuration,
220 constraints,
phoglund@webrtc.org006521d2015-02-12 09:23:59 +0000221 chosen_allocator_factory,
wu@webrtc.org91053e72013-08-10 07:18:04 +0000222 dtls_identity_service,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223 observer)) {
224 return NULL;
225 }
226 return PeerConnectionProxy::Create(signaling_thread(), pc);
227}
228
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000229rtc::scoped_refptr<MediaStreamInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000231 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 return MediaStreamProxy::Create(signaling_thread_,
233 MediaStream::Create(label));
234}
235
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000236rtc::scoped_refptr<VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000237PeerConnectionFactory::CreateVideoTrack(
238 const std::string& id,
239 VideoSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000240 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000241 rtc::scoped_refptr<VideoTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242 VideoTrack::Create(id, source));
243 return VideoTrackProxy::Create(signaling_thread_, track);
244}
245
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000246rtc::scoped_refptr<AudioTrackInterface>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000247PeerConnectionFactory::CreateAudioTrack(const std::string& id,
248 AudioSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000249 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000250 rtc::scoped_refptr<AudioTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 AudioTrack::Create(id, source));
252 return AudioTrackProxy::Create(signaling_thread_, track);
253}
254
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000256 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 return channel_manager_.get();
258}
259
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000260rtc::Thread* PeerConnectionFactory::signaling_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000261 // This method can be called on a different thread when the factory is
262 // created in CreatePeerConnectionFactory().
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 return signaling_thread_;
264}
265
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000266rtc::Thread* PeerConnectionFactory::worker_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000267 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 return worker_thread_;
269}
270
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000271cricket::MediaEngineInterface* PeerConnectionFactory::CreateMediaEngine_w() {
272 ASSERT(worker_thread_ == rtc::Thread::Current());
273 return cricket::WebRtcMediaEngineFactory::Create(
274 default_adm_.get(), NULL, video_encoder_factory_.get(),
275 video_decoder_factory_.get());
276}
277
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278} // namespace webrtc