blob: 92be70ca18346561f8909d4bb8e8d2c4034f3b39 [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
13#ifdef HAVE_CONFIG_H
14#include <config.h>
15#endif
16
17#include <algorithm>
18
Henrik Kjellander15583c12016-02-10 10:53:12 +010019#include "webrtc/api/mediacontroller.h"
20#include "webrtc/base/bind.h"
21#include "webrtc/base/common.h"
22#include "webrtc/base/logging.h"
23#include "webrtc/base/sigslotrepeater.h"
24#include "webrtc/base/stringencode.h"
25#include "webrtc/base/stringutils.h"
26#include "webrtc/base/trace_event.h"
kjellandera96e2d72016-02-04 23:52:28 -080027#include "webrtc/media/base/capturemanager.h"
28#include "webrtc/media/base/device.h"
29#include "webrtc/media/base/hybriddataengine.h"
30#include "webrtc/media/base/rtpdataengine.h"
31#include "webrtc/media/base/videocapturer.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032#ifdef HAVE_SCTP
kjellandera96e2d72016-02-04 23:52:28 -080033#include "webrtc/media/sctp/sctpdataengine.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#endif
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010035#include "webrtc/pc/srtpfilter.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000036
37namespace cricket {
38
39enum {
40 MSG_VIDEOCAPTURESTATE = 1,
41};
42
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000043using rtc::Bind;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044
45static const int kNotSetOutputVolume = -1;
46
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000047struct CaptureStateParams : public rtc::MessageData {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048 CaptureStateParams(cricket::VideoCapturer* c, cricket::CaptureState s)
49 : capturer(c),
50 state(s) {}
51 cricket::VideoCapturer* capturer;
52 cricket::CaptureState state;
53};
54
55static DataEngineInterface* ConstructDataEngine() {
56#ifdef HAVE_SCTP
57 return new HybridDataEngine(new RtpDataEngine(), new SctpDataEngine());
58#else
59 return new RtpDataEngine();
60#endif
61}
62
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063ChannelManager::ChannelManager(MediaEngineInterface* me,
64 DataEngineInterface* dme,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 CaptureManager* cm,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000066 rtc::Thread* worker_thread) {
solenbergfacbbec2015-09-24 00:41:50 -070067 Construct(me, dme, cm, worker_thread);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068}
69
70ChannelManager::ChannelManager(MediaEngineInterface* me,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000071 rtc::Thread* worker_thread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072 Construct(me,
73 ConstructDataEngine(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074 new CaptureManager(),
75 worker_thread);
76}
77
78void ChannelManager::Construct(MediaEngineInterface* me,
79 DataEngineInterface* dme,
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080 CaptureManager* cm,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000081 rtc::Thread* worker_thread) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000082 media_engine_.reset(me);
83 data_media_engine_.reset(dme);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084 capture_manager_.reset(cm);
85 initialized_ = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000086 main_thread_ = rtc::Thread::Current();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000087 worker_thread_ = worker_thread;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088 audio_output_volume_ = kNotSetOutputVolume;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089 capturing_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090 enable_rtx_ = false;
91
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092 capture_manager_->SignalCapturerStateChange.connect(
93 this, &ChannelManager::OnVideoCaptureStateChange);
94}
95
96ChannelManager::~ChannelManager() {
wu@webrtc.org9dba5252013-08-05 20:36:57 +000097 if (initialized_) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000098 Terminate();
wu@webrtc.org9dba5252013-08-05 20:36:57 +000099 // If srtp is initialized (done by the Channel) then we must call
100 // srtp_shutdown to free all crypto kernel lists. But we need to make sure
101 // shutdown always called at the end, after channels are destroyed.
102 // ChannelManager d'tor is always called last, it's safe place to call
103 // shutdown.
104 ShutdownSrtp();
105 }
hbos@webrtc.org4aef5fe2015-02-25 10:09:05 +0000106 // Some deletes need to be on the worker thread for thread safe destruction,
107 // this includes the media engine and capture manager.
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000108 worker_thread_->Invoke<void>(Bind(
hbos@webrtc.org4aef5fe2015-02-25 10:09:05 +0000109 &ChannelManager::DestructorDeletes_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000110}
111
112bool ChannelManager::SetVideoRtxEnabled(bool enable) {
113 // To be safe, this call is only allowed before initialization. Apps like
114 // Flute only have a singleton ChannelManager and we don't want this flag to
115 // be toggled between calls or when there's concurrent calls. We expect apps
116 // to enable this at startup and retain that setting for the lifetime of the
117 // app.
118 if (!initialized_) {
119 enable_rtx_ = enable;
120 return true;
121 } else {
122 LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
123 return false;
124 }
125}
126
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000127void ChannelManager::GetSupportedAudioCodecs(
128 std::vector<AudioCodec>* codecs) const {
129 codecs->clear();
130
131 for (std::vector<AudioCodec>::const_iterator it =
132 media_engine_->audio_codecs().begin();
133 it != media_engine_->audio_codecs().end(); ++it) {
134 codecs->push_back(*it);
135 }
136}
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
143void ChannelManager::GetSupportedVideoCodecs(
144 std::vector<VideoCodec>* codecs) const {
145 codecs->clear();
146
147 std::vector<VideoCodec>::const_iterator it;
148 for (it = media_engine_->video_codecs().begin();
149 it != media_engine_->video_codecs().end(); ++it) {
150 if (!enable_rtx_ && _stricmp(kRtxCodecName, it->name.c_str()) == 0) {
151 continue;
152 }
153 codecs->push_back(*it);
154 }
155}
156
157void ChannelManager::GetSupportedVideoRtpHeaderExtensions(
158 RtpHeaderExtensions* ext) const {
Stefan Holmer9d69c3f2015-12-07 10:45:43 +0100159 *ext = media_engine_->GetVideoCapabilities().header_extensions;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000160}
161
162void ChannelManager::GetSupportedDataCodecs(
163 std::vector<DataCodec>* codecs) const {
164 *codecs = data_media_engine_->data_codecs();
165}
166
167bool ChannelManager::Init() {
168 ASSERT(!initialized_);
169 if (initialized_) {
170 return false;
171 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000172 ASSERT(worker_thread_ != NULL);
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000173 if (!worker_thread_) {
174 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000175 }
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000176 if (worker_thread_ != rtc::Thread::Current()) {
177 // Do not allow invoking calls to other threads on the worker thread.
178 worker_thread_->Invoke<bool>(rtc::Bind(
179 &rtc::Thread::SetAllowBlockingCalls, worker_thread_, false));
180 }
181
182 initialized_ = worker_thread_->Invoke<bool>(Bind(
183 &ChannelManager::InitMediaEngine_w, this));
184 ASSERT(initialized_);
185 if (!initialized_) {
186 return false;
187 }
188
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000189 // If audio_output_volume_ has been set via SetOutputVolume(), set the
190 // audio output volume of the engine.
191 if (kNotSetOutputVolume != audio_output_volume_ &&
192 !SetOutputVolume(audio_output_volume_)) {
193 LOG(LS_WARNING) << "Failed to SetOutputVolume to "
194 << audio_output_volume_;
195 }
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000196
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000197 return initialized_;
198}
199
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000200bool ChannelManager::InitMediaEngine_w() {
201 ASSERT(worker_thread_ == rtc::Thread::Current());
202 return (media_engine_->Init(worker_thread_));
203}
204
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205void ChannelManager::Terminate() {
206 ASSERT(initialized_);
207 if (!initialized_) {
208 return;
209 }
210 worker_thread_->Invoke<void>(Bind(&ChannelManager::Terminate_w, this));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000211 initialized_ = false;
212}
213
hbos@webrtc.org4aef5fe2015-02-25 10:09:05 +0000214void ChannelManager::DestructorDeletes_w() {
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000215 ASSERT(worker_thread_ == rtc::Thread::Current());
216 media_engine_.reset(NULL);
hbos@webrtc.org4aef5fe2015-02-25 10:09:05 +0000217 capture_manager_.reset(NULL);
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000218}
219
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220void ChannelManager::Terminate_w() {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000221 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 // Need to destroy the voice/video channels
223 while (!video_channels_.empty()) {
224 DestroyVideoChannel_w(video_channels_.back());
225 }
226 while (!voice_channels_.empty()) {
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200227 DestroyVoiceChannel_w(voice_channels_.back());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 }
henrika@webrtc.org62f6e752015-02-11 08:38:35 +0000229 media_engine_->Terminate();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000230}
231
232VoiceChannel* ChannelManager::CreateVoiceChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200233 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700234 TransportController* transport_controller,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200235 const std::string& content_name,
236 bool rtcp,
237 const AudioOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 return worker_thread_->Invoke<VoiceChannel*>(
deadbeefcbecd352015-09-23 11:50:27 -0700239 Bind(&ChannelManager::CreateVoiceChannel_w, this, media_controller,
240 transport_controller, content_name, rtcp, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241}
242
243VoiceChannel* ChannelManager::CreateVoiceChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200244 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700245 TransportController* transport_controller,
Jelena Marusicc28a8962015-05-29 15:05:44 +0200246 const std::string& content_name,
247 bool rtcp,
248 const AudioOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200250 ASSERT(worker_thread_ == rtc::Thread::Current());
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200251 ASSERT(nullptr != media_controller);
nisse51542be2016-02-12 02:27:06 -0800252 VoiceMediaChannel* media_channel = media_engine_->CreateChannel(
253 media_controller->call_w(), media_controller->config(), options);
Jelena Marusicc28a8962015-05-29 15:05:44 +0200254 if (!media_channel)
255 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256
deadbeefcbecd352015-09-23 11:50:27 -0700257 VoiceChannel* voice_channel =
258 new VoiceChannel(worker_thread_, media_engine_.get(), media_channel,
259 transport_controller, content_name, rtcp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000260 if (!voice_channel->Init()) {
261 delete voice_channel;
Jelena Marusicc28a8962015-05-29 15:05:44 +0200262 return nullptr;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 }
264 voice_channels_.push_back(voice_channel);
265 return voice_channel;
266}
267
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200268void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100269 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000270 if (voice_channel) {
271 worker_thread_->Invoke<void>(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200272 Bind(&ChannelManager::DestroyVoiceChannel_w, this, voice_channel));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000273 }
274}
275
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200276void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100277 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVoiceChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 // Destroy voice channel.
279 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200280 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 VoiceChannels::iterator it = std::find(voice_channels_.begin(),
282 voice_channels_.end(), voice_channel);
283 ASSERT(it != voice_channels_.end());
284 if (it == voice_channels_.end())
285 return;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286 voice_channels_.erase(it);
287 delete voice_channel;
288}
289
290VideoChannel* ChannelManager::CreateVideoChannel(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200291 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700292 TransportController* transport_controller,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000293 const std::string& content_name,
294 bool rtcp,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200295 const VideoOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000296 return worker_thread_->Invoke<VideoChannel*>(
deadbeefcbecd352015-09-23 11:50:27 -0700297 Bind(&ChannelManager::CreateVideoChannel_w, this, media_controller,
298 transport_controller, content_name, rtcp, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299}
300
301VideoChannel* ChannelManager::CreateVideoChannel_w(
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200302 webrtc::MediaControllerInterface* media_controller,
deadbeefcbecd352015-09-23 11:50:27 -0700303 TransportController* transport_controller,
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000304 const std::string& content_name,
305 bool rtcp,
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200306 const VideoOptions& options) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000307 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200308 ASSERT(worker_thread_ == rtc::Thread::Current());
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200309 ASSERT(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
316 VideoChannel* video_channel = new VideoChannel(
deadbeefcbecd352015-09-23 11:50:27 -0700317 worker_thread_, media_channel, transport_controller, content_name, rtcp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318 if (!video_channel->Init()) {
319 delete video_channel;
320 return NULL;
321 }
322 video_channels_.push_back(video_channel);
323 return video_channel;
324}
325
326void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100327 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 if (video_channel) {
329 worker_thread_->Invoke<void>(
330 Bind(&ChannelManager::DestroyVideoChannel_w, this, video_channel));
331 }
332}
333
334void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100335 TRACE_EVENT0("webrtc", "ChannelManager::DestroyVideoChannel_w");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336 // Destroy video channel.
337 ASSERT(initialized_);
Fredrik Solenberg4b60c732015-05-07 14:07:48 +0200338 ASSERT(worker_thread_ == rtc::Thread::Current());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339 VideoChannels::iterator it = std::find(video_channels_.begin(),
340 video_channels_.end(), video_channel);
341 ASSERT(it != video_channels_.end());
342 if (it == video_channels_.end())
343 return;
344
345 video_channels_.erase(it);
346 delete video_channel;
347}
348
349DataChannel* ChannelManager::CreateDataChannel(
deadbeefcbecd352015-09-23 11:50:27 -0700350 TransportController* transport_controller,
351 const std::string& content_name,
352 bool rtcp,
353 DataChannelType channel_type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000354 return worker_thread_->Invoke<DataChannel*>(
deadbeefcbecd352015-09-23 11:50:27 -0700355 Bind(&ChannelManager::CreateDataChannel_w, this, transport_controller,
356 content_name, rtcp, channel_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357}
358
359DataChannel* ChannelManager::CreateDataChannel_w(
deadbeefcbecd352015-09-23 11:50:27 -0700360 TransportController* transport_controller,
361 const std::string& content_name,
362 bool rtcp,
363 DataChannelType data_channel_type) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364 // This is ok to alloc from a thread other than the worker thread.
365 ASSERT(initialized_);
366 DataMediaChannel* media_channel = data_media_engine_->CreateChannel(
367 data_channel_type);
368 if (!media_channel) {
369 LOG(LS_WARNING) << "Failed to create data channel of type "
370 << data_channel_type;
371 return NULL;
372 }
373
374 DataChannel* data_channel = new DataChannel(
deadbeefcbecd352015-09-23 11:50:27 -0700375 worker_thread_, media_channel, transport_controller, content_name, rtcp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000376 if (!data_channel->Init()) {
377 LOG(LS_WARNING) << "Failed to init data channel.";
378 delete data_channel;
379 return NULL;
380 }
381 data_channels_.push_back(data_channel);
382 return data_channel;
383}
384
385void ChannelManager::DestroyDataChannel(DataChannel* data_channel) {
Peter Boström1a9d6152015-12-08 22:15:17 +0100386 TRACE_EVENT0("webrtc", "ChannelManager::DestroyDataChannel");
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000387 if (data_channel) {
388 worker_thread_->Invoke<void>(
389 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
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407bool ChannelManager::GetOutputVolume(int* level) {
408 if (!initialized_) {
409 return false;
410 }
411 return worker_thread_->Invoke<bool>(
412 Bind(&MediaEngineInterface::GetOutputVolume, media_engine_.get(), level));
413}
414
415bool ChannelManager::SetOutputVolume(int level) {
416 bool ret = level >= 0 && level <= 255;
417 if (initialized_) {
418 ret &= worker_thread_->Invoke<bool>(
419 Bind(&MediaEngineInterface::SetOutputVolume,
420 media_engine_.get(), level));
421 }
422
423 if (ret) {
424 audio_output_volume_ = level;
425 }
426
427 return ret;
428}
429
hbos@webrtc.org1e642632015-02-25 09:49:41 +0000430std::vector<cricket::VideoFormat> ChannelManager::GetSupportedFormats(
431 VideoCapturer* capturer) const {
432 ASSERT(capturer != NULL);
433 std::vector<VideoFormat> formats;
434 worker_thread_->Invoke<void>(rtc::Bind(&ChannelManager::GetSupportedFormats_w,
435 this, capturer, &formats));
436 return formats;
437}
438
439void ChannelManager::GetSupportedFormats_w(
440 VideoCapturer* capturer,
441 std::vector<cricket::VideoFormat>* out_formats) const {
442 const std::vector<VideoFormat>* formats = capturer->GetSupportedFormats();
443 if (formats != NULL)
444 *out_formats = *formats;
445}
446
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000447// The following are done in the new "CaptureManager" style that
448// all local video capturers, processors, and managers should move
449// to.
450// TODO(pthatcher): Add more of the CaptureManager interface.
451bool ChannelManager::StartVideoCapture(
452 VideoCapturer* capturer, const VideoFormat& video_format) {
453 return initialized_ && worker_thread_->Invoke<bool>(
454 Bind(&CaptureManager::StartVideoCapture,
455 capture_manager_.get(), capturer, video_format));
456}
457
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000458bool ChannelManager::StopVideoCapture(
459 VideoCapturer* capturer, const VideoFormat& video_format) {
460 return initialized_ && worker_thread_->Invoke<bool>(
461 Bind(&CaptureManager::StopVideoCapture,
462 capture_manager_.get(), capturer, video_format));
463}
464
nissee73afba2016-01-28 04:47:08 -0800465void ChannelManager::AddVideoSink(
466 VideoCapturer* capturer, rtc::VideoSinkInterface<VideoFrame>* sink) {
467 if (initialized_)
468 worker_thread_->Invoke<void>(
469 Bind(&CaptureManager::AddVideoSink,
470 capture_manager_.get(), capturer, sink));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000471}
472
nissee73afba2016-01-28 04:47:08 -0800473void ChannelManager::RemoveVideoSink(
474 VideoCapturer* capturer, rtc::VideoSinkInterface<VideoFrame>* sink) {
475 if (initialized_)
476 worker_thread_->Invoke<void>(
477 Bind(&CaptureManager::RemoveVideoSink,
478 capture_manager_.get(), capturer, sink));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000479}
480
481bool ChannelManager::IsScreencastRunning() const {
482 return initialized_ && worker_thread_->Invoke<bool>(
483 Bind(&ChannelManager::IsScreencastRunning_w, this));
484}
485
486bool ChannelManager::IsScreencastRunning_w() const {
487 VideoChannels::const_iterator it = video_channels_.begin();
488 for ( ; it != video_channels_.end(); ++it) {
489 if ((*it) && (*it)->IsScreencasting()) {
490 return true;
491 }
492 }
493 return false;
494}
495
496void ChannelManager::OnVideoCaptureStateChange(VideoCapturer* capturer,
497 CaptureState result) {
498 // TODO(whyuan): Check capturer and signal failure only for camera video, not
499 // screencast.
500 capturing_ = result == CS_RUNNING;
501 main_thread_->Post(this, MSG_VIDEOCAPTURESTATE,
502 new CaptureStateParams(capturer, result));
503}
504
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000505void ChannelManager::OnMessage(rtc::Message* message) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506 switch (message->message_id) {
507 case MSG_VIDEOCAPTURESTATE: {
508 CaptureStateParams* data =
509 static_cast<CaptureStateParams*>(message->pdata);
510 SignalVideoCaptureStateChange(data->capturer, data->state);
511 delete data;
512 break;
513 }
514 }
515}
516
ivocd66b44d2016-01-15 03:06:36 -0800517bool ChannelManager::StartAecDump(rtc::PlatformFile file,
518 int64_t max_size_bytes) {
519 return worker_thread_->Invoke<bool>(Bind(&MediaEngineInterface::StartAecDump,
520 media_engine_.get(), file,
521 max_size_bytes));
wu@webrtc.orga9890802013-12-13 00:21:03 +0000522}
523
ivoc797ef122015-10-22 03:25:41 -0700524void ChannelManager::StopAecDump() {
525 worker_thread_->Invoke<void>(
526 Bind(&MediaEngineInterface::StopAecDump, media_engine_.get()));
527}
528
ivoc112a3d82015-10-16 02:22:18 -0700529bool ChannelManager::StartRtcEventLog(rtc::PlatformFile file) {
530 return worker_thread_->Invoke<bool>(
531 Bind(&MediaEngineInterface::StartRtcEventLog, media_engine_.get(), file));
532}
533
534void ChannelManager::StopRtcEventLog() {
535 worker_thread_->Invoke<void>(
536 Bind(&MediaEngineInterface::StopRtcEventLog, media_engine_.get()));
537}
538
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539} // namespace cricket