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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/device_monitor_mac.h ('k') | media/media.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/device_monitor_mac.h" 5 #include "content/browser/device_monitor_mac.h"
6 6
7 #import <QTKit/QTKit.h> 7 #import <QTKit/QTKit.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/synchronization/lock.h"
11 #include "media/video/capture/mac/avfoundation_glue.h"
10 12
11 namespace content { 13 namespace {
12 14
13 class DeviceMonitorMac::QTMonitorImpl { 15 // Interface used by DeviceMonitorMac to interact with either a QTKit or an
16 // AVFoundation implementation of events and notifications.
17 class MacMonitorInterface {
14 public: 18 public:
15 explicit QTMonitorImpl(DeviceMonitorMac* monitor); 19 virtual ~MacMonitorInterface() {};
16 virtual ~QTMonitorImpl() {}
17 20
18 void Start(); 21 virtual void OnDeviceChanged() = 0;
19 void Stop(); 22 };
20 23
24 class QTKitMonitorImpl : public MacMonitorInterface {
25 public:
26 QTKitMonitorImpl() {};
27 explicit QTKitMonitorImpl(content::DeviceMonitorMac* monitor);
28 virtual ~QTKitMonitorImpl();
29
30 virtual void OnDeviceChanged() OVERRIDE;
21 private: 31 private:
22 void OnDeviceChanged(); 32 content::DeviceMonitorMac* monitor_;
23
24 DeviceMonitorMac* monitor_;
25 int number_audio_devices_; 33 int number_audio_devices_;
26 int number_video_devices_; 34 int number_video_devices_;
27 id device_arrival_; 35 id device_arrival_;
28 id device_removal_; 36 id device_removal_;
29
30 DISALLOW_COPY_AND_ASSIGN(QTMonitorImpl);
31 }; 37 };
32 38
33 DeviceMonitorMac::QTMonitorImpl::QTMonitorImpl(DeviceMonitorMac* monitor) 39 QTKitMonitorImpl::QTKitMonitorImpl(content::DeviceMonitorMac* monitor)
34 : monitor_(monitor), 40 : monitor_(monitor),
35 number_audio_devices_(0), 41 number_audio_devices_(0),
36 number_video_devices_(0), 42 number_video_devices_(0),
37 device_arrival_(nil), 43 device_arrival_(nil),
38 device_removal_(nil) { 44 device_removal_(nil) {
39 DCHECK(monitor); 45 DCHECK(monitor);
40 }
41 46
42 void DeviceMonitorMac::QTMonitorImpl::Start() {
43 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; 47 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
44 device_arrival_ = 48 device_arrival_ =
45 [nc addObserverForName:QTCaptureDeviceWasConnectedNotification 49 [nc addObserverForName:QTCaptureDeviceWasConnectedNotification
46 object:nil 50 object:nil
47 queue:nil 51 queue:nil
48 usingBlock:^(NSNotification* notification) { 52 usingBlock:^(NSNotification* notification) {
49 OnDeviceChanged();}]; 53 OnDeviceChanged();}];
50 54
51 device_removal_ = 55 device_removal_ =
52 [nc addObserverForName:QTCaptureDeviceWasDisconnectedNotification 56 [nc addObserverForName:QTCaptureDeviceWasDisconnectedNotification
53 object:nil 57 object:nil
54 queue:nil 58 queue:nil
55 usingBlock:^(NSNotification* notification) { 59 usingBlock:^(NSNotification* notification) {
56 OnDeviceChanged();}]; 60 OnDeviceChanged();}];
57 } 61 }
58 62
59 void DeviceMonitorMac::QTMonitorImpl::Stop() { 63 QTKitMonitorImpl::~QTKitMonitorImpl() {
60 if (!monitor_) 64 if (!monitor_)
61 return; 65 return;
62 66
63 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; 67 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
64 [nc removeObserver:device_arrival_]; 68 [nc removeObserver:device_arrival_];
65 [nc removeObserver:device_removal_]; 69 [nc removeObserver:device_removal_];
66 } 70 }
67 71
68 void DeviceMonitorMac::QTMonitorImpl::OnDeviceChanged() { 72 void QTKitMonitorImpl::OnDeviceChanged() {
73 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
69 NSArray* devices = [QTCaptureDevice inputDevices]; 74 NSArray* devices = [QTCaptureDevice inputDevices];
70 int number_video_devices = 0; 75 int number_video_devices = 0;
71 int number_audio_devices = 0; 76 int number_audio_devices = 0;
72 for (QTCaptureDevice* device in devices) { 77 for (QTCaptureDevice* device in devices) {
73 if ([device hasMediaType:QTMediaTypeVideo] || 78 if ([device hasMediaType:QTMediaTypeVideo] ||
74 [device hasMediaType:QTMediaTypeMuxed]) 79 [device hasMediaType:QTMediaTypeMuxed])
75 ++number_video_devices; 80 ++number_video_devices;
76 81
77 if ([device hasMediaType:QTMediaTypeSound] || 82 if ([device hasMediaType:QTMediaTypeSound] ||
78 [device hasMediaType:QTMediaTypeMuxed]) 83 [device hasMediaType:QTMediaTypeMuxed])
79 ++number_audio_devices; 84 ++number_audio_devices;
80 } 85 }
81 86
82 if (number_video_devices_ != number_video_devices) { 87 if (number_video_devices_ != number_video_devices) {
83 number_video_devices_ = number_video_devices; 88 number_video_devices_ = number_video_devices;
84 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE); 89 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
85 } 90 }
86 91
87 if (number_audio_devices_ != number_audio_devices) { 92 if (number_audio_devices_ != number_audio_devices) {
88 number_audio_devices_ = number_audio_devices; 93 number_audio_devices_ = number_audio_devices;
89 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); 94 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
90 } 95 }
91 } 96 }
92 97
93 DeviceMonitorMac::DeviceMonitorMac() { 98 class AVFoundationMonitorImpl : public MacMonitorInterface {
94 qt_monitor_.reset(new QTMonitorImpl(this)); 99 public:
95 qt_monitor_->Start(); 100 AVFoundationMonitorImpl() {};
101 explicit AVFoundationMonitorImpl(content::DeviceMonitorMac* monitor);
102 virtual ~AVFoundationMonitorImpl();
103
104 virtual void OnDeviceChanged() OVERRIDE;
105 private:
106 content::DeviceMonitorMac* monitor_;
107 int number_audio_devices_;
108 int number_video_devices_;
109 id device_arrival_;
110 id device_removal_;
111 };
112
113 AVFoundationMonitorImpl::AVFoundationMonitorImpl(
114 content::DeviceMonitorMac* monitor)
115 : monitor_(monitor),
116 number_audio_devices_(0),
117 number_video_devices_(0),
118 device_arrival_(nil),
119 device_removal_(nil) {
120 DCHECK(monitor);
121
122 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
123 NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
124
125 device_arrival_ =
126 [nc addObserverForName:[AVFoundationGlue
127 avCaptureDeviceWasConnectedNotification]
128 object:nil
129 queue:mainQueue
130 usingBlock:^(NSNotification* notification) {
131 OnDeviceChanged();}];
132 DCHECK(device_arrival_);
133 device_removal_ =
134 [nc addObserverForName:[AVFoundationGlue
135 avCaptureDeviceWasDisconnectedNotification]
136 object:nil
137 queue:mainQueue
138 usingBlock:^(NSNotification* notification) {
139 OnDeviceChanged();}];
140 DCHECK(device_removal_);
96 } 141 }
97 142
98 DeviceMonitorMac::~DeviceMonitorMac() { 143 AVFoundationMonitorImpl::~AVFoundationMonitorImpl() {
99 qt_monitor_->Stop(); 144 if (!monitor_)
145 return;
146
147 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
148 [nc removeObserver:device_arrival_];
149 [nc removeObserver:device_removal_];
100 } 150 }
101 151
152 void AVFoundationMonitorImpl::OnDeviceChanged() {
153 base::AutoLock lock(monitor_->lock_);
154 NSArray* devices = [AVCaptureDeviceGlue devices];
155 int number_video_devices = 0;
156 int number_audio_devices = 0;
157 for (CrAVCaptureDevice* device in devices) {
158 if ([AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeVideo]
159 forCaptureDevice:device] ||
160 [AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeMuxed]
161 forCaptureDevice:device]) {
162 ++number_video_devices;
163 }
164 if ([AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeAudio]
165 forCaptureDevice:device] ||
166 [AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeMuxed]
167 forCaptureDevice:device]) {
168 ++number_audio_devices;
169 }
170 }
171
172 if (number_video_devices_ != number_video_devices) {
173 DVLOG(1) << "Video device plugged " <<
174 ((number_video_devices_ > number_video_devices)? "out" : "in");
175 number_video_devices_ = number_video_devices;
176 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
177 }
178
179 if (number_audio_devices_ != number_audio_devices) {
180 DVLOG(1) << "Audio device plugged " <<
181 ((number_audio_devices_ > number_audio_devices)? "out" : "in");
182 number_audio_devices_ = number_audio_devices;
183 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
184 }
185 }
186
187 } // namespace
188
189 namespace content {
190
191 DeviceMonitorMac::DeviceMonitorMac() {
192 if ([AVFoundationGlue isAVFoundationSupported]){
193 DVLOG(1) << "Monitoring via AVFoundation";
194 device_monitor_impl_.reset(new AVFoundationMonitorImpl(this));
195 // Force the device enumeration so we enumerate correctly devices already in
196 // the system and at the same time use the AVCaptureDeviceGlue so it in
197 // turn forces the AVCaptureDeviceGlue alloc-init.
198 device_monitor_impl_->OnDeviceChanged();
199 } else {
200 DVLOG(1) << "Monitoring via QTKit";
201 device_monitor_impl_.reset(new QTKitMonitorImpl(this));
202 }
203 }
204
205 DeviceMonitorMac::~DeviceMonitorMac() {}
206
102 void DeviceMonitorMac::NotifyDeviceChanged( 207 void DeviceMonitorMac::NotifyDeviceChanged(
103 base::SystemMonitor::DeviceType type) { 208 base::SystemMonitor::DeviceType type) {
104 // TODO(xians): Remove the global variable for SystemMonitor. 209 // TODO(xians): Remove the global variable for SystemMonitor.
105 base::SystemMonitor::Get()->ProcessDevicesChanged(type); 210 base::SystemMonitor::Get()->ProcessDevicesChanged(type);
106 } 211 }
107 212
108 } // namespace content 213 } // namespace content
OLDNEW
« 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