blob: c936caf16b3b96ff78f5d4ee85f9d15e1d9dfb91 [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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/channel_manager.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013#include <algorithm>
Steve Anton36b29d12017-10-30 09:57:42 -070014#include <utility>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000015
Karl Wiberg918f50c2018-07-05 11:40:33 +020016#include "absl/memory/memory.h"
Niels Möller3c7d5992018-10-19 15:29:54 +020017#include "absl/strings/match.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "media/base/media_constants.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "rtc_base/checks.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "rtc_base/location.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/logging.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "rtc_base/thread_checker.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_base/trace_event.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000024
25namespace cricket {
26
Steve Antonc9e15602017-11-06 15:40:09 -080027ChannelManager::ChannelManager(
28 std::unique_ptr<MediaEngineInterface> media_engine,
29 std::unique_ptr<DataEngineInterface> data_engine,
30 rtc::Thread* worker_thread,
31 rtc::Thread* network_thread)
32 : media_engine_(std::move(media_engine)),
33 data_engine_(std::move(data_engine)),
34 main_thread_(rtc::Thread::Current()),
35 worker_thread_(worker_thread),
36 network_thread_(network_thread) {
37 RTC_DCHECK(data_engine_);
38 RTC_DCHECK(worker_thread_);
39 RTC_DCHECK(network_thread_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040}
41
42ChannelManager::~ChannelManager() {
wu@webrtc.org9dba5252013-08-05 20:36:57 +000043 if (initialized_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044 Terminate();
wu@webrtc.org9dba5252013-08-05 20:36:57 +000045 }
perkjc11b1842016-03-07 17:34:13 -080046 // The media engine needs to be deleted on the worker thread for thread safe
47 // destruction,
Steve Antonc9e15602017-11-06 15:40:09 -080048 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] { media_engine_.reset(); });
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049}
50
51bool ChannelManager::SetVideoRtxEnabled(bool enable) {
52 // To be safe, this call is only allowed before initialization. Apps like
53 // Flute only have a singleton ChannelManager and we don't want this flag to
54 // be toggled between calls or when there's concurrent calls. We expect apps
55 // to enable this at startup and retain that setting for the lifetime of the
56 // app.
57 if (!initialized_) {
58 enable_rtx_ = enable;
59 return true;
60 } else {
Mirko Bonadei675513b2017-11-09 11:09:25 +010061 RTC_LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062 return false;
63 }
64}
65
ossudedfd282016-06-14 07:12:39 -070066void ChannelManager::GetSupportedAudioSendCodecs(
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067 std::vector<AudioCodec>* codecs) const {
zhihuang38ede132017-06-15 12:52:32 -070068 if (!media_engine_) {
69 return;
70 }
Sebastian Jansson6eb8a162018-11-16 11:29:55 +010071 *codecs = media_engine_->voice().send_codecs();
ossudedfd282016-06-14 07:12:39 -070072}
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073
ossudedfd282016-06-14 07:12:39 -070074void ChannelManager::GetSupportedAudioReceiveCodecs(
75 std::vector<AudioCodec>* codecs) const {
zhihuang38ede132017-06-15 12:52:32 -070076 if (!media_engine_) {
77 return;
78 }
Sebastian Jansson6eb8a162018-11-16 11:29:55 +010079 *codecs = media_engine_->voice().recv_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080}
81
82void ChannelManager::GetSupportedAudioRtpHeaderExtensions(
83 RtpHeaderExtensions* ext) const {
zhihuang38ede132017-06-15 12:52:32 -070084 if (!media_engine_) {
85 return;
86 }
Sebastian Jansson6eb8a162018-11-16 11:29:55 +010087 *ext = media_engine_->voice().GetCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088}
89
magjed3cf8ece2016-11-10 03:36:53 -080090void ChannelManager::GetSupportedVideoCodecs(
91 std::vector<VideoCodec>* codecs) const {
zhihuang38ede132017-06-15 12:52:32 -070092 if (!media_engine_) {
93 return;
94 }
magjed3cf8ece2016-11-10 03:36:53 -080095 codecs->clear();
96
Sebastian Jansson6eb8a162018-11-16 11:29:55 +010097 std::vector<VideoCodec> video_codecs = media_engine_->video().codecs();
brandtrffc61182016-11-28 06:02:22 -080098 for (const auto& video_codec : video_codecs) {
99 if (!enable_rtx_ &&
Niels Möller3c7d5992018-10-19 15:29:54 +0200100 absl::EqualsIgnoreCase(kRtxCodecName, video_codec.name)) {
magjed3cf8ece2016-11-10 03:36:53 -0800101 continue;
102 }
brandtrffc61182016-11-28 06:02:22 -0800103 codecs->push_back(video_codec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104 }
105}
106
107void ChannelManager::GetSupportedVideoRtpHeaderExtensions(
108 RtpHeaderExtensions* ext) const {
zhihuang38ede132017-06-15 12:52:32 -0700109 if (!media_engine_) {
110 return;
111 }
Sebastian Jansson6eb8a162018-11-16 11:29:55 +0100112 *ext = media_engine_->video().GetCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000113}
114
115void ChannelManager::GetSupportedDataCodecs(
116 std::vector<DataCodec>* codecs) const {
Steve Antonc9e15602017-11-06 15:40:09 -0800117 *codecs = data_engine_->data_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000118}
119
120bool ChannelManager::Init() {
nisseede5da42017-01-12 05:15:36 -0800121 RTC_DCHECK(!initialized_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122 if (initialized_) {
123 return false;
124 }
Danil Chapovalov33b01f22016-05-11 19:55:27 +0200125 RTC_DCHECK(network_thread_);
126 RTC_DCHECK(worker_thread_);
127 if (!network_thread_->IsCurrent()) {
128 // Do not allow invoking calls to other threads on the network thread.
Steve Antonc9e15602017-11-06 15:40:09 -0800129 network_thread_->Invoke<void>(
130 RTC_FROM_HERE, [&] { network_thread_->SetAllowBlockingCalls(false); });
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000131 }
132
zhihuang38ede132017-06-15 12:52:32 -0700133 if (media_engine_) {
Steve Antonc9e15602017-11-06 15:40:09 -0800134 initialized_ = worker_thread_->Invoke<bool>(
135 RTC_FROM_HERE, [&] { return media_engine_->Init(); });
136 RTC_DCHECK(initialized_);
137 } else {
138 initialized_ = true;
zhihuang38ede132017-06-15 12:52:32 -0700139 }
Steve Antonc9e15602017-11-06 15:40:09 -0800140 return initialized_;
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000141}
142
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000143void ChannelManager::Terminate() {
nisseede5da42017-01-12 05:15:36 -0800144 RTC_DCHECK(initialized_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145 if (!initialized_) {
146 return;
147 }
Steve Antonc9e15602017-11-06 15:40:09 -0800148 // Need to destroy the channels on the worker thread.
149 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
150 video_channels_.clear();
151 voice_channels_.clear();
152 data_channels_.clear();
153 });
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154 initialized_ = false;
155}
156
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157VoiceChannel* ChannelManager::CreateVoiceChannel(
nisseeaabdf62017-05-05 02:23:02 -0700158 webrtc::Call* call,
159 const cricket::MediaConfig& media_config,
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800160 webrtc::RtpTransportInternal* rtp_transport,
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700161 webrtc::MediaTransportInterface* media_transport,
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800162 rtc::Thread* signaling_thread,
163 const std::string& content_name,
164 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700165 const webrtc::CryptoOptions& crypto_options,
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800166 const AudioOptions& options) {
167 if (!worker_thread_->IsCurrent()) {
168 return worker_thread_->Invoke<VoiceChannel*>(RTC_FROM_HERE, [&] {
169 return CreateVoiceChannel(call, media_config, rtp_transport,
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700170 media_transport, signaling_thread, content_name,
171 srtp_required, crypto_options, options);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800172 });
173 }
174
175 RTC_DCHECK_RUN_ON(worker_thread_);
176 RTC_DCHECK(initialized_);
177 RTC_DCHECK(call);
178 if (!media_engine_) {
179 return nullptr;
180 }
181
Sebastian Jansson6eb8a162018-11-16 11:29:55 +0100182 VoiceMediaChannel* media_channel = media_engine_->voice().CreateMediaChannel(
183 call, media_config, options, crypto_options);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800184 if (!media_channel) {
185 return nullptr;
186 }
187
Karl Wiberg918f50c2018-07-05 11:40:33 +0200188 auto voice_channel = absl::make_unique<VoiceChannel>(
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800189 worker_thread_, network_thread_, signaling_thread, media_engine_.get(),
Karl Wiberg918f50c2018-07-05 11:40:33 +0200190 absl::WrapUnique(media_channel), content_name, srtp_required,
Zhi Huange830e682018-03-30 10:48:35 -0700191 crypto_options);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800192
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700193 voice_channel->Init_w(rtp_transport, media_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800194
195 VoiceChannel* voice_channel_ptr = voice_channel.get();
196 voice_channels_.push_back(std::move(voice_channel));
197 return voice_channel_ptr;
198}
199
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200200void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100201 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel");
Steve Antonc9e15602017-11-06 15:40:09 -0800202 if (!voice_channel) {
203 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000204 }
Steve Antonc9e15602017-11-06 15:40:09 -0800205 if (!worker_thread_->IsCurrent()) {
206 worker_thread_->Invoke<void>(RTC_FROM_HERE,
207 [&] { DestroyVoiceChannel(voice_channel); });
208 return;
209 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210
nisseede5da42017-01-12 05:15:36 -0800211 RTC_DCHECK(initialized_);
Steve Anton774115c2017-08-30 10:48:46 -0700212
213 auto it = std::find_if(voice_channels_.begin(), voice_channels_.end(),
214 [&](const std::unique_ptr<VoiceChannel>& p) {
215 return p.get() == voice_channel;
216 });
nisseede5da42017-01-12 05:15:36 -0800217 RTC_DCHECK(it != voice_channels_.end());
Steve Antonc9e15602017-11-06 15:40:09 -0800218 if (it == voice_channels_.end()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000219 return;
Steve Antonc9e15602017-11-06 15:40:09 -0800220 }
221
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 voice_channels_.erase(it);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223}
224
225VideoChannel* ChannelManager::CreateVideoChannel(
nisseeaabdf62017-05-05 02:23:02 -0700226 webrtc::Call* call,
227 const cricket::MediaConfig& media_config,
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800228 webrtc::RtpTransportInternal* rtp_transport,
Niels Möller46879152019-01-07 15:54:47 +0100229 webrtc::MediaTransportInterface* media_transport,
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800230 rtc::Thread* signaling_thread,
231 const std::string& content_name,
232 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700233 const webrtc::CryptoOptions& crypto_options,
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800234 const VideoOptions& options) {
235 if (!worker_thread_->IsCurrent()) {
236 return worker_thread_->Invoke<VideoChannel*>(RTC_FROM_HERE, [&] {
237 return CreateVideoChannel(call, media_config, rtp_transport,
Niels Möller46879152019-01-07 15:54:47 +0100238 media_transport, signaling_thread, content_name,
239 srtp_required, crypto_options, options);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800240 });
241 }
242
243 RTC_DCHECK_RUN_ON(worker_thread_);
244 RTC_DCHECK(initialized_);
245 RTC_DCHECK(call);
246 if (!media_engine_) {
247 return nullptr;
248 }
249
Sebastian Jansson6eb8a162018-11-16 11:29:55 +0100250 VideoMediaChannel* media_channel = media_engine_->video().CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700251 call, media_config, options, crypto_options);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800252 if (!media_channel) {
253 return nullptr;
254 }
255
Karl Wiberg918f50c2018-07-05 11:40:33 +0200256 auto video_channel = absl::make_unique<VideoChannel>(
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800257 worker_thread_, network_thread_, signaling_thread,
Karl Wiberg918f50c2018-07-05 11:40:33 +0200258 absl::WrapUnique(media_channel), content_name, srtp_required,
Zhi Huange830e682018-03-30 10:48:35 -0700259 crypto_options);
Anton Sukhanov98a462c2018-10-17 13:15:42 -0700260
Niels Möller46879152019-01-07 15:54:47 +0100261 video_channel->Init_w(rtp_transport, media_transport);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800262
263 VideoChannel* video_channel_ptr = video_channel.get();
264 video_channels_.push_back(std::move(video_channel));
265 return video_channel_ptr;
266}
267
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100269 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel");
Steve Antonc9e15602017-11-06 15:40:09 -0800270 if (!video_channel) {
271 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 }
Steve Antonc9e15602017-11-06 15:40:09 -0800273 if (!worker_thread_->IsCurrent()) {
274 worker_thread_->Invoke<void>(RTC_FROM_HERE,
275 [&] { DestroyVideoChannel(video_channel); });
276 return;
277 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278
nisseede5da42017-01-12 05:15:36 -0800279 RTC_DCHECK(initialized_);
Steve Anton774115c2017-08-30 10:48:46 -0700280
281 auto it = std::find_if(video_channels_.begin(), video_channels_.end(),
282 [&](const std::unique_ptr<VideoChannel>& p) {
283 return p.get() == video_channel;
284 });
nisseede5da42017-01-12 05:15:36 -0800285 RTC_DCHECK(it != video_channels_.end());
Steve Antonc9e15602017-11-06 15:40:09 -0800286 if (it == video_channels_.end()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000287 return;
Steve Antonc9e15602017-11-06 15:40:09 -0800288 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289
290 video_channels_.erase(it);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000291}
292
deadbeef953c2ce2017-01-09 14:53:41 -0800293RtpDataChannel* ChannelManager::CreateRtpDataChannel(
nisseeaabdf62017-05-05 02:23:02 -0700294 const cricket::MediaConfig& media_config,
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800295 webrtc::RtpTransportInternal* rtp_transport,
296 rtc::Thread* signaling_thread,
297 const std::string& content_name,
Zhi Huange830e682018-03-30 10:48:35 -0700298 bool srtp_required,
Benjamin Wrighta54daf12018-10-11 15:33:17 -0700299 const webrtc::CryptoOptions& crypto_options) {
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800300 if (!worker_thread_->IsCurrent()) {
301 return worker_thread_->Invoke<RtpDataChannel*>(RTC_FROM_HERE, [&] {
302 return CreateRtpDataChannel(media_config, rtp_transport, signaling_thread,
Zhi Huange830e682018-03-30 10:48:35 -0700303 content_name, srtp_required, crypto_options);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800304 });
305 }
306
307 // This is ok to alloc from a thread other than the worker thread.
308 RTC_DCHECK(initialized_);
309 DataMediaChannel* media_channel = data_engine_->CreateChannel(media_config);
310 if (!media_channel) {
311 RTC_LOG(LS_WARNING) << "Failed to create RTP data channel.";
312 return nullptr;
313 }
314
Karl Wiberg918f50c2018-07-05 11:40:33 +0200315 auto data_channel = absl::make_unique<RtpDataChannel>(
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800316 worker_thread_, network_thread_, signaling_thread,
Karl Wiberg918f50c2018-07-05 11:40:33 +0200317 absl::WrapUnique(media_channel), content_name, srtp_required,
Zhi Huange830e682018-03-30 10:48:35 -0700318 crypto_options);
Zhi Huang2dfc42d2017-12-04 13:38:48 -0800319 data_channel->Init_w(rtp_transport);
320
321 RtpDataChannel* data_channel_ptr = data_channel.get();
322 data_channels_.push_back(std::move(data_channel));
323 return data_channel_ptr;
324}
325
deadbeef953c2ce2017-01-09 14:53:41 -0800326void ChannelManager::DestroyRtpDataChannel(RtpDataChannel* data_channel) {
327 TRACE_EVENT0("webrtc", "ChannelManager::DestroyRtpDataChannel");
Steve Antonc9e15602017-11-06 15:40:09 -0800328 if (!data_channel) {
329 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 }
Steve Antonc9e15602017-11-06 15:40:09 -0800331 if (!worker_thread_->IsCurrent()) {
332 worker_thread_->Invoke<void>(
333 RTC_FROM_HERE, [&] { return DestroyRtpDataChannel(data_channel); });
334 return;
335 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336
nisseede5da42017-01-12 05:15:36 -0800337 RTC_DCHECK(initialized_);
Steve Anton774115c2017-08-30 10:48:46 -0700338
339 auto it = std::find_if(data_channels_.begin(), data_channels_.end(),
340 [&](const std::unique_ptr<RtpDataChannel>& p) {
341 return p.get() == data_channel;
342 });
nisseede5da42017-01-12 05:15:36 -0800343 RTC_DCHECK(it != data_channels_.end());
Steve Antonc9e15602017-11-06 15:40:09 -0800344 if (it == data_channels_.end()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000345 return;
Steve Antonc9e15602017-11-06 15:40:09 -0800346 }
Zhi Huang95e7dbb2018-03-29 00:08:03 +0000347
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000348 data_channels_.erase(it);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349}
350
ivocd66b44d2016-01-15 03:06:36 -0800351bool ChannelManager::StartAecDump(rtc::PlatformFile file,
352 int64_t max_size_bytes) {
Steve Antonc9e15602017-11-06 15:40:09 -0800353 return worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] {
Sebastian Jansson6eb8a162018-11-16 11:29:55 +0100354 return media_engine_->voice().StartAecDump(file, max_size_bytes);
Steve Antonc9e15602017-11-06 15:40:09 -0800355 });
wu@webrtc.orga9890802013-12-13 00:21:03 +0000356}
357
ivoc797ef122015-10-22 03:25:41 -0700358void ChannelManager::StopAecDump() {
Steve Antonc9e15602017-11-06 15:40:09 -0800359 worker_thread_->Invoke<void>(RTC_FROM_HERE,
Sebastian Jansson6eb8a162018-11-16 11:29:55 +0100360 [&] { media_engine_->voice().StopAecDump(); });
ivoc797ef122015-10-22 03:25:41 -0700361}
362
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000363} // namespace cricket