blob: ab8fdf5b251a028313a9bb9d11aadcd35dee2407 [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
kwiberg0eb15ed2015-12-17 03:04:15 -080030#include <utility>
31
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032#include "talk/app/webrtc/audiotrack.h"
33#include "talk/app/webrtc/localaudiosource.h"
deadbeefab9b2d12015-10-14 11:33:11 -070034#include "talk/app/webrtc/mediastream.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035#include "talk/app/webrtc/mediastreamproxy.h"
36#include "talk/app/webrtc/mediastreamtrackproxy.h"
37#include "talk/app/webrtc/peerconnection.h"
perkj@webrtc.org81134d02015-01-12 08:30:16 +000038#include "talk/app/webrtc/peerconnectionfactoryproxy.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/app/webrtc/peerconnectionproxy.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"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043#include "talk/media/webrtc/webrtcmediaengine.h"
44#include "talk/media/webrtc/webrtcvideodecoderfactory.h"
45#include "talk/media/webrtc/webrtcvideoencoderfactory.h"
jiayl@webrtc.org3987b6d2014-09-24 17:14:05 +000046#include "webrtc/base/bind.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047#include "webrtc/modules/audio_device/include/audio_device.h"
deadbeef41b07982015-12-01 15:01:24 -080048#include "webrtc/p2p/base/basicpacketsocketfactory.h"
49#include "webrtc/p2p/client/basicportallocator.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051namespace webrtc {
52
Henrik Boström5e56c592015-08-11 10:33:13 +020053namespace {
54
55// Passes down the calls to |store_|. See usage in CreatePeerConnection.
56class DtlsIdentityStoreWrapper : public DtlsIdentityStoreInterface {
57 public:
58 DtlsIdentityStoreWrapper(
59 const rtc::scoped_refptr<RefCountedDtlsIdentityStore>& store)
60 : store_(store) {
henrikg91d6ede2015-09-17 00:24:34 -070061 RTC_DCHECK(store_);
Henrik Boström5e56c592015-08-11 10:33:13 +020062 }
63
64 void RequestIdentity(
65 rtc::KeyType key_type,
66 const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>&
67 observer) override {
68 store_->RequestIdentity(key_type, observer);
69 }
70
71 private:
72 rtc::scoped_refptr<RefCountedDtlsIdentityStore> store_;
73};
74
75} // anonymous namespace
76
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000077rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078CreatePeerConnectionFactory() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000079 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
80 new rtc::RefCountedObject<PeerConnectionFactory>());
henrike@webrtc.org28e20752013-07-10 00:45:36 +000081
perkj@webrtc.org81134d02015-01-12 08:30:16 +000082
83 // Call Initialize synchronously but make sure its executed on
84 // |signaling_thread|.
85 MethodCall0<PeerConnectionFactory, bool> call(
86 pc_factory.get(),
87 &PeerConnectionFactory::Initialize);
88 bool result = call.Marshal(pc_factory->signaling_thread());
89
90 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091 return NULL;
92 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +000093 return PeerConnectionFactoryProxy::Create(pc_factory->signaling_thread(),
94 pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000095}
96
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000097rtc::scoped_refptr<PeerConnectionFactoryInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000098CreatePeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000099 rtc::Thread* worker_thread,
100 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000101 AudioDeviceModule* default_adm,
102 cricket::WebRtcVideoEncoderFactory* encoder_factory,
103 cricket::WebRtcVideoDecoderFactory* decoder_factory) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000104 rtc::scoped_refptr<PeerConnectionFactory> pc_factory(
105 new rtc::RefCountedObject<PeerConnectionFactory>(worker_thread,
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000106 signaling_thread,
107 default_adm,
108 encoder_factory,
109 decoder_factory));
110
111 // Call Initialize synchronously but make sure its executed on
112 // |signaling_thread|.
113 MethodCall0<PeerConnectionFactory, bool> call(
114 pc_factory.get(),
115 &PeerConnectionFactory::Initialize);
116 bool result = call.Marshal(signaling_thread);
117
118 if (!result) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119 return NULL;
120 }
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000121 return PeerConnectionFactoryProxy::Create(signaling_thread, pc_factory);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122}
123
124PeerConnectionFactory::PeerConnectionFactory()
125 : owns_ptrs_(true),
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000126 wraps_current_thread_(false),
127 signaling_thread_(rtc::ThreadManager::Instance()->CurrentThread()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000128 worker_thread_(new rtc::Thread) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000129 if (!signaling_thread_) {
130 signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread();
131 wraps_current_thread_ = true;
132 }
133 worker_thread_->Start();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000134}
135
136PeerConnectionFactory::PeerConnectionFactory(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000137 rtc::Thread* worker_thread,
138 rtc::Thread* signaling_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000139 AudioDeviceModule* default_adm,
140 cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
141 cricket::WebRtcVideoDecoderFactory* video_decoder_factory)
142 : owns_ptrs_(false),
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000143 wraps_current_thread_(false),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000144 signaling_thread_(signaling_thread),
145 worker_thread_(worker_thread),
146 default_adm_(default_adm),
147 video_encoder_factory_(video_encoder_factory),
148 video_decoder_factory_(video_decoder_factory) {
149 ASSERT(worker_thread != NULL);
150 ASSERT(signaling_thread != NULL);
151 // TODO: Currently there is no way creating an external adm in
152 // libjingle source tree. So we can 't currently assert if this is NULL.
153 // ASSERT(default_adm != NULL);
154}
155
156PeerConnectionFactory::~PeerConnectionFactory() {
henrikg91d6ede2015-09-17 00:24:34 -0700157 RTC_DCHECK(signaling_thread_->IsCurrent());
Henrik Boström5e56c592015-08-11 10:33:13 +0200158 channel_manager_.reset(nullptr);
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000159
160 // Make sure |worker_thread_| and |signaling_thread_| outlive
deadbeef41b07982015-12-01 15:01:24 -0800161 // |dtls_identity_store_|, |default_socket_factory_| and
162 // |default_network_manager_|.
Henrik Boström5e56c592015-08-11 10:33:13 +0200163 dtls_identity_store_ = nullptr;
deadbeef41b07982015-12-01 15:01:24 -0800164 default_socket_factory_ = nullptr;
165 default_network_manager_ = nullptr;
jiayl@webrtc.orgd83f4ef2015-03-13 21:26:12 +0000166
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167 if (owns_ptrs_) {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000168 if (wraps_current_thread_)
169 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
fischman@webrtc.org29540b12014-04-17 22:54:30 +0000170 delete worker_thread_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 }
172}
173
174bool PeerConnectionFactory::Initialize() {
henrikg91d6ede2015-09-17 00:24:34 -0700175 RTC_DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000176 rtc::InitRandom(rtc::Time());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000177
deadbeef41b07982015-12-01 15:01:24 -0800178 default_network_manager_.reset(new rtc::BasicNetworkManager());
179 if (!default_network_manager_) {
180 return false;
181 }
182
183 default_socket_factory_.reset(
184 new rtc::BasicPacketSocketFactory(worker_thread_));
185 if (!default_socket_factory_) {
186 return false;
187 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000188
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189 // TODO: Need to make sure only one VoE is created inside
190 // WebRtcMediaEngine.
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000191 cricket::MediaEngineInterface* media_engine =
192 worker_thread_->Invoke<cricket::MediaEngineInterface*>(rtc::Bind(
193 &PeerConnectionFactory::CreateMediaEngine_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000194
solenbergfacbbec2015-09-24 00:41:50 -0700195 channel_manager_.reset(
196 new cricket::ChannelManager(media_engine, worker_thread_));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000197
stefan@webrtc.org85d27942014-06-09 12:51:39 +0000198 channel_manager_->SetVideoRtxEnabled(true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 if (!channel_manager_->Init()) {
200 return false;
201 }
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000202
Henrik Boström5e56c592015-08-11 10:33:13 +0200203 dtls_identity_store_ = new RefCountedDtlsIdentityStore(
204 signaling_thread_, worker_thread_);
jiayl@webrtc.org61e00b02015-03-04 22:17:38 +0000205
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 return true;
207}
208
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000209rtc::scoped_refptr<AudioSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000210PeerConnectionFactory::CreateAudioSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211 const MediaConstraintsInterface* constraints) {
henrikg91d6ede2015-09-17 00:24:34 -0700212 RTC_DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000213 rtc::scoped_refptr<LocalAudioSource> source(
wu@webrtc.org97077a32013-10-25 21:18:33 +0000214 LocalAudioSource::Create(options_, constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000215 return source;
216}
217
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000218rtc::scoped_refptr<VideoSourceInterface>
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000219PeerConnectionFactory::CreateVideoSource(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 cricket::VideoCapturer* capturer,
221 const MediaConstraintsInterface* constraints) {
henrikg91d6ede2015-09-17 00:24:34 -0700222 RTC_DCHECK(signaling_thread_->IsCurrent());
tommi6eca7e32015-12-15 04:27:11 -0800223 rtc::scoped_refptr<VideoSource> source(VideoSource::Create(
224 channel_manager_.get(), capturer, constraints, false));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000225 return VideoSourceProxy::Create(signaling_thread_, source);
226}
227
ivocd66b44d2016-01-15 03:06:36 -0800228bool PeerConnectionFactory::StartAecDump(rtc::PlatformFile file,
229 int64_t max_size_bytes) {
henrikg91d6ede2015-09-17 00:24:34 -0700230 RTC_DCHECK(signaling_thread_->IsCurrent());
ivocd66b44d2016-01-15 03:06:36 -0800231 return channel_manager_->StartAecDump(file, max_size_bytes);
wu@webrtc.orga9890802013-12-13 00:21:03 +0000232}
233
ivoc797ef122015-10-22 03:25:41 -0700234void PeerConnectionFactory::StopAecDump() {
235 RTC_DCHECK(signaling_thread_->IsCurrent());
236 channel_manager_->StopAecDump();
237}
238
ivoc112a3d82015-10-16 02:22:18 -0700239bool PeerConnectionFactory::StartRtcEventLog(rtc::PlatformFile file) {
240 RTC_DCHECK(signaling_thread_->IsCurrent());
241 return channel_manager_->StartRtcEventLog(file);
242}
243
244void PeerConnectionFactory::StopRtcEventLog() {
245 RTC_DCHECK(signaling_thread_->IsCurrent());
246 channel_manager_->StopRtcEventLog();
247}
248
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000249rtc::scoped_refptr<PeerConnectionInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250PeerConnectionFactory::CreatePeerConnection(
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000251 const PeerConnectionInterface::RTCConfiguration& configuration,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 const MediaConstraintsInterface* constraints,
deadbeef41b07982015-12-01 15:01:24 -0800253 rtc::scoped_ptr<cricket::PortAllocator> allocator,
254 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store,
255 PeerConnectionObserver* observer) {
256 RTC_DCHECK(signaling_thread_->IsCurrent());
257
258 if (!dtls_identity_store.get()) {
259 // Because |pc|->Initialize takes ownership of the store we need a new
260 // wrapper object that can be deleted without deleting the underlying
261 // |dtls_identity_store_|, protecting it from being deleted multiple times.
262 dtls_identity_store.reset(
263 new DtlsIdentityStoreWrapper(dtls_identity_store_));
264 }
265
266 if (!allocator) {
267 allocator.reset(new cricket::BasicPortAllocator(
268 default_network_manager_.get(), default_socket_factory_.get()));
269 }
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800270 allocator->SetNetworkIgnoreMask(options_.network_ignore_mask);
deadbeef41b07982015-12-01 15:01:24 -0800271
272 rtc::scoped_refptr<PeerConnection> pc(
273 new rtc::RefCountedObject<PeerConnection>(this));
274 if (!pc->Initialize(configuration, constraints, std::move(allocator),
275 std::move(dtls_identity_store), observer)) {
276 return nullptr;
277 }
278 return PeerConnectionProxy::Create(signaling_thread(), pc);
279}
280
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000281rtc::scoped_refptr<MediaStreamInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000282PeerConnectionFactory::CreateLocalMediaStream(const std::string& label) {
henrikg91d6ede2015-09-17 00:24:34 -0700283 RTC_DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284 return MediaStreamProxy::Create(signaling_thread_,
285 MediaStream::Create(label));
286}
287
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000288rtc::scoped_refptr<VideoTrackInterface>
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289PeerConnectionFactory::CreateVideoTrack(
290 const std::string& id,
291 VideoSourceInterface* source) {
henrikg91d6ede2015-09-17 00:24:34 -0700292 RTC_DCHECK(signaling_thread_->IsCurrent());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000293 rtc::scoped_refptr<VideoTrackInterface> track(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000294 VideoTrack::Create(id, source));
295 return VideoTrackProxy::Create(signaling_thread_, track);
296}
297
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000298rtc::scoped_refptr<AudioTrackInterface>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000299PeerConnectionFactory::CreateAudioTrack(const std::string& id,
300 AudioSourceInterface* source) {
henrikg91d6ede2015-09-17 00:24:34 -0700301 RTC_DCHECK(signaling_thread_->IsCurrent());
tommi6eca7e32015-12-15 04:27:11 -0800302 rtc::scoped_refptr<AudioTrackInterface> track(AudioTrack::Create(id, source));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000303 return AudioTrackProxy::Create(signaling_thread_, track);
304}
305
stefanc1aeaf02015-10-15 07:26:07 -0700306webrtc::MediaControllerInterface* PeerConnectionFactory::CreateMediaController()
307 const {
henrikg91d6ede2015-09-17 00:24:34 -0700308 RTC_DCHECK(signaling_thread_->IsCurrent());
stefanc1aeaf02015-10-15 07:26:07 -0700309 return MediaControllerInterface::Create(worker_thread_,
310 channel_manager_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311}
312
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000313rtc::Thread* PeerConnectionFactory::signaling_thread() {
perkj@webrtc.org81134d02015-01-12 08:30:16 +0000314 // This method can be called on a different thread when the factory is
315 // created in CreatePeerConnectionFactory().
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000316 return signaling_thread_;
317}
318
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000319rtc::Thread* PeerConnectionFactory::worker_thread() {
henrikg91d6ede2015-09-17 00:24:34 -0700320 RTC_DCHECK(signaling_thread_->IsCurrent());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 return worker_thread_;
322}
323
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000324cricket::MediaEngineInterface* PeerConnectionFactory::CreateMediaEngine_w() {
325 ASSERT(worker_thread_ == rtc::Thread::Current());
326 return cricket::WebRtcMediaEngineFactory::Create(
Fredrik Solenbergccb49e72015-05-19 11:37:56 +0200327 default_adm_.get(), video_encoder_factory_.get(),
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000328 video_decoder_factory_.get());
329}
330
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000331} // namespace webrtc