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

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: OVerhauled following mark@ review. 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
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 "media/video/capture/mac/avfoundation_glue.h"
10 11
11 namespace content { 12 namespace {
12 13
13 class DeviceMonitorMac::QTMonitorImpl { 14 // Interface used by DeviceMonitorMac to interact with either a QTKit or an
15 // AVFoundation implementation of events and notifications.
16 class MacMonitorInterface {
14 public: 17 public:
15 explicit QTMonitorImpl(DeviceMonitorMac* monitor); 18 virtual ~MacMonitorInterface() {};
16 virtual ~QTMonitorImpl() {}
17 19
18 void Start(); 20 virtual void OnDeviceChanged() = 0;
19 void Stop(); 21 };
20 22
23 class QTKitMonitorImpl : public MacMonitorInterface {
24 public:
25 QTKitMonitorImpl() {};
26 explicit QTKitMonitorImpl(content::DeviceMonitorMac* monitor);
27 virtual ~QTKitMonitorImpl();
28
29 virtual void OnDeviceChanged() OVERRIDE;
21 private: 30 private:
22 void OnDeviceChanged(); 31 content::DeviceMonitorMac* monitor_;
23
24 DeviceMonitorMac* monitor_;
25 int number_audio_devices_; 32 int number_audio_devices_;
26 int number_video_devices_; 33 int number_video_devices_;
27 id device_arrival_; 34 id device_arrival_;
28 id device_removal_; 35 id device_removal_;
29
30 DISALLOW_COPY_AND_ASSIGN(QTMonitorImpl);
31 }; 36 };
32 37
33 DeviceMonitorMac::QTMonitorImpl::QTMonitorImpl(DeviceMonitorMac* monitor) 38 QTKitMonitorImpl::QTKitMonitorImpl(content::DeviceMonitorMac* monitor)
34 : monitor_(monitor), 39 : monitor_(monitor),
35 number_audio_devices_(0), 40 number_audio_devices_(0),
36 number_video_devices_(0), 41 number_video_devices_(0),
37 device_arrival_(nil), 42 device_arrival_(0),
Mark Mentovai 2013/10/01 18:53:23 If these are id again now, the initializers should
mcasas 2013/10/02 14:10:39 Done.
38 device_removal_(nil) { 43 device_removal_(0) {
39 DCHECK(monitor); 44 DCHECK(monitor);
40 }
41 45
42 void DeviceMonitorMac::QTMonitorImpl::Start() {
43 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; 46 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
44 device_arrival_ = 47 device_arrival_ =
45 [nc addObserverForName:QTCaptureDeviceWasConnectedNotification 48 [nc addObserverForName:QTCaptureDeviceWasConnectedNotification
46 object:nil 49 object:nil
47 queue:nil 50 queue:nil
48 usingBlock:^(NSNotification* notification) { 51 usingBlock:^(NSNotification* notification) {
49 OnDeviceChanged();}]; 52 OnDeviceChanged();}];
50 53
51 device_removal_ = 54 device_removal_ =
52 [nc addObserverForName:QTCaptureDeviceWasDisconnectedNotification 55 [nc addObserverForName:QTCaptureDeviceWasDisconnectedNotification
53 object:nil 56 object:nil
54 queue:nil 57 queue:nil
55 usingBlock:^(NSNotification* notification) { 58 usingBlock:^(NSNotification* notification) {
56 OnDeviceChanged();}]; 59 OnDeviceChanged();}];
57 } 60 }
58 61
59 void DeviceMonitorMac::QTMonitorImpl::Stop() { 62 QTKitMonitorImpl::~QTKitMonitorImpl() {
60 if (!monitor_) 63 if (!monitor_)
61 return; 64 return;
62 65
63 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; 66 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
64 [nc removeObserver:device_arrival_]; 67 [nc removeObserver:(id)device_arrival_];
Mark Mentovai 2013/10/01 18:53:23 Shouldn’t need these casts anymore since the type
mcasas 2013/10/02 14:10:39 Done.
65 [nc removeObserver:device_removal_]; 68 [nc removeObserver:(id)device_removal_];
66 } 69 }
67 70
68 void DeviceMonitorMac::QTMonitorImpl::OnDeviceChanged() { 71 void QTKitMonitorImpl::OnDeviceChanged() {
69 NSArray* devices = [QTCaptureDevice inputDevices]; 72 NSArray* devices = [QTCaptureDevice inputDevices];
70 int number_video_devices = 0; 73 int number_video_devices = 0;
71 int number_audio_devices = 0; 74 int number_audio_devices = 0;
72 for (QTCaptureDevice* device in devices) { 75 for (QTCaptureDevice* device in devices) {
73 if ([device hasMediaType:QTMediaTypeVideo] || 76 if ([device hasMediaType:QTMediaTypeVideo] ||
74 [device hasMediaType:QTMediaTypeMuxed]) 77 [device hasMediaType:QTMediaTypeMuxed])
75 ++number_video_devices; 78 ++number_video_devices;
76 79
77 if ([device hasMediaType:QTMediaTypeSound] || 80 if ([device hasMediaType:QTMediaTypeSound] ||
78 [device hasMediaType:QTMediaTypeMuxed]) 81 [device hasMediaType:QTMediaTypeMuxed])
79 ++number_audio_devices; 82 ++number_audio_devices;
83 DVLOG(1) << "I found "<< number_video_devices << "video devices";
80 } 84 }
81 85
82 if (number_video_devices_ != number_video_devices) { 86 if (number_video_devices_ != number_video_devices) {
83 number_video_devices_ = number_video_devices; 87 number_video_devices_ = number_video_devices;
84 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE); 88 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
85 } 89 }
86 90
87 if (number_audio_devices_ != number_audio_devices) { 91 if (number_audio_devices_ != number_audio_devices) {
88 number_audio_devices_ = number_audio_devices; 92 number_audio_devices_ = number_audio_devices;
89 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE); 93 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
90 } 94 }
91 } 95 }
92 96
93 DeviceMonitorMac::DeviceMonitorMac() { 97 class AVFoundationMonitorImpl : public MacMonitorInterface {
94 qt_monitor_.reset(new QTMonitorImpl(this)); 98 public:
95 qt_monitor_->Start(); 99 AVFoundationMonitorImpl() {};
100 explicit AVFoundationMonitorImpl(content::DeviceMonitorMac* monitor);
101 virtual ~AVFoundationMonitorImpl();
102
103 virtual void OnDeviceChanged() OVERRIDE;
104 private:
105 content::DeviceMonitorMac* monitor_;
106 int number_audio_devices_;
107 int number_video_devices_;
108 id device_arrival_;
109 id device_removal_;
110 };
111
112 AVFoundationMonitorImpl::AVFoundationMonitorImpl(
113 content::DeviceMonitorMac* monitor)
114 : monitor_(monitor),
115 number_audio_devices_(0),
116 number_video_devices_(0),
117 device_arrival_(0),
118 device_removal_(0) {
119 DCHECK(monitor);
120
121 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
122
123 // TEMPORARILY we subscribe to ALL events in the system. It should be done
124 // like further below, cherry picking the ones we want.
125 device_arrival_ =
126 [nc addObserverForName:nil
127 object:nil
128 queue:nil
129 usingBlock:^(NSNotification* notification) {
130 OnDeviceChanged();}];
131
132 //device_arrival_ =
133 // [nc addObserverForName:[AVFoundationGlue
134 // avCaptureDeviceWasConnectedNotification]
135 // object:nil
136 // queue:nil
137 // usingBlock:^(NSNotification* notification) {
138 // OnDeviceChanged();}];
139
140 // device_removal_ =
141 // [nc addObserverForName:[AVFoundationGlue
142 // avCaptureDeviceWasDisconnectedNotification]
143 // object:nil
144 // queue:nil
145 // usingBlock:^(NSNotification* notification) {
146 // OnDeviceChanged();}];
147
96 } 148 }
97 149
98 DeviceMonitorMac::~DeviceMonitorMac() { 150 AVFoundationMonitorImpl::~AVFoundationMonitorImpl() {
99 qt_monitor_->Stop(); 151 if (!monitor_)
152 return;
153
154 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
155 [nc removeObserver:(id)device_arrival_];
156 [nc removeObserver:(id)device_removal_];
100 } 157 }
101 158
159 void AVFoundationMonitorImpl::OnDeviceChanged() {
160 NSArray* devices = [AVCaptureDeviceGlue devices];
161 int number_video_devices = 0;
162 int number_audio_devices = 0;
163 for (id device in devices) {
164 if ([AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeVideo]
165 forId:device] ||
Mark Mentovai 2013/10/01 18:53:23 Objective-C style: line up the colons. Take a look
mcasas 2013/10/02 14:10:39 Done.
166 [AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeMuxed]
167 forId:device])
168 ++number_video_devices;
Mark Mentovai 2013/10/01 18:53:23 Since the condition took up so many lines, {braces
mcasas 2013/10/02 14:10:39 Done.
169
170 if ([AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeAudio]
171 forId:device] ||
172 [AVCaptureDeviceGlue hasMediaType:[AVFoundationGlue avMediaTypeMuxed]
173 forId:device])
174 ++number_audio_devices;
175 }
176
177 if (number_video_devices_ != number_video_devices) {
178 DVLOG(1) << "We have a video device plugged " <<
179 ((number_video_devices_ > number_video_devices)? "out" : "in");
180 number_video_devices_ = number_video_devices;
Mark Mentovai 2013/10/01 18:53:23 The synchronization problem I raised earlier still
mcasas 2013/10/02 14:10:39 Two things: I added a base::AutoLock to monitor_ s
181 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
182 }
183
184 if (number_audio_devices_ != number_audio_devices) {
185 DVLOG(1) << "We have an audio device plugged " <<
186 ((number_audio_devices_ > number_audio_devices)? "out" : "in");
187 number_audio_devices_ = number_audio_devices;
188 monitor_->NotifyDeviceChanged(base::SystemMonitor::DEVTYPE_AUDIO_CAPTURE);
189 }
190 }
191
192 } // anonymous namespace
Mark Mentovai 2013/10/01 18:53:23 Style: two spaces between } and //. In Chrome, it’
mcasas 2013/10/02 14:10:39 Done.
193
194 namespace content {
195
196 DeviceMonitorMac::DeviceMonitorMac() {
197 if ([AVFoundationGlue isAVFoundationSupported]){
198 DVLOG(1) << "Monitoring via AVFoundation";
199 device_monitor_impl_.reset(new AVFoundationMonitorImpl(this));
200 } else {
201 DVLOG(1) << "Monitoring via QTKit";
202 device_monitor_impl_.reset(new QTKitMonitorImpl(this));
203 }
204 }
205
206 DeviceMonitorMac::~DeviceMonitorMac() {}
207
102 void DeviceMonitorMac::NotifyDeviceChanged( 208 void DeviceMonitorMac::NotifyDeviceChanged(
103 base::SystemMonitor::DeviceType type) { 209 base::SystemMonitor::DeviceType type) {
104 // TODO(xians): Remove the global variable for SystemMonitor. 210 // TODO(xians): Remove the global variable for SystemMonitor.
105 base::SystemMonitor::Get()->ProcessDevicesChanged(type); 211 base::SystemMonitor::Get()->ProcessDevicesChanged(type);
106 } 212 }
107 213
108 } // namespace content 214 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698