| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include "webrtc/pc/channelmanager.h" | 11 #include "webrtc/pc/channelmanager.h" |
| 12 | 12 |
| 13 #ifdef HAVE_CONFIG_H | 13 #ifdef HAVE_CONFIG_H |
| 14 #include <config.h> | 14 #include <config.h> |
| 15 #endif | 15 #endif |
| 16 | 16 |
| 17 #include <algorithm> | 17 #include <algorithm> |
| 18 | 18 |
| 19 #include "webrtc/api/mediacontroller.h" | 19 #include "webrtc/api/mediacontroller.h" |
| 20 #include "webrtc/base/bind.h" | 20 #include "webrtc/base/bind.h" |
| 21 #include "webrtc/base/common.h" | 21 #include "webrtc/base/common.h" |
| 22 #include "webrtc/base/logging.h" | 22 #include "webrtc/base/logging.h" |
| 23 #include "webrtc/base/sigslotrepeater.h" | |
| 24 #include "webrtc/base/stringencode.h" | 23 #include "webrtc/base/stringencode.h" |
| 25 #include "webrtc/base/stringutils.h" | 24 #include "webrtc/base/stringutils.h" |
| 26 #include "webrtc/base/trace_event.h" | 25 #include "webrtc/base/trace_event.h" |
| 27 #include "webrtc/media/base/capturemanager.h" | |
| 28 #include "webrtc/media/base/device.h" | 26 #include "webrtc/media/base/device.h" |
| 29 #include "webrtc/media/base/hybriddataengine.h" | 27 #include "webrtc/media/base/hybriddataengine.h" |
| 30 #include "webrtc/media/base/rtpdataengine.h" | 28 #include "webrtc/media/base/rtpdataengine.h" |
| 31 #include "webrtc/media/base/videocapturer.h" | |
| 32 #ifdef HAVE_SCTP | 29 #ifdef HAVE_SCTP |
| 33 #include "webrtc/media/sctp/sctpdataengine.h" | 30 #include "webrtc/media/sctp/sctpdataengine.h" |
| 34 #endif | 31 #endif |
| 35 #include "webrtc/pc/srtpfilter.h" | 32 #include "webrtc/pc/srtpfilter.h" |
| 36 | 33 |
| 37 namespace cricket { | 34 namespace cricket { |
| 38 | 35 |
| 39 enum { | |
| 40 MSG_VIDEOCAPTURESTATE = 1, | |
| 41 }; | |
| 42 | 36 |
| 43 using rtc::Bind; | 37 using rtc::Bind; |
| 44 | 38 |
| 45 static const int kNotSetOutputVolume = -1; | 39 static const int kNotSetOutputVolume = -1; |
| 46 | 40 |
| 47 struct CaptureStateParams : public rtc::MessageData { | |
| 48 CaptureStateParams(cricket::VideoCapturer* c, cricket::CaptureState s) | |
| 49 : capturer(c), | |
| 50 state(s) {} | |
| 51 cricket::VideoCapturer* capturer; | |
| 52 cricket::CaptureState state; | |
| 53 }; | |
| 54 | |
| 55 static DataEngineInterface* ConstructDataEngine() { | 41 static DataEngineInterface* ConstructDataEngine() { |
| 56 #ifdef HAVE_SCTP | 42 #ifdef HAVE_SCTP |
| 57 return new HybridDataEngine(new RtpDataEngine(), new SctpDataEngine()); | 43 return new HybridDataEngine(new RtpDataEngine(), new SctpDataEngine()); |
| 58 #else | 44 #else |
| 59 return new RtpDataEngine(); | 45 return new RtpDataEngine(); |
| 60 #endif | 46 #endif |
| 61 } | 47 } |
| 62 | 48 |
| 63 ChannelManager::ChannelManager(MediaEngineInterface* me, | 49 ChannelManager::ChannelManager(MediaEngineInterface* me, |
| 64 DataEngineInterface* dme, | 50 DataEngineInterface* dme, |
| 65 CaptureManager* cm, | |
| 66 rtc::Thread* worker_thread) { | 51 rtc::Thread* worker_thread) { |
| 67 Construct(me, dme, cm, worker_thread); | 52 Construct(me, dme, worker_thread); |
| 68 } | 53 } |
| 69 | 54 |
| 70 ChannelManager::ChannelManager(MediaEngineInterface* me, | 55 ChannelManager::ChannelManager(MediaEngineInterface* me, |
| 71 rtc::Thread* worker_thread) { | 56 rtc::Thread* worker_thread) { |
| 72 Construct(me, | 57 Construct(me, |
| 73 ConstructDataEngine(), | 58 ConstructDataEngine(), |
| 74 new CaptureManager(), | |
| 75 worker_thread); | 59 worker_thread); |
| 76 } | 60 } |
| 77 | 61 |
| 78 void ChannelManager::Construct(MediaEngineInterface* me, | 62 void ChannelManager::Construct(MediaEngineInterface* me, |
| 79 DataEngineInterface* dme, | 63 DataEngineInterface* dme, |
| 80 CaptureManager* cm, | |
| 81 rtc::Thread* worker_thread) { | 64 rtc::Thread* worker_thread) { |
| 82 media_engine_.reset(me); | 65 media_engine_.reset(me); |
| 83 data_media_engine_.reset(dme); | 66 data_media_engine_.reset(dme); |
| 84 capture_manager_.reset(cm); | |
| 85 initialized_ = false; | 67 initialized_ = false; |
| 86 main_thread_ = rtc::Thread::Current(); | 68 main_thread_ = rtc::Thread::Current(); |
| 87 worker_thread_ = worker_thread; | 69 worker_thread_ = worker_thread; |
| 88 audio_output_volume_ = kNotSetOutputVolume; | 70 audio_output_volume_ = kNotSetOutputVolume; |
| 89 capturing_ = false; | 71 capturing_ = false; |
| 90 enable_rtx_ = false; | 72 enable_rtx_ = false; |
| 91 | |
| 92 capture_manager_->SignalCapturerStateChange.connect( | |
| 93 this, &ChannelManager::OnVideoCaptureStateChange); | |
| 94 } | 73 } |
| 95 | 74 |
| 96 ChannelManager::~ChannelManager() { | 75 ChannelManager::~ChannelManager() { |
| 97 if (initialized_) { | 76 if (initialized_) { |
| 98 Terminate(); | 77 Terminate(); |
| 99 // If srtp is initialized (done by the Channel) then we must call | 78 // 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 | 79 // 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. | 80 // shutdown always called at the end, after channels are destroyed. |
| 102 // ChannelManager d'tor is always called last, it's safe place to call | 81 // ChannelManager d'tor is always called last, it's safe place to call |
| 103 // shutdown. | 82 // shutdown. |
| 104 ShutdownSrtp(); | 83 ShutdownSrtp(); |
| 105 } | 84 } |
| 106 // Some deletes need to be on the worker thread for thread safe destruction, | 85 // The media engine needs to be deleted on the worker thread for thread safe |
| 107 // this includes the media engine and capture manager. | 86 // destruction, |
| 108 worker_thread_->Invoke<void>(Bind( | 87 worker_thread_->Invoke<void>(Bind( |
| 109 &ChannelManager::DestructorDeletes_w, this)); | 88 &ChannelManager::DestructorDeletes_w, this)); |
| 110 } | 89 } |
| 111 | 90 |
| 112 bool ChannelManager::SetVideoRtxEnabled(bool enable) { | 91 bool ChannelManager::SetVideoRtxEnabled(bool enable) { |
| 113 // To be safe, this call is only allowed before initialization. Apps like | 92 // 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 | 93 // 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 | 94 // 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 | 95 // to enable this at startup and retain that setting for the lifetime of the |
| 117 // app. | 96 // app. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 if (!initialized_) { | 186 if (!initialized_) { |
| 208 return; | 187 return; |
| 209 } | 188 } |
| 210 worker_thread_->Invoke<void>(Bind(&ChannelManager::Terminate_w, this)); | 189 worker_thread_->Invoke<void>(Bind(&ChannelManager::Terminate_w, this)); |
| 211 initialized_ = false; | 190 initialized_ = false; |
| 212 } | 191 } |
| 213 | 192 |
| 214 void ChannelManager::DestructorDeletes_w() { | 193 void ChannelManager::DestructorDeletes_w() { |
| 215 ASSERT(worker_thread_ == rtc::Thread::Current()); | 194 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 216 media_engine_.reset(NULL); | 195 media_engine_.reset(NULL); |
| 217 capture_manager_.reset(NULL); | |
| 218 } | 196 } |
| 219 | 197 |
| 220 void ChannelManager::Terminate_w() { | 198 void ChannelManager::Terminate_w() { |
| 221 ASSERT(worker_thread_ == rtc::Thread::Current()); | 199 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 222 // Need to destroy the voice/video channels | 200 // Need to destroy the voice/video channels |
| 223 while (!video_channels_.empty()) { | 201 while (!video_channels_.empty()) { |
| 224 DestroyVideoChannel_w(video_channels_.back()); | 202 DestroyVideoChannel_w(video_channels_.back()); |
| 225 } | 203 } |
| 226 while (!voice_channels_.empty()) { | 204 while (!voice_channels_.empty()) { |
| 227 DestroyVoiceChannel_w(voice_channels_.back()); | 205 DestroyVoiceChannel_w(voice_channels_.back()); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 media_engine_.get(), level)); | 398 media_engine_.get(), level)); |
| 421 } | 399 } |
| 422 | 400 |
| 423 if (ret) { | 401 if (ret) { |
| 424 audio_output_volume_ = level; | 402 audio_output_volume_ = level; |
| 425 } | 403 } |
| 426 | 404 |
| 427 return ret; | 405 return ret; |
| 428 } | 406 } |
| 429 | 407 |
| 430 std::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 | |
| 439 void 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 | |
| 447 // 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. | |
| 451 bool 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 | |
| 458 bool 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 | |
| 465 void 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)); | |
| 471 } | |
| 472 | |
| 473 void 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)); | |
| 479 } | |
| 480 | |
| 481 bool ChannelManager::IsScreencastRunning() const { | |
| 482 return initialized_ && worker_thread_->Invoke<bool>( | |
| 483 Bind(&ChannelManager::IsScreencastRunning_w, this)); | |
| 484 } | |
| 485 | |
| 486 bool 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 | |
| 496 void 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 | |
| 505 void ChannelManager::OnMessage(rtc::Message* message) { | |
| 506 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 | 408 |
| 517 bool ChannelManager::StartAecDump(rtc::PlatformFile file, | 409 bool ChannelManager::StartAecDump(rtc::PlatformFile file, |
| 518 int64_t max_size_bytes) { | 410 int64_t max_size_bytes) { |
| 519 return worker_thread_->Invoke<bool>(Bind(&MediaEngineInterface::StartAecDump, | 411 return worker_thread_->Invoke<bool>(Bind(&MediaEngineInterface::StartAecDump, |
| 520 media_engine_.get(), file, | 412 media_engine_.get(), file, |
| 521 max_size_bytes)); | 413 max_size_bytes)); |
| 522 } | 414 } |
| 523 | 415 |
| 524 void ChannelManager::StopAecDump() { | 416 void ChannelManager::StopAecDump() { |
| 525 worker_thread_->Invoke<void>( | 417 worker_thread_->Invoke<void>( |
| 526 Bind(&MediaEngineInterface::StopAecDump, media_engine_.get())); | 418 Bind(&MediaEngineInterface::StopAecDump, media_engine_.get())); |
| 527 } | 419 } |
| 528 | 420 |
| 529 bool ChannelManager::StartRtcEventLog(rtc::PlatformFile file) { | 421 bool ChannelManager::StartRtcEventLog(rtc::PlatformFile file) { |
| 530 return worker_thread_->Invoke<bool>( | 422 return worker_thread_->Invoke<bool>( |
| 531 Bind(&MediaEngineInterface::StartRtcEventLog, media_engine_.get(), file)); | 423 Bind(&MediaEngineInterface::StartRtcEventLog, media_engine_.get(), file)); |
| 532 } | 424 } |
| 533 | 425 |
| 534 void ChannelManager::StopRtcEventLog() { | 426 void ChannelManager::StopRtcEventLog() { |
| 535 worker_thread_->Invoke<void>( | 427 worker_thread_->Invoke<void>( |
| 536 Bind(&MediaEngineInterface::StopRtcEventLog, media_engine_.get())); | 428 Bind(&MediaEngineInterface::StopRtcEventLog, media_engine_.get())); |
| 537 } | 429 } |
| 538 | 430 |
| 539 } // namespace cricket | 431 } // namespace cricket |
| OLD | NEW |