Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(799)

Unified Diff: content/browser/device_monitor_mac.mm

Issue 24615005: Added AVFoundation Glue and Device Monitoring for Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments addressed. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/browser/device_monitor_mac.h ('k') | media/media.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/browser/device_monitor_mac.mm
diff --git a/content/browser/device_monitor_mac.mm b/content/browser/device_monitor_mac.mm
index 7b12e91cbdf4ed8b57fc020d3b75c0579240d0ef..dac06f1bb20de7901f17857d41b3af65138a0261 100644
--- a/content/browser/device_monitor_mac.mm
+++ b/content/browser/device_monitor_mac.mm
@@ -7,39 +7,43 @@
#import <QTKit/QTKit.h>
#include "base/logging.h"
+#include "base/synchronization/lock.h"
+#include "media/video/capture/mac/avfoundation_glue.h"
-namespace content {
+namespace {
-class DeviceMonitorMac::QTMonitorImpl {
+// Interface used by DeviceMonitorMac to interact with either a QTKit or an
+// AVFoundation implementation of events and notifications.
+class MacMonitorInterface {
public:
- explicit QTMonitorImpl(DeviceMonitorMac* monitor);
- virtual ~QTMonitorImpl() {}
+ virtual ~MacMonitorInterface() {};
- void Start();
- void Stop();
+ virtual void OnDeviceChanged() = 0;
+};
- private:
- void OnDeviceChanged();
+class QTKitMonitorImpl : public MacMonitorInterface {
+ public:
+ QTKitMonitorImpl() {};
+ explicit QTKitMonitorImpl(content::DeviceMonitorMac* monitor);
+ virtual ~QTKitMonitorImpl();
- DeviceMonitorMac* monitor_;
+ virtual void OnDeviceChanged() OVERRIDE;
+ private:
+ content::DeviceMonitorMac* monitor_;
int number_audio_devices_;
int number_video_devices_;
id device_arrival_;
id device_removal_;
-
- DISALLOW_COPY_AND_ASSIGN(QTMonitorImpl);
};
-DeviceMonitorMac::QTMonitorImpl::QTMonitorImpl(DeviceMonitorMac* monitor)
+QTKitMonitorImpl::QTKitMonitorImpl(content::DeviceMonitorMac* monitor)
: monitor_(monitor),
number_audio_devices_(0),
number_video_devices_(0),
device_arrival_(nil),
device_removal_(nil) {
DCHECK(monitor);
-}
-void DeviceMonitorMac::QTMonitorImpl::Start() {
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
device_arrival_ =
[nc addObserverForName:QTCaptureDeviceWasConnectedNotification
@@ -56,7 +60,7 @@ void DeviceMonitorMac::QTMonitorImpl::Start() {
OnDeviceChanged();}];
}
-void DeviceMonitorMac::QTMonitorImpl::Stop() {
+QTKitMonitorImpl::~QTKitMonitorImpl() {
if (!monitor_)
return;
@@ -65,7 +69,8 @@ void DeviceMonitorMac::QTMonitorImpl::Stop() {
[nc removeObserver:device_removal_];
}
-void DeviceMonitorMac::QTMonitorImpl::OnDeviceChanged() {
+void QTKitMonitorImpl::OnDeviceChanged() {
+ base::AutoLock lock(monitor_->lock_);
Mark Mentovai 2013/10/02 14:24:34 How does this help? The major problem here isn’t
mcasas 2013/10/02 16:16:00 I thought that when we register to the notificati
NSArray* devices = [QTCaptureDevice inputDevices];
int number_video_devices = 0;
int number_audio_devices = 0;
@@ -90,15 +95,115 @@ void DeviceMonitorMac::QTMonitorImpl::OnDeviceChanged() {
}
}
-DeviceMonitorMac::DeviceMonitorMac() {
- qt_monitor_.reset(new QTMonitorImpl(this));
- qt_monitor_->Start();
+class AVFoundationMonitorImpl : public MacMonitorInterface {
+ public:
+ AVFoundationMonitorImpl() {};
+ explicit AVFoundationMonitorImpl(content::DeviceMonitorMac* monitor);
+ virtual ~AVFoundationMonitorImpl();
+
+ virtual void OnDeviceChanged() OVERRIDE;
+ private:
+ content::DeviceMonitorMac* monitor_;
+ int number_audio_devices_;
+ int number_video_devices_;
+ id device_arrival_;
+ id device_removal_;
+};
+
+AVFoundationMonitorImpl::AVFoundationMonitorImpl(
+ content::DeviceMonitorMac* monitor)
+ : monitor_(monitor),
+ number_audio_devices_(0),
+ number_video_devices_(0),
+ device_arrival_(nil),
+ device_removal_(nil) {
+ DCHECK(monitor);
+
+ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+ NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
+
+ device_arrival_ =
+ [nc addObserverForName:[AVFoundationGlue
+ avCaptureDeviceWasConnectedNotification]
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification* notification) {
+ OnDeviceChanged();}];
+ DCHECK(device_arrival_);
+ device_removal_ =
+ [nc addObserverForName:[AVFoundationGlue
+ avCaptureDeviceWasDisconnectedNotification]
+ object:nil
+ queue:mainQueue
+ usingBlock:^(NSNotification* notification) {
+ OnDeviceChanged();}];
+ DCHECK(device_removal_);
+}
+
+AVFoundationMonitorImpl::~AVFoundationMonitorImpl() {
+ if (!monitor_)
+ return;
+
+ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+ [nc removeObserver:device_arrival_];
+ [nc removeObserver:device_removal_];
+}
+
+void AVFoundationMonitorImpl::OnDeviceChanged() {
+ base::AutoLock lock(monitor_->lock_);
+ NSArray* devices = [AVCaptureDeviceGlue devices];
+ int number_video_devices = 0;
+ int number_audio_devices = 0;
+ for (CrAVCaptureDevice* device in devices) {
+ if ([AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeVideo]
+ forCaptureDevice:device] ||
+ [AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeMuxed]
+ forCaptureDevice:device]) {
+ ++number_video_devices;
+ }
+ if ([AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeAudio]
+ forCaptureDevice:device] ||
+ [AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeMuxed]
+ forCaptureDevice:device]) {
+ ++number_audio_devices;
+ }
+ }
+
+ if (number_video_devices_ != number_video_devices) {
+ DVLOG(1) << "Video device plugged " <<
+ ((number_video_devices_ > number_video_devices)? "out" : "in");
+ number_video_devices_ = number_video_devices;
+ monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
+ }
+
+ if (number_audio_devices_ != number_audio_devices) {
+ DVLOG(1) << "Audio device plugged " <<
+ ((number_audio_devices_ > number_audio_devices)? "out" : "in");
+ number_audio_devices_ = number_audio_devices;
+ monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
+ }
}
-DeviceMonitorMac::~DeviceMonitorMac() {
- qt_monitor_->Stop();
+} // namespace
+
+namespace content {
+
+DeviceMonitorMac::DeviceMonitorMac() {
+ if ([AVFoundationGlue isAVFoundationSupported]){
+ DVLOG(1) << "Monitoring via AVFoundation";
+ device_monitor_impl_.reset(new AVFoundationMonitorImpl(this));
+ // Force the device enumeration so we enumerate correctly devices already in
+ // the system and at the same time use the AVCaptureDeviceGlue so it in
+ // turn forces the AVCaptureDeviceGlue alloc-init.
+ device_monitor_impl_->OnDeviceChanged();
+ } else {
+ DVLOG(1) << "Monitoring via QTKit";
+ device_monitor_impl_.reset(new QTKitMonitorImpl(this));
+ }
}
+DeviceMonitorMac::~DeviceMonitorMac() {}
+
void DeviceMonitorMac::NotifyDeviceChanged(
base::SystemMonitor::DeviceType type) {
// TODO(xians): Remove the global variable for SystemMonitor.
« no previous file with comments | « content/browser/device_monitor_mac.h ('k') | media/media.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698