blob: 5e3bf42f0da53bf8421a2f6437931b0775e3d8d5 [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"
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
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000050rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051CreatePeerConnectionFactory() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000052 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
53 new rtc::RefCountedObject<PeerConnectionFactory>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054
perkj@webrtc.org81134d02015-01-12 08:30:16 +000055
56 // Call Initialize synchronously but make sure its executed on
57 // |signaling_thread|.
58 MethodCall0<PeerConnectionFactory, bool> call(
59 pc_factory.get(),
60 &PeerConnectionFactory::Initialize);
61 bool result = call.Marshal(pc_factory->signaling_thread());
62
63 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 return NULL;
65 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000066 return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(),
67 pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068}
69
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000070rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071CreatePeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000072 rtc::Thread* worker_thread,
73 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 AudioDeviceModule* default_adm,
75 cricket::WebRtcVideoEncoderFactory* encoder_factory,
76 cricket::WebRtcVideoDecoderFactory* decoder_factory) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000077 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
78 new rtc::RefCountedObject<PeerConnectionFactory>(worker_thread,
perkj@webrtc.org81134d02015-01-12 08:30:16 +000079 signaling_thread,
80 default_adm,
81 encoder_factory,
82 decoder_factory));
83
84 // Call Initialize synchronously but make sure its executed on
85 // |signaling_thread|.
86 MethodCall0<PeerConnectionFactory, bool> call(
87 pc_factory.get(),
88 &PeerConnectionFactory::Initialize);
89 bool result = call.Marshal(signaling_thread);
90
91 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092 return NULL;
93 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000094 return PeerConnectionFactoryProxy::Create(signaling_thread, pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000095}
96
97PeerConnectionFactory::PeerConnectionFactory()
98 : owns_ptrs_(true),
perkj@webrtc.org81134d02015-01-12 08:30:16 +000099 wraps_current_thread_(false),
100 signaling_thread_(rtc::ThreadManager::Instance()->CurrentThread()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000101 worker_thread_(new rtc::Thread) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000102 if (!signaling_thread_) {
103 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
104 wraps_current_thread_ = true;
105 }
106 worker_thread_->Start();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000107}
108
109PeerConnectionFactory::PeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000110 rtc::Thread* worker_thread,
111 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000112 AudioDeviceModule* default_adm,
113 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
114 cricket::WebRtcVideoDecoderFactory* video_decoder_factory)
115 : owns_ptrs_(false),
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000116 wraps_current_thread_(false),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000117 signaling_thread_(signaling_thread),
118 worker_thread_(worker_thread),
119 default_adm_(default_adm),
120 video_encoder_factory_(video_encoder_factory),
121 video_decoder_factory_(video_decoder_factory) {
122 ASSERT(worker_thread != NULL);
123 ASSERT(signaling_thread != NULL);
124 // TODO: Currently there is no way creating an external adm in
125 // libjingle source tree. So we can 't currently assert if this is NULL.
126 // ASSERT(default_adm != NULL);
127}
128
129PeerConnectionFactory::~PeerConnectionFactory() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000130 DCHECK(signaling_thread_->IsCurrent());
131 channel_manager_.reset(NULL);
132 allocator_factory_ = NULL;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133 if (owns_ptrs_) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000134 if (wraps_current_thread_)
135 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
fischman@webrtc.org29540b12014-04-17 22:54:30 +0000136 delete worker_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 }
138}
139
140bool PeerConnectionFactory::Initialize() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000141 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000142 rtc::InitRandom(rtc::Time());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143
144 allocator_factory_ = PortAllocatorFactory::Create(worker_thread_);
145 if (!allocator_factory_)
146 return false;
147
148 cricket::DummyDeviceManager* device_manager(
149 new cricket::DummyDeviceManager());
150 // TODO: Need to make sure only one VoE is created inside
151 // WebRtcMediaEngine.
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000152 cricket::MediaEngineInterface* media_engine(
153 cricket::WebRtcMediaEngineFactory::Create(default_adm_.get(),
154 NULL, // No secondary adm.
155 video_encoder_factory_.get(),
156 video_decoder_factory_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157
158 channel_manager_.reset(new cricket::ChannelManager(
henrike@webrtc.org0481f152014-08-19 14:56:59 +0000159 media_engine, device_manager, worker_thread_));
stefan@webrtc.org85d27942014-06-09 12:51:39 +0000160 channel_manager_->SetVideoRtxEnabled(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161 if (!channel_manager_->Init()) {
162 return false;
163 }
164 return true;
165}
166
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000167rtc::scoped_refptr<AudioSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000168PeerConnectionFactory::CreateAudioSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000170 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000171 rtc::scoped_refptr<LocalAudioSource> source(
wu@webrtc.org97077a32013-10-25 21:18:33 +0000172 LocalAudioSource::Create(options_, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173 return source;
174}
175
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000176rtc::scoped_refptr<VideoSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000177PeerConnectionFactory::CreateVideoSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000178 cricket::VideoCapturer* capturer,
179 const MediaConstraintsInterface* constraints) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000180 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000181 rtc::scoped_refptr<VideoSource> source(
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000182 VideoSource::Create(channel_manager_.get(), capturer, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000183 return VideoSourceProxy::Create(signaling_thread_, source);
184}
185
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000186bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file) {
187 DCHECK(signaling_thread_->IsCurrent());
wu@webrtc.orga9890802013-12-13 00:21:03 +0000188 return channel_manager_->StartAecDump(file);
189}
190
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000191rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000192PeerConnectionFactory::CreatePeerConnection(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000193 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000194 const MediaConstraintsInterface* constraints,
195 PortAllocatorFactoryInterface* allocator_factory,
196 DTLSIdentityServiceInterface* dtls_identity_service,
197 PeerConnectionObserver* observer) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000198 DCHECK(signaling_thread_->IsCurrent());
199 DCHECK(allocator_factory || allocator_factory_);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000200 rtc::scoped_refptr<PeerConnection> pc(
201 new rtc::RefCountedObject<PeerConnection>(this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 if (!pc->Initialize(
203 configuration,
204 constraints,
205 allocator_factory ? allocator_factory : allocator_factory_.get(),
wu@webrtc.org91053e72013-08-10 07:18:04 +0000206 dtls_identity_service,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 observer)) {
208 return NULL;
209 }
210 return PeerConnectionProxy::Create(signaling_thread(), pc);
211}
212
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000213rtc::scoped_refptr<MediaStreamInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000214PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000215 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000216 return MediaStreamProxy::Create(signaling_thread_,
217 MediaStream::Create(label));
218}
219
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000220rtc::scoped_refptr<VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221PeerConnectionFactory::CreateVideoTrack(
222 const std::string& id,
223 VideoSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000224 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000225 rtc::scoped_refptr<VideoTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 VideoTrack::Create(id, source));
227 return VideoTrackProxy::Create(signaling_thread_, track);
228}
229
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000230rtc::scoped_refptr<AudioTrackInterface>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000231PeerConnectionFactory::CreateAudioTrack(const std::string& id,
232 AudioSourceInterface* source) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000233 DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000234 rtc::scoped_refptr<AudioTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 AudioTrack::Create(id, source));
236 return AudioTrackProxy::Create(signaling_thread_, track);
237}
238
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239cricket::ChannelManager* PeerConnectionFactory::channel_manager() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000240 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241 return channel_manager_.get();
242}
243
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000244rtc::Thread* PeerConnectionFactory::signaling_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000245 // This method can be called on a different thread when the factory is
246 // created in CreatePeerConnectionFactory().
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000247 return signaling_thread_;
248}
249
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000250rtc::Thread* PeerConnectionFactory::worker_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000251 DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 return worker_thread_;
253}
254
255} // namespace webrtc