Remove DeviceManager and DeviceInfo.

BUG=webrtc:5615, webrtc:5620

Review URL: https://codereview.webrtc.org/1715883002

Cr-Commit-Position: refs/heads/master@{#12020}
This commit is contained in:
solenberg 2016-03-16 09:34:56 -07:00 committed by Commit bot
parent 34b11eb66e
commit 8ad582d83f
33 changed files with 40 additions and 3034 deletions

View File

@ -178,6 +178,7 @@
'xcode_settings': {
'OTHER_LDFLAGS': [
'-framework Cocoa',
'-framework OpenGL',
],
},
},

View File

@ -34,25 +34,16 @@
#include <memory>
#include "webrtc/media/base/videocapturer.h"
#include "webrtc/media/devices/devicemanager.h"
#include "webrtc/media/engine/webrtcvideocapturerfactory.h"
@implementation RTCVideoCapturer {
std::unique_ptr<cricket::VideoCapturer> _capturer;
}
+ (RTCVideoCapturer*)capturerWithDeviceName:(NSString*)deviceName {
const std::string& device_name = std::string([deviceName UTF8String]);
std::unique_ptr<cricket::DeviceManagerInterface> device_manager(
cricket::DeviceManagerFactory::Create());
bool initialized = device_manager->Init();
NSAssert(initialized, @"DeviceManager::Init() failed");
cricket::Device device;
if (!device_manager->GetVideoCaptureDevice(device_name, &device)) {
LOG(LS_ERROR) << "GetVideoCaptureDevice failed";
return 0;
}
std::unique_ptr<cricket::VideoCapturer> capturer(
device_manager->CreateVideoCapturer(device));
cricket::WebRtcVideoDeviceCapturerFactory factory;
cricket::Device device(std::string(deviceName.UTF8String), 0);
rtc::scoped_ptr<cricket::VideoCapturer> capturer(factory.Create(device));
RTCVideoCapturer* rtcCapturer =
[[RTCVideoCapturer alloc] initWithCapturer:capturer.release()];
return rtcCapturer;

View File

@ -236,6 +236,13 @@
'objc/RTCNSGLVideoView.h',
'objc/RTCNSGLVideoView.m',
],
'link_settings': {
'xcode_settings': {
'OTHER_LDFLAGS': [
'-framework OpenGL',
],
},
},
}],
],
}

View File

@ -19,7 +19,8 @@
#include "webrtc/base/json.h"
#include "webrtc/base/logging.h"
#include "webrtc/examples/peerconnection/client/defaults.h"
#include "webrtc/media/devices/devicemanager.h"
#include "webrtc/media/engine/webrtcvideocapturerfactory.h"
#include "webrtc/modules/video_capture/video_capture_factory.h"
// Names used for a IceCandidate JSON object.
const char kCandidateSdpMidName[] = "sdpMid";
@ -369,23 +370,31 @@ void Conductor::ConnectToPeer(int peer_id) {
}
cricket::VideoCapturer* Conductor::OpenVideoCaptureDevice() {
rtc::scoped_ptr<cricket::DeviceManagerInterface> dev_manager(
cricket::DeviceManagerFactory::Create());
if (!dev_manager->Init()) {
LOG(LS_ERROR) << "Can't create device manager";
return NULL;
std::vector<std::string> device_names;
{
std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(
webrtc::VideoCaptureFactory::CreateDeviceInfo(0));
if (!info) {
return nullptr;
}
int num_devices = info->NumberOfDevices();
for (int i = 0; i < num_devices; ++i) {
const uint32_t kSize = 256;
char name[kSize] = {0};
char id[kSize] = {0};
if (info->GetDeviceName(i, name, kSize, id, kSize) != -1) {
device_names.push_back(name);
}
}
}
std::vector<cricket::Device> devs;
if (!dev_manager->GetVideoCaptureDevices(&devs)) {
LOG(LS_ERROR) << "Can't enumerate video devices";
return NULL;
}
std::vector<cricket::Device>::iterator dev_it = devs.begin();
cricket::VideoCapturer* capturer = NULL;
for (; dev_it != devs.end(); ++dev_it) {
capturer = dev_manager->CreateVideoCapturer(*dev_it);
if (capturer != NULL)
cricket::WebRtcVideoDeviceCapturerFactory factory;
cricket::VideoCapturer* capturer = nullptr;
for (const auto& name : device_names) {
capturer = factory.Create(cricket::Device(name, 0));
if (capturer) {
break;
}
}
return capturer;
}

View File

@ -750,11 +750,6 @@ class FakeVideoEngine : public FakeBaseEngine {
const std::vector<VideoCodec>& codecs() const { return codecs_; }
void SetCodecs(const std::vector<VideoCodec> codecs) { codecs_ = codecs; }
bool SetCaptureDevice(const Device* device) {
in_device_ = (device) ? device->name : "";
options_changed_ = true;
return true;
}
bool SetCapture(bool capture) {
capture_ = capture;
return true;
@ -763,7 +758,6 @@ class FakeVideoEngine : public FakeBaseEngine {
private:
std::vector<FakeVideoMediaChannel*> channels_;
std::vector<VideoCodec> codecs_;
std::string in_device_;
bool capture_;
VideoOptions options_;

View File

@ -26,7 +26,6 @@
#include "webrtc/media/base/mediacommon.h"
#include "webrtc/media/base/videocapturer.h"
#include "webrtc/media/base/videocommon.h"
#include "webrtc/media/devices/devicemanager.h"
#if defined(GOOGLE_CHROME_BUILD) || defined(CHROMIUM_BUILD)
#define DISABLE_MEDIA_ENGINE_FACTORY

View File

@ -30,7 +30,6 @@
#include "webrtc/media/base/videobroadcaster.h"
#include "webrtc/media/base/videocommon.h"
#include "webrtc/media/base/videoframefactory.h"
#include "webrtc/media/devices/devicemanager.h"
namespace cricket {

View File

@ -109,7 +109,6 @@ class VideoMediaChannelTest : public testing::Test,
}
virtual void SetUp() {
cricket::Device device("test", "device");
engine_.Init();
channel_.reset(engine_.CreateChannel(call_.get(), cricket::MediaConfig(),
cricket::VideoOptions()));

View File

@ -1,25 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MEDIA_DEVICES_DEVICEINFO_H_
#define WEBRTC_MEDIA_DEVICES_DEVICEINFO_H_
#include <string>
#include "webrtc/media/devices/devicemanager.h"
namespace cricket {
bool GetUsbId(const Device& device, std::string* usb_id);
bool GetUsbVersion(const Device& device, std::string* usb_version);
} // namespace cricket
#endif // WEBRTC_MEDIA_DEVICES_DEVICEINFO_H_

View File

@ -1,305 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/devicemanager.h"
#include "webrtc/base/fileutils.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/windowpicker.h"
#include "webrtc/base/windowpickerfactory.h"
#include "webrtc/media/base/mediacommon.h"
#include "webrtc/media/base/videocapturer.h"
#include "webrtc/media/base/videocapturerfactory.h"
#include "webrtc/media/devices/deviceinfo.h"
#ifdef HAVE_WEBRTC_VIDEO
#include "webrtc/media/engine/webrtcvideocapturerfactory.h"
#endif // HAVE_WEBRTC_VIDEO
namespace {
bool StringMatchWithWildcard(
const std::pair<const std::basic_string<char>, cricket::VideoFormat> key,
const std::string& val) {
return rtc::string_match(val.c_str(), key.first.c_str());
}
} // namespace
namespace cricket {
// Initialize to empty string.
const char DeviceManagerInterface::kDefaultDeviceName[] = "";
DeviceManager::DeviceManager()
: initialized_(false),
window_picker_(rtc::WindowPickerFactory::CreateWindowPicker()) {
#ifdef HAVE_WEBRTC_VIDEO
SetVideoDeviceCapturerFactory(new WebRtcVideoDeviceCapturerFactory());
#endif // HAVE_WEBRTC_VIDEO
}
DeviceManager::~DeviceManager() {
if (initialized()) {
Terminate();
}
}
bool DeviceManager::Init() {
if (!initialized()) {
if (!watcher()->Start()) {
return false;
}
set_initialized(true);
}
return true;
}
void DeviceManager::Terminate() {
if (initialized()) {
watcher()->Stop();
set_initialized(false);
}
}
int DeviceManager::GetCapabilities() {
std::vector<Device> devices;
int caps = VIDEO_RECV;
if (GetAudioInputDevices(&devices) && !devices.empty()) {
caps |= AUDIO_SEND;
}
if (GetAudioOutputDevices(&devices) && !devices.empty()) {
caps |= AUDIO_RECV;
}
if (GetVideoCaptureDevices(&devices) && !devices.empty()) {
caps |= VIDEO_SEND;
}
return caps;
}
bool DeviceManager::GetAudioInputDevices(std::vector<Device>* devices) {
return GetAudioDevices(true, devices);
}
bool DeviceManager::GetAudioOutputDevices(std::vector<Device>* devices) {
return GetAudioDevices(false, devices);
}
bool DeviceManager::GetAudioInputDevice(const std::string& name, Device* out) {
return GetAudioDevice(true, name, out);
}
bool DeviceManager::GetAudioOutputDevice(const std::string& name, Device* out) {
return GetAudioDevice(false, name, out);
}
bool DeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
devices->clear();
#if defined(ANDROID) || defined(WEBRTC_IOS)
// On Android and iOS, we treat the camera(s) as a single device. Even if
// there are multiple cameras, that's abstracted away at a higher level.
Device dev("camera", "1"); // name and ID
devices->push_back(dev);
return true;
#else
return false;
#endif
}
bool DeviceManager::GetVideoCaptureDevice(const std::string& name,
Device* out) {
// If the name is empty, return the default device.
if (name.empty() || name == kDefaultDeviceName) {
return GetDefaultVideoCaptureDevice(out);
}
std::vector<Device> devices;
if (!GetVideoCaptureDevices(&devices)) {
return false;
}
for (std::vector<Device>::const_iterator it = devices.begin();
it != devices.end(); ++it) {
if (name == it->name) {
*out = *it;
return true;
}
}
return false;
}
void DeviceManager::SetVideoCaptureDeviceMaxFormat(
const std::string& usb_id,
const VideoFormat& max_format) {
max_formats_[usb_id] = max_format;
}
void DeviceManager::ClearVideoCaptureDeviceMaxFormat(
const std::string& usb_id) {
max_formats_.erase(usb_id);
}
VideoCapturer* DeviceManager::CreateVideoCapturer(const Device& device) const {
if (!video_device_capturer_factory_) {
LOG(LS_ERROR) << "No video capturer factory for devices.";
return NULL;
}
cricket::VideoCapturer* capturer =
video_device_capturer_factory_->Create(device);
if (!capturer) {
return NULL;
}
LOG(LS_INFO) << "Created VideoCapturer for " << device.name;
VideoFormat video_format;
bool has_max = GetMaxFormat(device, &video_format);
capturer->set_enable_camera_list(has_max);
if (has_max) {
capturer->ConstrainSupportedFormats(video_format);
}
return capturer;
}
bool DeviceManager::GetWindows(
std::vector<rtc::WindowDescription>* descriptions) {
if (!window_picker_) {
return false;
}
return window_picker_->GetWindowList(descriptions);
}
bool DeviceManager::GetDesktops(
std::vector<rtc::DesktopDescription>* descriptions) {
if (!window_picker_) {
return false;
}
return window_picker_->GetDesktopList(descriptions);
}
VideoCapturer* DeviceManager::CreateScreenCapturer(
const ScreencastId& screenid) const {
if (!screen_capturer_factory_) {
LOG(LS_ERROR) << "No video capturer factory for screens.";
return NULL;
}
return screen_capturer_factory_->Create(screenid);
}
bool DeviceManager::GetAudioDevices(bool input,
std::vector<Device>* devs) {
devs->clear();
#if defined(ANDROID)
// Under Android, 0 is always required for the playout device and 0 is the
// default for the recording device.
devs->push_back(Device("default-device", 0));
return true;
#else
// Other platforms either have their own derived class implementation
// (desktop) or don't use device manager for audio devices (iOS).
return false;
#endif
}
bool DeviceManager::GetAudioDevice(bool is_input, const std::string& name,
Device* out) {
// If the name is empty, return the default device id.
if (name.empty() || name == kDefaultDeviceName) {
*out = Device(name, -1);
return true;
}
std::vector<Device> devices;
bool ret = is_input ? GetAudioInputDevices(&devices) :
GetAudioOutputDevices(&devices);
if (ret) {
ret = false;
for (size_t i = 0; i < devices.size(); ++i) {
if (devices[i].name == name) {
*out = devices[i];
ret = true;
break;
}
}
}
return ret;
}
bool DeviceManager::GetDefaultVideoCaptureDevice(Device* device) {
bool ret = false;
// We just return the first device.
std::vector<Device> devices;
ret = (GetVideoCaptureDevices(&devices) && !devices.empty());
if (ret) {
*device = devices[0];
}
return ret;
}
bool DeviceManager::IsInWhitelist(const std::string& key,
VideoFormat* video_format) const {
std::map<std::string, VideoFormat>::const_iterator found =
std::search_n(max_formats_.begin(), max_formats_.end(), 1, key,
StringMatchWithWildcard);
if (found == max_formats_.end()) {
return false;
}
*video_format = found->second;
return true;
}
bool DeviceManager::GetMaxFormat(const Device& device,
VideoFormat* video_format) const {
// Match USB ID if available. Failing that, match device name.
std::string usb_id;
if (GetUsbId(device, &usb_id) && IsInWhitelist(usb_id, video_format)) {
return true;
}
return IsInWhitelist(device.name, video_format);
}
bool DeviceManager::ShouldDeviceBeIgnored(const std::string& device_name,
const char* const exclusion_list[]) {
// If exclusion_list is empty return directly.
if (!exclusion_list)
return false;
int i = 0;
while (exclusion_list[i]) {
if (strnicmp(device_name.c_str(), exclusion_list[i],
strlen(exclusion_list[i])) == 0) {
LOG(LS_INFO) << "Ignoring device " << device_name;
return true;
}
++i;
}
return false;
}
bool DeviceManager::FilterDevices(std::vector<Device>* devices,
const char* const exclusion_list[]) {
if (!devices) {
return false;
}
for (std::vector<Device>::iterator it = devices->begin();
it != devices->end(); ) {
if (ShouldDeviceBeIgnored(it->name, exclusion_list)) {
it = devices->erase(it);
} else {
++it;
}
}
return true;
}
} // namespace cricket

View File

@ -1,192 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MEDIA_DEVICES_DEVICEMANAGER_H_
#define WEBRTC_MEDIA_DEVICES_DEVICEMANAGER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "webrtc/base/sigslot.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/base/window.h"
#include "webrtc/media/base/device.h"
#include "webrtc/media/base/screencastid.h"
#include "webrtc/media/base/videocapturerfactory.h"
#include "webrtc/media/base/videocommon.h"
namespace rtc {
class DesktopDescription;
class WindowDescription;
class WindowPicker;
}
namespace cricket {
class VideoCapturer;
// DeviceManagerInterface - interface to manage the audio and
// video devices on the system.
class DeviceManagerInterface {
public:
virtual ~DeviceManagerInterface() { }
// Initialization
virtual bool Init() = 0;
virtual void Terminate() = 0;
// Capabilities
virtual int GetCapabilities() = 0;
// Device enumeration
virtual bool GetAudioInputDevices(std::vector<Device>* devices) = 0;
virtual bool GetAudioOutputDevices(std::vector<Device>* devices) = 0;
virtual bool GetAudioInputDevice(const std::string& name, Device* out) = 0;
virtual bool GetAudioOutputDevice(const std::string& name, Device* out) = 0;
virtual bool GetVideoCaptureDevices(std::vector<Device>* devs) = 0;
virtual bool GetVideoCaptureDevice(const std::string& name, Device* out) = 0;
// If the device manager needs to create video capturers, here is
// how to control which video capturers are created. These take
// ownership of the factories.
virtual void SetVideoDeviceCapturerFactory(
VideoDeviceCapturerFactory* video_device_capturer_factory) = 0;
virtual void SetScreenCapturerFactory(
ScreenCapturerFactory* screen_capturer_factory) = 0;
// Caps the capture format according to max format for capturers created
// by CreateVideoCapturer(). See ConstrainSupportedFormats() in
// videocapturer.h for more detail.
// Note that once a VideoCapturer has been created, calling this API will
// not affect it.
virtual void SetVideoCaptureDeviceMaxFormat(
const std::string& usb_id,
const VideoFormat& max_format) = 0;
virtual void ClearVideoCaptureDeviceMaxFormat(const std::string& usb_id) = 0;
// Device creation
virtual VideoCapturer* CreateVideoCapturer(const Device& device) const = 0;
virtual bool GetWindows(
std::vector<rtc::WindowDescription>* descriptions) = 0;
virtual bool GetDesktops(
std::vector<rtc::DesktopDescription>* descriptions) = 0;
virtual VideoCapturer* CreateScreenCapturer(
const ScreencastId& screenid) const = 0;
sigslot::signal0<> SignalDevicesChange;
static const char kDefaultDeviceName[];
};
class DeviceWatcher {
public:
explicit DeviceWatcher(DeviceManagerInterface* dm) {}
virtual ~DeviceWatcher() {}
virtual bool Start() { return true; }
virtual void Stop() {}
};
class DeviceManagerFactory {
public:
static DeviceManagerInterface* Create();
private:
DeviceManagerFactory() {}
};
class DeviceManager : public DeviceManagerInterface {
public:
DeviceManager();
virtual ~DeviceManager();
// Initialization
virtual bool Init();
virtual void Terminate();
// Capabilities
virtual int GetCapabilities();
// Device enumeration
virtual bool GetAudioInputDevices(std::vector<Device>* devices);
virtual bool GetAudioOutputDevices(std::vector<Device>* devices);
virtual bool GetAudioInputDevice(const std::string& name, Device* out);
virtual bool GetAudioOutputDevice(const std::string& name, Device* out);
virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
virtual bool GetVideoCaptureDevice(const std::string& name, Device* out);
virtual void SetVideoDeviceCapturerFactory(
VideoDeviceCapturerFactory* video_device_capturer_factory) {
video_device_capturer_factory_.reset(video_device_capturer_factory);
}
virtual void SetScreenCapturerFactory(
ScreenCapturerFactory* screen_capturer_factory) {
screen_capturer_factory_.reset(screen_capturer_factory);
}
virtual void SetVideoCaptureDeviceMaxFormat(const std::string& usb_id,
const VideoFormat& max_format);
virtual void ClearVideoCaptureDeviceMaxFormat(const std::string& usb_id);
// TODO(pthatcher): Rename to CreateVideoDeviceCapturer.
virtual VideoCapturer* CreateVideoCapturer(const Device& device) const;
virtual bool GetWindows(
std::vector<rtc::WindowDescription>* descriptions);
virtual bool GetDesktops(
std::vector<rtc::DesktopDescription>* descriptions);
virtual VideoCapturer* CreateScreenCapturer(
const ScreencastId& screenid) const;
// The exclusion_list MUST be a NULL terminated list.
static bool FilterDevices(std::vector<Device>* devices,
const char* const exclusion_list[]);
bool initialized() const { return initialized_; }
protected:
virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
virtual bool GetAudioDevice(bool is_input, const std::string& name,
Device* out);
virtual bool GetDefaultVideoCaptureDevice(Device* device);
bool IsInWhitelist(const std::string& key, VideoFormat* video_format) const;
virtual bool GetMaxFormat(const Device& device,
VideoFormat* video_format) const;
void set_initialized(bool initialized) { initialized_ = initialized; }
void set_watcher(DeviceWatcher* watcher) { watcher_.reset(watcher); }
DeviceWatcher* watcher() { return watcher_.get(); }
private:
// The exclusion_list MUST be a NULL terminated list.
static bool ShouldDeviceBeIgnored(const std::string& device_name,
const char* const exclusion_list[]);
bool initialized_;
std::unique_ptr<
VideoDeviceCapturerFactory> video_device_capturer_factory_;
std::unique_ptr<
ScreenCapturerFactory> screen_capturer_factory_;
std::map<std::string, VideoFormat> max_formats_;
std::unique_ptr<DeviceWatcher> watcher_;
std::unique_ptr<rtc::WindowPicker> window_picker_;
};
} // namespace cricket
#endif // WEBRTC_MEDIA_DEVICES_DEVICEMANAGER_H_

View File

@ -1,443 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/devicemanager.h"
#ifdef WIN32
#include <objbase.h>
#include "webrtc/base/win32.h"
#endif
#include <memory>
#include <string>
#include "webrtc/base/arraysize.h"
#include "webrtc/base/fileutils.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/windowpickerfactory.h"
#include "webrtc/media/base/fakevideocapturer.h"
#include "webrtc/media/base/screencastid.h"
#include "webrtc/media/base/testutils.h"
#include "webrtc/media/base/videocapturerfactory.h"
#include "webrtc/media/devices/v4llookup.h"
#ifdef WEBRTC_LINUX
// TODO(juberti): Figure out why this doesn't compile on Windows.
#include "webrtc/base/fileutils_mock.h"
#endif // WEBRTC_LINUX
using rtc::Pathname;
using rtc::FileTimeType;
using cricket::Device;
using cricket::DeviceManager;
using cricket::DeviceManagerFactory;
using cricket::DeviceManagerInterface;
const cricket::VideoFormat kVgaFormat(640, 480,
cricket::VideoFormat::FpsToInterval(30),
cricket::FOURCC_I420);
const cricket::VideoFormat kHdFormat(1280, 720,
cricket::VideoFormat::FpsToInterval(30),
cricket::FOURCC_I420);
class FakeVideoDeviceCapturerFactory :
public cricket::VideoDeviceCapturerFactory {
public:
FakeVideoDeviceCapturerFactory() {}
virtual ~FakeVideoDeviceCapturerFactory() {}
virtual cricket::VideoCapturer* Create(const cricket::Device& device) {
return new cricket::FakeVideoCapturer;
}
};
class FakeScreenCapturerFactory : public cricket::ScreenCapturerFactory {
public:
FakeScreenCapturerFactory() {}
virtual ~FakeScreenCapturerFactory() {}
virtual cricket::VideoCapturer* Create(
const cricket::ScreencastId& screenid) {
return new cricket::FakeVideoCapturer;
}
};
class DeviceManagerTestFake : public testing::Test {
public:
virtual void SetUp() {
dm_.reset(DeviceManagerFactory::Create());
EXPECT_TRUE(dm_->Init());
DeviceManager* device_manager = static_cast<DeviceManager*>(dm_.get());
device_manager->SetVideoDeviceCapturerFactory(
new FakeVideoDeviceCapturerFactory());
device_manager->SetScreenCapturerFactory(
new FakeScreenCapturerFactory());
}
virtual void TearDown() {
dm_->Terminate();
}
protected:
std::unique_ptr<DeviceManagerInterface> dm_;
};
// Test that we startup/shutdown properly.
TEST(DeviceManagerTest, StartupShutdown) {
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
EXPECT_TRUE(dm->Init());
dm->Terminate();
}
// Test CoInitEx behavior
#ifdef WIN32
TEST(DeviceManagerTest, CoInitialize) {
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> devices;
// Ensure that calls to video device work if COM is not yet initialized.
EXPECT_TRUE(dm->Init());
EXPECT_TRUE(dm->GetVideoCaptureDevices(&devices));
dm->Terminate();
// Ensure that the ref count is correct.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
CoUninitialize();
// Ensure that Init works in COINIT_APARTMENTTHREADED setting.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
EXPECT_TRUE(dm->Init());
dm->Terminate();
CoUninitialize();
// Ensure that the ref count is correct.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
CoUninitialize();
// Ensure that Init works in COINIT_MULTITHREADED setting.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
EXPECT_TRUE(dm->Init());
dm->Terminate();
CoUninitialize();
// Ensure that the ref count is correct.
EXPECT_EQ(S_OK, CoInitializeEx(NULL, COINIT_MULTITHREADED));
CoUninitialize();
}
#endif
// Test enumerating devices (although we may not find any).
TEST(DeviceManagerTest, GetDevices) {
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> audio_ins, audio_outs, video_ins;
std::vector<cricket::Device> video_in_devs;
cricket::Device def_video;
EXPECT_TRUE(dm->Init());
EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_in_devs));
EXPECT_EQ(video_ins.size(), video_in_devs.size());
// If we have any video devices, we should be able to pick a default.
EXPECT_TRUE(dm->GetVideoCaptureDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &def_video)
!= video_ins.empty());
}
// Test that we return correct ids for default and bogus devices.
TEST(DeviceManagerTest, GetAudioDeviceIds) {
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
Device device;
EXPECT_TRUE(dm->Init());
EXPECT_TRUE(dm->GetAudioInputDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
EXPECT_EQ("-1", device.id);
EXPECT_TRUE(dm->GetAudioOutputDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
EXPECT_EQ("-1", device.id);
EXPECT_FALSE(dm->GetAudioInputDevice("_NOT A REAL DEVICE_", &device));
EXPECT_FALSE(dm->GetAudioOutputDevice("_NOT A REAL DEVICE_", &device));
}
// Test that we get the video capture device by name properly.
TEST(DeviceManagerTest, GetVideoDeviceIds) {
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
Device device;
EXPECT_TRUE(dm->Init());
EXPECT_FALSE(dm->GetVideoCaptureDevice("_NOT A REAL DEVICE_", &device));
std::vector<Device> video_ins;
EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
if (!video_ins.empty()) {
// Get the default device with the parameter kDefaultDeviceName.
EXPECT_TRUE(dm->GetVideoCaptureDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
// Get the first device with the parameter video_ins[0].name.
EXPECT_TRUE(dm->GetVideoCaptureDevice(video_ins[0].name, &device));
EXPECT_EQ(device.name, video_ins[0].name);
EXPECT_EQ(device.id, video_ins[0].id);
}
}
TEST(DeviceManagerTest, VerifyDevicesListsAreCleared) {
const std::string imaginary("_NOT A REAL DEVICE_");
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> audio_ins, audio_outs, video_ins;
audio_ins.push_back(Device(imaginary, imaginary));
audio_outs.push_back(Device(imaginary, imaginary));
video_ins.push_back(Device(imaginary, imaginary));
EXPECT_TRUE(dm->Init());
EXPECT_TRUE(dm->GetAudioInputDevices(&audio_ins));
EXPECT_TRUE(dm->GetAudioOutputDevices(&audio_outs));
EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
for (size_t i = 0; i < audio_ins.size(); ++i) {
EXPECT_NE(imaginary, audio_ins[i].name);
}
for (size_t i = 0; i < audio_outs.size(); ++i) {
EXPECT_NE(imaginary, audio_outs[i].name);
}
for (size_t i = 0; i < video_ins.size(); ++i) {
EXPECT_NE(imaginary, video_ins[i].name);
}
}
static bool CompareDeviceList(std::vector<Device>& devices,
const char* const device_list[], int list_size) {
if (list_size != static_cast<int>(devices.size())) {
return false;
}
for (int i = 0; i < list_size; ++i) {
if (devices[i].name.compare(device_list[i]) != 0) {
return false;
}
}
return true;
}
TEST(DeviceManagerTest, VerifyFilterDevices) {
static const char* const kTotalDevicesName[] = {
"Google Camera Adapters are tons of fun.",
"device1",
"device2",
"device3",
"device4",
"device5",
"Google Camera Adapter 0",
"Google Camera Adapter 1",
};
static const char* const kFilteredDevicesName[] = {
"device2",
"device4",
"Google Camera Adapter",
NULL,
};
static const char* const kDevicesName[] = {
"device1",
"device3",
"device5",
};
std::vector<Device> devices;
for (int i = 0; i < arraysize(kTotalDevicesName); ++i) {
devices.push_back(Device(kTotalDevicesName[i], i));
}
EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
arraysize(kTotalDevicesName)));
// Return false if given NULL as the exclusion list.
EXPECT_TRUE(DeviceManager::FilterDevices(&devices, NULL));
// The devices should not change.
EXPECT_TRUE(CompareDeviceList(devices, kTotalDevicesName,
arraysize(kTotalDevicesName)));
EXPECT_TRUE(DeviceManager::FilterDevices(&devices, kFilteredDevicesName));
EXPECT_TRUE(CompareDeviceList(devices, kDevicesName,
arraysize(kDevicesName)));
}
#ifdef WEBRTC_LINUX
class FakeV4LLookup : public cricket::V4LLookup {
public:
explicit FakeV4LLookup(std::vector<std::string> device_paths)
: device_paths_(device_paths) {}
protected:
bool CheckIsV4L2Device(const std::string& device) {
return std::find(device_paths_.begin(), device_paths_.end(), device)
!= device_paths_.end();
}
private:
std::vector<std::string> device_paths_;
};
TEST(DeviceManagerTest, GetVideoCaptureDevices_K2_6) {
std::vector<std::string> devices;
devices.push_back("/dev/video0");
devices.push_back("/dev/video5");
cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
std::vector<rtc::FakeFileSystem::File> files;
files.push_back(rtc::FakeFileSystem::File("/dev/video0", ""));
files.push_back(rtc::FakeFileSystem::File("/dev/video5", ""));
files.push_back(rtc::FakeFileSystem::File(
"/sys/class/video4linux/video0/name", "Video Device 1"));
files.push_back(rtc::FakeFileSystem::File(
"/sys/class/video4linux/video1/model", "Bad Device"));
files.push_back(
rtc::FakeFileSystem::File("/sys/class/video4linux/video5/model",
"Video Device 2"));
rtc::FilesystemScope fs(new rtc::FakeFileSystem(files));
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> video_ins;
EXPECT_TRUE(dm->Init());
EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
EXPECT_EQ(2u, video_ins.size());
EXPECT_EQ("Video Device 1", video_ins.at(0).name);
EXPECT_EQ("Video Device 2", video_ins.at(1).name);
}
TEST(DeviceManagerTest, GetVideoCaptureDevices_K2_4) {
std::vector<std::string> devices;
devices.push_back("/dev/video0");
devices.push_back("/dev/video5");
cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
std::vector<rtc::FakeFileSystem::File> files;
files.push_back(rtc::FakeFileSystem::File("/dev/video0", ""));
files.push_back(rtc::FakeFileSystem::File("/dev/video5", ""));
files.push_back(rtc::FakeFileSystem::File(
"/proc/video/dev/video0",
"param1: value1\nname: Video Device 1\n param2: value2\n"));
files.push_back(rtc::FakeFileSystem::File(
"/proc/video/dev/video1",
"param1: value1\nname: Bad Device\n param2: value2\n"));
files.push_back(rtc::FakeFileSystem::File(
"/proc/video/dev/video5",
"param1: value1\nname: Video Device 2\n param2: value2\n"));
rtc::FilesystemScope fs(new rtc::FakeFileSystem(files));
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> video_ins;
EXPECT_TRUE(dm->Init());
EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
EXPECT_EQ(2u, video_ins.size());
EXPECT_EQ("Video Device 1", video_ins.at(0).name);
EXPECT_EQ("Video Device 2", video_ins.at(1).name);
}
TEST(DeviceManagerTest, GetVideoCaptureDevices_KUnknown) {
std::vector<std::string> devices;
devices.push_back("/dev/video0");
devices.push_back("/dev/video5");
cricket::V4LLookup::SetV4LLookup(new FakeV4LLookup(devices));
std::vector<rtc::FakeFileSystem::File> files;
files.push_back(rtc::FakeFileSystem::File("/dev/video0", ""));
files.push_back(rtc::FakeFileSystem::File("/dev/video1", ""));
files.push_back(rtc::FakeFileSystem::File("/dev/video5", ""));
rtc::FilesystemScope fs(new rtc::FakeFileSystem(files));
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
std::vector<Device> video_ins;
EXPECT_TRUE(dm->Init());
EXPECT_TRUE(dm->GetVideoCaptureDevices(&video_ins));
EXPECT_EQ(2u, video_ins.size());
EXPECT_EQ("/dev/video0", video_ins.at(0).name);
EXPECT_EQ("/dev/video5", video_ins.at(1).name);
}
#endif // WEBRTC_LINUX
// TODO(noahric): These are flaky on windows on headless machines.
#ifndef WIN32
TEST(DeviceManagerTest, GetWindows) {
if (!rtc::WindowPickerFactory::IsSupported()) {
LOG(LS_INFO) << "skipping test: window capturing is not supported with "
<< "current configuration.";
return;
}
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
dm->SetScreenCapturerFactory(new FakeScreenCapturerFactory());
std::vector<rtc::WindowDescription> descriptions;
EXPECT_TRUE(dm->Init());
if (!dm->GetWindows(&descriptions) || descriptions.empty()) {
LOG(LS_INFO) << "skipping test: window capturing. Does not have any "
<< "windows to capture.";
return;
}
std::unique_ptr<cricket::VideoCapturer> capturer(dm->CreateScreenCapturer(
cricket::ScreencastId(descriptions.front().id())));
EXPECT_FALSE(capturer.get() == NULL);
// TODO(hellner): creating a window capturer and immediately deleting it
// results in "Continuous Build and Test Mainline - Mac opt" failure (crash).
// Remove the following line as soon as this has been resolved.
rtc::Thread::Current()->ProcessMessages(1);
}
TEST(DeviceManagerTest, GetDesktops) {
if (!rtc::WindowPickerFactory::IsSupported()) {
LOG(LS_INFO) << "skipping test: desktop capturing is not supported with "
<< "current configuration.";
return;
}
std::unique_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
dm->SetScreenCapturerFactory(new FakeScreenCapturerFactory());
std::vector<rtc::DesktopDescription> descriptions;
EXPECT_TRUE(dm->Init());
if (!dm->GetDesktops(&descriptions) || descriptions.empty()) {
LOG(LS_INFO) << "skipping test: desktop capturing. Does not have any "
<< "desktops to capture.";
return;
}
std::unique_ptr<cricket::VideoCapturer> capturer(dm->CreateScreenCapturer(
cricket::ScreencastId(descriptions.front().id())));
EXPECT_FALSE(capturer.get() == NULL);
}
#endif // !WIN32
TEST_F(DeviceManagerTestFake, CaptureConstraintsWhitelisted) {
const Device device("white", "white_id");
dm_->SetVideoCaptureDeviceMaxFormat(device.name, kHdFormat);
std::unique_ptr<cricket::VideoCapturer> capturer(
dm_->CreateVideoCapturer(device));
cricket::VideoFormat best_format;
capturer->set_enable_camera_list(true);
EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
EXPECT_EQ(kHdFormat, best_format);
}
TEST_F(DeviceManagerTestFake, CaptureConstraintsNotWhitelisted) {
const Device device("regular", "regular_id");
std::unique_ptr<cricket::VideoCapturer> capturer(
dm_->CreateVideoCapturer(device));
cricket::VideoFormat best_format;
capturer->set_enable_camera_list(true);
EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
EXPECT_EQ(kHdFormat, best_format);
}
TEST_F(DeviceManagerTestFake, CaptureConstraintsUnWhitelisted) {
const Device device("un_white", "un_white_id");
dm_->SetVideoCaptureDeviceMaxFormat(device.name, kHdFormat);
dm_->ClearVideoCaptureDeviceMaxFormat(device.name);
std::unique_ptr<cricket::VideoCapturer> capturer(
dm_->CreateVideoCapturer(device));
cricket::VideoFormat best_format;
capturer->set_enable_camera_list(true);
EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
EXPECT_EQ(kHdFormat, best_format);
}
TEST_F(DeviceManagerTestFake, CaptureConstraintsWildcard) {
const Device device("any_device", "any_device");
dm_->SetVideoCaptureDeviceMaxFormat("*", kHdFormat);
std::unique_ptr<cricket::VideoCapturer> capturer(
dm_->CreateVideoCapturer(device));
cricket::VideoFormat best_format;
capturer->set_enable_camera_list(true);
EXPECT_TRUE(capturer->GetBestCaptureFormat(kHdFormat, &best_format));
EXPECT_EQ(kHdFormat, best_format);
}

View File

@ -1,21 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/dummydevicemanager.h"
namespace cricket {
const char DeviceManagerInterface::kDefaultDeviceName[] = "";
DeviceManagerInterface* DeviceManagerFactory::Create() {
return new DummyDeviceManager();
}
}; // namespace cricket

View File

@ -1,34 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MEDIA_DEVICES_DUMMYDEVICEMANAGER_H_
#define WEBRTC_MEDIA_DEVICES_DUMMYDEVICEMANAGER_H_
#include <vector>
#include "webrtc/media/base/mediacommon.h"
#include "webrtc/media/devices/fakedevicemanager.h"
namespace cricket {
class DummyDeviceManager : public FakeDeviceManager {
public:
DummyDeviceManager() {
std::vector<std::string> devices;
devices.push_back(DeviceManagerInterface::kDefaultDeviceName);
SetAudioInputDevices(devices);
SetAudioOutputDevices(devices);
SetVideoCaptureDevices(devices);
}
};
} // namespace cricket
#endif // WEBRTC_MEDIA_DEVICES_DUMMYDEVICEMANAGER_H_

View File

@ -1,87 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/base/gunit.h"
#include "webrtc/media/devices/dummydevicemanager.h"
using cricket::Device;
using cricket::DummyDeviceManager;
// Test that we startup/shutdown properly.
TEST(DummyDeviceManagerTest, StartupShutdown) {
DummyDeviceManager dm;
EXPECT_TRUE(dm.Init());
dm.Terminate();
}
// Test enumerating capabilities.
TEST(DummyDeviceManagerTest, GetCapabilities) {
DummyDeviceManager dm;
int capabilities = dm.GetCapabilities();
EXPECT_EQ((cricket::AUDIO_SEND | cricket::AUDIO_RECV |
cricket::VIDEO_SEND | cricket::VIDEO_RECV), capabilities);
}
// Test enumerating devices.
TEST(DummyDeviceManagerTest, GetDevices) {
DummyDeviceManager dm;
EXPECT_TRUE(dm.Init());
std::vector<Device> audio_ins, audio_outs, video_ins;
EXPECT_TRUE(dm.GetAudioInputDevices(&audio_ins));
EXPECT_TRUE(dm.GetAudioOutputDevices(&audio_outs));
EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
}
// Test that we return correct ids for default and bogus devices.
TEST(DummyDeviceManagerTest, GetAudioDeviceIds) {
DummyDeviceManager dm;
Device device;
EXPECT_TRUE(dm.Init());
EXPECT_TRUE(dm.GetAudioInputDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
EXPECT_EQ("-1", device.id);
EXPECT_TRUE(dm.GetAudioOutputDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
EXPECT_EQ("-1", device.id);
EXPECT_FALSE(dm.GetAudioInputDevice("_NOT A REAL DEVICE_", &device));
EXPECT_FALSE(dm.GetAudioOutputDevice("_NOT A REAL DEVICE_", &device));
}
// Test that we get the video capture device by name properly.
TEST(DummyDeviceManagerTest, GetVideoDeviceIds) {
DummyDeviceManager dm;
Device device;
EXPECT_TRUE(dm.Init());
EXPECT_FALSE(dm.GetVideoCaptureDevice("_NOT A REAL DEVICE_", &device));
EXPECT_TRUE(dm.GetVideoCaptureDevice(
cricket::DeviceManagerInterface::kDefaultDeviceName, &device));
}
TEST(DummyDeviceManagerTest, VerifyDevicesListsAreCleared) {
const std::string imaginary("_NOT A REAL DEVICE_");
DummyDeviceManager dm;
std::vector<Device> audio_ins, audio_outs, video_ins;
audio_ins.push_back(Device(imaginary, imaginary));
audio_outs.push_back(Device(imaginary, imaginary));
video_ins.push_back(Device(imaginary, imaginary));
EXPECT_TRUE(dm.Init());
EXPECT_TRUE(dm.GetAudioInputDevices(&audio_ins));
EXPECT_TRUE(dm.GetAudioOutputDevices(&audio_outs));
EXPECT_TRUE(dm.GetVideoCaptureDevices(&video_ins));
for (size_t i = 0; i < audio_ins.size(); ++i) {
EXPECT_NE(imaginary, audio_ins[i].name);
}
for (size_t i = 0; i < audio_outs.size(); ++i) {
EXPECT_NE(imaginary, audio_outs[i].name);
}
for (size_t i = 0; i < video_ins.size(); ++i) {
EXPECT_NE(imaginary, video_ins[i].name);
}
}

View File

@ -1,222 +0,0 @@
/*
* Copyright (c) 2008 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MEDIA_DEVICES_FAKEDEVICEMANAGER_H_
#define WEBRTC_MEDIA_DEVICES_FAKEDEVICEMANAGER_H_
#include <memory>
#include <string>
#include <vector>
#include "webrtc/base/window.h"
#include "webrtc/base/windowpicker.h"
#include "webrtc/media/base/fakevideocapturer.h"
#include "webrtc/media/base/mediacommon.h"
#include "webrtc/media/devices/devicemanager.h"
namespace cricket {
class FakeDeviceManager : public DeviceManagerInterface {
public:
FakeDeviceManager() {}
virtual bool Init() {
return true;
}
virtual void Terminate() {
}
virtual int GetCapabilities() {
std::vector<Device> devices;
int caps = VIDEO_RECV;
if (!input_devices_.empty()) {
caps |= AUDIO_SEND;
}
if (!output_devices_.empty()) {
caps |= AUDIO_RECV;
}
if (!vidcap_devices_.empty()) {
caps |= VIDEO_SEND;
}
return caps;
}
virtual bool GetAudioInputDevices(std::vector<Device>* devs) {
*devs = input_devices_;
return true;
}
virtual bool GetAudioOutputDevices(std::vector<Device>* devs) {
*devs = output_devices_;
return true;
}
virtual bool GetAudioInputDevice(const std::string& name, Device* out) {
return GetAudioDevice(true, name, out);
}
virtual bool GetAudioOutputDevice(const std::string& name, Device* out) {
return GetAudioDevice(false, name, out);
}
virtual bool GetVideoCaptureDevices(std::vector<Device>* devs) {
*devs = vidcap_devices_;
return true;
}
virtual void SetVideoDeviceCapturerFactory(
VideoDeviceCapturerFactory* video_device_capturer_factory) {
}
virtual void SetScreenCapturerFactory(
ScreenCapturerFactory* screen_capturer_factory) {
screen_capturer_factory_.reset(screen_capturer_factory);
}
virtual void SetVideoCaptureDeviceMaxFormat(const std::string& usb_id,
const VideoFormat& max_format) {
max_formats_[usb_id] = max_format;
}
bool IsMaxFormatForDevice(const std::string& usb_id,
const VideoFormat& max_format) const {
std::map<std::string, VideoFormat>::const_iterator found =
max_formats_.find(usb_id);
return (found != max_formats_.end()) ?
max_format == found->second :
false;
}
virtual void ClearVideoCaptureDeviceMaxFormat(const std::string& usb_id) {
max_formats_.erase(usb_id);
}
virtual VideoCapturer* CreateVideoCapturer(const Device& device) const {
return new FakeVideoCapturer();
}
virtual VideoCapturer* CreateScreenCapturer(
const ScreencastId& screenid) const {
if (!screen_capturer_factory_) {
return new FakeVideoCapturer();
}
return screen_capturer_factory_->Create(screenid);
}
virtual bool GetWindows(
std::vector<rtc::WindowDescription>* descriptions) {
descriptions->clear();
const uint32_t id = 1u; // Note that 0 is not a valid ID.
const rtc::WindowId window_id =
rtc::WindowId::Cast(id);
std::string title = "FakeWindow";
rtc::WindowDescription window_description(window_id, title);
descriptions->push_back(window_description);
return true;
}
virtual VideoCapturer* CreateWindowCapturer(rtc::WindowId window) {
if (!window.IsValid()) {
return NULL;
}
return new FakeVideoCapturer;
}
virtual bool GetDesktops(
std::vector<rtc::DesktopDescription>* descriptions) {
descriptions->clear();
const int id = 0;
const int valid_index = 0;
const rtc::DesktopId desktop_id =
rtc::DesktopId::Cast(id, valid_index);
std::string title = "FakeDesktop";
rtc::DesktopDescription desktop_description(desktop_id, title);
descriptions->push_back(desktop_description);
return true;
}
virtual VideoCapturer* CreateDesktopCapturer(rtc::DesktopId desktop) {
if (!desktop.IsValid()) {
return NULL;
}
return new FakeVideoCapturer;
}
virtual bool GetDefaultVideoCaptureDevice(Device* device) {
if (vidcap_devices_.empty()) {
return false;
}
*device = vidcap_devices_[0];
return true;
}
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
bool QtKitToSgDevice(const std::string& qtkit_name, Device* out) {
out->name = qtkit_name;
out->id = "sg:" + qtkit_name;
return true;
}
#endif
void SetAudioInputDevices(const std::vector<std::string>& devices) {
input_devices_.clear();
for (size_t i = 0; i < devices.size(); ++i) {
input_devices_.push_back(Device(devices[i],
static_cast<int>(i)));
}
SignalDevicesChange();
}
void SetAudioOutputDevices(const std::vector<std::string>& devices) {
output_devices_.clear();
for (size_t i = 0; i < devices.size(); ++i) {
output_devices_.push_back(Device(devices[i],
static_cast<int>(i)));
}
SignalDevicesChange();
}
void SetVideoCaptureDevices(const std::vector<std::string>& devices) {
vidcap_devices_.clear();
for (size_t i = 0; i < devices.size(); ++i) {
vidcap_devices_.push_back(Device(devices[i],
static_cast<int>(i)));
}
SignalDevicesChange();
}
virtual bool GetVideoCaptureDevice(const std::string& name,
Device* out) {
if (vidcap_devices_.empty())
return false;
// If the name is empty, return the default device.
if (name.empty() || name == kDefaultDeviceName) {
*out = vidcap_devices_[0];
return true;
}
return FindDeviceByName(vidcap_devices_, name, out);
}
bool GetAudioDevice(bool is_input, const std::string& name,
Device* out) {
// If the name is empty, return the default device.
if (name.empty() || name == kDefaultDeviceName) {
*out = Device(name, -1);
return true;
}
return FindDeviceByName((is_input ? input_devices_ : output_devices_),
name, out);
}
static bool FindDeviceByName(const std::vector<Device>& devices,
const std::string& name,
Device* out) {
for (std::vector<Device>::const_iterator it = devices.begin();
it != devices.end(); ++it) {
if (name == it->name) {
*out = *it;
return true;
}
}
return false;
}
private:
std::vector<Device> input_devices_;
std::vector<Device> output_devices_;
std::vector<Device> vidcap_devices_;
std::map<std::string, VideoFormat> max_formats_;
std::unique_ptr<
ScreenCapturerFactory> screen_capturer_factory_;
};
} // namespace cricket
#endif // WEBRTC_MEDIA_DEVICES_FAKEDEVICEMANAGER_H_

View File

@ -1,159 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include "webrtc/media/devices/deviceinfo.h"
#include "webrtc/base/common.h" // for ASSERT
#include "webrtc/media/devices/libudevsymboltable.h"
namespace cricket {
class ScopedLibUdev {
public:
static ScopedLibUdev* Create() {
ScopedLibUdev* ret_val = new ScopedLibUdev();
if (!ret_val->Init()) {
delete ret_val;
return NULL;
}
return ret_val;
}
~ScopedLibUdev() {
libudev_.Unload();
}
LibUDevSymbolTable* instance() { return &libudev_; }
private:
ScopedLibUdev() {}
bool Init() {
return libudev_.Load() &&
!IsWrongLibUDevAbiVersion(libudev_.GetDllHandle());
}
LibUDevSymbolTable libudev_;
};
class ScopedUdev {
public:
explicit ScopedUdev(LibUDevSymbolTable* libudev) : libudev_(libudev) {
udev_ = libudev_->udev_new()();
}
~ScopedUdev() {
if (udev_) libudev_->udev_unref()(udev_);
}
udev* instance() { return udev_; }
private:
LibUDevSymbolTable* libudev_;
udev* udev_;
};
class ScopedUdevEnumerate {
public:
ScopedUdevEnumerate(LibUDevSymbolTable* libudev, udev* udev)
: libudev_(libudev) {
enumerate_ = libudev_->udev_enumerate_new()(udev);
}
~ScopedUdevEnumerate() {
if (enumerate_) libudev_->udev_enumerate_unref()(enumerate_);
}
udev_enumerate* instance() { return enumerate_; }
private:
LibUDevSymbolTable* libudev_;
udev_enumerate* enumerate_;
};
bool GetUsbProperty(const Device& device, const char* property_name,
std::string* property) {
std::unique_ptr<ScopedLibUdev> libudev_context(ScopedLibUdev::Create());
if (!libudev_context) {
return false;
}
ScopedUdev udev_context(libudev_context->instance());
if (!udev_context.instance()) {
return false;
}
ScopedUdevEnumerate enumerate_context(libudev_context->instance(),
udev_context.instance());
if (!enumerate_context.instance()) {
return false;
}
libudev_context->instance()->udev_enumerate_add_match_subsystem()(
enumerate_context.instance(), "video4linux");
libudev_context->instance()->udev_enumerate_scan_devices()(
enumerate_context.instance());
udev_list_entry* devices =
libudev_context->instance()->udev_enumerate_get_list_entry()(
enumerate_context.instance());
if (!devices) {
return false;
}
udev_list_entry* dev_list_entry = NULL;
const char* property_value = NULL;
// Macro that expands to a for-loop over the devices.
for (dev_list_entry = devices; dev_list_entry != NULL;
dev_list_entry = libudev_context->instance()->
udev_list_entry_get_next()(dev_list_entry)) {
const char* path = libudev_context->instance()->udev_list_entry_get_name()(
dev_list_entry);
if (!path) continue;
udev_device* dev =
libudev_context->instance()->udev_device_new_from_syspath()(
udev_context.instance(), path);
if (!dev) continue;
const char* device_node =
libudev_context->instance()->udev_device_get_devnode()(dev);
if (!device_node || device.id.compare(device_node) != 0) {
continue;
}
dev = libudev_context->instance()->
udev_device_get_parent_with_subsystem_devtype()(
dev, "usb", "usb_device");
if (!dev) continue;
property_value = libudev_context->instance()->
udev_device_get_sysattr_value()(
dev, property_name);
break;
}
if (!property_value) {
return false;
}
property->assign(property_value);
return true;
}
bool GetUsbId(const Device& device, std::string* usb_id) {
std::string id_vendor;
std::string id_product;
if (!GetUsbProperty(device, "idVendor", &id_vendor)) {
return false;
}
if (!GetUsbProperty(device, "idProduct", &id_product)) {
return false;
}
usb_id->clear();
usb_id->append(id_vendor);
usb_id->append(":");
usb_id->append(id_product);
return true;
}
bool GetUsbVersion(const Device& device, std::string* usb_version) {
return GetUsbProperty(device, "version", usb_version);
}
} // namespace cricket

View File

@ -1,396 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/linuxdevicemanager.h"
#include <unistd.h>
#include <memory>
#include "webrtc/base/fileutils.h"
#include "webrtc/base/linux.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/physicalsocketserver.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/base/thread.h"
#include "webrtc/media/base/mediacommon.h"
#include "webrtc/media/devices/libudevsymboltable.h"
#include "webrtc/media/devices/v4llookup.h"
#include "webrtc/sound/platformsoundsystem.h"
#include "webrtc/sound/platformsoundsystemfactory.h"
#include "webrtc/sound/sounddevicelocator.h"
#include "webrtc/sound/soundsysteminterface.h"
namespace cricket {
DeviceManagerInterface* DeviceManagerFactory::Create() {
return new LinuxDeviceManager();
}
class LinuxDeviceWatcher
: public DeviceWatcher,
private rtc::Dispatcher {
public:
explicit LinuxDeviceWatcher(DeviceManagerInterface* dm);
virtual ~LinuxDeviceWatcher();
virtual bool Start();
virtual void Stop();
private:
virtual uint32_t GetRequestedEvents();
virtual void OnPreEvent(uint32_t ff);
virtual void OnEvent(uint32_t ff, int err);
virtual int GetDescriptor();
virtual bool IsDescriptorClosed();
DeviceManagerInterface* manager_;
LibUDevSymbolTable libudev_;
struct udev* udev_;
struct udev_monitor* udev_monitor_;
bool registered_;
};
static const char* const kFilteredAudioDevicesName[] = {
#if defined(CHROMEOS)
"surround40:",
"surround41:",
"surround50:",
"surround51:",
"surround71:",
"iec958:", // S/PDIF
#endif
NULL,
};
static const char* kFilteredVideoDevicesName[] = {
NULL,
};
LinuxDeviceManager::LinuxDeviceManager()
: sound_system_(new rtc::PlatformSoundSystemFactory()) {
set_watcher(new LinuxDeviceWatcher(this));
}
LinuxDeviceManager::~LinuxDeviceManager() {
}
bool LinuxDeviceManager::GetAudioDevices(bool input,
std::vector<Device>* devs) {
devs->clear();
if (!sound_system_.get()) {
return false;
}
rtc::SoundSystemInterface::SoundDeviceLocatorList list;
bool success;
if (input) {
success = sound_system_->EnumerateCaptureDevices(&list);
} else {
success = sound_system_->EnumeratePlaybackDevices(&list);
}
if (!success) {
LOG(LS_ERROR) << "Can't enumerate devices";
sound_system_.release();
return false;
}
// We have to start the index at 1 because webrtc VoiceEngine puts the default
// device at index 0, but Enumerate(Capture|Playback)Devices does not include
// a locator for the default device.
int index = 1;
for (rtc::SoundSystemInterface::SoundDeviceLocatorList::iterator i = list.begin();
i != list.end();
++i, ++index) {
devs->push_back(Device((*i)->name(), index));
}
rtc::SoundSystemInterface::ClearSoundDeviceLocatorList(&list);
sound_system_.release();
return FilterDevices(devs, kFilteredAudioDevicesName);
}
static const std::string kVideoMetaPathK2_4("/proc/video/dev/");
static const std::string kVideoMetaPathK2_6("/sys/class/video4linux/");
enum MetaType { M2_4, M2_6, NONE };
static void ScanDeviceDirectory(const std::string& devdir,
std::vector<Device>* devices) {
std::unique_ptr<rtc::DirectoryIterator> directoryIterator(
rtc::Filesystem::IterateDirectory());
if (directoryIterator->Iterate(rtc::Pathname(devdir))) {
do {
std::string filename = directoryIterator->Name();
std::string device_name = devdir + filename;
if (!directoryIterator->IsDots()) {
if (filename.find("video") == 0 &&
V4LLookup::IsV4L2Device(device_name)) {
devices->push_back(Device(device_name, device_name));
}
}
} while (directoryIterator->Next());
}
}
static std::string GetVideoDeviceNameK2_6(const std::string& device_meta_path) {
std::string device_name;
std::unique_ptr<rtc::FileStream> device_meta_stream(
rtc::Filesystem::OpenFile(device_meta_path, "r"));
if (device_meta_stream) {
if (device_meta_stream->ReadLine(&device_name) != rtc::SR_SUCCESS) {
LOG(LS_ERROR) << "Failed to read V4L2 device meta " << device_meta_path;
}
device_meta_stream->Close();
}
return device_name;
}
static std::string Trim(const std::string& s, const std::string& drop = " \t") {
std::string::size_type first = s.find_first_not_of(drop);
std::string::size_type last = s.find_last_not_of(drop);
if (first == std::string::npos || last == std::string::npos)
return std::string("");
return s.substr(first, last - first + 1);
}
static std::string GetVideoDeviceNameK2_4(const std::string& device_meta_path) {
rtc::ConfigParser::MapVector all_values;
rtc::ConfigParser config_parser;
rtc::FileStream* file_stream =
rtc::Filesystem::OpenFile(device_meta_path, "r");
if (file_stream == NULL) return "";
config_parser.Attach(file_stream);
config_parser.Parse(&all_values);
for (rtc::ConfigParser::MapVector::iterator i = all_values.begin();
i != all_values.end(); ++i) {
rtc::ConfigParser::SimpleMap::iterator device_name_i =
i->find("name");
if (device_name_i != i->end()) {
return device_name_i->second;
}
}
return "";
}
static std::string GetVideoDeviceName(MetaType meta,
const std::string& device_file_name) {
std::string device_meta_path;
std::string device_name;
std::string meta_file_path;
if (meta == M2_6) {
meta_file_path = kVideoMetaPathK2_6 + device_file_name + "/name";
LOG(LS_INFO) << "Trying " + meta_file_path;
device_name = GetVideoDeviceNameK2_6(meta_file_path);
if (device_name.empty()) {
meta_file_path = kVideoMetaPathK2_6 + device_file_name + "/model";
LOG(LS_INFO) << "Trying " << meta_file_path;
device_name = GetVideoDeviceNameK2_6(meta_file_path);
}
} else {
meta_file_path = kVideoMetaPathK2_4 + device_file_name;
LOG(LS_INFO) << "Trying " << meta_file_path;
device_name = GetVideoDeviceNameK2_4(meta_file_path);
}
if (device_name.empty()) {
device_name = "/dev/" + device_file_name;
LOG(LS_ERROR)
<< "Device name not found, defaulting to device path " << device_name;
}
LOG(LS_INFO) << "Name for " << device_file_name << " is " << device_name;
return Trim(device_name);
}
static void ScanV4L2Devices(std::vector<Device>* devices) {
LOG(LS_INFO) << ("Enumerating V4L2 devices");
MetaType meta;
std::string metadata_dir;
std::unique_ptr<rtc::DirectoryIterator> directoryIterator(
rtc::Filesystem::IterateDirectory());
// Try and guess kernel version
if (directoryIterator->Iterate(kVideoMetaPathK2_6)) {
meta = M2_6;
metadata_dir = kVideoMetaPathK2_6;
} else if (directoryIterator->Iterate(kVideoMetaPathK2_4)) {
meta = M2_4;
metadata_dir = kVideoMetaPathK2_4;
} else {
meta = NONE;
}
if (meta != NONE) {
LOG(LS_INFO) << "V4L2 device metadata found at " << metadata_dir;
do {
std::string filename = directoryIterator->Name();
if (filename.find("video") == 0) {
std::string device_path = "/dev/" + filename;
if (V4LLookup::IsV4L2Device(device_path)) {
devices->push_back(
Device(GetVideoDeviceName(meta, filename), device_path));
}
}
} while (directoryIterator->Next());
} else {
LOG(LS_ERROR) << "Unable to detect v4l2 metadata directory";
}
if (devices->size() == 0) {
LOG(LS_INFO) << "Plan B. Scanning all video devices in /dev directory";
ScanDeviceDirectory("/dev/", devices);
}
LOG(LS_INFO) << "Total V4L2 devices found : " << devices->size();
}
bool LinuxDeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
devices->clear();
ScanV4L2Devices(devices);
return FilterDevices(devices, kFilteredVideoDevicesName);
}
LinuxDeviceWatcher::LinuxDeviceWatcher(DeviceManagerInterface* dm)
: DeviceWatcher(dm),
manager_(dm),
udev_(NULL),
udev_monitor_(NULL),
registered_(false) {
}
LinuxDeviceWatcher::~LinuxDeviceWatcher() {
}
static rtc::PhysicalSocketServer* CurrentSocketServer() {
rtc::SocketServer* ss =
rtc::ThreadManager::Instance()->WrapCurrentThread()->socketserver();
return reinterpret_cast<rtc::PhysicalSocketServer*>(ss);
}
bool LinuxDeviceWatcher::Start() {
// We deliberately return true in the failure paths here because libudev is
// not a critical component of a Linux system so it may not be present/usable,
// and we don't want to halt LinuxDeviceManager initialization in such a case.
if (!libudev_.Load() || IsWrongLibUDevAbiVersion(libudev_.GetDllHandle())) {
LOG(LS_WARNING)
<< "libudev not present/usable; LinuxDeviceWatcher disabled";
return true;
}
udev_ = libudev_.udev_new()();
if (!udev_) {
LOG_ERR(LS_ERROR) << "udev_new()";
return true;
}
// The second argument here is the event source. It can be either "kernel" or
// "udev", but "udev" is the only correct choice. Apps listen on udev and the
// udev daemon in turn listens on the kernel.
udev_monitor_ = libudev_.udev_monitor_new_from_netlink()(udev_, "udev");
if (!udev_monitor_) {
LOG_ERR(LS_ERROR) << "udev_monitor_new_from_netlink()";
return true;
}
// We only listen for changes in the video devices. Audio devices are more or
// less unimportant because receiving device change notifications really only
// matters for broadcasting updated send/recv capabilities based on whether
// there is at least one device available, and almost all computers have at
// least one audio device. Also, PulseAudio device notifications don't come
// from the udev daemon, they come from the PulseAudio daemon, so we'd only
// want to listen for audio device changes from udev if using ALSA. For
// simplicity, we don't bother with any audio stuff at all.
if (libudev_.udev_monitor_filter_add_match_subsystem_devtype()(
udev_monitor_, "video4linux", NULL) < 0) {
LOG_ERR(LS_ERROR) << "udev_monitor_filter_add_match_subsystem_devtype()";
return true;
}
if (libudev_.udev_monitor_enable_receiving()(udev_monitor_) < 0) {
LOG_ERR(LS_ERROR) << "udev_monitor_enable_receiving()";
return true;
}
CurrentSocketServer()->Add(this);
registered_ = true;
return true;
}
void LinuxDeviceWatcher::Stop() {
if (registered_) {
CurrentSocketServer()->Remove(this);
registered_ = false;
}
if (udev_monitor_) {
libudev_.udev_monitor_unref()(udev_monitor_);
udev_monitor_ = NULL;
}
if (udev_) {
libudev_.udev_unref()(udev_);
udev_ = NULL;
}
libudev_.Unload();
}
uint32_t LinuxDeviceWatcher::GetRequestedEvents() {
return rtc::DE_READ;
}
void LinuxDeviceWatcher::OnPreEvent(uint32_t ff) {
// Nothing to do.
}
void LinuxDeviceWatcher::OnEvent(uint32_t ff, int err) {
udev_device* device = libudev_.udev_monitor_receive_device()(udev_monitor_);
if (!device) {
// Probably the socket connection to the udev daemon was terminated (perhaps
// the daemon crashed or is being restarted?).
LOG_ERR(LS_WARNING) << "udev_monitor_receive_device()";
// Stop listening to avoid potential livelock (an fd with EOF in it is
// always considered readable).
CurrentSocketServer()->Remove(this);
registered_ = false;
return;
}
// Else we read the device successfully.
// Since we already have our own filesystem-based device enumeration code, we
// simply re-enumerate rather than inspecting the device event.
libudev_.udev_device_unref()(device);
manager_->SignalDevicesChange();
}
int LinuxDeviceWatcher::GetDescriptor() {
return libudev_.udev_monitor_get_fd()(udev_monitor_);
}
bool LinuxDeviceWatcher::IsDescriptorClosed() {
// If it is closed then we will just get an error in
// udev_monitor_receive_device and unregister, so we don't need to check for
// it separately.
return false;
}
}; // namespace cricket

View File

@ -1,38 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MEDIA_DEVICES_LINUXDEVICEMANAGER_H_
#define WEBRTC_MEDIA_DEVICES_LINUXDEVICEMANAGER_H_
#include <string>
#include <vector>
#include "webrtc/base/sigslot.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/media/devices/devicemanager.h"
#include "webrtc/sound/soundsystemfactory.h"
namespace cricket {
class LinuxDeviceManager : public DeviceManager {
public:
LinuxDeviceManager();
virtual ~LinuxDeviceManager();
virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
private:
virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
rtc::SoundSystemHandle sound_system_;
};
} // namespace cricket
#endif // WEBRTC_MEDIA_DEVICES_LINUXDEVICEMANAGER_H_

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/deviceinfo.h"
namespace cricket {
bool GetUsbId(const Device& device, std::string* usb_id) {
// Both PID and VID are 4 characters.
const int id_size = 4;
if (device.id.size() < 2 * id_size) {
return false;
}
// The last characters of device id is a concatenation of VID and then PID.
const size_t vid_location = device.id.size() - 2 * id_size;
std::string id_vendor = device.id.substr(vid_location, id_size);
const size_t pid_location = device.id.size() - id_size;
std::string id_product = device.id.substr(pid_location, id_size);
usb_id->clear();
usb_id->append(id_vendor);
usb_id->append(":");
usb_id->append(id_product);
return true;
}
bool GetUsbVersion(const Device& device, std::string* usb_version) {
return false;
}
} // namespace cricket

View File

@ -1,181 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/macdevicemanager.h"
#include <memory>
#include <CoreAudio/CoreAudio.h>
#include <QuickTime/QuickTime.h>
#include "webrtc/base/logging.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/base/thread.h"
#include "webrtc/media/base/mediacommon.h"
class DeviceWatcherImpl;
namespace cricket {
DeviceManagerInterface* DeviceManagerFactory::Create() {
return new MacDeviceManager();
}
class MacDeviceWatcher : public DeviceWatcher {
public:
explicit MacDeviceWatcher(DeviceManagerInterface* dm);
virtual ~MacDeviceWatcher();
virtual bool Start();
virtual void Stop();
private:
DeviceManagerInterface* manager_;
DeviceWatcherImpl* impl_;
};
static const char* kFilteredAudioDevicesName[] = {
NULL,
};
// TODO(tommyw): Try to get hold of a copy of Final Cut to understand why we
// crash while scanning their components on OS X.
static const char* const kFilteredVideoDevicesName[] = {
"DVCPRO HD", // Final cut
"Sonix SN9C201p", // Crashes in OpenAComponent and CloseComponent
NULL,
};
static const UInt32 kAudioDeviceNameLength = 64;
// Obj-C functions defined in macdevicemanagermm.mm
// TODO(ronghuawu): have a shared header for these function defines.
extern DeviceWatcherImpl* CreateDeviceWatcherCallback(
DeviceManagerInterface* dm);
extern void ReleaseDeviceWatcherCallback(DeviceWatcherImpl* impl);
extern bool GetAVFoundationVideoDevices(std::vector<Device>* out);
static bool GetAudioDeviceIDs(bool inputs, std::vector<AudioDeviceID>* out);
static bool GetAudioDeviceName(AudioDeviceID id, bool input, std::string* out);
MacDeviceManager::MacDeviceManager() {
set_watcher(new MacDeviceWatcher(this));
}
MacDeviceManager::~MacDeviceManager() {
}
bool MacDeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
devices->clear();
if (!GetAVFoundationVideoDevices(devices)) {
return false;
}
return FilterDevices(devices, kFilteredVideoDevicesName);
}
bool MacDeviceManager::GetAudioDevices(bool input,
std::vector<Device>* devs) {
devs->clear();
std::vector<AudioDeviceID> dev_ids;
bool ret = GetAudioDeviceIDs(input, &dev_ids);
if (!ret) {
return false;
}
for (size_t i = 0; i < dev_ids.size(); ++i) {
std::string name;
if (GetAudioDeviceName(dev_ids[i], input, &name)) {
devs->push_back(Device(name, dev_ids[i]));
}
}
return FilterDevices(devs, kFilteredAudioDevicesName);
}
static bool GetAudioDeviceIDs(bool input,
std::vector<AudioDeviceID>* out_dev_ids) {
UInt32 propsize;
OSErr err = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
&propsize, NULL);
if (0 != err) {
LOG(LS_ERROR) << "Couldn't get information about property, "
<< "so no device list acquired.";
return false;
}
size_t num_devices = propsize / sizeof(AudioDeviceID);
std::unique_ptr<AudioDeviceID[]> device_ids(
new AudioDeviceID[num_devices]);
err = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
&propsize, device_ids.get());
if (0 != err) {
LOG(LS_ERROR) << "Failed to get device ids, "
<< "so no device listing acquired.";
return false;
}
for (size_t i = 0; i < num_devices; ++i) {
AudioDeviceID an_id = device_ids[i];
// find out the number of channels for this direction
// (input/output) on this device -
// we'll ignore anything with no channels.
err = AudioDeviceGetPropertyInfo(an_id, 0, input,
kAudioDevicePropertyStreams,
&propsize, NULL);
if (0 == err) {
unsigned num_channels = propsize / sizeof(AudioStreamID);
if (0 < num_channels) {
out_dev_ids->push_back(an_id);
}
} else {
LOG(LS_ERROR) << "No property info for stream property for device id "
<< an_id << "(is_input == " << input
<< "), so not including it in the list.";
}
}
return true;
}
static bool GetAudioDeviceName(AudioDeviceID id,
bool input,
std::string* out_name) {
UInt32 nameLength = kAudioDeviceNameLength;
char name[kAudioDeviceNameLength + 1];
OSErr err = AudioDeviceGetProperty(id, 0, input,
kAudioDevicePropertyDeviceName,
&nameLength, name);
if (0 != err) {
LOG(LS_ERROR) << "No name acquired for device id " << id;
return false;
}
*out_name = name;
return true;
}
MacDeviceWatcher::MacDeviceWatcher(DeviceManagerInterface* manager)
: DeviceWatcher(manager),
manager_(manager),
impl_(NULL) {
}
MacDeviceWatcher::~MacDeviceWatcher() {
}
bool MacDeviceWatcher::Start() {
if (!impl_) {
impl_ = CreateDeviceWatcherCallback(manager_);
}
return impl_ != NULL;
}
void MacDeviceWatcher::Stop() {
if (impl_) {
ReleaseDeviceWatcherCallback(impl_);
impl_ = NULL;
}
}
}; // namespace cricket

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MEDIA_DEVICES_MACDEVICEMANAGER_H_
#define WEBRTC_MEDIA_DEVICES_MACDEVICEMANAGER_H_
#include <string>
#include <vector>
#include "webrtc/base/sigslot.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/media/devices/devicemanager.h"
namespace cricket {
class DeviceWatcher;
class MacDeviceManager : public DeviceManager {
public:
MacDeviceManager();
virtual ~MacDeviceManager();
virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
private:
virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
bool FilterDevice(const Device& d);
};
} // namespace cricket
#endif // WEBRTC_MEDIA_DEVICES_MACDEVICEMANAGER_H_

View File

@ -1,175 +0,0 @@
/*
* Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// support GCC compiler
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#include "webrtc/media/devices/devicemanager.h"
#import <assert.h>
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
#import <AVFoundation/AVFoundation.h>
#endif
#endif
#import <QTKit/QTKit.h>
#include "webrtc/base/logging.h"
@interface DeviceWatcherImpl : NSObject {
@private
cricket::DeviceManagerInterface* manager_;
}
- (id)init:(cricket::DeviceManagerInterface*)manager;
- (void)onDevicesChanged:(NSNotification*)notification;
@end
@implementation DeviceWatcherImpl
- (id)init:(cricket::DeviceManagerInterface*)manager {
if ((self = [super init])) {
assert(manager != NULL);
manager_ = manager;
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onDevicesChanged:)
name:QTCaptureDeviceWasConnectedNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onDevicesChanged:)
name:QTCaptureDeviceWasDisconnectedNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
#if !__has_feature(objc_arc)
[super dealloc];
#endif
}
- (void)onDevicesChanged:(NSNotification*)notification {
manager_->SignalDevicesChange();
}
@end
namespace cricket {
DeviceWatcherImpl* CreateDeviceWatcherCallback(
DeviceManagerInterface* manager) {
DeviceWatcherImpl* impl;
#if !__has_feature(objc_arc)
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
#else
@autoreleasepool
#endif
{ impl = [[DeviceWatcherImpl alloc] init:manager]; }
#if !__has_feature(objc_arc)
[pool drain];
#endif
return impl;
}
void ReleaseDeviceWatcherCallback(DeviceWatcherImpl* watcher) {
#if !__has_feature(objc_arc)
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
[watcher release];
[pool drain];
#endif
}
bool GetQTKitVideoDevices(std::vector<Device>* devices) {
#if !__has_feature(objc_arc)
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
#else
@autoreleasepool
#endif
{
NSArray* qt_capture_devices =
[QTCaptureDevice inputDevicesWithMediaType:QTMediaTypeVideo];
NSUInteger count = [qt_capture_devices count];
LOG(LS_INFO) << count << " capture device(s) found:";
for (QTCaptureDevice* qt_capture_device in qt_capture_devices) {
static NSString* const kFormat = @"localizedDisplayName: \"%@\", "
@"modelUniqueID: \"%@\", uniqueID \"%@\", isConnected: %d, "
@"isOpen: %d, isInUseByAnotherApplication: %d";
NSString* info = [NSString
stringWithFormat:kFormat,
[qt_capture_device localizedDisplayName],
[qt_capture_device modelUniqueID],
[qt_capture_device uniqueID],
[qt_capture_device isConnected],
[qt_capture_device isOpen],
[qt_capture_device isInUseByAnotherApplication]];
LOG(LS_INFO) << [info UTF8String];
std::string name([[qt_capture_device localizedDisplayName] UTF8String]);
devices->push_back(
Device(name, [[qt_capture_device uniqueID] UTF8String]));
}
}
#if !__has_feature(objc_arc)
[pool drain];
#endif
return true;
}
bool GetAVFoundationVideoDevices(std::vector<Device>* devices) {
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
#if __MAC_OS_X_VERSION_MAX_ALLOWED >=1070
if (![AVCaptureDevice class]) {
// Fallback to using QTKit if AVFoundation is not available
return GetQTKitVideoDevices(devices);
}
#if !__has_feature(objc_arc)
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
#else
@autoreleasepool
#endif
{
NSArray* capture_devices = [AVCaptureDevice devices];
LOG(LS_INFO) << [capture_devices count] << " capture device(s) found:";
for (AVCaptureDevice* capture_device in capture_devices) {
if ([capture_device hasMediaType:AVMediaTypeVideo] ||
[capture_device hasMediaType:AVMediaTypeMuxed]) {
static NSString* const kFormat = @"localizedName: \"%@\", "
@"modelID: \"%@\", uniqueID \"%@\", isConnected: %d, "
@"isInUseByAnotherApplication: %d";
NSString* info = [NSString
stringWithFormat:kFormat,
[capture_device localizedName],
[capture_device modelID],
[capture_device uniqueID],
[capture_device isConnected],
[capture_device isInUseByAnotherApplication]];
LOG(LS_INFO) << [info UTF8String];
std::string name([[capture_device localizedName] UTF8String]);
devices->push_back(
Device(name, [[capture_device uniqueID] UTF8String]));
}
}
}
#if !__has_feature(objc_arc)
[pool drain];
#endif
return true;
#else // __MAC_OS_X_VERSION_MAX_ALLOWED >=1070
return GetQTKitVideoDevices(devices);
#endif // __MAC_OS_X_VERSION_MAX_ALLOWED >=1070
#else // __MAC_OS_X_VERSION_MAX_ALLOWED
return GetQTKitVideoDevices(devices);
#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
}
} // namespace cricket

View File

@ -1,62 +0,0 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <memory>
#include "webrtc/base/arraysize.h"
#include "webrtc/media/devices/devicemanager.h"
#include "webrtc/modules/video_capture/video_capture_factory.h"
namespace cricket {
class MobileDeviceManager : public DeviceManager {
public:
MobileDeviceManager();
virtual ~MobileDeviceManager();
virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
};
MobileDeviceManager::MobileDeviceManager() {
// We don't expect available devices to change on Android/iOS, so use a
// do-nothing watcher.
set_watcher(new DeviceWatcher(this));
}
MobileDeviceManager::~MobileDeviceManager() {}
bool MobileDeviceManager::GetVideoCaptureDevices(std::vector<Device>* devs) {
devs->clear();
std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(
webrtc::VideoCaptureFactory::CreateDeviceInfo(0));
if (!info)
return false;
uint32_t num_cams = info->NumberOfDevices();
char id[256];
char name[256];
for (uint32_t i = 0; i < num_cams; ++i) {
if (info->GetDeviceName(i, name, arraysize(name), id, arraysize(id)))
continue;
devs->push_back(Device(name, id));
}
return true;
}
DeviceManagerInterface* DeviceManagerFactory::Create() {
return new MobileDeviceManager();
}
bool GetUsbId(const Device& device, std::string* usb_id) { return false; }
bool GetUsbVersion(const Device& device, std::string* usb_version) {
return false;
}
} // namespace cricket

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/deviceinfo.h"
namespace cricket {
bool GetUsbId(const Device& device, std::string* usb_id) {
// Both PID and VID are 4 characters.
const int id_size = 4;
const char vid[] = "vid_"; // Also contains '\0'.
const size_t vid_location = device.id.find(vid);
if (vid_location == std::string::npos ||
vid_location + sizeof(vid) - 1 + id_size > device.id.size()) {
return false;
}
const char pid[] = "pid_";
const size_t pid_location = device.id.find(pid);
if (pid_location == std::string::npos ||
pid_location + sizeof(pid) - 1 + id_size > device.id.size()) {
return false;
}
std::string id_vendor = device.id.substr(vid_location + sizeof(vid) - 1,
id_size);
std::string id_product = device.id.substr(pid_location + sizeof(pid) -1,
id_size);
usb_id->clear();
usb_id->append(id_vendor);
usb_id->append(":");
usb_id->append(id_product);
return true;
}
bool GetUsbVersion(const Device& device, std::string* usb_version) {
return false;
}
} // namespace cricket

View File

@ -1,398 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/media/devices/win32devicemanager.h"
#include <atlbase.h>
#include <dbt.h>
#include <strmif.h> // must come before ks.h
#include <ks.h>
#include <ksmedia.h>
#include <mmdeviceapi.h>
#include <mmsystem.h>
#include <functiondiscoverykeys_devpkey.h>
#include <uuids.h>
// PKEY_AudioEndpoint_GUID isn't included in uuid.lib and we don't want
// to define INITGUID in order to define all the uuids in this object file
// as it will conflict with uuid.lib (multiply defined symbols).
// So our workaround is to define this one missing symbol here manually.
// See: https://code.google.com/p/webrtc/issues/detail?id=3996
EXTERN_C const PROPERTYKEY PKEY_AudioEndpoint_GUID = { {
0x1da5d803, 0xd492, 0x4edd, {
0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e
} }, 4
};
#include "webrtc/base/arraysize.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/stringutils.h"
#include "webrtc/base/thread.h"
#include "webrtc/base/win32.h" // ToUtf8
#include "webrtc/base/win32window.h"
#include "webrtc/media/base/mediacommon.h"
#ifdef HAVE_LOGITECH_HEADERS
#include "third_party/logitech/files/logitechquickcam.h"
#endif
namespace cricket {
DeviceManagerInterface* DeviceManagerFactory::Create() {
return new Win32DeviceManager();
}
class Win32DeviceWatcher
: public DeviceWatcher,
public rtc::Win32Window {
public:
explicit Win32DeviceWatcher(Win32DeviceManager* dm);
virtual ~Win32DeviceWatcher();
virtual bool Start();
virtual void Stop();
private:
HDEVNOTIFY Register(REFGUID guid);
void Unregister(HDEVNOTIFY notify);
virtual bool OnMessage(UINT msg, WPARAM wp, LPARAM lp, LRESULT& result);
Win32DeviceManager* manager_;
HDEVNOTIFY audio_notify_;
HDEVNOTIFY video_notify_;
};
static const char* kFilteredAudioDevicesName[] = {
NULL,
};
static const char* const kFilteredVideoDevicesName[] = {
"Asus virtual Camera", // Bad Asus desktop virtual cam
"Bluetooth Video", // Bad Sony viao bluetooth sharing driver
NULL,
};
static const wchar_t kFriendlyName[] = L"FriendlyName";
static const wchar_t kDevicePath[] = L"DevicePath";
static const char kUsbDevicePathPrefix[] = "\\\\?\\usb";
static bool GetDevices(const CLSID& catid, std::vector<Device>* out);
static bool GetCoreAudioDevices(bool input, std::vector<Device>* devs);
static bool GetWaveDevices(bool input, std::vector<Device>* devs);
Win32DeviceManager::Win32DeviceManager()
: need_couninitialize_(false) {
set_watcher(new Win32DeviceWatcher(this));
}
Win32DeviceManager::~Win32DeviceManager() {
if (initialized()) {
Terminate();
}
}
bool Win32DeviceManager::Init() {
if (!initialized()) {
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
need_couninitialize_ = SUCCEEDED(hr);
if (FAILED(hr)) {
LOG(LS_ERROR) << "CoInitialize failed, hr=" << hr;
if (hr != RPC_E_CHANGED_MODE) {
return false;
}
}
if (!watcher()->Start()) {
return false;
}
set_initialized(true);
}
return true;
}
void Win32DeviceManager::Terminate() {
if (initialized()) {
watcher()->Stop();
if (need_couninitialize_) {
CoUninitialize();
need_couninitialize_ = false;
}
set_initialized(false);
}
}
bool Win32DeviceManager::GetDefaultVideoCaptureDevice(Device* device) {
bool ret = false;
// If there are multiple capture devices, we want the first USB one.
// This avoids issues with defaulting to virtual cameras or grabber cards.
std::vector<Device> devices;
ret = (GetVideoCaptureDevices(&devices) && !devices.empty());
if (ret) {
*device = devices[0];
for (size_t i = 0; i < devices.size(); ++i) {
if (strnicmp(devices[i].id.c_str(), kUsbDevicePathPrefix,
arraysize(kUsbDevicePathPrefix) - 1) == 0) {
*device = devices[i];
break;
}
}
}
return ret;
}
bool Win32DeviceManager::GetAudioDevices(bool input,
std::vector<Device>* devs) {
devs->clear();
if (rtc::IsWindowsVistaOrLater()) {
if (!GetCoreAudioDevices(input, devs))
return false;
} else {
if (!GetWaveDevices(input, devs))
return false;
}
return FilterDevices(devs, kFilteredAudioDevicesName);
}
bool Win32DeviceManager::GetVideoCaptureDevices(std::vector<Device>* devices) {
devices->clear();
if (!GetDevices(CLSID_VideoInputDeviceCategory, devices)) {
return false;
}
return FilterDevices(devices, kFilteredVideoDevicesName);
}
bool GetDevices(const CLSID& catid, std::vector<Device>* devices) {
HRESULT hr;
// CComPtr is a scoped pointer that will be auto released when going
// out of scope. CoUninitialize must not be called before the
// release.
CComPtr<ICreateDevEnum> sys_dev_enum;
CComPtr<IEnumMoniker> cam_enum;
if (FAILED(hr = sys_dev_enum.CoCreateInstance(CLSID_SystemDeviceEnum)) ||
FAILED(hr = sys_dev_enum->CreateClassEnumerator(catid, &cam_enum, 0))) {
LOG(LS_ERROR) << "Failed to create device enumerator, hr=" << hr;
return false;
}
// Only enum devices if CreateClassEnumerator returns S_OK. If there are no
// devices available, S_FALSE will be returned, but enumMk will be NULL.
if (hr == S_OK) {
CComPtr<IMoniker> mk;
while (cam_enum->Next(1, &mk, NULL) == S_OK) {
#ifdef HAVE_LOGITECH_HEADERS
// Initialize Logitech device if applicable
MaybeLogitechDeviceReset(mk);
#endif
CComPtr<IPropertyBag> bag;
if (SUCCEEDED(mk->BindToStorage(NULL, NULL,
__uuidof(bag), reinterpret_cast<void**>(&bag)))) {
CComVariant name, path;
std::string name_str, path_str;
if (SUCCEEDED(bag->Read(kFriendlyName, &name, 0)) &&
name.vt == VT_BSTR) {
name_str = rtc::ToUtf8(name.bstrVal);
// Get the device id if one exists.
if (SUCCEEDED(bag->Read(kDevicePath, &path, 0)) &&
path.vt == VT_BSTR) {
path_str = rtc::ToUtf8(path.bstrVal);
}
devices->push_back(Device(name_str, path_str));
}
}
mk = NULL;
}
}
return true;
}
HRESULT GetStringProp(IPropertyStore* bag, PROPERTYKEY key, std::string* out) {
out->clear();
PROPVARIANT var;
PropVariantInit(&var);
HRESULT hr = bag->GetValue(key, &var);
if (SUCCEEDED(hr)) {
if (var.pwszVal)
*out = rtc::ToUtf8(var.pwszVal);
else
hr = E_FAIL;
}
PropVariantClear(&var);
return hr;
}
// Adapted from http://msdn.microsoft.com/en-us/library/dd370812(v=VS.85).aspx
HRESULT CricketDeviceFromImmDevice(IMMDevice* device, Device* out) {
CComPtr<IPropertyStore> props;
HRESULT hr = device->OpenPropertyStore(STGM_READ, &props);
if (FAILED(hr)) {
return hr;
}
// Get the endpoint's name and id.
std::string name, guid;
hr = GetStringProp(props, PKEY_Device_FriendlyName, &name);
if (SUCCEEDED(hr)) {
hr = GetStringProp(props, PKEY_AudioEndpoint_GUID, &guid);
if (SUCCEEDED(hr)) {
out->name = name;
out->id = guid;
}
}
return hr;
}
bool GetCoreAudioDevices(
bool input, std::vector<Device>* devs) {
HRESULT hr = S_OK;
CComPtr<IMMDeviceEnumerator> enumerator;
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator), reinterpret_cast<void**>(&enumerator));
if (SUCCEEDED(hr)) {
CComPtr<IMMDeviceCollection> devices;
hr = enumerator->EnumAudioEndpoints((input ? eCapture : eRender),
DEVICE_STATE_ACTIVE, &devices);
if (SUCCEEDED(hr)) {
unsigned int count;
hr = devices->GetCount(&count);
if (SUCCEEDED(hr)) {
for (unsigned int i = 0; i < count; i++) {
CComPtr<IMMDevice> device;
// Get pointer to endpoint number i.
hr = devices->Item(i, &device);
if (FAILED(hr)) {
break;
}
Device dev;
hr = CricketDeviceFromImmDevice(device, &dev);
if (SUCCEEDED(hr)) {
devs->push_back(dev);
} else {
LOG(LS_WARNING) << "Unable to query IMM Device, skipping. HR="
<< hr;
hr = S_FALSE;
}
}
}
}
}
if (FAILED(hr)) {
LOG(LS_WARNING) << "GetCoreAudioDevices failed with hr " << hr;
return false;
}
return true;
}
bool GetWaveDevices(bool input, std::vector<Device>* devs) {
// Note, we don't use the System Device Enumerator interface here since it
// adds lots of pseudo-devices to the list, such as DirectSound and Wave
// variants of the same device.
if (input) {
int num_devs = waveInGetNumDevs();
for (int i = 0; i < num_devs; ++i) {
WAVEINCAPS caps;
if (waveInGetDevCaps(i, &caps, sizeof(caps)) == MMSYSERR_NOERROR &&
caps.wChannels > 0) {
devs->push_back(Device(rtc::ToUtf8(caps.szPname),
rtc::ToString(i)));
}
}
} else {
int num_devs = waveOutGetNumDevs();
for (int i = 0; i < num_devs; ++i) {
WAVEOUTCAPS caps;
if (waveOutGetDevCaps(i, &caps, sizeof(caps)) == MMSYSERR_NOERROR &&
caps.wChannels > 0) {
devs->push_back(Device(rtc::ToUtf8(caps.szPname), i));
}
}
}
return true;
}
Win32DeviceWatcher::Win32DeviceWatcher(Win32DeviceManager* manager)
: DeviceWatcher(manager),
manager_(manager),
audio_notify_(NULL),
video_notify_(NULL) {
}
Win32DeviceWatcher::~Win32DeviceWatcher() {
}
bool Win32DeviceWatcher::Start() {
if (!Create(NULL, _T("libjingle Win32DeviceWatcher Window"),
0, 0, 0, 0, 0, 0)) {
return false;
}
audio_notify_ = Register(KSCATEGORY_AUDIO);
if (!audio_notify_) {
Stop();
return false;
}
video_notify_ = Register(KSCATEGORY_VIDEO);
if (!video_notify_) {
Stop();
return false;
}
return true;
}
void Win32DeviceWatcher::Stop() {
UnregisterDeviceNotification(video_notify_);
video_notify_ = NULL;
UnregisterDeviceNotification(audio_notify_);
audio_notify_ = NULL;
Destroy();
}
HDEVNOTIFY Win32DeviceWatcher::Register(REFGUID guid) {
DEV_BROADCAST_DEVICEINTERFACE dbdi;
dbdi.dbcc_size = sizeof(dbdi);
dbdi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
dbdi.dbcc_classguid = guid;
dbdi.dbcc_name[0] = '\0';
return RegisterDeviceNotification(handle(), &dbdi,
DEVICE_NOTIFY_WINDOW_HANDLE);
}
void Win32DeviceWatcher::Unregister(HDEVNOTIFY handle) {
UnregisterDeviceNotification(handle);
}
bool Win32DeviceWatcher::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT& result) {
if (uMsg == WM_DEVICECHANGE) {
if (wParam == DBT_DEVICEARRIVAL ||
wParam == DBT_DEVICEREMOVECOMPLETE) {
DEV_BROADCAST_DEVICEINTERFACE* dbdi =
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(lParam);
if (dbdi->dbcc_classguid == KSCATEGORY_AUDIO ||
dbdi->dbcc_classguid == KSCATEGORY_VIDEO) {
manager_->SignalDevicesChange();
}
}
result = 0;
return true;
}
return false;
}
}; // namespace cricket

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_MEDIA_DEVICES_WIN32DEVICEMANAGER_H_
#define WEBRTC_MEDIA_DEVICES_WIN32DEVICEMANAGER_H_
#include <string>
#include <vector>
#include "webrtc/base/sigslot.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/media/devices/devicemanager.h"
namespace cricket {
class Win32DeviceManager : public DeviceManager {
public:
Win32DeviceManager();
virtual ~Win32DeviceManager();
// Initialization
virtual bool Init();
virtual void Terminate();
virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
private:
virtual bool GetAudioDevices(bool input, std::vector<Device>* devs);
virtual bool GetDefaultVideoCaptureDevice(Device* device);
bool need_couninitialize_;
};
} // namespace cricket
#endif // WEBRTC_MEDIA_DEVICES_WIN32DEVICEMANAGER_H_

View File

@ -13,6 +13,7 @@
#include <vector>
#include "webrtc/media/engine/fakewebrtcdeviceinfo.h"
#include "webrtc/media/engine/fakewebrtcvideocapturemodule.h"
#include "webrtc/media/engine/webrtcvideocapturer.h"

View File

@ -14,7 +14,6 @@
#include <vector>
#include "webrtc/media/base/testutils.h"
#include "webrtc/media/engine/fakewebrtcdeviceinfo.h"
#include "webrtc/media/engine/webrtcvideocapturer.h"
class FakeWebRtcVcmFactory;

View File

@ -18,6 +18,7 @@
#include "webrtc/base/asyncinvoker.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/media/base/device.h"
#include "webrtc/media/base/videocapturer.h"
#include "webrtc/media/engine/webrtcvideoframe.h"
#include "webrtc/modules/video_capture/video_capture.h"

View File

@ -61,7 +61,7 @@ const int kElevatedTraceFilter = kDefaultTraceFilter | webrtc::kTraceStateInfo |
// -1 or 0 to select the default device.
#ifdef WIN32
const int kDefaultAudioDeviceId = -1;
#else
#elif !defined(WEBRTC_IOS)
const int kDefaultAudioDeviceId = 0;
#endif

View File

@ -78,7 +78,6 @@
'base/videosourcebase.h',
'base/yuvframegenerator.cc',
'base/yuvframegenerator.h',
'devices/deviceinfo.h',
'devices/videorendererfactory.h',
'engine/nullwebrtcvideoengine.h',
'engine/simulcast.cc',
@ -123,17 +122,6 @@
4389, # signed/unsigned mismatch.
],
'conditions': [
['include_internal_device_management==1', {
'sources': [
'devices/devicemanager.cc',
'devices/devicemanager.h',
],
}, {
'sources': [
'devices/dummydevicemanager.cc',
'devices/dummydevicemanager.h',
],
}],
['build_libyuv==1', {
'dependencies': ['<(DEPTH)/third_party/libyuv/libyuv.gyp:libyuv',],
}],
@ -172,9 +160,6 @@
'sources': [
'devices/libudevsymboltable.cc',
'devices/libudevsymboltable.h',
'devices/linuxdeviceinfo.cc',
'devices/linuxdevicemanager.cc',
'devices/linuxdevicemanager.h',
'devices/v4llookup.cc',
'devices/v4llookup.h',
],
@ -209,51 +194,6 @@
},
},
}],
['OS=="win" and include_internal_device_management==1', {
'sources': [
'devices/win32deviceinfo.cc',
'devices/win32devicemanager.cc',
'devices/win32devicemanager.h',
],
'msvs_settings': {
'VCLibrarianTool': {
'AdditionalDependencies': [
'winmm.lib',
],
},
},
}],
['OS=="mac" and include_internal_device_management==1', {
'sources': [
'devices/macdeviceinfo.cc',
'devices/macdevicemanager.cc',
'devices/macdevicemanager.h',
'devices/macdevicemanagermm.mm',
],
'xcode_settings': {
'WARNING_CFLAGS': [
# TODO(perkj): Update macdevicemanager.cc to stop using
# deprecated functions and remove this flag.
'-Wno-deprecated-declarations',
],
# Disable partial availability warning to prevent errors
# in macdevicemanagermm.mm using AVFoundation.
# https://code.google.com/p/webrtc/issues/detail?id=4695
'WARNING_CFLAGS!': ['-Wpartial-availability'],
},
'link_settings': {
'xcode_settings': {
'OTHER_LDFLAGS': [
'-weak_framework AVFoundation',
'-framework Cocoa',
'-framework CoreAudio',
'-framework CoreVideo',
'-framework OpenGL',
'-framework QTKit',
],
},
},
}],
['OS=="mac" and target_arch=="ia32"', {
'sources': [
'devices/carbonvideorenderer.cc',
@ -267,36 +207,11 @@
},
},
}],
['OS=="ios" and include_internal_device_management==1', {
'sources': [
'devices/mobiledevicemanager.cc',
],
'include_dirs': [
# TODO(sjlee) Remove when vp8 is building for iOS. vp8 pulls in
# libjpeg which pulls in libyuv which currently disabled.
'../../third_party/libyuv/include',
],
# TODO(kjellander): Make the code compile without disabling these.
# See https://bugs.chromium.org/p/webrtc/issues/detail?id=3307
'cflags': [
'-Wno-unused-const-variable',
],
'xcode_settings': {
'WARNING_CFLAGS': [
'-Wno-unused-const-variable',
],
},
}],
['OS=="ios" or (OS=="mac" and target_arch!="ia32")', {
'defines': [
'CARBON_DEPRECATED=YES',
],
}],
['OS=="android" and include_internal_device_management==1', {
'sources': [
'devices/mobiledevicemanager.cc',
],
}],
],
}, # target rtc_media
], # targets.

View File

@ -51,7 +51,6 @@
'base/fakevideorenderer.h',
'base/testutils.cc',
'base/testutils.h',
'devices/fakedevicemanager.h',
'engine/fakewebrtccall.cc',
'engine/fakewebrtccall.h',
'engine/fakewebrtccommon.h',
@ -88,16 +87,12 @@
'base/videocommon_unittest.cc',
'base/videoengine_unittest.h',
'base/videoframe_unittest.h',
'devices/dummydevicemanager_unittest.cc',
'engine/nullwebrtcvideoengine_unittest.cc',
'engine/simulcast_unittest.cc',
'engine/webrtcmediaengine_unittest.cc',
'engine/webrtcvideocapturer_unittest.cc',
'engine/webrtcvideoframe_unittest.cc',
'engine/webrtcvideoframefactory_unittest.cc',
# Disabled because some tests fail.
# TODO(ronghuawu): Reenable these tests.
# 'devices/devicemanager_unittest.cc',
'engine/webrtcvideoengine2_unittest.cc',
'engine/webrtcvoiceengine_unittest.cc',
'sctp/sctpdataengine_unittest.cc',