blob: 057026756879e9d0e1b632560450a0fb10c77dc6 [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"
nisseede5da42017-01-12 05:15:36 -080017#include "webrtc/base/checks.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010018#include "webrtc/base/common.h"
19#include "webrtc/base/logging.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010020#include "webrtc/base/stringencode.h"
21#include "webrtc/base/stringutils.h"
22#include "webrtc/base/trace_event.h"
kjellandera96e2d72016-02-04 23:52:28 -080023#include "webrtc/media/base/device.h"
kjellandera96e2d72016-02-04 23:52:28 -080024#include "webrtc/media/base/rtpdataengine.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010025#include "webrtc/pc/srtpfilter.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000026
27namespace cricket {
28
henrike@webrtc.org28e20752013-07-10 00:45:36 +000029
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000030using rtc::Bind;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032static DataEngineInterface* ConstructDataEngine() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033 return new RtpDataEngine();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034}
35
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036ChannelManager::ChannelManager(MediaEngineInterface* me,
37 DataEngineInterface* dme,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020038 rtc::Thread* thread) {
39 Construct(me, dme, thread, thread);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040}
41
42ChannelManager::ChannelManager(MediaEngineInterface* me,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020043 rtc::Thread* worker_thread,
44 rtc::Thread* network_thread) {
45 Construct(me, ConstructDataEngine(), worker_thread, network_thread);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046}
47
48void ChannelManager::Construct(MediaEngineInterface* me,
49 DataEngineInterface* dme,
Danil Chapovalov33b01f22016-05-11 19:55:27 +020050 rtc::Thread* worker_thread,
51 rtc::Thread* network_thread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000052 media_engine_.reset(me);
53 data_media_engine_.reset(dme);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000054 initialized_ = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000055 main_thread_ = rtc::Thread::Current();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056 worker_thread_ = worker_thread;
Danil Chapovalov33b01f22016-05-11 19:55:27 +020057 network_thread_ = network_thread;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000058 capturing_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000059 enable_rtx_ = false;
jbauchcb560652016-08-04 05:20:32 -070060 crypto_options_ = rtc::CryptoOptions::NoGcm();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061}
62
63ChannelManager::~ChannelManager() {
wu@webrtc.org9dba5252013-08-05 20:36:57 +000064 if (initialized_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 Terminate();
wu@webrtc.org9dba5252013-08-05 20:36:57 +000066 // If srtp is initialized (done by the Channel) then we must call
67 // srtp_shutdown to free all crypto kernel lists. But we need to make sure
68 // shutdown always called at the end, after channels are destroyed.
69 // ChannelManager d'tor is always called last, it's safe place to call
70 // shutdown.
71 ShutdownSrtp();
72 }
perkjc11b1842016-03-07 17:34:13 -080073 // The media engine needs to be deleted on the worker thread for thread safe
74 // destruction,
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -070075 worker_thread_->Invoke<void>(
76 RTC_FROM_HERE, Bind(&ChannelManager::DestructorDeletes_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077}
78
79bool ChannelManager::SetVideoRtxEnabled(bool enable) {
80 // To be safe, this call is only allowed before initialization. Apps like
81 // Flute only have a singleton ChannelManager and we don't want this flag to
82 // be toggled between calls or when there's concurrent calls. We expect apps
83 // to enable this at startup and retain that setting for the lifetime of the
84 // app.
85 if (!initialized_) {
86 enable_rtx_ = enable;
87 return true;
88 } else {
89 LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
90 return false;
91 }
92}
93
jbauchcb560652016-08-04 05:20:32 -070094bool ChannelManager::SetCryptoOptions(
95 const rtc::CryptoOptions& crypto_options) {
96 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, Bind(
97 &ChannelManager::SetCryptoOptions_w, this, crypto_options));
98}
99
100bool ChannelManager::SetCryptoOptions_w(
101 const rtc::CryptoOptions& crypto_options) {
102 if (!video_channels_.empty() || !voice_channels_.empty() ||
103 !data_channels_.empty()) {
104 LOG(LS_WARNING) << "Not changing crypto options in existing channels.";
105 }
106 crypto_options_ = crypto_options;
107#if defined(ENABLE_EXTERNAL_AUTH)
108 if (crypto_options_.enable_gcm_crypto_suites) {
109 // TODO(jbauch): Re-enable once https://crbug.com/628400 is resolved.
110 crypto_options_.enable_gcm_crypto_suites = false;
111 LOG(LS_WARNING) << "GCM ciphers are not supported with " <<
112 "ENABLE_EXTERNAL_AUTH and will be disabled.";
113 }
114#endif
115 return true;
116}
117
ossudedfd282016-06-14 07:12:39 -0700118void ChannelManager::GetSupportedAudioSendCodecs(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119 std::vector<AudioCodec>* codecs) const {
ossudedfd282016-06-14 07:12:39 -0700120 *codecs = media_engine_->audio_send_codecs();
121}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122
ossudedfd282016-06-14 07:12:39 -0700123void ChannelManager::GetSupportedAudioReceiveCodecs(
124 std::vector<AudioCodec>* codecs) const {
125 *codecs = media_engine_->audio_recv_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126}
127
128void ChannelManager::GetSupportedAudioRtpHeaderExtensions(
129 RtpHeaderExtensions* ext) const {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100130 *ext = media_engine_->GetAudioCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000131}
132
magjed3cf8ece2016-11-10 03:36:53 -0800133void ChannelManager::GetSupportedVideoCodecs(
134 std::vector<VideoCodec>* codecs) const {
135 codecs->clear();
136
brandtrffc61182016-11-28 06:02:22 -0800137 std::vector<VideoCodec> video_codecs = media_engine_->video_codecs();
138 for (const auto& video_codec : video_codecs) {
139 if (!enable_rtx_ &&
140 _stricmp(kRtxCodecName, video_codec.name.c_str()) == 0) {
magjed3cf8ece2016-11-10 03:36:53 -0800141 continue;
142 }
brandtrffc61182016-11-28 06:02:22 -0800143 codecs->push_back(video_codec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000144 }
145}
146
147void ChannelManager::GetSupportedVideoRtpHeaderExtensions(
148 RtpHeaderExtensions* ext) const {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100149 *ext = media_engine_->GetVideoCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150}
151
152void ChannelManager::GetSupportedDataCodecs(
153 std::vector<DataCodec>* codecs) const {
154 *codecs = data_media_engine_->data_codecs();
155}
156
157bool ChannelManager::Init() {
nisseede5da42017-01-12 05:15:36 -0800158 RTC_DCHECK(!initialized_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000159 if (initialized_) {
160 return false;
161 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200162 RTC_DCHECK(network_thread_);
163 RTC_DCHECK(worker_thread_);
164 if (!network_thread_->IsCurrent()) {
165 // Do not allow invoking calls to other threads on the network thread.
166 network_thread_->Invoke<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700167 RTC_FROM_HERE,
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200168 rtc::Bind(&rtc::Thread::SetAllowBlockingCalls, network_thread_, false));
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000169 }
170
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200171 initialized_ = worker_thread_->Invoke<bool>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700172 RTC_FROM_HERE, Bind(&ChannelManager::InitMediaEngine_w, this));
nisseede5da42017-01-12 05:15:36 -0800173 RTC_DCHECK(initialized_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174 return initialized_;
175}
176
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000177bool ChannelManager::InitMediaEngine_w() {
nisseede5da42017-01-12 05:15:36 -0800178 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
solenbergff976312016-03-30 23:28:51 -0700179 return media_engine_->Init();
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000180}
181
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000182void ChannelManager::Terminate() {
nisseede5da42017-01-12 05:15:36 -0800183 RTC_DCHECK(initialized_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000184 if (!initialized_) {
185 return;
186 }
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700187 worker_thread_->Invoke<void>(RTC_FROM_HERE,
188 Bind(&ChannelManager::Terminate_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189 initialized_ = false;
190}
191
hbos@webrtc.org4aef5fe2015-02-25 10:09:05 +0000192void ChannelManager::DestructorDeletes_w() {
nisseede5da42017-01-12 05:15:36 -0800193 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000194 media_engine_.reset(NULL);
195}
196
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000197void ChannelManager::Terminate_w() {
nisseede5da42017-01-12 05:15:36 -0800198 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 // Need to destroy the voice/video channels
200 while (!video_channels_.empty()) {
201 DestroyVideoChannel_w(video_channels_.back());
202 }
203 while (!voice_channels_.empty()) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200204 DestroyVoiceChannel_w(voice_channels_.back());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206}
207
208VoiceChannel* ChannelManager::CreateVoiceChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200209 webrtc::MediaControllerInterface* media_controller,
zhihuangb2cdd932017-01-19 16:54:25 -0800210 DtlsTransportInternal* rtp_transport,
211 DtlsTransportInternal* rtcp_transport,
zhihuangf5b251b2017-01-12 19:37:48 -0800212 rtc::Thread* signaling_thread,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200213 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700214 const std::string* bundle_transport_name,
deadbeefac22f702017-01-12 21:59:29 -0800215 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -0800216 bool srtp_required,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200217 const AudioOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218 return worker_thread_->Invoke<VoiceChannel*>(
zhihuangf5b251b2017-01-12 19:37:48 -0800219 RTC_FROM_HERE,
220 Bind(&ChannelManager::CreateVoiceChannel_w, this, media_controller,
221 rtp_transport, rtcp_transport, signaling_thread, content_name,
deadbeefac22f702017-01-12 21:59:29 -0800222 bundle_transport_name, rtcp_mux_required, srtp_required, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223}
224
225VoiceChannel* ChannelManager::CreateVoiceChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200226 webrtc::MediaControllerInterface* media_controller,
zhihuangb2cdd932017-01-19 16:54:25 -0800227 DtlsTransportInternal* rtp_transport,
228 DtlsTransportInternal* rtcp_transport,
zhihuangf5b251b2017-01-12 19:37:48 -0800229 rtc::Thread* signaling_thread,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200230 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700231 const std::string* bundle_transport_name,
deadbeefac22f702017-01-12 21:59:29 -0800232 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -0800233 bool srtp_required,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200234 const AudioOptions& options) {
nisseede5da42017-01-12 05:15:36 -0800235 RTC_DCHECK(initialized_);
236 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
237 RTC_DCHECK(nullptr != media_controller);
zhihuangf5b251b2017-01-12 19:37:48 -0800238
nisse51542be2016-02-12 02:27:06 -0800239 VoiceMediaChannel* media_channel = media_engine_->CreateChannel(
240 media_controller->call_w(), media_controller->config(), options);
Jelena Marusicc28a8962015-05-29 15:05:44 +0200241 if (!media_channel)
242 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000243
deadbeef7af91dd2016-12-13 11:29:11 -0800244 VoiceChannel* voice_channel = new VoiceChannel(
zhihuangf5b251b2017-01-12 19:37:48 -0800245 worker_thread_, network_thread_, signaling_thread, media_engine_.get(),
deadbeefac22f702017-01-12 21:59:29 -0800246 media_channel, content_name, rtcp_mux_required, srtp_required);
jbauchcb560652016-08-04 05:20:32 -0700247 voice_channel->SetCryptoOptions(crypto_options_);
zhihuangf5b251b2017-01-12 19:37:48 -0800248
249 if (!voice_channel->Init_w(rtp_transport, rtcp_transport)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 delete voice_channel;
Jelena Marusicc28a8962015-05-29 15:05:44 +0200251 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000252 }
253 voice_channels_.push_back(voice_channel);
254 return voice_channel;
255}
256
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200257void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100258 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000259 if (voice_channel) {
260 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700261 RTC_FROM_HERE,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200262 Bind(&ChannelManager::DestroyVoiceChannel_w, this, voice_channel));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 }
264}
265
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200266void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100267 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 // Destroy voice channel.
nisseede5da42017-01-12 05:15:36 -0800269 RTC_DCHECK(initialized_);
270 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271 VoiceChannels::iterator it = std::find(voice_channels_.begin(),
272 voice_channels_.end(), voice_channel);
nisseede5da42017-01-12 05:15:36 -0800273 RTC_DCHECK(it != voice_channels_.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274 if (it == voice_channels_.end())
275 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000276 voice_channels_.erase(it);
277 delete voice_channel;
278}
279
280VideoChannel* ChannelManager::CreateVideoChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200281 webrtc::MediaControllerInterface* media_controller,
zhihuangb2cdd932017-01-19 16:54:25 -0800282 DtlsTransportInternal* rtp_transport,
283 DtlsTransportInternal* rtcp_transport,
zhihuangf5b251b2017-01-12 19:37:48 -0800284 rtc::Thread* signaling_thread,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000285 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700286 const std::string* bundle_transport_name,
deadbeefac22f702017-01-12 21:59:29 -0800287 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -0800288 bool srtp_required,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200289 const VideoOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000290 return worker_thread_->Invoke<VideoChannel*>(
zhihuangf5b251b2017-01-12 19:37:48 -0800291 RTC_FROM_HERE,
292 Bind(&ChannelManager::CreateVideoChannel_w, this, media_controller,
293 rtp_transport, rtcp_transport, signaling_thread, content_name,
deadbeefac22f702017-01-12 21:59:29 -0800294 bundle_transport_name, rtcp_mux_required, srtp_required, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000295}
296
297VideoChannel* ChannelManager::CreateVideoChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200298 webrtc::MediaControllerInterface* media_controller,
zhihuangb2cdd932017-01-19 16:54:25 -0800299 DtlsTransportInternal* rtp_transport,
300 DtlsTransportInternal* rtcp_transport,
zhihuangf5b251b2017-01-12 19:37:48 -0800301 rtc::Thread* signaling_thread,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000302 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700303 const std::string* bundle_transport_name,
deadbeefac22f702017-01-12 21:59:29 -0800304 bool rtcp_mux_required,
deadbeef7af91dd2016-12-13 11:29:11 -0800305 bool srtp_required,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200306 const VideoOptions& options) {
nisseede5da42017-01-12 05:15:36 -0800307 RTC_DCHECK(initialized_);
308 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
309 RTC_DCHECK(nullptr != media_controller);
nisse51542be2016-02-12 02:27:06 -0800310 VideoMediaChannel* media_channel = media_engine_->CreateVideoChannel(
311 media_controller->call_w(), media_controller->config(), options);
deadbeefcbecd352015-09-23 11:50:27 -0700312 if (media_channel == NULL) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000313 return NULL;
deadbeefcbecd352015-09-23 11:50:27 -0700314 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000315
deadbeefac22f702017-01-12 21:59:29 -0800316 VideoChannel* video_channel = new VideoChannel(
317 worker_thread_, network_thread_, signaling_thread, media_channel,
318 content_name, rtcp_mux_required, srtp_required);
jbauchcb560652016-08-04 05:20:32 -0700319 video_channel->SetCryptoOptions(crypto_options_);
zhihuangf5b251b2017-01-12 19:37:48 -0800320 if (!video_channel->Init_w(rtp_transport, rtcp_transport)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000321 delete video_channel;
322 return NULL;
323 }
324 video_channels_.push_back(video_channel);
325 return video_channel;
326}
327
328void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100329 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 if (video_channel) {
331 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700332 RTC_FROM_HERE,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 Bind(&ChannelManager::DestroyVideoChannel_w, this, video_channel));
334 }
335}
336
337void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100338 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 // Destroy video channel.
nisseede5da42017-01-12 05:15:36 -0800340 RTC_DCHECK(initialized_);
341 RTC_DCHECK(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 VideoChannels::iterator it = std::find(video_channels_.begin(),
343 video_channels_.end(), video_channel);
nisseede5da42017-01-12 05:15:36 -0800344 RTC_DCHECK(it != video_channels_.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 if (it == video_channels_.end())
346 return;
347
348 video_channels_.erase(it);
349 delete video_channel;
350}
351
deadbeef953c2ce2017-01-09 14:53:41 -0800352RtpDataChannel* ChannelManager::CreateRtpDataChannel(
zhihuangebbe4f22016-12-06 10:45:42 -0800353 webrtc::MediaControllerInterface* media_controller,
zhihuangb2cdd932017-01-19 16:54:25 -0800354 DtlsTransportInternal* rtp_transport,
355 DtlsTransportInternal* rtcp_transport,
zhihuangf5b251b2017-01-12 19:37:48 -0800356 rtc::Thread* signaling_thread,
zhihuangebbe4f22016-12-06 10:45:42 -0800357 const std::string& content_name,
358 const std::string* bundle_transport_name,
deadbeefac22f702017-01-12 21:59:29 -0800359 bool rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -0800360 bool srtp_required) {
361 return worker_thread_->Invoke<RtpDataChannel*>(
zhihuangf5b251b2017-01-12 19:37:48 -0800362 RTC_FROM_HERE,
363 Bind(&ChannelManager::CreateRtpDataChannel_w, this, media_controller,
364 rtp_transport, rtcp_transport, signaling_thread, content_name,
deadbeefac22f702017-01-12 21:59:29 -0800365 bundle_transport_name, rtcp_mux_required, srtp_required));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366}
367
deadbeef953c2ce2017-01-09 14:53:41 -0800368RtpDataChannel* ChannelManager::CreateRtpDataChannel_w(
deadbeef7af91dd2016-12-13 11:29:11 -0800369 webrtc::MediaControllerInterface* media_controller,
zhihuangb2cdd932017-01-19 16:54:25 -0800370 DtlsTransportInternal* rtp_transport,
371 DtlsTransportInternal* rtcp_transport,
zhihuangf5b251b2017-01-12 19:37:48 -0800372 rtc::Thread* signaling_thread,
deadbeefcbecd352015-09-23 11:50:27 -0700373 const std::string& content_name,
skvlad6c87a672016-05-17 17:49:52 -0700374 const std::string* bundle_transport_name,
deadbeefac22f702017-01-12 21:59:29 -0800375 bool rtcp_mux_required,
deadbeef953c2ce2017-01-09 14:53:41 -0800376 bool srtp_required) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 // This is ok to alloc from a thread other than the worker thread.
nisseede5da42017-01-12 05:15:36 -0800378 RTC_DCHECK(initialized_);
zhihuangebbe4f22016-12-06 10:45:42 -0800379 MediaConfig config;
380 if (media_controller) {
381 config = media_controller->config();
382 }
deadbeef953c2ce2017-01-09 14:53:41 -0800383 DataMediaChannel* media_channel = data_media_engine_->CreateChannel(config);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000384 if (!media_channel) {
deadbeef953c2ce2017-01-09 14:53:41 -0800385 LOG(LS_WARNING) << "Failed to create RTP data channel.";
386 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000387 }
388
deadbeefac22f702017-01-12 21:59:29 -0800389 RtpDataChannel* data_channel = new RtpDataChannel(
390 worker_thread_, network_thread_, signaling_thread, media_channel,
391 content_name, rtcp_mux_required, srtp_required);
jbauchcb560652016-08-04 05:20:32 -0700392 data_channel->SetCryptoOptions(crypto_options_);
zhihuangf5b251b2017-01-12 19:37:48 -0800393 if (!data_channel->Init_w(rtp_transport, rtcp_transport)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000394 LOG(LS_WARNING) << "Failed to init data channel.";
395 delete data_channel;
deadbeef953c2ce2017-01-09 14:53:41 -0800396 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000397 }
398 data_channels_.push_back(data_channel);
399 return data_channel;
400}
401
deadbeef953c2ce2017-01-09 14:53:41 -0800402void ChannelManager::DestroyRtpDataChannel(RtpDataChannel* data_channel) {
403 TRACE_EVENT0("webrtc", "ChannelManager::DestroyRtpDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000404 if (data_channel) {
405 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700406 RTC_FROM_HERE,
deadbeef953c2ce2017-01-09 14:53:41 -0800407 Bind(&ChannelManager::DestroyRtpDataChannel_w, this, data_channel));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000408 }
409}
410
deadbeef953c2ce2017-01-09 14:53:41 -0800411void ChannelManager::DestroyRtpDataChannel_w(RtpDataChannel* data_channel) {
412 TRACE_EVENT0("webrtc", "ChannelManager::DestroyRtpDataChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000413 // Destroy data channel.
nisseede5da42017-01-12 05:15:36 -0800414 RTC_DCHECK(initialized_);
deadbeef953c2ce2017-01-09 14:53:41 -0800415 RtpDataChannels::iterator it =
416 std::find(data_channels_.begin(), data_channels_.end(), data_channel);
nisseede5da42017-01-12 05:15:36 -0800417 RTC_DCHECK(it != data_channels_.end());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000418 if (it == data_channels_.end())
419 return;
420
421 data_channels_.erase(it);
422 delete data_channel;
423}
424
ivocd66b44d2016-01-15 03:06:36 -0800425bool ChannelManager::StartAecDump(rtc::PlatformFile file,
426 int64_t max_size_bytes) {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700427 return worker_thread_->Invoke<bool>(
428 RTC_FROM_HERE, Bind(&MediaEngineInterface::StartAecDump,
429 media_engine_.get(), file, max_size_bytes));
wu@webrtc.orga9890802013-12-13 00:21:03 +0000430}
431
ivoc797ef122015-10-22 03:25:41 -0700432void ChannelManager::StopAecDump() {
433 worker_thread_->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700434 RTC_FROM_HERE,
ivoc797ef122015-10-22 03:25:41 -0700435 Bind(&MediaEngineInterface::StopAecDump, media_engine_.get()));
436}
437
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000438} // namespace cricket