1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/*
2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle
3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2008, Google Inc.
4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without
6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met:
7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  1. Redistributions of source code must retain the above copyright notice,
9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer.
10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  2. Redistributions in binary form must reproduce the above copyright notice,
11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     this list of conditions and the following disclaimer in the documentation
12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     and/or other materials provided with the distribution.
13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *  3. The name of the author may not be used to endorse or promote products
14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *     derived from this software without specific prior written permission.
15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch *
16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */
27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/session/phone/channelmanager.h"
29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#ifdef HAVE_CONFIG_H
31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <config.h>
32f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#endif
33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
34f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include <algorithm>
35f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h"
37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/logging.h"
38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/sigslotrepeater.h"
39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/stringencode.h"
40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/session/phone/mediaengine.h"
41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/session/phone/soundclip.h"
42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace cricket {
44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochenum {
46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_CREATEVOICECHANNEL = 1,
47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_DESTROYVOICECHANNEL = 2,
48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETAUDIOOPTIONS = 3,
49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETOUTPUTVOLUME = 4,
50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETLOCALMONITOR = 5,
51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETVOICELOGGING = 6,
52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_CREATEVIDEOCHANNEL = 11,
53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_DESTROYVIDEOCHANNEL = 12,
54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETVIDEOOPTIONS = 13,
55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETLOCALRENDERER = 14,
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MSG_SETDEFAULTVIDEOENCODERCONFIG = 15,
57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETVIDEOLOGGING = 16,
58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_CREATESOUNDCLIP = 17,
59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_DESTROYSOUNDCLIP = 18,
60f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_CAMERASTARTED = 19,
61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  MSG_SETVIDEOCAPTURE = 20,
62f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
63f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct CreationParams : public talk_base::MessageData {
65731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreationParams(BaseSession* session, const std::string& content_name,
66731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                 bool rtcp, VoiceChannel* voice_channel)
67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : session(session),
68731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        content_name(content_name),
69731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rtcp(rtcp),
70731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        voice_channel(voice_channel),
71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch        video_channel(NULL) {}
72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BaseSession* session;
73731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  std::string content_name;
74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool rtcp;
75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VoiceChannel* voice_channel;
76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VideoChannel* video_channel;
77f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
78f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
79f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct AudioOptions : public talk_base::MessageData {
80f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  AudioOptions(int o, const Device* in, const Device* out)
81f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      : options(o), in_device(in), out_device(out) {}
82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int options;
83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const Device* in_device;
84f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const Device* out_device;
85f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool result;
86f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
87f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
88f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct VolumeLevel : public talk_base::MessageData {
89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit VolumeLevel(int l) : level(l), result(false) {}
90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int level;
91f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool result;
92f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct VideoOptions : public talk_base::MessageData {
95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit VideoOptions(const Device* d) : cam_device(d), result(false) {}
96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  const Device* cam_device;
97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool result;
98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstruct DefaultVideoEncoderConfig : public talk_base::MessageData {
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit DefaultVideoEncoderConfig(const VideoEncoderConfig& c)
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      : config(c), result(false) {}
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  VideoEncoderConfig config;
104f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool result;
105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct LocalMonitor : public talk_base::MessageData {
108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit LocalMonitor(bool e) : enable(e), result(false) {}
109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool enable;
110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool result;
111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct LocalRenderer : public talk_base::MessageData {
114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit LocalRenderer(VideoRenderer* r) : renderer(r), result(false) {}
115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VideoRenderer* renderer;
116f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool result;
117f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct LoggingOptions : public talk_base::MessageData {
120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  explicit LoggingOptions(int lev, const char* f) : level(lev), filter(f) {}
121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  int level;
122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::string filter;
123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
125f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstruct CaptureParams : public talk_base::MessageData {
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  explicit CaptureParams(bool c) : capture(c), result(CR_FAILURE) {}
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool capture;
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CaptureResult result;
130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch};
131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochChannelManager::ChannelManager(talk_base::Thread* worker_thread)
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    : media_engine_(MediaEngine::Create()),
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      device_manager_(new DeviceManager()),
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      initialized_(false),
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      main_thread_(talk_base::Thread::Current()),
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      worker_thread_(worker_thread),
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      audio_in_device_(DeviceManager::kDefaultDeviceName),
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      audio_out_device_(DeviceManager::kDefaultDeviceName),
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      audio_options_(MediaEngine::DEFAULT_AUDIO_OPTIONS),
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      local_renderer_(NULL),
142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      capturing_(false),
143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      monitoring_(false) {
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Construct();
145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochChannelManager::ChannelManager(MediaEngine* me, DeviceManager* dm,
148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                               talk_base::Thread* worker_thread)
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    : media_engine_(me),
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      device_manager_(dm),
1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      initialized_(false),
1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      main_thread_(talk_base::Thread::Current()),
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      worker_thread_(worker_thread),
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      audio_in_device_(DeviceManager::kDefaultDeviceName),
155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      audio_out_device_(DeviceManager::kDefaultDeviceName),
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      audio_options_(MediaEngine::DEFAULT_AUDIO_OPTIONS),
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      local_renderer_(NULL),
158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      capturing_(false),
159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      monitoring_(false) {
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Construct();
161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ChannelManager::Construct() {
164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Init the device manager immediately, and set up our default video device.
165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  SignalDevicesChange.repeat(device_manager_->SignalDevicesChange);
166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  device_manager_->Init();
167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Set camera_device_ to the name of the default video capturer.
168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SetVideoOptions(DeviceManager::kDefaultDeviceName);
169f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
170f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Camera is started asynchronously, request callbacks when startup
171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // completes to be able to forward them to the rendering manager.
172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  media_engine_->SignalVideoCaptureResult.connect(
173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      this, &ChannelManager::OnVideoCaptureResult);
174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
176f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochChannelManager::~ChannelManager() {
177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (initialized_)
178f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Terminate();
179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochint ChannelManager::GetCapabilities() {
182f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return media_engine_->GetCapabilities() & device_manager_->GetCapabilities();
183f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ChannelManager::GetSupportedAudioCodecs(
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<AudioCodec>* codecs) const {
187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  codecs->clear();
188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  for (std::vector<AudioCodec>::const_iterator it =
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick           media_engine_->audio_codecs().begin();
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      it != media_engine_->audio_codecs().end(); ++it) {
192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    codecs->push_back(*it);
193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::GetSupportedVideoCodecs(
197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    std::vector<VideoCodec>* codecs) const {
198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  codecs->clear();
199f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::vector<VideoCodec>::const_iterator it;
201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (it = media_engine_->video_codecs().begin();
202f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      it != media_engine_->video_codecs().end(); ++it) {
203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    codecs->push_back(*it);
204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ChannelManager::Init() {
208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(!initialized_);
209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (initialized_) {
210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT(worker_thread_ != NULL);
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (worker_thread_ && worker_thread_->started()) {
215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    if (media_engine_->Init()) {
216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      initialized_ = true;
217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // Now that we're initialized, apply any stored preferences. A preferred
219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // device might have been unplugged. In this case, we fallback to the
220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // default device but keep the user preferences. The preferences are
221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // changed only when the Javascript FE changes them.
222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const std::string preferred_audio_in_device = audio_in_device_;
223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const std::string preferred_audio_out_device = audio_out_device_;
224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      const std::string preferred_camera_device = camera_device_;
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      Device device;
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (!device_manager_->GetAudioInputDevice(audio_in_device_, &device)) {
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(LS_WARNING) << "The preferred microphone '" << audio_in_device_
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        << "' is unavailable. Fall back to the default.";
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        audio_in_device_ = DeviceManager::kDefaultDeviceName;
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (!device_manager_->GetAudioOutputDevice(audio_out_device_, &device)) {
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(LS_WARNING) << "The preferred speaker '" << audio_out_device_
233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        << "' is unavailable. Fall back to the default.";
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        audio_out_device_ = DeviceManager::kDefaultDeviceName;
235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if (!device_manager_->GetVideoCaptureDevice(camera_device_, &device)) {
237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(LS_WARNING) << "The preferred camera '" << camera_device_
238dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        << "' is unavailable. Fall back to the default.";
239dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        camera_device_ = DeviceManager::kDefaultDeviceName;
240dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
241dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      if (!SetAudioOptions(audio_in_device_, audio_out_device_,
243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                           audio_options_)) {
244dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(LS_WARNING) << "Failed to SetAudioOptions with"
245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        << " microphone: " << audio_in_device_
246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        << " speaker: " << audio_out_device_
247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        << " options: " << audio_options_;
248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      if (!SetVideoOptions(camera_device_)) {
250dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        LOG(LS_WARNING) << "Failed to SetVideoOptions with camera: "
251dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                        << camera_device_;
252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
253dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
254dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      // Restore the user preferences.
255dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      audio_in_device_ = preferred_audio_in_device;
256dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      audio_out_device_ = preferred_audio_out_device;
257dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      camera_device_ = preferred_camera_device;
258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      // Now apply the default video codec that has been set earlier.
2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (default_video_encoder_config_.max_codec.id != 0) {
2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        SetDefaultVideoEncoderConfig(default_video_encoder_config_);
2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // And the local renderer.
2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (local_renderer_) {
2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        SetLocalRenderer(local_renderer_);
266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      }
267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return initialized_;
270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::Terminate() {
273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!initialized_) {
275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Need to destroy the voice/video channels
279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  while (!video_channels_.empty()) {
280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    DestroyVideoChannel_w(video_channels_.back());
281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  while (!voice_channels_.empty()) {
283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    DestroyVoiceChannel_w(voice_channels_.back());
284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  while (!soundclips_.empty()) {
286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    DestroySoundclip_w(soundclips_.back());
287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  media_engine_->Terminate();
290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  initialized_ = false;
291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
293731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickVoiceChannel* ChannelManager::CreateVoiceChannel(
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BaseSession* session, const std::string& content_name, bool rtcp) {
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreationParams params(session, content_name, rtcp, NULL);
296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return (Send(MSG_CREATEVOICECHANNEL, &params)) ? params.voice_channel : NULL;
297f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
298f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
299731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickVoiceChannel* ChannelManager::CreateVoiceChannel_w(
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BaseSession* session, const std::string& content_name, bool rtcp) {
301f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::CritScope cs(&crit_);
302f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
303f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // This is ok to alloc from a thread other than the worker thread
304f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
305f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VoiceMediaChannel* media_channel = media_engine_->CreateChannel();
306f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (media_channel == NULL)
307f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return NULL;
308f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VoiceChannel* voice_channel = new VoiceChannel(
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      worker_thread_, media_engine_.get(), media_channel,
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      session, content_name, rtcp);
312f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  voice_channels_.push_back(voice_channel);
313f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return voice_channel;
314f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
315f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
316f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
317f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (voice_channel) {
318f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    talk_base::TypedMessageData<VoiceChannel *> data(voice_channel);
319f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Send(MSG_DESTROYVOICECHANNEL, &data);
320f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
321f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
322f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
323f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
324f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::CritScope cs(&crit_);
325f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Destroy voice channel.
326f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
327f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VoiceChannels::iterator it = std::find(voice_channels_.begin(),
328f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      voice_channels_.end(), voice_channel);
329f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(it != voice_channels_.end());
330f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (it == voice_channels_.end())
331f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
332f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
333f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  voice_channels_.erase(it);
334f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  delete voice_channel;
335f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
336f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
337731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickVideoChannel* ChannelManager::CreateVideoChannel(
338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BaseSession* session, const std::string& content_name, bool rtcp,
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VoiceChannel* voice_channel) {
340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  CreationParams params(session, content_name, rtcp, voice_channel);
341f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return (Send(MSG_CREATEVIDEOCHANNEL, &params)) ? params.video_channel : NULL;
342f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
343f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
344731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickVideoChannel* ChannelManager::CreateVideoChannel_w(
345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BaseSession* session, const std::string& content_name, bool rtcp,
346731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    VoiceChannel* voice_channel) {
347f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::CritScope cs(&crit_);
348f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
349f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // This is ok to alloc from a thread other than the worker thread
350f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
351f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VideoMediaChannel* media_channel =
352f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      // voice_channel can be NULL in case of NullVoiceEngine.
353f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      media_engine_->CreateVideoChannel(voice_channel ?
354f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          voice_channel->media_channel() : NULL);
355f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (media_channel == NULL)
356f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return NULL;
357f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  VideoChannel* video_channel = new VideoChannel(
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      worker_thread_, media_engine_.get(), media_channel,
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      session, content_name, rtcp, voice_channel);
361f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  video_channels_.push_back(video_channel);
362f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return video_channel;
363f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
364f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
365f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::DestroyVideoChannel(VideoChannel* video_channel) {
366f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (video_channel) {
367f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    talk_base::TypedMessageData<VideoChannel *> data(video_channel);
368f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Send(MSG_DESTROYVIDEOCHANNEL, &data);
369f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
370f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
371f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
372f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::DestroyVideoChannel_w(VideoChannel *video_channel) {
373f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::CritScope cs(&crit_);
374f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Destroy voice channel.
375f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
376f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VideoChannels::iterator it = std::find(video_channels_.begin(),
377f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      video_channels_.end(), video_channel);
378f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(it != video_channels_.end());
379f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (it == video_channels_.end())
380f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
381f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
382f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  video_channels_.erase(it);
383f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  delete video_channel;
384f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
385f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
386f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochSoundclip* ChannelManager::CreateSoundclip() {
387f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::TypedMessageData<Soundclip*> data(NULL);
388f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Send(MSG_CREATESOUNDCLIP, &data);
389f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return data.data();
390f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
391f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
392f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochSoundclip* ChannelManager::CreateSoundclip_w() {
393f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::CritScope cs(&crit_);
394f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
395f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
396f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
397f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
398f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  SoundclipMedia* soundclip_media = media_engine_->CreateSoundclip();
399f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!soundclip_media) {
400f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return NULL;
401f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
402f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
403f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Soundclip* soundclip = new Soundclip(worker_thread_, soundclip_media);
404f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  soundclips_.push_back(soundclip);
405f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return soundclip;
406f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
407f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
408f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::DestroySoundclip(Soundclip* soundclip) {
409f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (soundclip) {
410f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    talk_base::TypedMessageData<Soundclip*> data(soundclip);
411f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Send(MSG_DESTROYSOUNDCLIP, &data);
412f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
413f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
414f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
415f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::DestroySoundclip_w(Soundclip* soundclip) {
416f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::CritScope cs(&crit_);
417f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Destroy soundclip.
418f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
419f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Soundclips::iterator it = std::find(soundclips_.begin(),
420f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      soundclips_.end(), soundclip);
421f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(it != soundclips_.end());
422f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (it == soundclips_.end())
423f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return;
424f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
425f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  soundclips_.erase(it);
426f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  delete soundclip;
427f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
428f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
429f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::GetAudioOptions(std::string* in_name,
430f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                     std::string* out_name, int* opts) {
431f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  *in_name = audio_in_device_;
432f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  *out_name = audio_out_device_;
433f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  *opts = audio_options_;
434f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return true;
435f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
436f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
437f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetAudioOptions(const std::string& in_name,
438f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                     const std::string& out_name, int opts) {
439f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Get device ids from DeviceManager.
440f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Device in_dev, out_dev;
441f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (!device_manager_->GetAudioInputDevice(in_name, &in_dev) ||
442f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      !device_manager_->GetAudioOutputDevice(out_name, &out_dev)) {
443f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    LOG(LS_WARNING) << "Device manager can't find selected device";
444f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    return false;
445f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
446f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
447f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // If we're initialized, pass the settings to the media engine.
448f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret = true;
449f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (initialized_) {
450f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    AudioOptions options(opts, &in_dev, &out_dev);
451f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ret = (Send(MSG_SETAUDIOOPTIONS, &options) && options.result);
452f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
453f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
454f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // If all worked well, save the values for use in GetAudioOptions.
455f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret) {
456f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    audio_options_ = opts;
457f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    audio_in_device_ = in_name;
458f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    audio_out_device_ = out_name;
459f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
460f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
461f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
462f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
463f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetAudioOptions_w(int opts, const Device* in_dev,
464f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    const Device* out_dev) {
465f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
466f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
467f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
468f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Set audio options
469f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret = media_engine_->SetAudioOptions(opts);
470f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
471f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Set the audio devices
472f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret) {
473f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    talk_base::CritScope cs(&crit_);
474f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    ret = media_engine_->SetSoundDevices(in_dev, out_dev);
475f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
476f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
477f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
478f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
479f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
480f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetOutputVolume(int level) {
481f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  VolumeLevel volume(level);
482f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return (Send(MSG_SETOUTPUTVOLUME, &volume) && volume.result);
483f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
484f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
485f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetOutputVolume_w(int level) {
486f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
487f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
488f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return media_engine_->SetOutputVolume(level);
489f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
490f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
491f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::GetVideoOptions(std::string* cam_name) {
492f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  *cam_name = camera_device_;
493f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return true;
494f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
495f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
496f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetVideoOptions(const std::string& cam_name) {
497f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  Device device;
498dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (!device_manager_->GetVideoCaptureDevice(cam_name, &device)) {
499dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG(LS_WARNING) << "Device manager can't find camera: " << cam_name;
500dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return false;
501f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
502f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
503f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // If we're running, tell the media engine about it.
504dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool ret = true;
505dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (initialized_) {
506dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    VideoOptions options(&device);
507dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ret = (Send(MSG_SETVIDEOOPTIONS, &options) && options.result);
508f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
509f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
510f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // If everything worked, retain the name of the selected camera.
511f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret) {
512f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    camera_device_ = device.name;
513f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
514f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
515f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
516f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
517f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetVideoOptions_w(const Device* cam_device) {
518f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
519f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
520f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
521f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Set the video input device
522f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return media_engine_->SetVideoCaptureDevice(cam_device);
523f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
524f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
5253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ChannelManager::SetDefaultVideoEncoderConfig(const VideoEncoderConfig& c) {
526f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret = true;
527f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (initialized_) {
5283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DefaultVideoEncoderConfig config(c);
5293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ret = Send(MSG_SETDEFAULTVIDEOENCODERCONFIG, &config) && config.result;
530f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
531f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret) {
5323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    default_video_encoder_config_ = c;
533f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
534f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
535f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
536f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
5373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ChannelManager::SetDefaultVideoEncoderConfig_w(
5383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const VideoEncoderConfig& c) {
539f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
540f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
5413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return media_engine_->SetDefaultVideoEncoderConfig(c);
542f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
543f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
544f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetLocalMonitor(bool enable) {
545f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  LocalMonitor monitor(enable);
546f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret = Send(MSG_SETLOCALMONITOR, &monitor) && monitor.result;
547f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret) {
548f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    monitoring_ = enable;
549f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
550f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
551f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
552f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
553f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetLocalMonitor_w(bool enable) {
554f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
555f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
556f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return media_engine_->SetLocalMonitor(enable);
557f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
558f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
559f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetLocalRenderer(VideoRenderer* renderer) {
5603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool ret = true;
5613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (initialized_) {
5623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    LocalRenderer local(renderer);
5633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ret = (Send(MSG_SETLOCALRENDERER, &local) && local.result);
5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
565f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret) {
5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    local_renderer_ = renderer;
567f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
568f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
569f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
570f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
571f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::SetLocalRenderer_w(VideoRenderer* renderer) {
572f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
573f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
574f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return media_engine_->SetLocalRenderer(renderer);
575f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
576f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickCaptureResult ChannelManager::SetVideoCapture(bool capture) {
578f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret;
579f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  CaptureParams capture_params(capture);
580f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ret = (Send(MSG_SETVIDEOCAPTURE, &capture_params) &&
5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick         (capture_params.result != CR_FAILURE));
582f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret) {
583f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    capturing_ = capture;
584f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
585f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return capture_params.result;
586f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
587f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickCaptureResult ChannelManager::SetVideoCapture_w(bool capture) {
589f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current());
590f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(initialized_);
591f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return media_engine_->SetVideoCapture(capture);
592f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
593f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
594f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::SetVoiceLogging(int level, const char* filter) {
595f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  SetMediaLogging(false, level, filter);
596f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
597f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
598f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::SetVideoLogging(int level, const char* filter) {
599f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  SetMediaLogging(true, level, filter);
600f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
601f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
602f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::SetMediaLogging(bool video, int level,
603f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                     const char* filter) {
604f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Can be called before initialization; in this case, the worker function
605f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // is simply called on the main thread.
606f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (initialized_) {
607f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    LoggingOptions options(level, filter);
608f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    Send((video) ? MSG_SETVIDEOLOGGING : MSG_SETVOICELOGGING, &options);
609f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else {
610f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    SetMediaLogging_w(video, level, filter);
611f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
612f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
613f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
614f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::SetMediaLogging_w(bool video, int level,
615f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                       const char* filter) {
616f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  // Can be called before initialization
617f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  ASSERT(worker_thread_ == talk_base::Thread::Current() || !initialized_);
618f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (video) {
619f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    media_engine_->SetVideoLogging(level, filter);
620f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  } else {
621f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    media_engine_->SetVoiceLogging(level, filter);
622f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
623f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
624f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
625f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::Send(uint32 id, talk_base::MessageData* data) {
6263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!worker_thread_ || !initialized_) return false;
627f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  worker_thread_->Send(this, id, data);
628f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return true;
629f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
630f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
631dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid ChannelManager::OnVideoCaptureResult(CaptureResult result) {
632dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  capturing_ = result == CR_SUCCESS;
633f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  main_thread_->Post(this, MSG_CAMERASTARTED,
634dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                     new talk_base::TypedMessageData<CaptureResult>(result));
635f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
636f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
637f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid ChannelManager::OnMessage(talk_base::Message* message) {
638f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  talk_base::MessageData* data = message->pdata;
639f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  switch (message->message_id) {
640f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_CREATEVOICECHANNEL: {
641f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      CreationParams* p = static_cast<CreationParams*>(data);
642731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      p->voice_channel =
643731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          CreateVoiceChannel_w(p->session, p->content_name, p->rtcp);
644f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
645f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
646f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_DESTROYVOICECHANNEL: {
647f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      VoiceChannel* p = static_cast<talk_base::TypedMessageData<VoiceChannel*>*>
648f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          (data)->data();
649f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      DestroyVoiceChannel_w(p);
650f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
651f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
652f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_CREATEVIDEOCHANNEL: {
653f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      CreationParams* p = static_cast<CreationParams*>(data);
654731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      p->video_channel = CreateVideoChannel_w(p->session, p->content_name,
655f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                              p->rtcp, p->voice_channel);
656f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
657f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
658f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_DESTROYVIDEOCHANNEL: {
659f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      VideoChannel* p = static_cast<talk_base::TypedMessageData<VideoChannel*>*>
660f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          (data)->data();
661f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      DestroyVideoChannel_w(p);
662f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
663f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
664f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_CREATESOUNDCLIP: {
665f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      talk_base::TypedMessageData<Soundclip*> *p =
666f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          static_cast<talk_base::TypedMessageData<Soundclip*>*>(data);
667f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      p->data() = CreateSoundclip_w();
668f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
669f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
670f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_DESTROYSOUNDCLIP: {
671f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      talk_base::TypedMessageData<Soundclip*> *p =
672f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch          static_cast<talk_base::TypedMessageData<Soundclip*>*>(data);
673f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      DestroySoundclip_w(p->data());
674f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
675f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
676f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETAUDIOOPTIONS: {
677f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      AudioOptions* p = static_cast<AudioOptions*>(data);
678f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      p->result = SetAudioOptions_w(p->options,
679f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                                    p->in_device, p->out_device);
680f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
681f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
682f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETOUTPUTVOLUME: {
683f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      VolumeLevel* p = static_cast<VolumeLevel*>(data);
684f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      p->result = SetOutputVolume_w(p->level);
685f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
686f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
687f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETLOCALMONITOR: {
688f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      LocalMonitor* p = static_cast<LocalMonitor*>(data);
689f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      p->result = SetLocalMonitor_w(p->enable);
690f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
691f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
692f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETVIDEOOPTIONS: {
693f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      VideoOptions* p = static_cast<VideoOptions*>(data);
694f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      p->result = SetVideoOptions_w(p->cam_device);
695f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
696f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
6973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case MSG_SETDEFAULTVIDEOENCODERCONFIG: {
6983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      DefaultVideoEncoderConfig* p =
6993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          static_cast<DefaultVideoEncoderConfig*>(data);
7003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      p->result = SetDefaultVideoEncoderConfig_w(p->config);
701f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
702f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
703f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETLOCALRENDERER: {
704f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      LocalRenderer* p = static_cast<LocalRenderer*>(data);
705f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      p->result = SetLocalRenderer_w(p->renderer);
706f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
707f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
708f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETVIDEOCAPTURE: {
709f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      CaptureParams* p = static_cast<CaptureParams*>(data);
710f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      p->result = SetVideoCapture_w(p->capture);
711f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
712f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
713f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETVOICELOGGING:
714f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_SETVIDEOLOGGING: {
715f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      LoggingOptions* p = static_cast<LoggingOptions*>(data);
716f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      bool video = (message->message_id == MSG_SETVIDEOLOGGING);
717f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      SetMediaLogging_w(video, p->level, p->filter.c_str());
718f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
719f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
720f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    case MSG_CAMERASTARTED: {
721dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      talk_base::TypedMessageData<CaptureResult>* data =
722dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          static_cast<talk_base::TypedMessageData<CaptureResult>*>(
723dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen              message->pdata);
724f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      SignalVideoCaptureResult(data->data());
725f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      delete data;
726f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch      break;
727f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    }
728f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
729f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
730f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
731f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochstatic void GetDeviceNames(const std::vector<Device>& devs,
732f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch                           std::vector<std::string>* names) {
733f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  names->clear();
734f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  for (size_t i = 0; i < devs.size(); ++i) {
735f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    names->push_back(devs[i].name);
736f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  }
737f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
738f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
739f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::GetAudioInputDevices(std::vector<std::string>* names) {
740f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  names->clear();
741f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::vector<Device> devs;
742f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret = device_manager_->GetAudioInputDevices(&devs);
743f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret)
744f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    GetDeviceNames(devs, names);
745f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
746f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
747f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
748f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
749f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::GetAudioOutputDevices(std::vector<std::string>* names) {
750f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  names->clear();
751f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::vector<Device> devs;
752f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret = device_manager_->GetAudioOutputDevices(&devs);
753f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret)
754f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    GetDeviceNames(devs, names);
755f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
756f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
757f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
758f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
759f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool ChannelManager::GetVideoCaptureDevices(std::vector<std::string>* names) {
760f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  names->clear();
761f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  std::vector<Device> devs;
762f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  bool ret = device_manager_->GetVideoCaptureDevices(&devs);
763f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  if (ret)
764f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch    GetDeviceNames(devs, names);
765f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
766f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch  return ret;
767f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}
768f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch
769f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch}  // namespace cricket
770