Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / session / media / channelmanager.cc
1 /*
2  * libjingle
3  * Copyright 2004 Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "talk/session/media/channelmanager.h"
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include <algorithm>
35
36 #include "talk/media/base/capturemanager.h"
37 #include "talk/media/base/hybriddataengine.h"
38 #include "talk/media/base/rtpdataengine.h"
39 #include "talk/media/base/videocapturer.h"
40 #include "talk/media/devices/devicemanager.h"
41 #ifdef HAVE_SCTP
42 #include "talk/media/sctp/sctpdataengine.h"
43 #endif
44 #include "talk/session/media/soundclip.h"
45 #include "talk/session/media/srtpfilter.h"
46 #include "webrtc/base/bind.h"
47 #include "webrtc/base/common.h"
48 #include "webrtc/base/logging.h"
49 #include "webrtc/base/sigslotrepeater.h"
50 #include "webrtc/base/stringencode.h"
51 #include "webrtc/base/stringutils.h"
52
53 namespace cricket {
54
55 enum {
56   MSG_VIDEOCAPTURESTATE = 1,
57 };
58
59 using rtc::Bind;
60
61 static const int kNotSetOutputVolume = -1;
62
63 struct CaptureStateParams : public rtc::MessageData {
64   CaptureStateParams(cricket::VideoCapturer* c, cricket::CaptureState s)
65       : capturer(c),
66         state(s) {}
67   cricket::VideoCapturer* capturer;
68   cricket::CaptureState state;
69 };
70
71 static DataEngineInterface* ConstructDataEngine() {
72 #ifdef HAVE_SCTP
73   return new HybridDataEngine(new RtpDataEngine(), new SctpDataEngine());
74 #else
75   return new RtpDataEngine();
76 #endif
77 }
78
79 #if !defined(DISABLE_MEDIA_ENGINE_FACTORY)
80 ChannelManager::ChannelManager(rtc::Thread* worker_thread) {
81   Construct(MediaEngineFactory::Create(),
82             ConstructDataEngine(),
83             cricket::DeviceManagerFactory::Create(),
84             new CaptureManager(),
85             worker_thread);
86 }
87 #endif
88
89 ChannelManager::ChannelManager(MediaEngineInterface* me,
90                                DataEngineInterface* dme,
91                                DeviceManagerInterface* dm,
92                                CaptureManager* cm,
93                                rtc::Thread* worker_thread) {
94   Construct(me, dme, dm, cm, worker_thread);
95 }
96
97 ChannelManager::ChannelManager(MediaEngineInterface* me,
98                                DeviceManagerInterface* dm,
99                                rtc::Thread* worker_thread) {
100   Construct(me,
101             ConstructDataEngine(),
102             dm,
103             new CaptureManager(),
104             worker_thread);
105 }
106
107 void ChannelManager::Construct(MediaEngineInterface* me,
108                                DataEngineInterface* dme,
109                                DeviceManagerInterface* dm,
110                                CaptureManager* cm,
111                                rtc::Thread* worker_thread) {
112   media_engine_.reset(me);
113   data_media_engine_.reset(dme);
114   device_manager_.reset(dm);
115   capture_manager_.reset(cm);
116   initialized_ = false;
117   main_thread_ = rtc::Thread::Current();
118   worker_thread_ = worker_thread;
119   // Get the default audio options from the media engine.
120   audio_options_ = media_engine_->GetAudioOptions();
121   audio_in_device_ = DeviceManagerInterface::kDefaultDeviceName;
122   audio_out_device_ = DeviceManagerInterface::kDefaultDeviceName;
123   audio_delay_offset_ = kDefaultAudioDelayOffset;
124   audio_output_volume_ = kNotSetOutputVolume;
125   local_renderer_ = NULL;
126   capturing_ = false;
127   monitoring_ = false;
128   enable_rtx_ = false;
129
130   // Init the device manager immediately, and set up our default video device.
131   SignalDevicesChange.repeat(device_manager_->SignalDevicesChange);
132   device_manager_->Init();
133
134   // Camera is started asynchronously, request callbacks when startup
135   // completes to be able to forward them to the rendering manager.
136   media_engine_->SignalVideoCaptureStateChange().connect(
137       this, &ChannelManager::OnVideoCaptureStateChange);
138   capture_manager_->SignalCapturerStateChange.connect(
139       this, &ChannelManager::OnVideoCaptureStateChange);
140 }
141
142 ChannelManager::~ChannelManager() {
143   if (initialized_) {
144     Terminate();
145     // If srtp is initialized (done by the Channel) then we must call
146     // srtp_shutdown to free all crypto kernel lists. But we need to make sure
147     // shutdown always called at the end, after channels are destroyed.
148     // ChannelManager d'tor is always called last, it's safe place to call
149     // shutdown.
150     ShutdownSrtp();
151   }
152 }
153
154 bool ChannelManager::SetVideoRtxEnabled(bool enable) {
155   // To be safe, this call is only allowed before initialization. Apps like
156   // Flute only have a singleton ChannelManager and we don't want this flag to
157   // be toggled between calls or when there's concurrent calls. We expect apps
158   // to enable this at startup and retain that setting for the lifetime of the
159   // app.
160   if (!initialized_) {
161     enable_rtx_ = enable;
162     return true;
163   } else {
164     LOG(LS_WARNING) << "Cannot toggle rtx after initialization!";
165     return false;
166   }
167 }
168
169 int ChannelManager::GetCapabilities() {
170   return media_engine_->GetCapabilities() & device_manager_->GetCapabilities();
171 }
172
173 void ChannelManager::GetSupportedAudioCodecs(
174     std::vector<AudioCodec>* codecs) const {
175   codecs->clear();
176
177   for (std::vector<AudioCodec>::const_iterator it =
178            media_engine_->audio_codecs().begin();
179       it != media_engine_->audio_codecs().end(); ++it) {
180     codecs->push_back(*it);
181   }
182 }
183
184 void ChannelManager::GetSupportedAudioRtpHeaderExtensions(
185     RtpHeaderExtensions* ext) const {
186   *ext = media_engine_->audio_rtp_header_extensions();
187 }
188
189 void ChannelManager::GetSupportedVideoCodecs(
190     std::vector<VideoCodec>* codecs) const {
191   codecs->clear();
192
193   std::vector<VideoCodec>::const_iterator it;
194   for (it = media_engine_->video_codecs().begin();
195       it != media_engine_->video_codecs().end(); ++it) {
196     if (!enable_rtx_ && _stricmp(kRtxCodecName, it->name.c_str()) == 0) {
197       continue;
198     }
199     codecs->push_back(*it);
200   }
201 }
202
203 void ChannelManager::GetSupportedVideoRtpHeaderExtensions(
204     RtpHeaderExtensions* ext) const {
205   *ext = media_engine_->video_rtp_header_extensions();
206 }
207
208 void ChannelManager::GetSupportedDataCodecs(
209     std::vector<DataCodec>* codecs) const {
210   *codecs = data_media_engine_->data_codecs();
211 }
212
213 bool ChannelManager::Init() {
214   ASSERT(!initialized_);
215   if (initialized_) {
216     return false;
217   }
218
219   ASSERT(worker_thread_ != NULL);
220   if (worker_thread_) {
221     if (worker_thread_ != rtc::Thread::Current()) {
222       // Do not allow invoking calls to other threads on the worker thread.
223       worker_thread_->Invoke<bool>(rtc::Bind(
224           &rtc::Thread::SetAllowBlockingCalls, worker_thread_, false));
225     }
226
227     if (media_engine_->Init(worker_thread_)) {
228       initialized_ = true;
229
230       // Now that we're initialized, apply any stored preferences. A preferred
231       // device might have been unplugged. In this case, we fallback to the
232       // default device but keep the user preferences. The preferences are
233       // changed only when the Javascript FE changes them.
234       const std::string preferred_audio_in_device = audio_in_device_;
235       const std::string preferred_audio_out_device = audio_out_device_;
236       const std::string preferred_camera_device = camera_device_;
237       Device device;
238       if (!device_manager_->GetAudioInputDevice(audio_in_device_, &device)) {
239         LOG(LS_WARNING) << "The preferred microphone '" << audio_in_device_
240                         << "' is unavailable. Fall back to the default.";
241         audio_in_device_ = DeviceManagerInterface::kDefaultDeviceName;
242       }
243       if (!device_manager_->GetAudioOutputDevice(audio_out_device_, &device)) {
244         LOG(LS_WARNING) << "The preferred speaker '" << audio_out_device_
245                         << "' is unavailable. Fall back to the default.";
246         audio_out_device_ = DeviceManagerInterface::kDefaultDeviceName;
247       }
248       if (!device_manager_->GetVideoCaptureDevice(camera_device_, &device)) {
249         if (!camera_device_.empty()) {
250           LOG(LS_WARNING) << "The preferred camera '" << camera_device_
251                           << "' is unavailable. Fall back to the default.";
252         }
253         camera_device_ = DeviceManagerInterface::kDefaultDeviceName;
254       }
255
256       if (!SetAudioOptions(audio_in_device_, audio_out_device_,
257                            audio_options_, audio_delay_offset_)) {
258         LOG(LS_WARNING) << "Failed to SetAudioOptions with"
259                         << " microphone: " << audio_in_device_
260                         << " speaker: " << audio_out_device_
261                         << " options: " << audio_options_.ToString()
262                         << " delay: " << audio_delay_offset_;
263       }
264
265       // If audio_output_volume_ has been set via SetOutputVolume(), set the
266       // audio output volume of the engine.
267       if (kNotSetOutputVolume != audio_output_volume_ &&
268           !SetOutputVolume(audio_output_volume_)) {
269         LOG(LS_WARNING) << "Failed to SetOutputVolume to "
270                         << audio_output_volume_;
271       }
272       if (!SetCaptureDevice(camera_device_) && !camera_device_.empty()) {
273         LOG(LS_WARNING) << "Failed to SetCaptureDevice with camera: "
274                         << camera_device_;
275       }
276
277       // Restore the user preferences.
278       audio_in_device_ = preferred_audio_in_device;
279       audio_out_device_ = preferred_audio_out_device;
280       camera_device_ = preferred_camera_device;
281
282       // Now apply the default video codec that has been set earlier.
283       if (default_video_encoder_config_.max_codec.id != 0) {
284         SetDefaultVideoEncoderConfig(default_video_encoder_config_);
285       }
286     }
287   }
288   return initialized_;
289 }
290
291 void ChannelManager::Terminate() {
292   ASSERT(initialized_);
293   if (!initialized_) {
294     return;
295   }
296   worker_thread_->Invoke<void>(Bind(&ChannelManager::Terminate_w, this));
297   media_engine_->Terminate();
298   initialized_ = false;
299 }
300
301 void ChannelManager::Terminate_w() {
302   ASSERT(worker_thread_ == rtc::Thread::Current());
303   // Need to destroy the voice/video channels
304   while (!video_channels_.empty()) {
305     DestroyVideoChannel_w(video_channels_.back());
306   }
307   while (!voice_channels_.empty()) {
308     DestroyVoiceChannel_w(voice_channels_.back());
309   }
310   while (!soundclips_.empty()) {
311     DestroySoundclip_w(soundclips_.back());
312   }
313   if (!SetCaptureDevice_w(NULL)) {
314     LOG(LS_WARNING) << "failed to delete video capturer";
315   }
316 }
317
318 VoiceChannel* ChannelManager::CreateVoiceChannel(
319     BaseSession* session, const std::string& content_name, bool rtcp) {
320   return worker_thread_->Invoke<VoiceChannel*>(
321       Bind(&ChannelManager::CreateVoiceChannel_w, this,
322            session, content_name, rtcp));
323 }
324
325 VoiceChannel* ChannelManager::CreateVoiceChannel_w(
326     BaseSession* session, const std::string& content_name, bool rtcp) {
327   // This is ok to alloc from a thread other than the worker thread
328   ASSERT(initialized_);
329   VoiceMediaChannel* media_channel = media_engine_->CreateChannel();
330   if (media_channel == NULL)
331     return NULL;
332
333   VoiceChannel* voice_channel = new VoiceChannel(
334       worker_thread_, media_engine_.get(), media_channel,
335       session, content_name, rtcp);
336   if (!voice_channel->Init()) {
337     delete voice_channel;
338     return NULL;
339   }
340   voice_channels_.push_back(voice_channel);
341   return voice_channel;
342 }
343
344 void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
345   if (voice_channel) {
346     worker_thread_->Invoke<void>(
347         Bind(&ChannelManager::DestroyVoiceChannel_w, this, voice_channel));
348   }
349 }
350
351 void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
352   // Destroy voice channel.
353   ASSERT(initialized_);
354   VoiceChannels::iterator it = std::find(voice_channels_.begin(),
355       voice_channels_.end(), voice_channel);
356   ASSERT(it != voice_channels_.end());
357   if (it == voice_channels_.end())
358     return;
359
360   voice_channels_.erase(it);
361   delete voice_channel;
362 }
363
364 VideoChannel* ChannelManager::CreateVideoChannel(
365     BaseSession* session,
366     const std::string& content_name,
367     bool rtcp,
368     VoiceChannel* voice_channel) {
369   return worker_thread_->Invoke<VideoChannel*>(
370       Bind(&ChannelManager::CreateVideoChannel_w,
371            this,
372            session,
373            content_name,
374            rtcp,
375            VideoOptions(),
376            voice_channel));
377 }
378
379 VideoChannel* ChannelManager::CreateVideoChannel(
380     BaseSession* session,
381     const std::string& content_name,
382     bool rtcp,
383     const VideoOptions& options,
384     VoiceChannel* voice_channel) {
385   return worker_thread_->Invoke<VideoChannel*>(
386       Bind(&ChannelManager::CreateVideoChannel_w,
387            this,
388            session,
389            content_name,
390            rtcp,
391            options,
392            voice_channel));
393 }
394
395 VideoChannel* ChannelManager::CreateVideoChannel_w(
396     BaseSession* session,
397     const std::string& content_name,
398     bool rtcp,
399     const VideoOptions& options,
400     VoiceChannel* voice_channel) {
401   // This is ok to alloc from a thread other than the worker thread
402   ASSERT(initialized_);
403   VideoMediaChannel* media_channel =
404       // voice_channel can be NULL in case of NullVoiceEngine.
405       media_engine_->CreateVideoChannel(
406           options, voice_channel ? voice_channel->media_channel() : NULL);
407   if (media_channel == NULL)
408     return NULL;
409
410   VideoChannel* video_channel = new VideoChannel(
411       worker_thread_, media_engine_.get(), media_channel,
412       session, content_name, rtcp, voice_channel);
413   if (!video_channel->Init()) {
414     delete video_channel;
415     return NULL;
416   }
417   video_channels_.push_back(video_channel);
418   return video_channel;
419 }
420
421 void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
422   if (video_channel) {
423     worker_thread_->Invoke<void>(
424         Bind(&ChannelManager::DestroyVideoChannel_w, this, video_channel));
425   }
426 }
427
428 void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
429   // Destroy video channel.
430   ASSERT(initialized_);
431   VideoChannels::iterator it = std::find(video_channels_.begin(),
432       video_channels_.end(), video_channel);
433   ASSERT(it != video_channels_.end());
434   if (it == video_channels_.end())
435     return;
436
437   video_channels_.erase(it);
438   delete video_channel;
439 }
440
441 DataChannel* ChannelManager::CreateDataChannel(
442     BaseSession* session, const std::string& content_name,
443     bool rtcp, DataChannelType channel_type) {
444   return worker_thread_->Invoke<DataChannel*>(
445       Bind(&ChannelManager::CreateDataChannel_w, this, session, content_name,
446            rtcp, channel_type));
447 }
448
449 DataChannel* ChannelManager::CreateDataChannel_w(
450     BaseSession* session, const std::string& content_name,
451     bool rtcp, DataChannelType data_channel_type) {
452   // This is ok to alloc from a thread other than the worker thread.
453   ASSERT(initialized_);
454   DataMediaChannel* media_channel = data_media_engine_->CreateChannel(
455       data_channel_type);
456   if (!media_channel) {
457     LOG(LS_WARNING) << "Failed to create data channel of type "
458                     << data_channel_type;
459     return NULL;
460   }
461
462   DataChannel* data_channel = new DataChannel(
463       worker_thread_, media_channel,
464       session, content_name, rtcp);
465   if (!data_channel->Init()) {
466     LOG(LS_WARNING) << "Failed to init data channel.";
467     delete data_channel;
468     return NULL;
469   }
470   data_channels_.push_back(data_channel);
471   return data_channel;
472 }
473
474 void ChannelManager::DestroyDataChannel(DataChannel* data_channel) {
475   if (data_channel) {
476     worker_thread_->Invoke<void>(
477         Bind(&ChannelManager::DestroyDataChannel_w, this, data_channel));
478   }
479 }
480
481 void ChannelManager::DestroyDataChannel_w(DataChannel* data_channel) {
482   // Destroy data channel.
483   ASSERT(initialized_);
484   DataChannels::iterator it = std::find(data_channels_.begin(),
485       data_channels_.end(), data_channel);
486   ASSERT(it != data_channels_.end());
487   if (it == data_channels_.end())
488     return;
489
490   data_channels_.erase(it);
491   delete data_channel;
492 }
493
494 Soundclip* ChannelManager::CreateSoundclip() {
495   return worker_thread_->Invoke<Soundclip*>(
496       Bind(&ChannelManager::CreateSoundclip_w, this));
497 }
498
499 Soundclip* ChannelManager::CreateSoundclip_w() {
500   ASSERT(initialized_);
501   ASSERT(worker_thread_ == rtc::Thread::Current());
502
503   SoundclipMedia* soundclip_media = media_engine_->CreateSoundclip();
504   if (!soundclip_media) {
505     return NULL;
506   }
507
508   Soundclip* soundclip = new Soundclip(worker_thread_, soundclip_media);
509   soundclips_.push_back(soundclip);
510   return soundclip;
511 }
512
513 void ChannelManager::DestroySoundclip(Soundclip* soundclip) {
514   if (soundclip) {
515     worker_thread_->Invoke<void>(
516         Bind(&ChannelManager::DestroySoundclip_w, this, soundclip));
517   }
518 }
519
520 void ChannelManager::DestroySoundclip_w(Soundclip* soundclip) {
521   // Destroy soundclip.
522   ASSERT(initialized_);
523   Soundclips::iterator it = std::find(soundclips_.begin(),
524       soundclips_.end(), soundclip);
525   ASSERT(it != soundclips_.end());
526   if (it == soundclips_.end())
527     return;
528
529   soundclips_.erase(it);
530   delete soundclip;
531 }
532
533 bool ChannelManager::GetAudioOptions(std::string* in_name,
534                                      std::string* out_name,
535                                      AudioOptions* options) {
536   if (in_name)
537     *in_name = audio_in_device_;
538   if (out_name)
539     *out_name = audio_out_device_;
540   if (options)
541     *options = audio_options_;
542   return true;
543 }
544
545 bool ChannelManager::SetAudioOptions(const std::string& in_name,
546                                      const std::string& out_name,
547                                      const AudioOptions& options) {
548   return SetAudioOptions(in_name, out_name, options, audio_delay_offset_);
549 }
550
551 bool ChannelManager::SetAudioOptions(const std::string& in_name,
552                                      const std::string& out_name,
553                                      const AudioOptions& options,
554                                      int delay_offset) {
555   // Get device ids from DeviceManager.
556   Device in_dev, out_dev;
557   if (!device_manager_->GetAudioInputDevice(in_name, &in_dev)) {
558     LOG(LS_WARNING) << "Failed to GetAudioInputDevice: " << in_name;
559     return false;
560   }
561   if (!device_manager_->GetAudioOutputDevice(out_name, &out_dev)) {
562     LOG(LS_WARNING) << "Failed to GetAudioOutputDevice: " << out_name;
563     return false;
564   }
565
566   // If we're initialized, pass the settings to the media engine.
567   bool ret = true;
568   if (initialized_) {
569     ret = worker_thread_->Invoke<bool>(
570         Bind(&ChannelManager::SetAudioOptions_w, this,
571              options, delay_offset, &in_dev, &out_dev));
572   }
573
574   // If all worked well, save the values for use in GetAudioOptions.
575   if (ret) {
576     audio_options_ = options;
577     audio_in_device_ = in_name;
578     audio_out_device_ = out_name;
579     audio_delay_offset_ = delay_offset;
580   }
581   return ret;
582 }
583
584 bool ChannelManager::SetAudioOptions_w(
585     const AudioOptions& options, int delay_offset,
586     const Device* in_dev, const Device* out_dev) {
587   ASSERT(worker_thread_ == rtc::Thread::Current());
588   ASSERT(initialized_);
589
590   // Set audio options
591   bool ret = media_engine_->SetAudioOptions(options);
592
593   if (ret) {
594     ret = media_engine_->SetAudioDelayOffset(delay_offset);
595   }
596
597   // Set the audio devices
598   if (ret) {
599     ret = media_engine_->SetSoundDevices(in_dev, out_dev);
600   }
601
602   return ret;
603 }
604
605 // Sets Engine-specific audio options according to enabled experiments.
606 bool ChannelManager::SetEngineAudioOptions(const AudioOptions& options) {
607   // If we're initialized, pass the settings to the media engine.
608   bool ret = false;
609   if (initialized_) {
610     ret = worker_thread_->Invoke<bool>(
611         Bind(&ChannelManager::SetEngineAudioOptions_w, this, options));
612   }
613
614   // If all worked well, save the audio options.
615   if (ret) {
616     audio_options_ = options;
617   }
618   return ret;
619 }
620
621 bool ChannelManager::SetEngineAudioOptions_w(const AudioOptions& options) {
622   ASSERT(worker_thread_ == rtc::Thread::Current());
623   ASSERT(initialized_);
624
625   return media_engine_->SetAudioOptions(options);
626 }
627
628 bool ChannelManager::GetOutputVolume(int* level) {
629   if (!initialized_) {
630     return false;
631   }
632   return worker_thread_->Invoke<bool>(
633       Bind(&MediaEngineInterface::GetOutputVolume, media_engine_.get(), level));
634 }
635
636 bool ChannelManager::SetOutputVolume(int level) {
637   bool ret = level >= 0 && level <= 255;
638   if (initialized_) {
639     ret &= worker_thread_->Invoke<bool>(
640         Bind(&MediaEngineInterface::SetOutputVolume,
641              media_engine_.get(), level));
642   }
643
644   if (ret) {
645     audio_output_volume_ = level;
646   }
647
648   return ret;
649 }
650
651 bool ChannelManager::IsSameCapturer(const std::string& capturer_name,
652                                     VideoCapturer* capturer) {
653   if (capturer == NULL) {
654     return false;
655   }
656   Device device;
657   if (!device_manager_->GetVideoCaptureDevice(capturer_name, &device)) {
658     return false;
659   }
660   return capturer->GetId() == device.id;
661 }
662
663 bool ChannelManager::GetVideoCaptureDevice(Device* device) {
664   std::string device_name;
665   if (!GetCaptureDevice(&device_name)) {
666     return false;
667   }
668   return device_manager_->GetVideoCaptureDevice(device_name, device);
669 }
670
671 bool ChannelManager::GetCaptureDevice(std::string* cam_name) {
672   if (camera_device_.empty()) {
673     // Initialize camera_device_ with default.
674     Device device;
675     if (!device_manager_->GetVideoCaptureDevice(
676         DeviceManagerInterface::kDefaultDeviceName, &device)) {
677       LOG(LS_WARNING) << "Device manager can't find default camera: " <<
678           DeviceManagerInterface::kDefaultDeviceName;
679       return false;
680     }
681     camera_device_ = device.name;
682   }
683   *cam_name = camera_device_;
684   return true;
685 }
686
687 bool ChannelManager::SetCaptureDevice(const std::string& cam_name) {
688   Device device;
689   bool ret = true;
690   if (!device_manager_->GetVideoCaptureDevice(cam_name, &device)) {
691     if (!cam_name.empty()) {
692       LOG(LS_WARNING) << "Device manager can't find camera: " << cam_name;
693     }
694     ret = false;
695   }
696
697   // If we're running, tell the media engine about it.
698   if (initialized_ && ret) {
699     ret = worker_thread_->Invoke<bool>(
700         Bind(&ChannelManager::SetCaptureDevice_w, this, &device));
701   }
702
703   // If everything worked, retain the name of the selected camera.
704   if (ret) {
705     camera_device_ = device.name;
706   } else if (camera_device_.empty()) {
707     // When video option setting fails, we still want camera_device_ to be in a
708     // good state, so we initialize it with default if it's empty.
709     Device default_device;
710     if (!device_manager_->GetVideoCaptureDevice(
711         DeviceManagerInterface::kDefaultDeviceName, &default_device)) {
712       LOG(LS_WARNING) << "Device manager can't find default camera: " <<
713           DeviceManagerInterface::kDefaultDeviceName;
714     }
715     camera_device_ = default_device.name;
716   }
717
718   return ret;
719 }
720
721 VideoCapturer* ChannelManager::CreateVideoCapturer() {
722   Device device;
723   if (!device_manager_->GetVideoCaptureDevice(camera_device_, &device)) {
724     if (!camera_device_.empty()) {
725       LOG(LS_WARNING) << "Device manager can't find camera: " << camera_device_;
726     }
727     return NULL;
728   }
729   VideoCapturer* capturer = device_manager_->CreateVideoCapturer(device);
730   if (capturer && default_video_encoder_config_.max_codec.id != 0) {
731     // For now, use the aspect ratio of the default_video_encoder_config_,
732     // which may be different than the native aspect ratio of the start
733     // format the camera may use.
734     capturer->UpdateAspectRatio(
735         default_video_encoder_config_.max_codec.width,
736         default_video_encoder_config_.max_codec.height);
737   }
738   return capturer;
739 }
740
741 VideoCapturer* ChannelManager::CreateScreenCapturer(
742     const ScreencastId& screenid) {
743   return device_manager_->CreateScreenCapturer(screenid);
744 }
745
746 bool ChannelManager::SetCaptureDevice_w(const Device* cam_device) {
747   ASSERT(worker_thread_ == rtc::Thread::Current());
748   ASSERT(initialized_);
749
750   if (!cam_device) {
751     video_device_name_.clear();
752     return true;
753   }
754   video_device_name_ = cam_device->name;
755   return true;
756 }
757
758 bool ChannelManager::SetDefaultVideoEncoderConfig(const VideoEncoderConfig& c) {
759   bool ret = true;
760   if (initialized_) {
761     ret = worker_thread_->Invoke<bool>(
762         Bind(&MediaEngineInterface::SetDefaultVideoEncoderConfig,
763              media_engine_.get(), c));
764   }
765   if (ret) {
766     default_video_encoder_config_ = c;
767   }
768   return ret;
769 }
770
771 bool ChannelManager::SetLocalMonitor(bool enable) {
772   bool ret = initialized_ && worker_thread_->Invoke<bool>(
773       Bind(&MediaEngineInterface::SetLocalMonitor,
774            media_engine_.get(), enable));
775   if (ret) {
776     monitoring_ = enable;
777   }
778   return ret;
779 }
780
781 void ChannelManager::SetVoiceLogging(int level, const char* filter) {
782   if (initialized_) {
783     worker_thread_->Invoke<void>(
784         Bind(&MediaEngineInterface::SetVoiceLogging,
785              media_engine_.get(), level, filter));
786   } else {
787     media_engine_->SetVoiceLogging(level, filter);
788   }
789 }
790
791 void ChannelManager::SetVideoLogging(int level, const char* filter) {
792   if (initialized_) {
793     worker_thread_->Invoke<void>(
794         Bind(&MediaEngineInterface::SetVideoLogging,
795              media_engine_.get(), level, filter));
796   } else {
797     media_engine_->SetVideoLogging(level, filter);
798   }
799 }
800
801 // TODO(janahan): For now pass this request through the mediaengine to the
802 // voice and video engines to do the real work. Once the capturer refactoring
803 // is done, we will access the capturer using the ssrc (similar to how the
804 // renderer is accessed today) and register with it directly.
805 bool ChannelManager::RegisterVideoProcessor(VideoCapturer* capturer,
806                                             VideoProcessor* processor) {
807   return initialized_ && worker_thread_->Invoke<bool>(
808       Bind(&ChannelManager::RegisterVideoProcessor_w, this,
809            capturer, processor));
810 }
811
812 bool ChannelManager::RegisterVideoProcessor_w(VideoCapturer* capturer,
813                                               VideoProcessor* processor) {
814   return capture_manager_->AddVideoProcessor(capturer, processor);
815 }
816
817 bool ChannelManager::UnregisterVideoProcessor(VideoCapturer* capturer,
818                                               VideoProcessor* processor) {
819   return initialized_ && worker_thread_->Invoke<bool>(
820       Bind(&ChannelManager::UnregisterVideoProcessor_w, this,
821            capturer, processor));
822 }
823
824 bool ChannelManager::UnregisterVideoProcessor_w(VideoCapturer* capturer,
825                                                 VideoProcessor* processor) {
826   return capture_manager_->RemoveVideoProcessor(capturer, processor);
827 }
828
829 bool ChannelManager::RegisterVoiceProcessor(
830     uint32 ssrc,
831     VoiceProcessor* processor,
832     MediaProcessorDirection direction) {
833   return initialized_ && worker_thread_->Invoke<bool>(
834       Bind(&MediaEngineInterface::RegisterVoiceProcessor, media_engine_.get(),
835            ssrc, processor, direction));
836 }
837
838 bool ChannelManager::UnregisterVoiceProcessor(
839     uint32 ssrc,
840     VoiceProcessor* processor,
841     MediaProcessorDirection direction) {
842   return initialized_ && worker_thread_->Invoke<bool>(
843       Bind(&MediaEngineInterface::UnregisterVoiceProcessor,
844            media_engine_.get(), ssrc, processor, direction));
845 }
846
847 // The following are done in the new "CaptureManager" style that
848 // all local video capturers, processors, and managers should move
849 // to.
850 // TODO(pthatcher): Add more of the CaptureManager interface.
851 bool ChannelManager::StartVideoCapture(
852     VideoCapturer* capturer, const VideoFormat& video_format) {
853   return initialized_ && worker_thread_->Invoke<bool>(
854       Bind(&CaptureManager::StartVideoCapture,
855            capture_manager_.get(), capturer, video_format));
856 }
857
858 bool ChannelManager::MuteToBlackThenPause(
859     VideoCapturer* video_capturer, bool muted) {
860   if (!initialized_) {
861     return false;
862   }
863   worker_thread_->Invoke<void>(
864       Bind(&VideoCapturer::MuteToBlackThenPause, video_capturer, muted));
865   return true;
866 }
867
868 bool ChannelManager::StopVideoCapture(
869     VideoCapturer* capturer, const VideoFormat& video_format) {
870   return initialized_ && worker_thread_->Invoke<bool>(
871       Bind(&CaptureManager::StopVideoCapture,
872            capture_manager_.get(), capturer, video_format));
873 }
874
875 bool ChannelManager::RestartVideoCapture(
876     VideoCapturer* video_capturer,
877     const VideoFormat& previous_format,
878     const VideoFormat& desired_format,
879     CaptureManager::RestartOptions options) {
880   return initialized_ && worker_thread_->Invoke<bool>(
881       Bind(&CaptureManager::RestartVideoCapture, capture_manager_.get(),
882            video_capturer, previous_format, desired_format, options));
883 }
884
885 bool ChannelManager::AddVideoRenderer(
886     VideoCapturer* capturer, VideoRenderer* renderer) {
887   return initialized_ && worker_thread_->Invoke<bool>(
888       Bind(&CaptureManager::AddVideoRenderer,
889            capture_manager_.get(), capturer, renderer));
890 }
891
892 bool ChannelManager::RemoveVideoRenderer(
893     VideoCapturer* capturer, VideoRenderer* renderer) {
894   return initialized_ && worker_thread_->Invoke<bool>(
895       Bind(&CaptureManager::RemoveVideoRenderer,
896            capture_manager_.get(), capturer, renderer));
897 }
898
899 bool ChannelManager::IsScreencastRunning() const {
900   return initialized_ && worker_thread_->Invoke<bool>(
901       Bind(&ChannelManager::IsScreencastRunning_w, this));
902 }
903
904 bool ChannelManager::IsScreencastRunning_w() const {
905   VideoChannels::const_iterator it = video_channels_.begin();
906   for ( ; it != video_channels_.end(); ++it) {
907     if ((*it) && (*it)->IsScreencasting()) {
908       return true;
909     }
910   }
911   return false;
912 }
913
914 void ChannelManager::OnVideoCaptureStateChange(VideoCapturer* capturer,
915                                                CaptureState result) {
916   // TODO(whyuan): Check capturer and signal failure only for camera video, not
917   // screencast.
918   capturing_ = result == CS_RUNNING;
919   main_thread_->Post(this, MSG_VIDEOCAPTURESTATE,
920                      new CaptureStateParams(capturer, result));
921 }
922
923 void ChannelManager::OnMessage(rtc::Message* message) {
924   switch (message->message_id) {
925     case MSG_VIDEOCAPTURESTATE: {
926       CaptureStateParams* data =
927           static_cast<CaptureStateParams*>(message->pdata);
928       SignalVideoCaptureStateChange(data->capturer, data->state);
929       delete data;
930       break;
931     }
932   }
933 }
934
935
936 static void GetDeviceNames(const std::vector<Device>& devs,
937                            std::vector<std::string>* names) {
938   names->clear();
939   for (size_t i = 0; i < devs.size(); ++i) {
940     names->push_back(devs[i].name);
941   }
942 }
943
944 bool ChannelManager::GetAudioInputDevices(std::vector<std::string>* names) {
945   names->clear();
946   std::vector<Device> devs;
947   bool ret = device_manager_->GetAudioInputDevices(&devs);
948   if (ret)
949     GetDeviceNames(devs, names);
950
951   return ret;
952 }
953
954 bool ChannelManager::GetAudioOutputDevices(std::vector<std::string>* names) {
955   names->clear();
956   std::vector<Device> devs;
957   bool ret = device_manager_->GetAudioOutputDevices(&devs);
958   if (ret)
959     GetDeviceNames(devs, names);
960
961   return ret;
962 }
963
964 bool ChannelManager::GetVideoCaptureDevices(std::vector<std::string>* names) {
965   names->clear();
966   std::vector<Device> devs;
967   bool ret = device_manager_->GetVideoCaptureDevices(&devs);
968   if (ret)
969     GetDeviceNames(devs, names);
970
971   return ret;
972 }
973
974 void ChannelManager::SetVideoCaptureDeviceMaxFormat(
975     const std::string& usb_id,
976     const VideoFormat& max_format) {
977   device_manager_->SetVideoCaptureDeviceMaxFormat(usb_id, max_format);
978 }
979
980 VideoFormat ChannelManager::GetStartCaptureFormat() {
981   return worker_thread_->Invoke<VideoFormat>(
982       Bind(&MediaEngineInterface::GetStartCaptureFormat, media_engine_.get()));
983 }
984
985 bool ChannelManager::StartAecDump(rtc::PlatformFile file) {
986   return worker_thread_->Invoke<bool>(
987       Bind(&MediaEngineInterface::StartAecDump, media_engine_.get(), file));
988 }
989
990 }  // namespace cricket