blob: 06475e9eaa26f13ec0883a1c8e8654675cbf8e9e [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander65c7f672016-02-12 00:05:01 -08002 * Copyright 2004 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander65c7f672016-02-12 00:05:01 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010011#include "webrtc/pc/channelmanager.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013#include <algorithm>
14
Henrik Kjellander15583c12016-02-10 10:53:12 +010015#include "webrtc/api/mediacontroller.h"
16#include "webrtc/base/bind.h"
17#include "webrtc/base/common.h"
18#include "webrtc/base/logging.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010019#include "webrtc/base/stringencode.h"
20#include "webrtc/base/stringutils.h"
21#include "webrtc/base/trace_event.h"
kjellandera96e2d72016-02-04 23:52:28 -080022#include "webrtc/media/base/device.h"
23#include "webrtc/media/base/hybriddataengine.h"
24#include "webrtc/media/base/rtpdataengine.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025#ifdef HAVE_SCTP
kjellandera96e2d72016-02-04 23:52:28 -080026#include "webrtc/media/sctp/sctpdataengine.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027#endif
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010028#include "webrtc/pc/srtpfilter.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000029
30namespace cricket {
31
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000033using rtc::Bind;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035static DataEngineInterface* ConstructDataEngine() {
36#ifdef HAVE_SCTP
37 return new HybridDataEngine(new RtpDataEngine(), new SctpDataEngine());
38#else
39 return new RtpDataEngine();
40#endif
41}
42
henrike@webrtc.org28e20752013-07-10 00:45:36 +000043ChannelManager::ChannelManager(MediaEngineInterface* me,
44 DataEngineInterface* dme,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020045 rtc::Thread* thread) {
46 Construct(me, dme, thread, thread);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000047}
48
49ChannelManager::ChannelManager(MediaEngineInterface* me,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020050 rtc::Thread* worker_thread,
51 rtc::Thread* network_thread) {
52 Construct(me, ConstructDataEngine(), worker_thread, network_thread);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000053}
54
55void ChannelManager::Construct(MediaEngineInterface* me,
56 DataEngineInterface* dme,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020057 rtc::Thread* worker_thread,
58 rtc::Thread* network_thread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059 media_engine_.reset(me);
60 data_media_engine_.reset(dme);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061 initialized_ = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000062 main_thread_ = rtc::Thread::Current();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063 worker_thread_ = worker_thread;
Danil Chapovalov33b01f22016-05-11 19:55:27 +020064 network_thread_ = network_thread;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 capturing_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 enable_rtx_ = false;
jbauchcb560652016-08-04 05:20:32 -070067 crypto_options_ = rtc::CryptoOptions::NoGcm();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068}
69
70ChannelManager::~ChannelManager() {
wu@webrtc.org9dba5252013-08-05 20:36:57 +000071 if (initialized_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072 Terminate();
wu@webrtc.org9dba5252013-08-05 20:36:57 +000073 // If srtp is initialized (done by the Channel) then we must call
74 // srtp_shutdown to free all crypto kernel lists. But we need to make sure
75 // shutdown always called at the end, after channels are destroyed.
76 // ChannelManager d'tor is always called last, it's safe place to call
77 // shutdown.
78 ShutdownSrtp();
79 }
perkjc11b1842016-03-07 17:34:13 -080080 // The media engine needs to be deleted on the worker thread for thread safe
81 // destruction,
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070082 worker_thread_->Invoke<void>(
83 RTC_FROM_HERE, Bind(&ChannelManager::DestructorDeletes_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084}
85
86bool ChannelManager::SetVideoRtxEnabled(bool enable) {
87 // To be safe, this call is only allowed before initialization. Apps like
88 // Flute only have a singleton ChannelManager and we don't want this flag to
89 // be toggled between calls or when there's concurrent calls. We expect apps
90 // to enable this at startup and retain that setting for the lifetime of the
91 // app.
92 if (!initialized_) {
93 enable_rtx_ = enable;
94 return true;
95 } else {
96 LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
97 return false;
98 }
99}
100
jbauchcb560652016-08-04 05:20:32 -0700101bool ChannelManager::SetCryptoOptions(
102 const rtc::CryptoOptions& crypto_options) {
103 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, Bind(
104 &ChannelManager::SetCryptoOptions_w, this, crypto_options));
105}
106
107bool ChannelManager::SetCryptoOptions_w(
108 const rtc::CryptoOptions& crypto_options) {
109 if (!video_channels_.empty() || !voice_channels_.empty() ||
110 !data_channels_.empty()) {
111 LOG(LS_WARNING) << "Not changing crypto options in existing channels.";
112 }
113 crypto_options_ = crypto_options;
114#if defined(ENABLE_EXTERNAL_AUTH)
115 if (crypto_options_.enable_gcm_crypto_suites) {
116 // TODO(jbauch): Re-enable once https://crbug.com/628400 is resolved.
117 crypto_options_.enable_gcm_crypto_suites = false;
118 LOG(LS_WARNING) << "GCM ciphers are not supported with " <<
119 "ENABLE_EXTERNAL_AUTH and will be disabled.";
120 }
121#endif
122 return true;
123}
124
ossudedfd282016-06-14 07:12:39 -0700125void ChannelManager::GetSupportedAudioSendCodecs(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126 std::vector<AudioCodec>* codecs) const {
ossudedfd282016-06-14 07:12:39 -0700127 *codecs = media_engine_->audio_send_codecs();
128}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129
ossudedfd282016-06-14 07:12:39 -0700130void ChannelManager::GetSupportedAudioReceiveCodecs(
131 std::vector<AudioCodec>* codecs) const {
132 *codecs = media_engine_->audio_recv_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000133}
134
135void ChannelManager::GetSupportedAudioRtpHeaderExtensions(
136 RtpHeaderExtensions* ext) const {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100137 *ext = media_engine_->GetAudioCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000138}
139
magjed3cf8ece2016-11-10 03:36:53 -0800140void ChannelManager::GetSupportedVideoCodecs(
141 std::vector<VideoCodec>* codecs) const {
142 codecs->clear();
143
144 std::vector<VideoCodec>::const_iterator it;
145 for (it = media_engine_->video_codecs().begin();
146 it != media_engine_->video_codecs().end(); ++it) {
147 if (!enable_rtx_ && _stricmp(kRtxCodecName, it->name.c_str()) == 0) {
148 continue;
149 }
150 codecs->push_back(*it);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 }
152}
153
154void ChannelManager::GetSupportedVideoRtpHeaderExtensions(
155 RtpHeaderExtensions* ext) const {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100156 *ext = media_engine_->GetVideoCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157}
158
159void ChannelManager::GetSupportedDataCodecs(
160 std::vector<DataCodec>* codecs) const {
161 *codecs = data_media_engine_->data_codecs();
162}
163
164bool ChannelManager::Init() {
165 ASSERT(!initialized_);
166 if (initialized_) {
167 return false;
168 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200169 RTC_DCHECK(network_thread_);
170 RTC_DCHECK(worker_thread_);
171 if (!network_thread_->IsCurrent()) {
172 // Do not allow invoking calls to other threads on the network thread.
173 network_thread_->Invoke<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700174 RTC_FROM_HERE,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200175 rtc::Bind(&rtc::Thread::SetAllowBlockingCalls, network_thread_, false));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000176 }
177
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200178 initialized_ = worker_thread_->Invoke<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700179 RTC_FROM_HERE, Bind(&ChannelManager::InitMediaEngine_w, this));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000180 ASSERT(initialized_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181 return initialized_;
182}
183
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000184bool ChannelManager::InitMediaEngine_w() {
185 ASSERT(worker_thread_ == rtc::Thread::Current());
solenbergff976312016-03-30 23:28:51 -0700186 return media_engine_->Init();
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000187}
188
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189void ChannelManager::Terminate() {
190 ASSERT(initialized_);
191 if (!initialized_) {
192 return;
193 }
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700194 worker_thread_->Invoke<void>(RTC_FROM_HERE,
195 Bind(&ChannelManager::Terminate_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000196 initialized_ = false;
197}
198
hbos@webrtc.org4aef5fe2015-02-25 10:09:05 +0000199void ChannelManager::DestructorDeletes_w() {
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000200 ASSERT(worker_thread_ == rtc::Thread::Current());
201 media_engine_.reset(NULL);
202}
203
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204void ChannelManager::Terminate_w() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000205 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 // Need to destroy the voice/video channels
207 while (!video_channels_.empty()) {
208 DestroyVideoChannel_w(video_channels_.back());
209 }
210 while (!voice_channels_.empty()) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200211 DestroyVoiceChannel_w(voice_channels_.back());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000212 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000213}
214
215VoiceChannel* ChannelManager::CreateVoiceChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200216 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700217 TransportController* transport_controller,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200218 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700219 const std::string* bundle_transport_name,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200220 bool rtcp,
221 const AudioOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 return worker_thread_->Invoke<VoiceChannel*>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700223 RTC_FROM_HERE, Bind(&ChannelManager::CreateVoiceChannel_w, this,
224 media_controller, transport_controller, content_name,
225 bundle_transport_name, rtcp, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226}
227
228VoiceChannel* ChannelManager::CreateVoiceChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200229 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700230 TransportController* transport_controller,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200231 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700232 const std::string* bundle_transport_name,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200233 bool rtcp,
234 const AudioOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200236 ASSERT(worker_thread_ == rtc::Thread::Current());
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200237 ASSERT(nullptr != media_controller);
nisse51542be2016-02-12 02:27:06 -0800238 VoiceMediaChannel* media_channel = media_engine_->CreateChannel(
239 media_controller->call_w(), media_controller->config(), options);
Jelena Marusicc28a8962015-05-29 15:05:44 +0200240 if (!media_channel)
241 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000242
deadbeefcbecd352015-09-23 11:50:27 -0700243 VoiceChannel* voice_channel =
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200244 new VoiceChannel(worker_thread_, network_thread_, media_engine_.get(),
245 media_channel, transport_controller, content_name, rtcp);
jbauchcb560652016-08-04 05:20:32 -0700246 voice_channel->SetCryptoOptions(crypto_options_);
skvlad6c87a672016-05-17 17:49:52 -0700247 if (!voice_channel->Init_w(bundle_transport_name)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 delete voice_channel;
Jelena Marusicc28a8962015-05-29 15:05:44 +0200249 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 }
251 voice_channels_.push_back(voice_channel);
252 return voice_channel;
253}
254
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200255void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100256 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 if (voice_channel) {
258 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700259 RTC_FROM_HERE,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200260 Bind(&ChannelManager::DestroyVoiceChannel_w, this, voice_channel));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000261 }
262}
263
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200264void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100265 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000266 // Destroy voice channel.
267 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200268 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000269 VoiceChannels::iterator it = std::find(voice_channels_.begin(),
270 voice_channels_.end(), voice_channel);
271 ASSERT(it != voice_channels_.end());
272 if (it == voice_channels_.end())
273 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274 voice_channels_.erase(it);
275 delete voice_channel;
276}
277
278VideoChannel* ChannelManager::CreateVideoChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200279 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700280 TransportController* transport_controller,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000281 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700282 const std::string* bundle_transport_name,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000283 bool rtcp,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200284 const VideoOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000285 return worker_thread_->Invoke<VideoChannel*>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700286 RTC_FROM_HERE, Bind(&ChannelManager::CreateVideoChannel_w, this,
287 media_controller, transport_controller, content_name,
288 bundle_transport_name, rtcp, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289}
290
291VideoChannel* ChannelManager::CreateVideoChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200292 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700293 TransportController* transport_controller,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000294 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700295 const std::string* bundle_transport_name,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000296 bool rtcp,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200297 const VideoOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200299 ASSERT(worker_thread_ == rtc::Thread::Current());
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200300 ASSERT(nullptr != media_controller);
nisse51542be2016-02-12 02:27:06 -0800301 VideoMediaChannel* media_channel = media_engine_->CreateVideoChannel(
302 media_controller->call_w(), media_controller->config(), options);
deadbeefcbecd352015-09-23 11:50:27 -0700303 if (media_channel == NULL) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304 return NULL;
deadbeefcbecd352015-09-23 11:50:27 -0700305 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200307 VideoChannel* video_channel =
308 new VideoChannel(worker_thread_, network_thread_, media_channel,
309 transport_controller, content_name, rtcp);
jbauchcb560652016-08-04 05:20:32 -0700310 video_channel->SetCryptoOptions(crypto_options_);
skvlad6c87a672016-05-17 17:49:52 -0700311 if (!video_channel->Init_w(bundle_transport_name)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000312 delete video_channel;
313 return NULL;
314 }
315 video_channels_.push_back(video_channel);
316 return video_channel;
317}
318
319void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100320 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 if (video_channel) {
322 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700323 RTC_FROM_HERE,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 Bind(&ChannelManager::DestroyVideoChannel_w, this, video_channel));
325 }
326}
327
328void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100329 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 // Destroy video channel.
331 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200332 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 VideoChannels::iterator it = std::find(video_channels_.begin(),
334 video_channels_.end(), video_channel);
335 ASSERT(it != video_channels_.end());
336 if (it == video_channels_.end())
337 return;
338
339 video_channels_.erase(it);
340 delete video_channel;
341}
342
343DataChannel* ChannelManager::CreateDataChannel(
deadbeefcbecd352015-09-23 11:50:27 -0700344 TransportController* transport_controller,
345 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700346 const std::string* bundle_transport_name,
deadbeefcbecd352015-09-23 11:50:27 -0700347 bool rtcp,
348 DataChannelType channel_type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 return worker_thread_->Invoke<DataChannel*>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700350 RTC_FROM_HERE,
deadbeefcbecd352015-09-23 11:50:27 -0700351 Bind(&ChannelManager::CreateDataChannel_w, this, transport_controller,
skvlad6c87a672016-05-17 17:49:52 -0700352 content_name, bundle_transport_name, rtcp, channel_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353}
354
355DataChannel* ChannelManager::CreateDataChannel_w(
deadbeefcbecd352015-09-23 11:50:27 -0700356 TransportController* transport_controller,
357 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700358 const std::string* bundle_transport_name,
deadbeefcbecd352015-09-23 11:50:27 -0700359 bool rtcp,
360 DataChannelType data_channel_type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000361 // This is ok to alloc from a thread other than the worker thread.
362 ASSERT(initialized_);
363 DataMediaChannel* media_channel = data_media_engine_->CreateChannel(
364 data_channel_type);
365 if (!media_channel) {
366 LOG(LS_WARNING) << "Failed to create data channel of type "
367 << data_channel_type;
368 return NULL;
369 }
370
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200371 DataChannel* data_channel =
372 new DataChannel(worker_thread_, network_thread_, media_channel,
373 transport_controller, content_name, rtcp);
jbauchcb560652016-08-04 05:20:32 -0700374 data_channel->SetCryptoOptions(crypto_options_);
skvlad6c87a672016-05-17 17:49:52 -0700375 if (!data_channel->Init_w(bundle_transport_name)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000376 LOG(LS_WARNING) << "Failed to init data channel.";
377 delete data_channel;
378 return NULL;
379 }
380 data_channels_.push_back(data_channel);
381 return data_channel;
382}
383
384void ChannelManager::DestroyDataChannel(DataChannel* data_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100385 TRACE_EVENT0("webrtc", "ChannelManager::DestroyDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000386 if (data_channel) {
387 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700388 RTC_FROM_HERE,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389 Bind(&ChannelManager::DestroyDataChannel_w, this, data_channel));
390 }
391}
392
393void ChannelManager::DestroyDataChannel_w(DataChannel* data_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100394 TRACE_EVENT0("webrtc", "ChannelManager::DestroyDataChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395 // Destroy data channel.
396 ASSERT(initialized_);
397 DataChannels::iterator it = std::find(data_channels_.begin(),
398 data_channels_.end(), data_channel);
399 ASSERT(it != data_channels_.end());
400 if (it == data_channels_.end())
401 return;
402
403 data_channels_.erase(it);
404 delete data_channel;
405}
406
ivocd66b44d2016-01-15 03:06:36 -0800407bool ChannelManager::StartAecDump(rtc::PlatformFile file,
408 int64_t max_size_bytes) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700409 return worker_thread_->Invoke<bool>(
410 RTC_FROM_HERE, Bind(&MediaEngineInterface::StartAecDump,
411 media_engine_.get(), file, max_size_bytes));
wu@webrtc.orga9890802013-12-13 00:21:03 +0000412}
413
ivoc797ef122015-10-22 03:25:41 -0700414void ChannelManager::StopAecDump() {
415 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700416 RTC_FROM_HERE,
ivoc797ef122015-10-22 03:25:41 -0700417 Bind(&MediaEngineInterface::StopAecDump, media_engine_.get()));
418}
419
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000420} // namespace cricket