1 /*
2  * libjingle
3  * Copyright 2004--2008, 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/phone/channelmanager.h"
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include <algorithm>
35 
36 #include "talk/base/common.h"
37 #include "talk/base/logging.h"
38 #include "talk/base/sigslotrepeater.h"
39 #include "talk/base/stringencode.h"
40 #include "talk/session/phone/dataengine.h"
41 #include "talk/session/phone/soundclip.h"
42 
43 namespace cricket {
44 
45 enum {
46   MSG_CREATEVOICECHANNEL = 1,
47   MSG_DESTROYVOICECHANNEL = 2,
48   MSG_SETAUDIOOPTIONS = 3,
49   MSG_GETOUTPUTVOLUME = 4,
50   MSG_SETOUTPUTVOLUME = 5,
51   MSG_SETLOCALMONITOR = 6,
52   MSG_SETVOICELOGGING = 7,
53   MSG_CREATEVIDEOCHANNEL = 11,
54   MSG_DESTROYVIDEOCHANNEL = 12,
55   MSG_SETVIDEOOPTIONS = 13,
56   MSG_SETLOCALRENDERER = 14,
57   MSG_SETDEFAULTVIDEOENCODERCONFIG = 15,
58   MSG_SETVIDEOLOGGING = 16,
59   MSG_CREATESOUNDCLIP = 17,
60   MSG_DESTROYSOUNDCLIP = 18,
61   MSG_CAMERASTARTED = 19,
62   MSG_SETVIDEOCAPTURE = 20,
63   MSG_TERMINATE = 21,
64   MSG_REGISTERVIDEOPROCESSOR = 22,
65   MSG_UNREGISTERVIDEOPROCESSOR = 23,
66   MSG_REGISTERVOICEPROCESSOR = 24,
67   MSG_UNREGISTERVOICEPROCESSOR = 25,
68   MSG_SETVIDEOCAPTURER = 26,
69   MSG_CREATEDATACHANNEL = 27,
70   MSG_DESTROYDATACHANNEL = 28,
71 };
72 
73 static const int kNotSetOutputVolume = -1;
74 
75 struct CreationParams : public talk_base::MessageData {
CreationParamscricket::CreationParams76   CreationParams(BaseSession* session, const std::string& content_name,
77                  bool rtcp, VoiceChannel* voice_channel)
78       : session(session),
79         content_name(content_name),
80         rtcp(rtcp),
81         voice_channel(voice_channel),
82         video_channel(NULL),
83         data_channel(NULL) {
84   }
85   BaseSession* session;
86   std::string content_name;
87   bool rtcp;
88   VoiceChannel* voice_channel;
89   VideoChannel* video_channel;
90   DataChannel* data_channel;
91 };
92 
93 struct AudioOptions : public talk_base::MessageData {
AudioOptionscricket::AudioOptions94   AudioOptions(int o, const Device* in, const Device* out)
95       : options(o), in_device(in), out_device(out) {}
96   int options;
97   const Device* in_device;
98   const Device* out_device;
99   bool result;
100 };
101 
102 struct VolumeLevel : public talk_base::MessageData {
VolumeLevelcricket::VolumeLevel103   VolumeLevel() : level(-1), result(false) {}
VolumeLevelcricket::VolumeLevel104   explicit VolumeLevel(int l) : level(l), result(false) {}
105   int level;
106   bool result;
107 };
108 
109 struct VideoOptions : public talk_base::MessageData {
VideoOptionscricket::VideoOptions110   explicit VideoOptions(const Device* d) : cam_device(d), result(false) {}
111   const Device* cam_device;
112   bool result;
113 };
114 
115 struct DefaultVideoEncoderConfig : public talk_base::MessageData {
DefaultVideoEncoderConfigcricket::DefaultVideoEncoderConfig116   explicit DefaultVideoEncoderConfig(const VideoEncoderConfig& c)
117       : config(c), result(false) {}
118   VideoEncoderConfig config;
119   bool result;
120 };
121 
122 struct LocalMonitor : public talk_base::MessageData {
LocalMonitorcricket::LocalMonitor123   explicit LocalMonitor(bool e) : enable(e), result(false) {}
124   bool enable;
125   bool result;
126 };
127 
128 struct LocalRenderer : public talk_base::MessageData {
LocalRenderercricket::LocalRenderer129   explicit LocalRenderer(VideoRenderer* r) : renderer(r), result(false) {}
130   VideoRenderer* renderer;
131   bool result;
132 };
133 
134 struct Capturer : public talk_base::MessageData {
Capturercricket::Capturer135   Capturer(VideoCapturer* c, uint32 s)
136       : capturer(c),
137         ssrc(s),
138         result(false) {}
139   VideoCapturer* capturer;
140   uint32 ssrc;
141   bool result;
142 };
143 
144 struct LoggingOptions : public talk_base::MessageData {
LoggingOptionscricket::LoggingOptions145   explicit LoggingOptions(int lev, const char* f) : level(lev), filter(f) {}
146   int level;
147   std::string filter;
148 };
149 
150 struct CaptureParams : public talk_base::MessageData {
CaptureParamscricket::CaptureParams151   explicit CaptureParams(bool c) : capture(c), result(CR_FAILURE) {}
152   bool capture;
153   CaptureResult result;
154 };
155 
156 struct VideoProcessorParams : public talk_base::MessageData {
VideoProcessorParamscricket::VideoProcessorParams157   VideoProcessorParams(uint32 s, VideoProcessor* p)
158       : ssrc(s), processor(p), result(false) {}
159   uint32 ssrc;
160   VideoProcessor* processor;
161   bool result;
162 };
163 
164 struct VoiceProcessorParams : public talk_base::MessageData {
VoiceProcessorParamscricket::VoiceProcessorParams165   VoiceProcessorParams(uint32 c, VoiceProcessor* p, MediaProcessorDirection d)
166       : ssrc(c), direction(d), processor(p), result(false) {}
167   uint32 ssrc;
168   MediaProcessorDirection direction;
169   VoiceProcessor* processor;
170   bool result;
171 };
172 
ChannelManager(talk_base::Thread * worker_thread)173 ChannelManager::ChannelManager(talk_base::Thread* worker_thread) {
174   Construct(MediaEngineFactory::Create(),
175             new DataEngine(),
176             cricket::DeviceManagerFactory::Create(),
177             worker_thread);
178 }
179 
ChannelManager(MediaEngineInterface * me,DataEngineInterface * dme,DeviceManagerInterface * dm,talk_base::Thread * worker_thread)180 ChannelManager::ChannelManager(MediaEngineInterface* me,
181                                DataEngineInterface* dme,
182                                DeviceManagerInterface* dm,
183                                talk_base::Thread* worker_thread) {
184   Construct(me, dme, dm, worker_thread);
185 }
186 
ChannelManager(MediaEngineInterface * me,DeviceManagerInterface * dm,talk_base::Thread * worker_thread)187 ChannelManager::ChannelManager(MediaEngineInterface* me,
188                                DeviceManagerInterface* dm,
189                                talk_base::Thread* worker_thread) {
190   Construct(me, new DataEngine(), dm, worker_thread);
191 }
192 
Construct(MediaEngineInterface * me,DataEngineInterface * dme,DeviceManagerInterface * dm,talk_base::Thread * worker_thread)193 void ChannelManager::Construct(MediaEngineInterface* me,
194                                DataEngineInterface* dme,
195                                DeviceManagerInterface* dm,
196                                talk_base::Thread* worker_thread) {
197   media_engine_.reset(me);
198   data_media_engine_.reset(dme);
199   device_manager_.reset(dm);
200   initialized_ = false;
201   main_thread_ = talk_base::Thread::Current();
202   worker_thread_ = worker_thread;
203   audio_in_device_ = DeviceManagerInterface::kDefaultDeviceName;
204   audio_out_device_ = DeviceManagerInterface::kDefaultDeviceName;
205   audio_options_ = MediaEngineInterface::DEFAULT_AUDIO_OPTIONS;
206   audio_output_volume_ = kNotSetOutputVolume;
207   local_renderer_ = NULL;
208   capturing_ = false;
209   monitoring_ = false;
210 
211   // Init the device manager immediately, and set up our default video device.
212   SignalDevicesChange.repeat(device_manager_->SignalDevicesChange);
213   device_manager_->Init();
214 
215   // Camera is started asynchronously, request callbacks when startup
216   // completes to be able to forward them to the rendering manager.
217   media_engine_->SignalVideoCaptureResult.connect(
218       this, &ChannelManager::OnVideoCaptureResult);
219 }
220 
~ChannelManager()221 ChannelManager::~ChannelManager() {
222   if (initialized_)
223     Terminate();
224 }
225 
GetCapabilities()226 int ChannelManager::GetCapabilities() {
227   return media_engine_->GetCapabilities() & device_manager_->GetCapabilities();
228 }
229 
GetSupportedAudioCodecs(std::vector<AudioCodec> * codecs) const230 void ChannelManager::GetSupportedAudioCodecs(
231     std::vector<AudioCodec>* codecs) const {
232   codecs->clear();
233 
234   for (std::vector<AudioCodec>::const_iterator it =
235            media_engine_->audio_codecs().begin();
236       it != media_engine_->audio_codecs().end(); ++it) {
237     codecs->push_back(*it);
238   }
239 }
240 
GetSupportedVideoCodecs(std::vector<VideoCodec> * codecs) const241 void ChannelManager::GetSupportedVideoCodecs(
242     std::vector<VideoCodec>* codecs) const {
243   codecs->clear();
244 
245   std::vector<VideoCodec>::const_iterator it;
246   for (it = media_engine_->video_codecs().begin();
247       it != media_engine_->video_codecs().end(); ++it) {
248     codecs->push_back(*it);
249   }
250 }
251 
GetSupportedDataCodecs(std::vector<DataCodec> * codecs) const252 void ChannelManager::GetSupportedDataCodecs(
253     std::vector<DataCodec>* codecs) const {
254   *codecs = data_media_engine_->data_codecs();
255 }
256 
Init()257 bool ChannelManager::Init() {
258   ASSERT(!initialized_);
259   if (initialized_) {
260     return false;
261   }
262 
263   ASSERT(worker_thread_ != NULL);
264   if (worker_thread_ && worker_thread_->started()) {
265     if (media_engine_->Init()) {
266       initialized_ = true;
267 
268       // Now that we're initialized, apply any stored preferences. A preferred
269       // device might have been unplugged. In this case, we fallback to the
270       // default device but keep the user preferences. The preferences are
271       // changed only when the Javascript FE changes them.
272       const std::string preferred_audio_in_device = audio_in_device_;
273       const std::string preferred_audio_out_device = audio_out_device_;
274       const std::string preferred_camera_device = camera_device_;
275       Device device;
276       if (!device_manager_->GetAudioInputDevice(audio_in_device_, &device)) {
277         LOG(LS_WARNING) << "The preferred microphone '" << audio_in_device_
278                         << "' is unavailable. Fall back to the default.";
279         audio_in_device_ = DeviceManagerInterface::kDefaultDeviceName;
280       }
281       if (!device_manager_->GetAudioOutputDevice(audio_out_device_, &device)) {
282         LOG(LS_WARNING) << "The preferred speaker '" << audio_out_device_
283                         << "' is unavailable. Fall back to the default.";
284         audio_out_device_ = DeviceManagerInterface::kDefaultDeviceName;
285       }
286       if (!device_manager_->GetVideoCaptureDevice(camera_device_, &device)) {
287         if (!camera_device_.empty()) {
288           LOG(LS_WARNING) << "The preferred camera '" << camera_device_
289                           << "' is unavailable. Fall back to the default.";
290         }
291         camera_device_ = DeviceManagerInterface::kDefaultDeviceName;
292       }
293 
294       if (!SetAudioOptions(audio_in_device_, audio_out_device_,
295                            audio_options_)) {
296         LOG(LS_WARNING) << "Failed to SetAudioOptions with"
297                         << " microphone: " << audio_in_device_
298                         << " speaker: " << audio_out_device_
299                         << " options: " << audio_options_;
300       }
301 
302       // If audio_output_volume_ has been set via SetOutputVolume(), set the
303       // audio output volume of the engine.
304       if (kNotSetOutputVolume != audio_output_volume_ &&
305           !SetOutputVolume(audio_output_volume_)) {
306         LOG(LS_WARNING) << "Failed to SetOutputVolume to "
307                         << audio_output_volume_;
308       }
309       if (!SetVideoOptions(camera_device_) && !camera_device_.empty()) {
310         LOG(LS_WARNING) << "Failed to SetVideoOptions with camera: "
311                         << camera_device_;
312       }
313 
314       // Restore the user preferences.
315       audio_in_device_ = preferred_audio_in_device;
316       audio_out_device_ = preferred_audio_out_device;
317       camera_device_ = preferred_camera_device;
318 
319       // Now apply the default video codec that has been set earlier.
320       if (default_video_encoder_config_.max_codec.id != 0) {
321         SetDefaultVideoEncoderConfig(default_video_encoder_config_);
322       }
323       // And the local renderer.
324       if (local_renderer_) {
325         SetLocalRenderer(local_renderer_);
326       }
327     }
328   }
329   return initialized_;
330 }
331 
Terminate()332 void ChannelManager::Terminate() {
333   ASSERT(initialized_);
334   if (!initialized_) {
335     return;
336   }
337   Send(MSG_TERMINATE, NULL);
338   media_engine_->Terminate();
339   initialized_ = false;
340 }
341 
Terminate_w()342 void ChannelManager::Terminate_w() {
343   ASSERT(worker_thread_ == talk_base::Thread::Current());
344     // Need to destroy the voice/video channels
345   while (!video_channels_.empty()) {
346     DestroyVideoChannel_w(video_channels_.back());
347   }
348   while (!voice_channels_.empty()) {
349     DestroyVoiceChannel_w(voice_channels_.back());
350   }
351   while (!soundclips_.empty()) {
352     DestroySoundclip_w(soundclips_.back());
353   }
354 }
355 
CreateVoiceChannel(BaseSession * session,const std::string & content_name,bool rtcp)356 VoiceChannel* ChannelManager::CreateVoiceChannel(
357     BaseSession* session, const std::string& content_name, bool rtcp) {
358   CreationParams params(session, content_name, rtcp, NULL);
359   return (Send(MSG_CREATEVOICECHANNEL, &params)) ? params.voice_channel : NULL;
360 }
361 
CreateVoiceChannel_w(BaseSession * session,const std::string & content_name,bool rtcp)362 VoiceChannel* ChannelManager::CreateVoiceChannel_w(
363     BaseSession* session, const std::string& content_name, bool rtcp) {
364   // This is ok to alloc from a thread other than the worker thread
365   ASSERT(initialized_);
366   VoiceMediaChannel* media_channel = media_engine_->CreateChannel();
367   if (media_channel == NULL)
368     return NULL;
369 
370   VoiceChannel* voice_channel = new VoiceChannel(
371       worker_thread_, media_engine_.get(), media_channel,
372       session, content_name, rtcp);
373   if (!voice_channel->Init()) {
374     delete voice_channel;
375     return NULL;
376   }
377   voice_channels_.push_back(voice_channel);
378   return voice_channel;
379 }
380 
DestroyVoiceChannel(VoiceChannel * voice_channel)381 void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
382   if (voice_channel) {
383     talk_base::TypedMessageData<VoiceChannel*> data(voice_channel);
384     Send(MSG_DESTROYVOICECHANNEL, &data);
385   }
386 }
387 
DestroyVoiceChannel_w(VoiceChannel * voice_channel)388 void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
389   // Destroy voice channel.
390   ASSERT(initialized_);
391   VoiceChannels::iterator it = std::find(voice_channels_.begin(),
392       voice_channels_.end(), voice_channel);
393   ASSERT(it != voice_channels_.end());
394   if (it == voice_channels_.end())
395     return;
396 
397   voice_channels_.erase(it);
398   delete voice_channel;
399 }
400 
CreateVideoChannel(BaseSession * session,const std::string & content_name,bool rtcp,VoiceChannel * voice_channel)401 VideoChannel* ChannelManager::CreateVideoChannel(
402     BaseSession* session, const std::string& content_name, bool rtcp,
403     VoiceChannel* voice_channel) {
404   CreationParams params(session, content_name, rtcp, voice_channel);
405   return (Send(MSG_CREATEVIDEOCHANNEL, &params)) ? params.video_channel : NULL;
406 }
407 
CreateVideoChannel_w(BaseSession * session,const std::string & content_name,bool rtcp,VoiceChannel * voice_channel)408 VideoChannel* ChannelManager::CreateVideoChannel_w(
409     BaseSession* session, const std::string& content_name, bool rtcp,
410     VoiceChannel* voice_channel) {
411   // This is ok to alloc from a thread other than the worker thread
412   ASSERT(initialized_);
413   VideoMediaChannel* media_channel =
414       // voice_channel can be NULL in case of NullVoiceEngine.
415       media_engine_->CreateVideoChannel(voice_channel ?
416           voice_channel->media_channel() : NULL);
417   if (media_channel == NULL)
418     return NULL;
419 
420   VideoChannel* video_channel = new VideoChannel(
421       worker_thread_, media_engine_.get(), media_channel,
422       session, content_name, rtcp, voice_channel);
423   if (!video_channel->Init()) {
424     delete video_channel;
425     return NULL;
426   }
427   video_channels_.push_back(video_channel);
428   return video_channel;
429 }
430 
DestroyVideoChannel(VideoChannel * video_channel)431 void ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
432   if (video_channel) {
433     talk_base::TypedMessageData<VideoChannel*> data(video_channel);
434     Send(MSG_DESTROYVIDEOCHANNEL, &data);
435   }
436 }
437 
DestroyVideoChannel_w(VideoChannel * video_channel)438 void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
439   // Destroy video channel.
440   ASSERT(initialized_);
441   VideoChannels::iterator it = std::find(video_channels_.begin(),
442       video_channels_.end(), video_channel);
443   ASSERT(it != video_channels_.end());
444   if (it == video_channels_.end())
445     return;
446 
447   video_channels_.erase(it);
448   delete video_channel;
449 }
450 
CreateDataChannel(BaseSession * session,const std::string & content_name,bool rtcp)451 DataChannel* ChannelManager::CreateDataChannel(
452     BaseSession* session, const std::string& content_name, bool rtcp) {
453   CreationParams params(session, content_name, rtcp, NULL);
454   return (Send(MSG_CREATEDATACHANNEL, &params)) ? params.data_channel : NULL;
455 }
456 
CreateDataChannel_w(BaseSession * session,const std::string & content_name,bool rtcp)457 DataChannel* ChannelManager::CreateDataChannel_w(
458     BaseSession* session, const std::string& content_name, bool rtcp) {
459   // This is ok to alloc from a thread other than the worker thread.
460   ASSERT(initialized_);
461   DataMediaChannel* media_channel = data_media_engine_->CreateChannel();
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 
DestroyDataChannel(DataChannel * data_channel)474 void ChannelManager::DestroyDataChannel(DataChannel* data_channel) {
475   if (data_channel) {
476     talk_base::TypedMessageData<DataChannel*> data(data_channel);
477     Send(MSG_DESTROYDATACHANNEL, &data);
478   }
479 }
480 
DestroyDataChannel_w(DataChannel * data_channel)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 
CreateSoundclip()494 Soundclip* ChannelManager::CreateSoundclip() {
495   talk_base::TypedMessageData<Soundclip*> data(NULL);
496   Send(MSG_CREATESOUNDCLIP, &data);
497   return data.data();
498 }
499 
CreateSoundclip_w()500 Soundclip* ChannelManager::CreateSoundclip_w() {
501   ASSERT(initialized_);
502   ASSERT(worker_thread_ == talk_base::Thread::Current());
503 
504   SoundclipMedia* soundclip_media = media_engine_->CreateSoundclip();
505   if (!soundclip_media) {
506     return NULL;
507   }
508 
509   Soundclip* soundclip = new Soundclip(worker_thread_, soundclip_media);
510   soundclips_.push_back(soundclip);
511   return soundclip;
512 }
513 
DestroySoundclip(Soundclip * soundclip)514 void ChannelManager::DestroySoundclip(Soundclip* soundclip) {
515   if (soundclip) {
516     talk_base::TypedMessageData<Soundclip*> data(soundclip);
517     Send(MSG_DESTROYSOUNDCLIP, &data);
518   }
519 }
520 
DestroySoundclip_w(Soundclip * soundclip)521 void ChannelManager::DestroySoundclip_w(Soundclip* soundclip) {
522   // Destroy soundclip.
523   ASSERT(initialized_);
524   Soundclips::iterator it = std::find(soundclips_.begin(),
525       soundclips_.end(), soundclip);
526   ASSERT(it != soundclips_.end());
527   if (it == soundclips_.end())
528     return;
529 
530   soundclips_.erase(it);
531   delete soundclip;
532 }
533 
GetAudioOptions(std::string * in_name,std::string * out_name,int * opts)534 bool ChannelManager::GetAudioOptions(std::string* in_name,
535                                      std::string* out_name, int* opts) {
536   *in_name = audio_in_device_;
537   *out_name = audio_out_device_;
538   *opts = audio_options_;
539   return true;
540 }
541 
SetAudioOptions(const std::string & in_name,const std::string & out_name,int opts)542 bool ChannelManager::SetAudioOptions(const std::string& in_name,
543                                      const std::string& out_name, int opts) {
544   // Get device ids from DeviceManager.
545   Device in_dev, out_dev;
546   if (!device_manager_->GetAudioInputDevice(in_name, &in_dev)) {
547     LOG(LS_WARNING) << "Failed to GetAudioInputDevice: " << in_name;
548     return false;
549   }
550   if (!device_manager_->GetAudioOutputDevice(out_name, &out_dev)) {
551     LOG(LS_WARNING) << "Failed to GetAudioOutputDevice: " << out_name;
552     return false;
553   }
554 
555   // If we're initialized, pass the settings to the media engine.
556   bool ret = true;
557   if (initialized_) {
558     AudioOptions options(opts, &in_dev, &out_dev);
559     ret = (Send(MSG_SETAUDIOOPTIONS, &options) && options.result);
560   }
561 
562   // If all worked well, save the values for use in GetAudioOptions.
563   if (ret) {
564     audio_options_ = opts;
565     audio_in_device_ = in_name;
566     audio_out_device_ = out_name;
567   }
568   return ret;
569 }
570 
SetAudioOptions_w(int opts,const Device * in_dev,const Device * out_dev)571 bool ChannelManager::SetAudioOptions_w(int opts, const Device* in_dev,
572     const Device* out_dev) {
573   ASSERT(worker_thread_ == talk_base::Thread::Current());
574   ASSERT(initialized_);
575 
576   // Set audio options
577   bool ret = media_engine_->SetAudioOptions(opts);
578 
579   // Set the audio devices
580   if (ret) {
581     ret = media_engine_->SetSoundDevices(in_dev, out_dev);
582   }
583 
584   return ret;
585 }
586 
GetOutputVolume(int * level)587 bool ChannelManager::GetOutputVolume(int* level) {
588   VolumeLevel volume;
589   if (!Send(MSG_GETOUTPUTVOLUME, &volume) || !volume.result) {
590     return false;
591   }
592 
593   *level = volume.level;
594   return true;
595 }
596 
GetOutputVolume_w(int * level)597 bool ChannelManager::GetOutputVolume_w(int* level) {
598   ASSERT(worker_thread_ == talk_base::Thread::Current());
599   ASSERT(initialized_);
600   return media_engine_->GetOutputVolume(level);
601 }
602 
SetOutputVolume(int level)603 bool ChannelManager::SetOutputVolume(int level) {
604   bool ret = level >= 0 && level <= 255;
605   if (initialized_) {
606     VolumeLevel volume(level);
607     ret &= Send(MSG_SETOUTPUTVOLUME, &volume) && volume.result;
608   }
609 
610   if (ret) {
611     audio_output_volume_ = level;
612   }
613 
614   return ret;
615 }
616 
SetOutputVolume_w(int level)617 bool ChannelManager::SetOutputVolume_w(int level) {
618   ASSERT(worker_thread_ == talk_base::Thread::Current());
619   ASSERT(initialized_);
620   return media_engine_->SetOutputVolume(level);
621 }
622 
GetVideoOptions(std::string * cam_name)623 bool ChannelManager::GetVideoOptions(std::string* cam_name) {
624   if (camera_device_.empty()) {
625     // Initialize camera_device_ with default.
626     Device device;
627     if (!device_manager_->GetVideoCaptureDevice(
628         DeviceManagerInterface::kDefaultDeviceName, &device)) {
629       LOG(LS_WARNING) << "Device manager can't find default camera: " <<
630           DeviceManagerInterface::kDefaultDeviceName;
631       return false;
632     }
633     camera_device_ = device.name;
634   }
635   *cam_name = camera_device_;
636   return true;
637 }
638 
SetVideoOptions(const std::string & cam_name)639 bool ChannelManager::SetVideoOptions(const std::string& cam_name) {
640   Device device;
641   bool ret = true;
642   if (!device_manager_->GetVideoCaptureDevice(cam_name, &device)) {
643     if (!cam_name.empty()) {
644       LOG(LS_WARNING) << "Device manager can't find camera: " << cam_name;
645     }
646     ret = false;
647   }
648 
649   // If we're running, tell the media engine about it.
650   if (initialized_ && ret) {
651     VideoOptions options(&device);
652     ret = (Send(MSG_SETVIDEOOPTIONS, &options) && options.result);
653   }
654 
655   // If everything worked, retain the name of the selected camera.
656   if (ret) {
657     camera_device_ = device.name;
658   } else if (camera_device_.empty()) {
659     // When video option setting fails, we still want camera_device_ to be in a
660     // good state, so we initialize it with default if it's empty.
661     Device default_device;
662     if (!device_manager_->GetVideoCaptureDevice(
663         DeviceManagerInterface::kDefaultDeviceName, &default_device)) {
664       LOG(LS_WARNING) << "Device manager can't find default camera: " <<
665           DeviceManagerInterface::kDefaultDeviceName;
666     }
667     camera_device_ = default_device.name;
668   }
669 
670   return ret;
671 }
672 
SetVideoOptions_w(const Device * cam_device)673 bool ChannelManager::SetVideoOptions_w(const Device* cam_device) {
674   ASSERT(worker_thread_ == talk_base::Thread::Current());
675   ASSERT(initialized_);
676 
677   // Set the video input device
678   return media_engine_->SetVideoCaptureDevice(cam_device);
679 }
680 
SetDefaultVideoEncoderConfig(const VideoEncoderConfig & c)681 bool ChannelManager::SetDefaultVideoEncoderConfig(const VideoEncoderConfig& c) {
682   bool ret = true;
683   if (initialized_) {
684     DefaultVideoEncoderConfig config(c);
685     ret = Send(MSG_SETDEFAULTVIDEOENCODERCONFIG, &config) && config.result;
686   }
687   if (ret) {
688     default_video_encoder_config_ = c;
689   }
690   return ret;
691 }
692 
SetDefaultVideoEncoderConfig_w(const VideoEncoderConfig & c)693 bool ChannelManager::SetDefaultVideoEncoderConfig_w(
694     const VideoEncoderConfig& c) {
695   ASSERT(worker_thread_ == talk_base::Thread::Current());
696   ASSERT(initialized_);
697   return media_engine_->SetDefaultVideoEncoderConfig(c);
698 }
699 
SetLocalMonitor(bool enable)700 bool ChannelManager::SetLocalMonitor(bool enable) {
701   LocalMonitor monitor(enable);
702   bool ret = Send(MSG_SETLOCALMONITOR, &monitor) && monitor.result;
703   if (ret) {
704     monitoring_ = enable;
705   }
706   return ret;
707 }
708 
SetLocalMonitor_w(bool enable)709 bool ChannelManager::SetLocalMonitor_w(bool enable) {
710   ASSERT(worker_thread_ == talk_base::Thread::Current());
711   ASSERT(initialized_);
712   return media_engine_->SetLocalMonitor(enable);
713 }
714 
SetLocalRenderer(VideoRenderer * renderer)715 bool ChannelManager::SetLocalRenderer(VideoRenderer* renderer) {
716   bool ret = true;
717   if (initialized_) {
718     LocalRenderer local(renderer);
719     ret = (Send(MSG_SETLOCALRENDERER, &local) && local.result);
720   }
721   if (ret) {
722     local_renderer_ = renderer;
723   }
724   return ret;
725 }
726 
SetLocalRenderer_w(VideoRenderer * renderer)727 bool ChannelManager::SetLocalRenderer_w(VideoRenderer* renderer) {
728   ASSERT(worker_thread_ == talk_base::Thread::Current());
729   ASSERT(initialized_);
730   return media_engine_->SetLocalRenderer(renderer);
731 }
732 
SetVideoCapturer(VideoCapturer * capturer,uint32 ssrc)733 bool ChannelManager::SetVideoCapturer(VideoCapturer* capturer, uint32 ssrc) {
734   bool ret = true;
735   if (initialized_) {
736     Capturer capture(capturer, ssrc);
737     ret = (Send(MSG_SETVIDEOCAPTURER, &capture) && capture.result);
738   }
739   return ret;
740 }
741 
SetVideoCapturer_w(VideoCapturer * capturer,uint32 ssrc)742 bool ChannelManager::SetVideoCapturer_w(VideoCapturer* capturer, uint32 ssrc) {
743   ASSERT(worker_thread_ == talk_base::Thread::Current());
744   ASSERT(initialized_);
745   return media_engine_->SetVideoCapturer(capturer, ssrc);
746 }
747 
SetVideoCapture(bool capture)748 CaptureResult ChannelManager::SetVideoCapture(bool capture) {
749   bool ret;
750   CaptureParams capture_params(capture);
751   ret = (Send(MSG_SETVIDEOCAPTURE, &capture_params) &&
752          (capture_params.result != CR_FAILURE));
753   if (ret) {
754     capturing_ = capture;
755   }
756   return capture_params.result;
757 }
758 
SetVideoCapture_w(bool capture)759 CaptureResult ChannelManager::SetVideoCapture_w(bool capture) {
760   ASSERT(worker_thread_ == talk_base::Thread::Current());
761   ASSERT(initialized_);
762   return media_engine_->SetVideoCapture(capture);
763 }
764 
SetVoiceLogging(int level,const char * filter)765 void ChannelManager::SetVoiceLogging(int level, const char* filter) {
766   SetMediaLogging(false, level, filter);
767 }
768 
SetVideoLogging(int level,const char * filter)769 void ChannelManager::SetVideoLogging(int level, const char* filter) {
770   SetMediaLogging(true, level, filter);
771 }
772 
SetMediaLogging(bool video,int level,const char * filter)773 void ChannelManager::SetMediaLogging(bool video, int level,
774                                      const char* filter) {
775   // Can be called before initialization; in this case, the worker function
776   // is simply called on the main thread.
777   if (initialized_) {
778     LoggingOptions options(level, filter);
779     Send((video) ? MSG_SETVIDEOLOGGING : MSG_SETVOICELOGGING, &options);
780   } else {
781     SetMediaLogging_w(video, level, filter);
782   }
783 }
784 
SetMediaLogging_w(bool video,int level,const char * filter)785 void ChannelManager::SetMediaLogging_w(bool video, int level,
786                                        const char* filter) {
787   // Can be called before initialization
788   ASSERT(worker_thread_ == talk_base::Thread::Current() || !initialized_);
789   if (video) {
790     media_engine_->SetVideoLogging(level, filter);
791   } else {
792     media_engine_->SetVoiceLogging(level, filter);
793   }
794 }
795 
796 // TODO: For now pass this request through the mediaengine to the
797 // voice and video engines to do the real work. Once the capturer refactoring
798 // is done, we will access the capturer using the ssrc (similar to how the
799 // renderer is accessed today) and register with it directly.
RegisterVideoProcessor(uint32 ssrc,VideoProcessor * processor)800 bool ChannelManager::RegisterVideoProcessor(uint32 ssrc,
801                                             VideoProcessor* processor) {
802   VideoProcessorParams processor_params(ssrc, processor);
803   return (Send(MSG_REGISTERVIDEOPROCESSOR, &processor_params) &&
804       processor_params.result);
805 }
RegisterVideoProcessor_w(uint32 ssrc,VideoProcessor * processor)806 bool ChannelManager::RegisterVideoProcessor_w(uint32 ssrc,
807                                               VideoProcessor* processor) {
808   return media_engine_->RegisterVideoProcessor(processor);
809 }
810 
UnregisterVideoProcessor(uint32 ssrc,VideoProcessor * processor)811 bool ChannelManager::UnregisterVideoProcessor(uint32 ssrc,
812                                               VideoProcessor* processor) {
813   VideoProcessorParams processor_params(ssrc, processor);
814   return (Send(MSG_UNREGISTERVIDEOPROCESSOR, &processor_params) &&
815       processor_params.result);
816 }
UnregisterVideoProcessor_w(uint32 ssrc,VideoProcessor * processor)817 bool ChannelManager::UnregisterVideoProcessor_w(uint32 ssrc,
818                                                 VideoProcessor* processor) {
819   return media_engine_->UnregisterVideoProcessor(processor);
820 }
821 
RegisterVoiceProcessor(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)822 bool ChannelManager::RegisterVoiceProcessor(
823     uint32 ssrc,
824     VoiceProcessor* processor,
825     MediaProcessorDirection direction) {
826   VoiceProcessorParams processor_params(ssrc, processor, direction);
827   return (Send(MSG_REGISTERVOICEPROCESSOR, &processor_params) &&
828       processor_params.result);
829 }
RegisterVoiceProcessor_w(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)830 bool ChannelManager::RegisterVoiceProcessor_w(
831     uint32 ssrc,
832     VoiceProcessor* processor,
833     MediaProcessorDirection direction) {
834   return media_engine_->RegisterVoiceProcessor(ssrc, processor, direction);
835 }
836 
UnregisterVoiceProcessor(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)837 bool ChannelManager::UnregisterVoiceProcessor(
838     uint32 ssrc,
839     VoiceProcessor* processor,
840     MediaProcessorDirection direction) {
841   VoiceProcessorParams processor_params(ssrc, processor, direction);
842   return (Send(MSG_UNREGISTERVOICEPROCESSOR, &processor_params) &&
843       processor_params.result);
844 }
UnregisterVoiceProcessor_w(uint32 ssrc,VoiceProcessor * processor,MediaProcessorDirection direction)845 bool ChannelManager::UnregisterVoiceProcessor_w(
846     uint32 ssrc,
847     VoiceProcessor* processor,
848     MediaProcessorDirection direction) {
849   return media_engine_->UnregisterVoiceProcessor(ssrc, processor, direction);
850 }
851 
Send(uint32 id,talk_base::MessageData * data)852 bool ChannelManager::Send(uint32 id, talk_base::MessageData* data) {
853   if (!worker_thread_ || !initialized_) return false;
854   worker_thread_->Send(this, id, data);
855   return true;
856 }
857 
OnVideoCaptureResult(VideoCapturer * capturer,CaptureResult result)858 void ChannelManager::OnVideoCaptureResult(VideoCapturer* capturer,
859                                           CaptureResult result) {
860   // TODO: Check capturer and signal failure only for camera video, not
861   // screencast.
862   capturing_ = result == CR_SUCCESS;
863   main_thread_->Post(this, MSG_CAMERASTARTED,
864                      new talk_base::TypedMessageData<CaptureResult>(result));
865 }
866 
OnMessage(talk_base::Message * message)867 void ChannelManager::OnMessage(talk_base::Message* message) {
868   talk_base::MessageData* data = message->pdata;
869   switch (message->message_id) {
870     case MSG_CREATEVOICECHANNEL: {
871       CreationParams* p = static_cast<CreationParams*>(data);
872       p->voice_channel =
873           CreateVoiceChannel_w(p->session, p->content_name, p->rtcp);
874       break;
875     }
876     case MSG_DESTROYVOICECHANNEL: {
877       VoiceChannel* p = static_cast<talk_base::TypedMessageData<VoiceChannel*>*>
878           (data)->data();
879       DestroyVoiceChannel_w(p);
880       break;
881     }
882     case MSG_CREATEVIDEOCHANNEL: {
883       CreationParams* p = static_cast<CreationParams*>(data);
884       p->video_channel = CreateVideoChannel_w(p->session, p->content_name,
885                                               p->rtcp, p->voice_channel);
886       break;
887     }
888     case MSG_DESTROYVIDEOCHANNEL: {
889       VideoChannel* p = static_cast<talk_base::TypedMessageData<VideoChannel*>*>
890           (data)->data();
891       DestroyVideoChannel_w(p);
892       break;
893     }
894     case MSG_CREATEDATACHANNEL: {
895       CreationParams* p = static_cast<CreationParams*>(data);
896       p->data_channel =
897           CreateDataChannel_w(p->session, p->content_name, p->rtcp);
898       break;
899     }
900     case MSG_DESTROYDATACHANNEL: {
901       DataChannel* p = static_cast<talk_base::TypedMessageData<DataChannel*>*>
902           (data)->data();
903       DestroyDataChannel_w(p);
904       break;
905     }
906     case MSG_CREATESOUNDCLIP: {
907       talk_base::TypedMessageData<Soundclip*> *p =
908           static_cast<talk_base::TypedMessageData<Soundclip*>*>(data);
909       p->data() = CreateSoundclip_w();
910       break;
911     }
912     case MSG_DESTROYSOUNDCLIP: {
913       talk_base::TypedMessageData<Soundclip*> *p =
914           static_cast<talk_base::TypedMessageData<Soundclip*>*>(data);
915       DestroySoundclip_w(p->data());
916       break;
917     }
918     case MSG_SETAUDIOOPTIONS: {
919       AudioOptions* p = static_cast<AudioOptions*>(data);
920       p->result = SetAudioOptions_w(p->options,
921                                     p->in_device, p->out_device);
922       break;
923     }
924     case MSG_GETOUTPUTVOLUME: {
925       VolumeLevel* p = static_cast<VolumeLevel*>(data);
926       p->result = GetOutputVolume_w(&p->level);
927       break;
928     }
929     case MSG_SETOUTPUTVOLUME: {
930       VolumeLevel* p = static_cast<VolumeLevel*>(data);
931       p->result = SetOutputVolume_w(p->level);
932       break;
933     }
934     case MSG_SETLOCALMONITOR: {
935       LocalMonitor* p = static_cast<LocalMonitor*>(data);
936       p->result = SetLocalMonitor_w(p->enable);
937       break;
938     }
939     case MSG_SETVIDEOOPTIONS: {
940       VideoOptions* p = static_cast<VideoOptions*>(data);
941       p->result = SetVideoOptions_w(p->cam_device);
942       break;
943     }
944     case MSG_SETDEFAULTVIDEOENCODERCONFIG: {
945       DefaultVideoEncoderConfig* p =
946           static_cast<DefaultVideoEncoderConfig*>(data);
947       p->result = SetDefaultVideoEncoderConfig_w(p->config);
948       break;
949     }
950     case MSG_SETLOCALRENDERER: {
951       LocalRenderer* p = static_cast<LocalRenderer*>(data);
952       p->result = SetLocalRenderer_w(p->renderer);
953       break;
954     }
955     case MSG_SETVIDEOCAPTURER: {
956       Capturer* p = static_cast<Capturer*>(data);
957       p->result = SetVideoCapturer_w(p->capturer, p->ssrc);
958       break;
959     }
960     case MSG_SETVIDEOCAPTURE: {
961       CaptureParams* p = static_cast<CaptureParams*>(data);
962       p->result = SetVideoCapture_w(p->capture);
963       break;
964     }
965     case MSG_SETVOICELOGGING:
966     case MSG_SETVIDEOLOGGING: {
967       LoggingOptions* p = static_cast<LoggingOptions*>(data);
968       bool video = (message->message_id == MSG_SETVIDEOLOGGING);
969       SetMediaLogging_w(video, p->level, p->filter.c_str());
970       break;
971     }
972     case MSG_CAMERASTARTED: {
973       talk_base::TypedMessageData<CaptureResult>* data =
974           static_cast<talk_base::TypedMessageData<CaptureResult>*>(
975               message->pdata);
976       SignalVideoCaptureResult(data->data());
977       delete data;
978       break;
979     }
980     case MSG_TERMINATE: {
981       Terminate_w();
982       break;
983     }
984     case MSG_REGISTERVIDEOPROCESSOR: {
985       VideoProcessorParams* data =
986           static_cast<VideoProcessorParams*>(message->pdata);
987       data->result = RegisterVideoProcessor_w(data->ssrc, data->processor);
988       break;
989     }
990     case MSG_UNREGISTERVIDEOPROCESSOR: {
991       VideoProcessorParams* data =
992           static_cast<VideoProcessorParams*>(message->pdata);
993       data->result = UnregisterVideoProcessor_w(data->ssrc, data->processor);
994       break;
995     }
996     case MSG_REGISTERVOICEPROCESSOR: {
997       VoiceProcessorParams* data =
998           static_cast<VoiceProcessorParams*>(message->pdata);
999       data->result = RegisterVoiceProcessor_w(data->ssrc,
1000                                               data->processor,
1001                                               data->direction);
1002       break;
1003     }
1004     case MSG_UNREGISTERVOICEPROCESSOR: {
1005       VoiceProcessorParams* data =
1006           static_cast<VoiceProcessorParams*>(message->pdata);
1007       data->result = UnregisterVoiceProcessor_w(data->ssrc,
1008                                               data->processor,
1009                                               data->direction);
1010       break;
1011     }
1012   }
1013 }
1014 
GetDeviceNames(const std::vector<Device> & devs,std::vector<std::string> * names)1015 static void GetDeviceNames(const std::vector<Device>& devs,
1016                            std::vector<std::string>* names) {
1017   names->clear();
1018   for (size_t i = 0; i < devs.size(); ++i) {
1019     names->push_back(devs[i].name);
1020   }
1021 }
1022 
GetAudioInputDevices(std::vector<std::string> * names)1023 bool ChannelManager::GetAudioInputDevices(std::vector<std::string>* names) {
1024   names->clear();
1025   std::vector<Device> devs;
1026   bool ret = device_manager_->GetAudioInputDevices(&devs);
1027   if (ret)
1028     GetDeviceNames(devs, names);
1029 
1030   return ret;
1031 }
1032 
GetAudioOutputDevices(std::vector<std::string> * names)1033 bool ChannelManager::GetAudioOutputDevices(std::vector<std::string>* names) {
1034   names->clear();
1035   std::vector<Device> devs;
1036   bool ret = device_manager_->GetAudioOutputDevices(&devs);
1037   if (ret)
1038     GetDeviceNames(devs, names);
1039 
1040   return ret;
1041 }
1042 
GetVideoCaptureDevices(std::vector<std::string> * names)1043 bool ChannelManager::GetVideoCaptureDevices(std::vector<std::string>* names) {
1044   names->clear();
1045   std::vector<Device> devs;
1046   bool ret = device_manager_->GetVideoCaptureDevices(&devs);
1047   if (ret)
1048     GetDeviceNames(devs, names);
1049 
1050   return ret;
1051 }
1052 
1053 }  // namespace cricket
1054