blob: fb6f44f846d7acf50543ec83f491a22a84bc5b80 [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
magjed9f71ec52016-11-09 23:45:11 -080032static bool IsRtxCodec(const VideoCodec& codec) {
33 return _stricmp(kRtxCodecName, codec.name.c_str()) == 0;
34}
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000036using rtc::Bind;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038static DataEngineInterface* ConstructDataEngine() {
39#ifdef HAVE_SCTP
40 return new HybridDataEngine(new RtpDataEngine(), new SctpDataEngine());
41#else
42 return new RtpDataEngine();
43#endif
44}
45
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046ChannelManager::ChannelManager(MediaEngineInterface* me,
47 DataEngineInterface* dme,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020048 rtc::Thread* thread) {
49 Construct(me, dme, thread, thread);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000050}
51
52ChannelManager::ChannelManager(MediaEngineInterface* me,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020053 rtc::Thread* worker_thread,
54 rtc::Thread* network_thread) {
55 Construct(me, ConstructDataEngine(), worker_thread, network_thread);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056}
57
58void ChannelManager::Construct(MediaEngineInterface* me,
59 DataEngineInterface* dme,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020060 rtc::Thread* worker_thread,
61 rtc::Thread* network_thread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 media_engine_.reset(me);
63 data_media_engine_.reset(dme);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000064 initialized_ = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000065 main_thread_ = rtc::Thread::Current();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 worker_thread_ = worker_thread;
Danil Chapovalov33b01f22016-05-11 19:55:27 +020067 network_thread_ = network_thread;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068 capturing_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069 enable_rtx_ = false;
jbauchcb560652016-08-04 05:20:32 -070070 crypto_options_ = rtc::CryptoOptions::NoGcm();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000071}
72
73ChannelManager::~ChannelManager() {
wu@webrtc.org9dba5252013-08-05 20:36:57 +000074 if (initialized_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000075 Terminate();
wu@webrtc.org9dba5252013-08-05 20:36:57 +000076 // If srtp is initialized (done by the Channel) then we must call
77 // srtp_shutdown to free all crypto kernel lists. But we need to make sure
78 // shutdown always called at the end, after channels are destroyed.
79 // ChannelManager d'tor is always called last, it's safe place to call
80 // shutdown.
81 ShutdownSrtp();
82 }
perkjc11b1842016-03-07 17:34:13 -080083 // The media engine needs to be deleted on the worker thread for thread safe
84 // destruction,
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070085 worker_thread_->Invoke<void>(
86 RTC_FROM_HERE, Bind(&ChannelManager::DestructorDeletes_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087}
88
89bool ChannelManager::SetVideoRtxEnabled(bool enable) {
90 // To be safe, this call is only allowed before initialization. Apps like
91 // Flute only have a singleton ChannelManager and we don't want this flag to
92 // be toggled between calls or when there's concurrent calls. We expect apps
93 // to enable this at startup and retain that setting for the lifetime of the
94 // app.
95 if (!initialized_) {
96 enable_rtx_ = enable;
97 return true;
98 } else {
99 LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
100 return false;
101 }
102}
103
jbauchcb560652016-08-04 05:20:32 -0700104bool ChannelManager::SetCryptoOptions(
105 const rtc::CryptoOptions& crypto_options) {
106 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, Bind(
107 &ChannelManager::SetCryptoOptions_w, this, crypto_options));
108}
109
110bool ChannelManager::SetCryptoOptions_w(
111 const rtc::CryptoOptions& crypto_options) {
112 if (!video_channels_.empty() || !voice_channels_.empty() ||
113 !data_channels_.empty()) {
114 LOG(LS_WARNING) << "Not changing crypto options in existing channels.";
115 }
116 crypto_options_ = crypto_options;
117#if defined(ENABLE_EXTERNAL_AUTH)
118 if (crypto_options_.enable_gcm_crypto_suites) {
119 // TODO(jbauch): Re-enable once https://crbug.com/628400 is resolved.
120 crypto_options_.enable_gcm_crypto_suites = false;
121 LOG(LS_WARNING) << "GCM ciphers are not supported with " <<
122 "ENABLE_EXTERNAL_AUTH and will be disabled.";
123 }
124#endif
125 return true;
126}
127
ossudedfd282016-06-14 07:12:39 -0700128void ChannelManager::GetSupportedAudioSendCodecs(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129 std::vector<AudioCodec>* codecs) const {
ossudedfd282016-06-14 07:12:39 -0700130 *codecs = media_engine_->audio_send_codecs();
131}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000132
ossudedfd282016-06-14 07:12:39 -0700133void ChannelManager::GetSupportedAudioReceiveCodecs(
134 std::vector<AudioCodec>* codecs) const {
135 *codecs = media_engine_->audio_recv_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136}
137
138void ChannelManager::GetSupportedAudioRtpHeaderExtensions(
139 RtpHeaderExtensions* ext) const {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100140 *ext = media_engine_->GetAudioCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000141}
142
magjed9f71ec52016-11-09 23:45:11 -0800143std::vector<VideoCodec> ChannelManager::GetSupportedVideoCodecs() const {
144 std::vector<VideoCodec> codecs = media_engine_->video_codecs();
145 if (!enable_rtx_) {
146 codecs.erase(std::remove_if(codecs.begin(), codecs.end(), &IsRtxCodec),
147 codecs.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148 }
magjed9f71ec52016-11-09 23:45:11 -0800149 return codecs;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150}
151
152void ChannelManager::GetSupportedVideoRtpHeaderExtensions(
153 RtpHeaderExtensions* ext) const {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100154 *ext = media_engine_->GetVideoCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000155}
156
157void ChannelManager::GetSupportedDataCodecs(
158 std::vector<DataCodec>* codecs) const {
159 *codecs = data_media_engine_->data_codecs();
160}
161
162bool ChannelManager::Init() {
163 ASSERT(!initialized_);
164 if (initialized_) {
165 return false;
166 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200167 RTC_DCHECK(network_thread_);
168 RTC_DCHECK(worker_thread_);
169 if (!network_thread_->IsCurrent()) {
170 // Do not allow invoking calls to other threads on the network thread.
171 network_thread_->Invoke<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700172 RTC_FROM_HERE,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200173 rtc::Bind(&rtc::Thread::SetAllowBlockingCalls, network_thread_, false));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000174 }
175
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200176 initialized_ = worker_thread_->Invoke<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700177 RTC_FROM_HERE, Bind(&ChannelManager::InitMediaEngine_w, this));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000178 ASSERT(initialized_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000179 return initialized_;
180}
181
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000182bool ChannelManager::InitMediaEngine_w() {
183 ASSERT(worker_thread_ == rtc::Thread::Current());
solenbergff976312016-03-30 23:28:51 -0700184 return media_engine_->Init();
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000185}
186
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000187void ChannelManager::Terminate() {
188 ASSERT(initialized_);
189 if (!initialized_) {
190 return;
191 }
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700192 worker_thread_->Invoke<void>(RTC_FROM_HERE,
193 Bind(&ChannelManager::Terminate_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000194 initialized_ = false;
195}
196
hbos@webrtc.org4aef5fe2015-02-25 10:09:05 +0000197void ChannelManager::DestructorDeletes_w() {
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000198 ASSERT(worker_thread_ == rtc::Thread::Current());
199 media_engine_.reset(NULL);
200}
201
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202void ChannelManager::Terminate_w() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000203 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204 // Need to destroy the voice/video channels
205 while (!video_channels_.empty()) {
206 DestroyVideoChannel_w(video_channels_.back());
207 }
208 while (!voice_channels_.empty()) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200209 DestroyVoiceChannel_w(voice_channels_.back());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211}
212
213VoiceChannel* ChannelManager::CreateVoiceChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200214 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700215 TransportController* transport_controller,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200216 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700217 const std::string* bundle_transport_name,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200218 bool rtcp,
219 const AudioOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 return worker_thread_->Invoke<VoiceChannel*>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700221 RTC_FROM_HERE, Bind(&ChannelManager::CreateVoiceChannel_w, this,
222 media_controller, transport_controller, content_name,
223 bundle_transport_name, rtcp, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000224}
225
226VoiceChannel* ChannelManager::CreateVoiceChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200227 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700228 TransportController* transport_controller,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200229 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700230 const std::string* bundle_transport_name,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200231 bool rtcp,
232 const AudioOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000233 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200234 ASSERT(worker_thread_ == rtc::Thread::Current());
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200235 ASSERT(nullptr != media_controller);
nisse51542be2016-02-12 02:27:06 -0800236 VoiceMediaChannel* media_channel = media_engine_->CreateChannel(
237 media_controller->call_w(), media_controller->config(), options);
Jelena Marusicc28a8962015-05-29 15:05:44 +0200238 if (!media_channel)
239 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000240
deadbeefcbecd352015-09-23 11:50:27 -0700241 VoiceChannel* voice_channel =
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200242 new VoiceChannel(worker_thread_, network_thread_, media_engine_.get(),
243 media_channel, transport_controller, content_name, rtcp);
jbauchcb560652016-08-04 05:20:32 -0700244 voice_channel->SetCryptoOptions(crypto_options_);
skvlad6c87a672016-05-17 17:49:52 -0700245 if (!voice_channel->Init_w(bundle_transport_name)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000246 delete voice_channel;
Jelena Marusicc28a8962015-05-29 15:05:44 +0200247 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 }
249 voice_channels_.push_back(voice_channel);
250 return voice_channel;
251}
252
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200253void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100254 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 if (voice_channel) {
256 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700257 RTC_FROM_HERE,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200258 Bind(&ChannelManager::DestroyVoiceChannel_w, this, voice_channel));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 }
260}
261
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200262void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100263 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000264 // Destroy voice channel.
265 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200266 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000267 VoiceChannels::iterator it = std::find(voice_channels_.begin(),
268 voice_channels_.end(), voice_channel);
269 ASSERT(it != voice_channels_.end());
270 if (it == voice_channels_.end())
271 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 voice_channels_.erase(it);
273 delete voice_channel;
274}
275
276VideoChannel* ChannelManager::CreateVideoChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200277 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700278 TransportController* transport_controller,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000279 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700280 const std::string* bundle_transport_name,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000281 bool rtcp,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200282 const VideoOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000283 return worker_thread_->Invoke<VideoChannel*>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700284 RTC_FROM_HERE, Bind(&ChannelManager::CreateVideoChannel_w, this,
285 media_controller, transport_controller, content_name,
286 bundle_transport_name, rtcp, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000287}
288
289VideoChannel* ChannelManager::CreateVideoChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200290 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700291 TransportController* transport_controller,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000292 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700293 const std::string* bundle_transport_name,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000294 bool rtcp,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200295 const VideoOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000296 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200297 ASSERT(worker_thread_ == rtc::Thread::Current());
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200298 ASSERT(nullptr != media_controller);
nisse51542be2016-02-12 02:27:06 -0800299 VideoMediaChannel* media_channel = media_engine_->CreateVideoChannel(
300 media_controller->call_w(), media_controller->config(), options);
deadbeefcbecd352015-09-23 11:50:27 -0700301 if (media_channel == NULL) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000302 return NULL;
deadbeefcbecd352015-09-23 11:50:27 -0700303 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200305 VideoChannel* video_channel =
306 new VideoChannel(worker_thread_, network_thread_, media_channel,
307 transport_controller, content_name, rtcp);
jbauchcb560652016-08-04 05:20:32 -0700308 video_channel->SetCryptoOptions(crypto_options_);
skvlad6c87a672016-05-17 17:49:52 -0700309 if (!video_channel->Init_w(bundle_transport_name)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000310 delete video_channel;
311 return NULL;
312 }
313 video_channels_.push_back(video_channel);
314 return video_channel;
315}
316
317void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100318 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319 if (video_channel) {
320 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700321 RTC_FROM_HERE,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 Bind(&ChannelManager::DestroyVideoChannel_w, this, video_channel));
323 }
324}
325
326void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100327 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 // Destroy video channel.
329 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200330 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000331 VideoChannels::iterator it = std::find(video_channels_.begin(),
332 video_channels_.end(), video_channel);
333 ASSERT(it != video_channels_.end());
334 if (it == video_channels_.end())
335 return;
336
337 video_channels_.erase(it);
338 delete video_channel;
339}
340
341DataChannel* ChannelManager::CreateDataChannel(
deadbeefcbecd352015-09-23 11:50:27 -0700342 TransportController* transport_controller,
343 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700344 const std::string* bundle_transport_name,
deadbeefcbecd352015-09-23 11:50:27 -0700345 bool rtcp,
346 DataChannelType channel_type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 return worker_thread_->Invoke<DataChannel*>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700348 RTC_FROM_HERE,
deadbeefcbecd352015-09-23 11:50:27 -0700349 Bind(&ChannelManager::CreateDataChannel_w, this, transport_controller,
skvlad6c87a672016-05-17 17:49:52 -0700350 content_name, bundle_transport_name, rtcp, channel_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351}
352
353DataChannel* ChannelManager::CreateDataChannel_w(
deadbeefcbecd352015-09-23 11:50:27 -0700354 TransportController* transport_controller,
355 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700356 const std::string* bundle_transport_name,
deadbeefcbecd352015-09-23 11:50:27 -0700357 bool rtcp,
358 DataChannelType data_channel_type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 // This is ok to alloc from a thread other than the worker thread.
360 ASSERT(initialized_);
361 DataMediaChannel* media_channel = data_media_engine_->CreateChannel(
362 data_channel_type);
363 if (!media_channel) {
364 LOG(LS_WARNING) << "Failed to create data channel of type "
365 << data_channel_type;
366 return NULL;
367 }
368
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200369 DataChannel* data_channel =
370 new DataChannel(worker_thread_, network_thread_, media_channel,
371 transport_controller, content_name, rtcp);
jbauchcb560652016-08-04 05:20:32 -0700372 data_channel->SetCryptoOptions(crypto_options_);
skvlad6c87a672016-05-17 17:49:52 -0700373 if (!data_channel->Init_w(bundle_transport_name)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374 LOG(LS_WARNING) << "Failed to init data channel.";
375 delete data_channel;
376 return NULL;
377 }
378 data_channels_.push_back(data_channel);
379 return data_channel;
380}
381
382void ChannelManager::DestroyDataChannel(DataChannel* data_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100383 TRACE_EVENT0("webrtc", "ChannelManager::DestroyDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384 if (data_channel) {
385 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700386 RTC_FROM_HERE,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000387 Bind(&ChannelManager::DestroyDataChannel_w, this, data_channel));
388 }
389}
390
391void ChannelManager::DestroyDataChannel_w(DataChannel* data_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100392 TRACE_EVENT0("webrtc", "ChannelManager::DestroyDataChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000393 // Destroy data channel.
394 ASSERT(initialized_);
395 DataChannels::iterator it = std::find(data_channels_.begin(),
396 data_channels_.end(), data_channel);
397 ASSERT(it != data_channels_.end());
398 if (it == data_channels_.end())
399 return;
400
401 data_channels_.erase(it);
402 delete data_channel;
403}
404
ivocd66b44d2016-01-15 03:06:36 -0800405bool ChannelManager::StartAecDump(rtc::PlatformFile file,
406 int64_t max_size_bytes) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700407 return worker_thread_->Invoke<bool>(
408 RTC_FROM_HERE, Bind(&MediaEngineInterface::StartAecDump,
409 media_engine_.get(), file, max_size_bytes));
wu@webrtc.orga9890802013-12-13 00:21:03 +0000410}
411
ivoc797ef122015-10-22 03:25:41 -0700412void ChannelManager::StopAecDump() {
413 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700414 RTC_FROM_HERE,
ivoc797ef122015-10-22 03:25:41 -0700415 Bind(&MediaEngineInterface::StopAecDump, media_engine_.get()));
416}
417
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000418} // namespace cricket