15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/*
25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle
35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004 Google Inc.
45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without
65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met:
75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer.
105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer in the documentation
125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     and/or other materials provided with the distribution.
135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  3. The name of the author may not be used to endorse or promote products
145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     derived from this software without specific prior written permission.
155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */
275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/devices/devicemanager.h"
295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/fileutils.h"
315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/logging.h"
325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/pathutils.h"
335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/stringutils.h"
345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/thread.h"
355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/windowpicker.h"
365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/windowpickerfactory.h"
375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/base/mediacommon.h"
385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/devices/deviceinfo.h"
395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/devices/filevideocapturer.h"
405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if !defined(IOS)
425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(HAVE_WEBRTC_VIDEO)
445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h"
455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(HAVE_WEBRTC_VIDEO)
495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define VIDEO_CAPTURER_NAME WebRtcVideoCapturer
505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace {
565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool StringMatchWithWildcard(
585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::pair<const std::basic_string<char>, cricket::VideoFormat> key,
595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::string& val) {
605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return talk_base::string_match(val.c_str(), key.first.c_str());
615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}  // namespace
645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace cricket {
665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Initialize to empty string.
685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char DeviceManagerInterface::kDefaultDeviceName[] = "";
695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass DefaultVideoCapturerFactory : public VideoCapturerFactory {
725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  DefaultVideoCapturerFactory() {}
745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual ~DefaultVideoCapturerFactory() {}
755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VideoCapturer* Create(const Device& device) {
775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(VIDEO_CAPTURER_NAME)
785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    VIDEO_CAPTURER_NAME* return_value = new VIDEO_CAPTURER_NAME;
795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!return_value->Init(device)) {
805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      delete return_value;
815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return NULL;
825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return return_value;
845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else
855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return NULL;
865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgDeviceManager::DeviceManager()
915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    : initialized_(false),
925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      device_video_capturer_factory_(new DefaultVideoCapturerFactory),
935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      window_picker_(talk_base::WindowPickerFactory::CreateWindowPicker()) {
945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgDeviceManager::~DeviceManager() {
975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (initialized()) {
985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    Terminate();
995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::Init() {
1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!initialized()) {
1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!watcher()->Start()) {
1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return false;
1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    set_initialized(true);
1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid DeviceManager::Terminate() {
1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (initialized()) {
1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    watcher()->Stop();
1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    set_initialized(false);
1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint DeviceManager::GetCapabilities() {
1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::vector<Device> devices;
1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int caps = VIDEO_RECV;
1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (GetAudioInputDevices(&devices) && !devices.empty()) {
1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    caps |= AUDIO_SEND;
1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (GetAudioOutputDevices(&devices) && !devices.empty()) {
1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    caps |= AUDIO_RECV;
1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (GetVideoCaptureDevices(&devices) && !devices.empty()) {
1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    caps |= VIDEO_SEND;
1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return caps;
1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetAudioInputDevices(std::vector<Device>* devices) {
1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GetAudioDevices(true, devices);
1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetAudioOutputDevices(std::vector<Device>* devices) {
1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GetAudioDevices(false, devices);
1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetAudioInputDevice(const std::string& name, Device* out) {
1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GetAudioDevice(true, name, out);
1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetAudioOutputDevice(const std::string& name, Device* out) {
1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GetAudioDevice(false, name, out);
1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  devices->clear();
152204b178db6a965bcdee700f384174d4303e8e9d8stefan@webrtc.org#if defined(ANDROID) || defined(IOS)
153204b178db6a965bcdee700f384174d4303e8e9d8stefan@webrtc.org  // On Android and iOS, we treat the camera(s) as a single device. Even if
154204b178db6a965bcdee700f384174d4303e8e9d8stefan@webrtc.org  // there are multiple cameras, that's abstracted away at a higher level.
1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  Device dev("camera", "1");    // name and ID
1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  devices->push_back(dev);
1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else
1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetVideoCaptureDevice(const std::string& name,
1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                          Device* out) {
1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // If the name is empty, return the default device.
1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (name.empty() || name == kDefaultDeviceName) {
1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return GetDefaultVideoCaptureDevice(out);
1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::vector<Device> devices;
1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!GetVideoCaptureDevices(&devices)) {
1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  for (std::vector<Device>::const_iterator it = devices.begin();
1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      it != devices.end(); ++it) {
1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (name == it->name) {
1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      *out = *it;
1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return true;
1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // If |name| is a valid name for a file, return a file video capturer device.
1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (talk_base::Filesystem::IsFile(name)) {
1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    *out = FileVideoCapturer::CreateFileVideoCapturerDevice(name);
1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;
1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid DeviceManager::SetVideoCaptureDeviceMaxFormat(
1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::string& usb_id,
1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const VideoFormat& max_format) {
1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  max_formats_[usb_id] = max_format;
1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid DeviceManager::ClearVideoCaptureDeviceMaxFormat(
1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::string& usb_id) {
2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  max_formats_.erase(usb_id);
2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgVideoCapturer* DeviceManager::CreateVideoCapturer(const Device& device) const {
2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(IOS)
2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  LOG_F(LS_ERROR) << " should never be called!";
2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return NULL;
2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else
2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // TODO(hellner): Throw out the creation of a file video capturer once the
2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // refactoring is completed.
2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (FileVideoCapturer::IsFileVideoCapturerDevice(device)) {
2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    FileVideoCapturer* capturer = new FileVideoCapturer;
2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!capturer->Init(device)) {
2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      delete capturer;
2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return NULL;
2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    LOG(LS_INFO) << "Created file video capturer " << device.name;
2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    capturer->set_repeat(talk_base::kForever);
2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return capturer;
2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VideoCapturer* capturer = device_video_capturer_factory_->Create(device);
2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!capturer) {
2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return NULL;
2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  LOG(LS_INFO) << "Created VideoCapturer for " << device.name;
2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  VideoFormat video_format;
2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool has_max = GetMaxFormat(device, &video_format);
2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  capturer->set_enable_camera_list(has_max);
2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (has_max) {
2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    capturer->ConstrainSupportedFormats(video_format);
2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return capturer;
2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetWindows(
2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::vector<talk_base::WindowDescription>* descriptions) {
2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!window_picker_) {
2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return window_picker_->GetWindowList(descriptions);
2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgVideoCapturer* DeviceManager::CreateWindowCapturer(talk_base::WindowId window) {
2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(WINDOW_CAPTURER_NAME)
2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  WINDOW_CAPTURER_NAME* window_capturer = new WINDOW_CAPTURER_NAME();
2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!window_capturer->Init(window)) {
2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    delete window_capturer;
2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return NULL;
2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return window_capturer;
2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else
2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return NULL;
2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetDesktops(
2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::vector<talk_base::DesktopDescription>* descriptions) {
2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!window_picker_) {
2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return window_picker_->GetDesktopList(descriptions);
2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgVideoCapturer* DeviceManager::CreateDesktopCapturer(
2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::DesktopId desktop) {
2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(DESKTOP_CAPTURER_NAME)
2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  DESKTOP_CAPTURER_NAME* desktop_capturer = new DESKTOP_CAPTURER_NAME();
2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!desktop_capturer->Init(desktop.index())) {
2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    delete desktop_capturer;
2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return NULL;
2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return desktop_capturer;
2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else
2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return NULL;
2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetAudioDevices(bool input,
2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    std::vector<Device>* devs) {
2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  devs->clear();
281582fe818e571fa2571267f5e369715188472f352wu@webrtc.org#if defined(ANDROID)
282582fe818e571fa2571267f5e369715188472f352wu@webrtc.org  // Under Android, 0 is always required for the playout device and 0 is the
283582fe818e571fa2571267f5e369715188472f352wu@webrtc.org  // default for the recording device.
284582fe818e571fa2571267f5e369715188472f352wu@webrtc.org  devs->push_back(Device("default-device", 0));
2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else
287582fe818e571fa2571267f5e369715188472f352wu@webrtc.org  // Other platforms either have their own derived class implementation
288582fe818e571fa2571267f5e369715188472f352wu@webrtc.org  // (desktop) or don't use device manager for audio devices (iOS).
2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif
2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetAudioDevice(bool is_input, const std::string& name,
2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                   Device* out) {
2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // If the name is empty, return the default device id.
2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (name.empty() || name == kDefaultDeviceName) {
2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    *out = Device(name, -1);
2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;
2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::vector<Device> devices;
3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = is_input ? GetAudioInputDevices(&devices) :
3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        GetAudioOutputDevices(&devices);
3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (ret) {
3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ret = false;
3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    for (size_t i = 0; i < devices.size(); ++i) {
3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      if (devices[i].name == name) {
3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        *out = devices[i];
3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        ret = true;
3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        break;
3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      }
3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetDefaultVideoCaptureDevice(Device* device) {
3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool ret = false;
3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // We just return the first device.
3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::vector<Device> devices;
3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ret = (GetVideoCaptureDevices(&devices) && !devices.empty());
3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (ret) {
3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    *device = devices[0];
3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return ret;
3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::IsInWhitelist(const std::string& key,
3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                  VideoFormat* video_format) const {
3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::map<std::string, VideoFormat>::const_iterator found =
3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      std::search_n(max_formats_.begin(), max_formats_.end(), 1, key,
3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    StringMatchWithWildcard);
3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (found == max_formats_.end()) {
3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  *video_format = found->second;
3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::GetMaxFormat(const Device& device,
3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 VideoFormat* video_format) const {
3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Match USB ID if available. Failing that, match device name.
3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string usb_id;
3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (GetUsbId(device, &usb_id) && IsInWhitelist(usb_id, video_format)) {
3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return true;
3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return IsInWhitelist(device.name, video_format);
3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::ShouldDeviceBeIgnored(const std::string& device_name,
3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const char* const exclusion_list[]) {
3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // If exclusion_list is empty return directly.
3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!exclusion_list)
3545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
3555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int i = 0;
3575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  while (exclusion_list[i]) {
3585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (strnicmp(device_name.c_str(), exclusion_list[i],
3595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        strlen(exclusion_list[i])) == 0) {
3605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      LOG(LS_INFO) << "Ignoring device " << device_name;
3615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return true;
3625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
3635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ++i;
3645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return false;
3665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool DeviceManager::FilterDevices(std::vector<Device>* devices,
3695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const char* const exclusion_list[]) {
3705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!devices) {
3715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return false;
3725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  for (std::vector<Device>::iterator it = devices->begin();
3755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       it != devices->end(); ) {
3765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (ShouldDeviceBeIgnored(it->name, exclusion_list)) {
3775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      it = devices->erase(it);
3785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
3795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ++it;
3805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
3815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
3835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}  // namespace cricket
386