blob: 862ceda96a934e4226db82d49e93d9de35b5080e [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004--2011, Google Inc.
4 *
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"
35#include "talk/app/webrtc/peerconnectionproxy.h"
36#include "talk/app/webrtc/portallocatorfactory.h"
wu@webrtc.org967bfff2013-09-19 05:49:50 +000037#include "talk/app/webrtc/videosource.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038#include "talk/app/webrtc/videosourceproxy.h"
39#include "talk/app/webrtc/videotrack.h"
40#include "talk/media/devices/dummydevicemanager.h"
41#include "talk/media/webrtc/webrtcmediaengine.h"
42#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
43#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
jiayl@webrtc.org3987b6d2014-09-24 17:14:05 +000044#include "webrtc/base/bind.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000045#include "webrtc/modules/audio_device/include/audio_device.h"
46
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000047using rtc::scoped_refptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048
49namespace {
50
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000051typedef rtc::TypedMessageData<bool> InitMessageData;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000053struct CreatePeerConnectionParams : public rtc::MessageData {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 CreatePeerConnectionParams(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +000055 const webrtc::PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056 const webrtc::MediaConstraintsInterface* constraints,
57 webrtc::PortAllocatorFactoryInterface* allocator_factory,
wu@webrtc.org91053e72013-08-10 07:18:04 +000058 webrtc::DTLSIdentityServiceInterface* dtls_identity_service,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059 webrtc::PeerConnectionObserver* observer)
60 : configuration(configuration),
61 constraints(constraints),
62 allocator_factory(allocator_factory),
wu@webrtc.org91053e72013-08-10 07:18:04 +000063 dtls_identity_service(dtls_identity_service),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 observer(observer) {
65 }
66 scoped_refptr<webrtc::PeerConnectionInterface> peerconnection;
buildbot@webrtc.org41451d42014-05-03 05:39:45 +000067 const webrtc::PeerConnectionInterface::RTCConfiguration& configuration;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068 const webrtc::MediaConstraintsInterface* constraints;
69 scoped_refptr<webrtc::PortAllocatorFactoryInterface> allocator_factory;
wu@webrtc.org91053e72013-08-10 07:18:04 +000070 webrtc::DTLSIdentityServiceInterface* dtls_identity_service;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071 webrtc::PeerConnectionObserver* observer;
72};
73
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000074struct CreateAudioSourceParams : public rtc::MessageData {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075 explicit CreateAudioSourceParams(
76 const webrtc::MediaConstraintsInterface* constraints)
77 : constraints(constraints) {
78 }
79 const webrtc::MediaConstraintsInterface* constraints;
80 scoped_refptr<webrtc::AudioSourceInterface> source;
81};
82
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000083struct CreateVideoSourceParams : public rtc::MessageData {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084 CreateVideoSourceParams(cricket::VideoCapturer* capturer,
85 const webrtc::MediaConstraintsInterface* constraints)
86 : capturer(capturer),
87 constraints(constraints) {
88 }
89 cricket::VideoCapturer* capturer;
90 const webrtc::MediaConstraintsInterface* constraints;
91 scoped_refptr<webrtc::VideoSourceInterface> source;
92};
93
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000094struct StartAecDumpParams : public rtc::MessageData {
95 explicit StartAecDumpParams(rtc::PlatformFile aec_dump_file)
wu@webrtc.orga9890802013-12-13 00:21:03 +000096 : aec_dump_file(aec_dump_file) {
97 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000098 rtc::PlatformFile aec_dump_file;
wu@webrtc.orga9890802013-12-13 00:21:03 +000099 bool result;
100};
101
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000102enum {
103 MSG_INIT_FACTORY = 1,
104 MSG_TERMINATE_FACTORY,
105 MSG_CREATE_PEERCONNECTION,
106 MSG_CREATE_AUDIOSOURCE,
107 MSG_CREATE_VIDEOSOURCE,
wu@webrtc.orga9890802013-12-13 00:21:03 +0000108 MSG_START_AEC_DUMP,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000109};
110
111} // namespace
112
113namespace webrtc {
114
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000115rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116CreatePeerConnectionFactory() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000117 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
118 new rtc::RefCountedObject<PeerConnectionFactory>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119
120 if (!pc_factory->Initialize()) {
121 return NULL;
122 }
123 return pc_factory;
124}
125
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000126rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000127CreatePeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000128 rtc::Thread* worker_thread,
129 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000130 AudioDeviceModule* default_adm,
131 cricket::WebRtcVideoEncoderFactory* encoder_factory,
132 cricket::WebRtcVideoDecoderFactory* decoder_factory) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000133 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
134 new rtc::RefCountedObject<PeerConnectionFactory>(worker_thread,
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000135 signaling_thread,
136 default_adm,
137 encoder_factory,
138 decoder_factory));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000139 if (!pc_factory->Initialize()) {
140 return NULL;
141 }
142 return pc_factory;
143}
144
145PeerConnectionFactory::PeerConnectionFactory()
146 : owns_ptrs_(true),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000147 signaling_thread_(new rtc::Thread),
148 worker_thread_(new rtc::Thread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000149 bool result = signaling_thread_->Start();
150 ASSERT(result);
151 result = worker_thread_->Start();
152 ASSERT(result);
153}
154
155PeerConnectionFactory::PeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000156 rtc::Thread* worker_thread,
157 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158 AudioDeviceModule* default_adm,
159 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
160 cricket::WebRtcVideoDecoderFactory* video_decoder_factory)
161 : owns_ptrs_(false),
162 signaling_thread_(signaling_thread),
163 worker_thread_(worker_thread),
164 default_adm_(default_adm),
165 video_encoder_factory_(video_encoder_factory),
166 video_decoder_factory_(video_decoder_factory) {
167 ASSERT(worker_thread != NULL);
168 ASSERT(signaling_thread != NULL);
169 // TODO: Currently there is no way creating an external adm in
170 // libjingle source tree. So we can 't currently assert if this is NULL.
171 // ASSERT(default_adm != NULL);
172}
173
174PeerConnectionFactory::~PeerConnectionFactory() {
175 signaling_thread_->Clear(this);
176 signaling_thread_->Send(this, MSG_TERMINATE_FACTORY);
177 if (owns_ptrs_) {
fischman@webrtc.org29540b12014-04-17 22:54:30 +0000178 delete signaling_thread_;
179 delete worker_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180 }
181}
182
183bool PeerConnectionFactory::Initialize() {
184 InitMessageData result(false);
185 signaling_thread_->Send(this, MSG_INIT_FACTORY, &result);
186 return result.data();
187}
188
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000189void PeerConnectionFactory::OnMessage(rtc::Message* msg) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000190 switch (msg->message_id) {
191 case MSG_INIT_FACTORY: {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000192 InitMessageData* pdata = static_cast<InitMessageData*>(msg->pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193 pdata->data() = Initialize_s();
194 break;
195 }
196 case MSG_TERMINATE_FACTORY: {
197 Terminate_s();
198 break;
199 }
200 case MSG_CREATE_PEERCONNECTION: {
201 CreatePeerConnectionParams* pdata =
wu@webrtc.org91053e72013-08-10 07:18:04 +0000202 static_cast<CreatePeerConnectionParams*> (msg->pdata);
203 pdata->peerconnection = CreatePeerConnection_s(
204 pdata->configuration,
205 pdata->constraints,
206 pdata->allocator_factory,
207 pdata->dtls_identity_service,
208 pdata->observer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 break;
210 }
211 case MSG_CREATE_AUDIOSOURCE: {
212 CreateAudioSourceParams* pdata =
213 static_cast<CreateAudioSourceParams*>(msg->pdata);
214 pdata->source = CreateAudioSource_s(pdata->constraints);
215 break;
216 }
217 case MSG_CREATE_VIDEOSOURCE: {
218 CreateVideoSourceParams* pdata =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000219 static_cast<CreateVideoSourceParams*>(msg->pdata);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 pdata->source = CreateVideoSource_s(pdata->capturer, pdata->constraints);
221 break;
222 }
wu@webrtc.orga9890802013-12-13 00:21:03 +0000223 case MSG_START_AEC_DUMP: {
224 StartAecDumpParams* pdata =
225 static_cast<StartAecDumpParams*>(msg->pdata);
226 pdata->result = StartAecDump_s(pdata->aec_dump_file);
227 break;
228 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000229 }
230}
231
232bool PeerConnectionFactory::Initialize_s() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000233 rtc::InitRandom(rtc::Time());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234
235 allocator_factory_ = PortAllocatorFactory::Create(worker_thread_);
236 if (!allocator_factory_)
237 return false;
238
239 cricket::DummyDeviceManager* device_manager(
240 new cricket::DummyDeviceManager());
241 // TODO: Need to make sure only one VoE is created inside
242 // WebRtcMediaEngine.
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000243 cricket::MediaEngineInterface* media_engine(
244 cricket::WebRtcMediaEngineFactory::Create(default_adm_.get(),
245 NULL, // No secondary adm.
246 video_encoder_factory_.get(),
247 video_decoder_factory_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248
249 channel_manager_.reset(new cricket::ChannelManager(
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000250 media_engine, device_manager, worker_thread_));
stefan@webrtc.org85d27942014-06-09 12:51:39 +0000251 channel_manager_->SetVideoRtxEnabled(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 if (!channel_manager_->Init()) {
253 return false;
254 }
255 return true;
256}
257
258// Terminate what we created on the signaling thread.
259void PeerConnectionFactory::Terminate_s() {
260 channel_manager_.reset(NULL);
261 allocator_factory_ = NULL;
262}
263
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000264rtc::scoped_refptr<AudioSourceInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000265PeerConnectionFactory::CreateAudioSource_s(
266 const MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000267 rtc::scoped_refptr<LocalAudioSource> source(
wu@webrtc.org97077a32013-10-25 21:18:33 +0000268 LocalAudioSource::Create(options_, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269 return source;
270}
271
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000272rtc::scoped_refptr<VideoSourceInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273PeerConnectionFactory::CreateVideoSource_s(
274 cricket::VideoCapturer* capturer,
275 const MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000276 rtc::scoped_refptr<VideoSource> source(
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000277 VideoSource::Create(channel_manager_.get(), capturer, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 return VideoSourceProxy::Create(signaling_thread_, source);
279}
280
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000281bool PeerConnectionFactory::StartAecDump_s(rtc::PlatformFile file) {
wu@webrtc.orga9890802013-12-13 00:21:03 +0000282 return channel_manager_->StartAecDump(file);
283}
284
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000285rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286PeerConnectionFactory::CreatePeerConnection(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000287 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288 const MediaConstraintsInterface* constraints,
289 PortAllocatorFactoryInterface* allocator_factory,
290 DTLSIdentityServiceInterface* dtls_identity_service,
291 PeerConnectionObserver* observer) {
292 CreatePeerConnectionParams params(configuration, constraints,
wu@webrtc.org91053e72013-08-10 07:18:04 +0000293 allocator_factory, dtls_identity_service,
294 observer);
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000295 signaling_thread_->Send(
296 this, MSG_CREATE_PEERCONNECTION, &params);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000297 return params.peerconnection;
298}
299
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000300rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301PeerConnectionFactory::CreatePeerConnection_s(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000302 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000303 const MediaConstraintsInterface* constraints,
304 PortAllocatorFactoryInterface* allocator_factory,
wu@webrtc.org91053e72013-08-10 07:18:04 +0000305 DTLSIdentityServiceInterface* dtls_identity_service,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306 PeerConnectionObserver* observer) {
307 ASSERT(allocator_factory || allocator_factory_);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000308 rtc::scoped_refptr<PeerConnection> pc(
309 new rtc::RefCountedObject<PeerConnection>(this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 if (!pc->Initialize(
311 configuration,
312 constraints,
313 allocator_factory ? allocator_factory : allocator_factory_.get(),
wu@webrtc.org91053e72013-08-10 07:18:04 +0000314 dtls_identity_service,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315 observer)) {
316 return NULL;
317 }
318 return PeerConnectionProxy::Create(signaling_thread(), pc);
319}
320
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000321rtc::scoped_refptr<MediaStreamInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
323 return MediaStreamProxy::Create(signaling_thread_,
324 MediaStream::Create(label));
325}
326
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000327rtc::scoped_refptr<AudioSourceInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328PeerConnectionFactory::CreateAudioSource(
329 const MediaConstraintsInterface* constraints) {
330 CreateAudioSourceParams params(constraints);
331 signaling_thread_->Send(this, MSG_CREATE_AUDIOSOURCE, &params);
332 return params.source;
333}
334
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000335rtc::scoped_refptr<VideoSourceInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336PeerConnectionFactory::CreateVideoSource(
337 cricket::VideoCapturer* capturer,
338 const MediaConstraintsInterface* constraints) {
339
340 CreateVideoSourceParams params(capturer,
341 constraints);
342 signaling_thread_->Send(this, MSG_CREATE_VIDEOSOURCE, &params);
343 return params.source;
344}
345
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000346rtc::scoped_refptr<VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347PeerConnectionFactory::CreateVideoTrack(
348 const std::string& id,
349 VideoSourceInterface* source) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000350 rtc::scoped_refptr<VideoTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 VideoTrack::Create(id, source));
352 return VideoTrackProxy::Create(signaling_thread_, track);
353}
354
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000355rtc::scoped_refptr<AudioTrackInterface>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000356PeerConnectionFactory::CreateAudioTrack(const std::string& id,
357 AudioSourceInterface* source) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000358 rtc::scoped_refptr<AudioTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 AudioTrack::Create(id, source));
360 return AudioTrackProxy::Create(signaling_thread_, track);
361}
362
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000363bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file) {
wu@webrtc.orga9890802013-12-13 00:21:03 +0000364 StartAecDumpParams params(file);
365 signaling_thread_->Send(this, MSG_START_AEC_DUMP, &params);
366 return params.result;
367}
368
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
370 return channel_manager_.get();
371}
372
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000373rtc::Thread* PeerConnectionFactory::signaling_thread() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374 return signaling_thread_;
375}
376
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000377rtc::Thread* PeerConnectionFactory::worker_thread() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378 return worker_thread_;
379}
380
381} // namespace webrtc