OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/renderer_host/media/video_capture_manager.h" | 5 #include "content/browser/renderer_host/media/video_capture_manager.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "content/browser/browser_thread.h" | 8 #include "content/browser/browser_thread.h" |
9 #include "media/video/capture/fake_video_capture_device.h" | 9 #include "media/video/capture/fake_video_capture_device.h" |
10 #include "media/video/capture/video_capture_device.h" | 10 #include "media/video/capture/video_capture_device.h" |
11 | 11 |
12 namespace media_stream { | 12 namespace media_stream { |
13 | 13 |
14 // Starting id for the first capture session. | 14 // Starting id for the first capture session. |
15 // VideoCaptureManager::kStartOpenSessionId is used as default id without | 15 // VideoCaptureManager::kStartOpenSessionId is used as default id without |
16 // explicitly calling open device. | 16 // explicitly calling open device. |
17 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 }; | 17 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 }; |
18 | 18 |
19 static ::base::LazyInstance<VideoCaptureManager> g_video_capture_manager( | 19 static ::base::LazyInstance<VideoCaptureManager> g_video_capture_manager( |
20 base::LINKER_INITIALIZED); | 20 base::LINKER_INITIALIZED); |
21 | 21 |
22 VideoCaptureManager* VideoCaptureManager::Get() { | 22 VideoCaptureManager* VideoCaptureManager::Get() { |
23 return g_video_capture_manager.Pointer(); | 23 return g_video_capture_manager.Pointer(); |
24 } | 24 } |
25 | 25 |
26 VideoCaptureManager::VideoCaptureManager() | 26 VideoCaptureManager::VideoCaptureManager() |
27 : vc_device_thread_("VideoCaptureManagerThread"), | 27 : vc_device_thread_("VideoCaptureManagerThread"), |
28 listener_(NULL), | 28 listener_(NULL), |
29 new_capture_session_id_(kFirstSessionId), | 29 new_capture_session_id_(kFirstSessionId), |
30 devices_(), | |
31 use_fake_device_(false) { | 30 use_fake_device_(false) { |
32 vc_device_thread_.Start(); | 31 vc_device_thread_.Start(); |
33 } | 32 } |
34 | 33 |
35 VideoCaptureManager::~VideoCaptureManager() { | 34 VideoCaptureManager::~VideoCaptureManager() { |
35 DCHECK(devices_.empty()); | |
36 vc_device_thread_.Stop(); | 36 vc_device_thread_.Stop(); |
37 } | 37 } |
38 | 38 |
39 bool VideoCaptureManager::Register(MediaStreamProviderListener* listener) { | 39 void VideoCaptureManager::Register(MediaStreamProviderListener* listener) { |
40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
41 DCHECK(!listener_); | 41 DCHECK(!listener_); |
42 listener_ = listener; | 42 listener_ = listener; |
43 return true; | |
44 } | 43 } |
45 | 44 |
46 void VideoCaptureManager::Unregister() { | 45 void VideoCaptureManager::Unregister() { |
47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 46 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
47 DCHECK(listener_); | |
48 listener_ = NULL; | 48 listener_ = NULL; |
49 } | 49 } |
50 | 50 |
51 void VideoCaptureManager::EnumerateDevices() { | 51 void VideoCaptureManager::EnumerateDevices() { |
52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 52 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
53 DCHECK(listener_); | 53 DCHECK(listener_); |
54 | 54 |
55 vc_device_thread_.message_loop()->PostTask( | 55 vc_device_thread_.message_loop()->PostTask( |
56 FROM_HERE, | 56 FROM_HERE, |
57 NewRunnableMethod(this, | 57 NewRunnableMethod(this, |
58 &VideoCaptureManager::OnEnumerateDevices)); | 58 &VideoCaptureManager::OnEnumerateDevices)); |
59 } | 59 } |
60 | 60 |
61 MediaCaptureSessionId VideoCaptureManager::Open( | 61 int VideoCaptureManager::Open(const StreamDeviceInfo& device) { |
62 const MediaCaptureDeviceInfo& device) { | |
63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
64 DCHECK(listener_); | 63 DCHECK(listener_); |
65 | 64 |
66 // Generate a new id for this device | 65 // Generate a new id for this device |
67 MediaCaptureSessionId video_capture_session_id = new_capture_session_id_++; | 66 int video_capture_session_id = new_capture_session_id_++; |
68 | 67 |
69 vc_device_thread_.message_loop()->PostTask( | 68 vc_device_thread_.message_loop()->PostTask( |
70 FROM_HERE, | 69 FROM_HERE, |
71 NewRunnableMethod(this, | 70 NewRunnableMethod(this, |
72 &VideoCaptureManager::OnOpen, | 71 &VideoCaptureManager::OnOpen, |
73 video_capture_session_id, | 72 video_capture_session_id, |
74 device)); | 73 device)); |
75 | 74 |
76 return video_capture_session_id; | 75 return video_capture_session_id; |
77 } | 76 } |
78 | 77 |
79 void VideoCaptureManager::Close(MediaCaptureSessionId capture_session_id) { | 78 void VideoCaptureManager::Close(int capture_session_id) { |
80 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
81 DCHECK(listener_); | 80 DCHECK(listener_); |
82 | 81 |
83 vc_device_thread_.message_loop()->PostTask( | 82 vc_device_thread_.message_loop()->PostTask( |
84 FROM_HERE, | 83 FROM_HERE, |
85 NewRunnableMethod(this, | 84 NewRunnableMethod(this, |
86 &VideoCaptureManager::OnClose, | 85 &VideoCaptureManager::OnClose, |
87 capture_session_id)); | 86 capture_session_id)); |
88 } | 87 } |
89 | 88 |
(...skipping 15 matching lines...) Expand all Loading... | |
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 104 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
106 | 105 |
107 vc_device_thread_.message_loop()->PostTask( | 106 vc_device_thread_.message_loop()->PostTask( |
108 FROM_HERE, | 107 FROM_HERE, |
109 NewRunnableMethod(this, | 108 NewRunnableMethod(this, |
110 &VideoCaptureManager::OnStop, | 109 &VideoCaptureManager::OnStop, |
111 capture_session_id, | 110 capture_session_id, |
112 stopped_task)); | 111 stopped_task)); |
113 } | 112 } |
114 | 113 |
114 void VideoCaptureManager::Error( | |
115 const media::VideoCaptureSessionId& capture_session_id) { | |
116 PostOnError(capture_session_id, kDeviceNotAvailable); | |
117 } | |
118 | |
115 void VideoCaptureManager::UseFakeDevice() { | 119 void VideoCaptureManager::UseFakeDevice() { |
116 use_fake_device_ = true; | 120 use_fake_device_ = true; |
117 } | 121 } |
118 | 122 |
119 MessageLoop* VideoCaptureManager::GetMessageLoop() { | 123 MessageLoop* VideoCaptureManager::GetMessageLoop() { |
120 return vc_device_thread_.message_loop(); | 124 return vc_device_thread_.message_loop(); |
121 } | 125 } |
122 | 126 |
123 void VideoCaptureManager::OnEnumerateDevices() { | 127 void VideoCaptureManager::OnEnumerateDevices() { |
124 DCHECK(IsOnCaptureDeviceThread()); | 128 DCHECK(IsOnCaptureDeviceThread()); |
125 | 129 |
126 scoped_ptr<media::VideoCaptureDevice::Names> device_names( | 130 media::VideoCaptureDevice::Names device_names; |
127 new media::VideoCaptureDevice::Names()); | 131 GetAvailableDevices(&device_names); |
128 GetAvailableDevices(device_names.get()); | |
129 | 132 |
130 MediaCaptureDevices devices; | 133 StreamDeviceInfoArray devices; |
131 for (media::VideoCaptureDevice::Names::iterator it = | 134 for (media::VideoCaptureDevice::Names::iterator it = |
132 device_names.get()->begin(); it != device_names.get()->end(); ++it) { | 135 device_names.begin(); it != device_names.end(); ++it) { |
133 bool opened = DeviceOpened(*it); | 136 bool opened = DeviceOpened(*it); |
134 devices.push_back(MediaCaptureDeviceInfo(kVideoCapture, it->device_name, | 137 devices.push_back(StreamDeviceInfo(kVideoCapture, it->device_name, |
135 it->unique_id, opened)); | 138 it->unique_id, opened)); |
136 } | 139 } |
137 | 140 |
138 PostOnDevicesEnumerated(devices); | 141 PostOnDevicesEnumerated(devices); |
139 | |
140 // Clean-up | |
141 devices.clear(); | |
142 device_names.get()->clear(); | |
143 } | 142 } |
144 | 143 |
145 void VideoCaptureManager::OnOpen(MediaCaptureSessionId capture_session_id, | 144 void VideoCaptureManager::OnOpen(int capture_session_id, |
146 const MediaCaptureDeviceInfo device) { | 145 const StreamDeviceInfo& device) { |
147 DCHECK(IsOnCaptureDeviceThread()); | 146 DCHECK(IsOnCaptureDeviceThread()); |
148 DCHECK(devices_.find(capture_session_id) == devices_.end()); | 147 DCHECK(devices_.find(capture_session_id) == devices_.end()); |
149 | 148 |
150 // Check if another session has already opened this device, only one user per | 149 // Check if another session has already opened this device, only one user per |
151 // device is supported. | 150 // device is supported. |
152 if (DeviceOpened(device)) { | 151 if (DeviceOpened(device)) { |
153 PostOnError(capture_session_id, kDeviceAlreadyInUse); | 152 PostOnError(capture_session_id, kDeviceAlreadyInUse); |
154 return; | 153 return; |
155 } | 154 } |
156 | 155 |
(...skipping 11 matching lines...) Expand all Loading... | |
168 } | 167 } |
169 if (video_capture_device == NULL) { | 168 if (video_capture_device == NULL) { |
170 PostOnError(capture_session_id, kDeviceNotAvailable); | 169 PostOnError(capture_session_id, kDeviceNotAvailable); |
171 return; | 170 return; |
172 } | 171 } |
173 | 172 |
174 devices_[capture_session_id] = video_capture_device; | 173 devices_[capture_session_id] = video_capture_device; |
175 PostOnOpened(capture_session_id); | 174 PostOnOpened(capture_session_id); |
176 } | 175 } |
177 | 176 |
178 void VideoCaptureManager::OnClose( | 177 void VideoCaptureManager::OnClose(int capture_session_id) { |
179 MediaCaptureSessionId capture_session_id) { | |
180 DCHECK(IsOnCaptureDeviceThread()); | 178 DCHECK(IsOnCaptureDeviceThread()); |
181 | 179 |
182 VideoCaptureDevices::iterator it = devices_.find(capture_session_id); | 180 VideoCaptureDevices::iterator it = devices_.find(capture_session_id); |
183 if (it != devices_.end()) { | 181 if (it != devices_.end()) { |
184 // Deallocate (if not done already) and delete the device | 182 // Deallocate (if not done already) and delete the device |
185 media::VideoCaptureDevice* video_capture_device = it->second; | 183 media::VideoCaptureDevice* video_capture_device = it->second; |
186 video_capture_device->DeAllocate(); | 184 video_capture_device->DeAllocate(); |
187 delete video_capture_device; | 185 delete video_capture_device; |
188 devices_.erase(it); | 186 devices_.erase(it); |
189 } | 187 } |
190 | 188 |
191 PostOnClosed(capture_session_id); | 189 PostOnClosed(capture_session_id); |
192 } | 190 } |
193 | 191 |
194 void VideoCaptureManager::OnStart( | 192 void VideoCaptureManager::OnStart( |
195 const media::VideoCaptureParams capture_params, | 193 const media::VideoCaptureParams capture_params, |
196 media::VideoCaptureDevice::EventHandler* video_capture_receiver) { | 194 media::VideoCaptureDevice::EventHandler* video_capture_receiver) { |
197 DCHECK(IsOnCaptureDeviceThread()); | 195 DCHECK(IsOnCaptureDeviceThread()); |
196 DCHECK(video_capture_receiver != NULL); | |
198 | 197 |
199 // Solution for not using MediaStreamManager | 198 // Solution for not using MediaStreamManager |
200 // This session id won't be returned by Open() | 199 // This session id won't be returned by Open() |
201 if (capture_params.session_id == kStartOpenSessionId) { | 200 if (capture_params.session_id == kStartOpenSessionId) { |
202 // Start() is called without using Open(), we need to open a device | 201 // Start() is called without using Open(), we need to open a device |
203 scoped_ptr<media::VideoCaptureDevice::Names> device_names( | 202 media::VideoCaptureDevice::Names device_names; |
204 new media::VideoCaptureDevice::Names()); | 203 GetAvailableDevices(&device_names); |
205 GetAvailableDevices(device_names.get()); | 204 if (device_names.empty()) { |
206 | 205 // No devices available. |
207 MediaCaptureDeviceInfo device(kVideoCapture, | 206 video_capture_receiver->OnError(); |
208 device_names.get()->front().device_name, | 207 return; |
209 device_names.get()->front().unique_id, false); | 208 } |
209 StreamDeviceInfo device(kVideoCapture, | |
210 device_names.front().device_name, | |
211 device_names.front().unique_id, false); | |
210 | 212 |
211 // Call OnOpen to open using the first device in the list | 213 // Call OnOpen to open using the first device in the list |
212 OnOpen(capture_params.session_id, device); | 214 OnOpen(capture_params.session_id, device); |
213 } | 215 } |
214 | 216 |
215 VideoCaptureDevices::iterator it = devices_.find(capture_params.session_id); | 217 VideoCaptureDevices::iterator it = devices_.find(capture_params.session_id); |
216 if (it == devices_.end()) { | 218 if (it == devices_.end()) { |
217 // Invalid session id | 219 // Invalid session id |
218 video_capture_receiver->OnError(); | 220 video_capture_receiver->OnError(); |
219 return; | 221 return; |
(...skipping 26 matching lines...) Expand all Loading... | |
246 stopped_task->Run(); | 248 stopped_task->Run(); |
247 delete stopped_task; | 249 delete stopped_task; |
248 } | 250 } |
249 | 251 |
250 if (capture_session_id == kStartOpenSessionId) { | 252 if (capture_session_id == kStartOpenSessionId) { |
251 // This device was opened from Start(), not Open(). Close it! | 253 // This device was opened from Start(), not Open(). Close it! |
252 OnClose(capture_session_id); | 254 OnClose(capture_session_id); |
253 } | 255 } |
254 } | 256 } |
255 | 257 |
256 void VideoCaptureManager::OnOpened( | 258 void VideoCaptureManager::OnOpened(int capture_session_id) { |
257 MediaCaptureSessionId capture_session_id) { | |
258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
259 if (listener_ == NULL) { | 260 if (listener_ == NULL) { |
Leandro Graciá Gil
2011/06/21 18:00:26
I've tried to find exactly where the style guideli
scherkus (not reviewing)
2011/06/21 18:03:42
there's no hard-and-fast rule about it... so it bo
mflodman1
2011/06/21 19:23:51
I agree. Done.
| |
260 // Listener has been removed | 261 // Listener has been removed |
Leandro Graciá Gil
2011/06/21 18:00:26
Style says comments should end with a period. Plea
mflodman1
2011/06/21 19:23:51
Done.
| |
261 return; | 262 return; |
262 } | 263 } |
263 listener_->Opened(kVideoCapture, capture_session_id); | 264 listener_->Opened(kVideoCapture, capture_session_id); |
264 } | 265 } |
265 | 266 |
266 void VideoCaptureManager::OnClosed( | 267 void VideoCaptureManager::OnClosed(int capture_session_id) { |
267 MediaCaptureSessionId capture_session_id) { | |
268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
269 if (listener_ == NULL) { | 269 if (listener_ == NULL) { |
270 // Listener has been removed | 270 // Listener has been removed |
271 return; | 271 return; |
272 } | 272 } |
273 listener_->Closed(kVideoCapture, capture_session_id); | 273 listener_->Closed(kVideoCapture, capture_session_id); |
274 } | 274 } |
275 | 275 |
276 void VideoCaptureManager::OnDevicesEnumerated( | 276 void VideoCaptureManager::OnDevicesEnumerated( |
277 const MediaCaptureDevices& devices) { | 277 const StreamDeviceInfoArray& devices) { |
278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 278 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
279 if (listener_ == NULL) { | 279 if (!listener_) { |
280 // Listener has been removed | 280 // Listener has been removed |
281 return; | 281 return; |
282 } | 282 } |
283 listener_->DevicesEnumerated(kVideoCapture, devices); | 283 listener_->DevicesEnumerated(kVideoCapture, devices); |
284 } | 284 } |
285 | 285 |
286 void VideoCaptureManager::OnError(MediaCaptureSessionId capture_session_id, | 286 void VideoCaptureManager::OnError(int capture_session_id, |
287 MediaStreamProviderError error) { | 287 MediaStreamProviderError error) { |
288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
289 if (listener_ == NULL) { | 289 if (listener_ == NULL) { |
290 // Listener has been removed | 290 // Listener has been removed |
291 return; | 291 return; |
292 } | 292 } |
293 listener_->Error(kVideoCapture, capture_session_id, error); | 293 listener_->Error(kVideoCapture, capture_session_id, error); |
294 } | 294 } |
295 | 295 |
296 void VideoCaptureManager::PostOnOpened( | 296 void VideoCaptureManager::PostOnOpened(int capture_session_id) { |
297 MediaCaptureSessionId capture_session_id) { | |
298 DCHECK(IsOnCaptureDeviceThread()); | 297 DCHECK(IsOnCaptureDeviceThread()); |
299 BrowserThread::PostTask(BrowserThread::IO, | 298 BrowserThread::PostTask(BrowserThread::IO, |
300 FROM_HERE, | 299 FROM_HERE, |
301 NewRunnableMethod(this, | 300 NewRunnableMethod(this, |
302 &VideoCaptureManager::OnOpened, | 301 &VideoCaptureManager::OnOpened, |
303 capture_session_id)); | 302 capture_session_id)); |
304 } | 303 } |
305 | 304 |
306 void VideoCaptureManager::PostOnClosed( | 305 void VideoCaptureManager::PostOnClosed(int capture_session_id) { |
307 MediaCaptureSessionId capture_session_id) { | |
308 DCHECK(IsOnCaptureDeviceThread()); | 306 DCHECK(IsOnCaptureDeviceThread()); |
309 BrowserThread::PostTask(BrowserThread::IO, | 307 BrowserThread::PostTask(BrowserThread::IO, |
310 FROM_HERE, | 308 FROM_HERE, |
311 NewRunnableMethod(this, | 309 NewRunnableMethod(this, |
312 &VideoCaptureManager::OnClosed, | 310 &VideoCaptureManager::OnClosed, |
313 capture_session_id)); | 311 capture_session_id)); |
314 } | 312 } |
315 | 313 |
316 void VideoCaptureManager::PostOnDevicesEnumerated(MediaCaptureDevices devices) { | 314 void VideoCaptureManager::PostOnDevicesEnumerated( |
315 const StreamDeviceInfoArray& devices) { | |
317 DCHECK(IsOnCaptureDeviceThread()); | 316 DCHECK(IsOnCaptureDeviceThread()); |
318 | |
319 BrowserThread::PostTask(BrowserThread::IO, | 317 BrowserThread::PostTask(BrowserThread::IO, |
320 FROM_HERE, | 318 FROM_HERE, |
321 NewRunnableMethod( | 319 NewRunnableMethod( |
322 this, | 320 this, |
323 &VideoCaptureManager::OnDevicesEnumerated, | 321 &VideoCaptureManager::OnDevicesEnumerated, |
324 devices)); | 322 devices)); |
325 } | 323 } |
326 | 324 |
327 void VideoCaptureManager::PostOnError(MediaCaptureSessionId capture_session_id, | 325 void VideoCaptureManager::PostOnError(int capture_session_id, |
328 MediaStreamProviderError error) { | 326 MediaStreamProviderError error) { |
329 // Don't check thread here, can be called from both IO thread and device | 327 // Don't check thread here, can be called from both IO thread and device |
330 // thread. | 328 // thread. |
331 BrowserThread::PostTask(BrowserThread::IO, | 329 BrowserThread::PostTask(BrowserThread::IO, |
332 FROM_HERE, | 330 FROM_HERE, |
333 NewRunnableMethod(this, | 331 NewRunnableMethod(this, |
334 &VideoCaptureManager::OnError, | 332 &VideoCaptureManager::OnError, |
335 capture_session_id, | 333 capture_session_id, |
336 error)); | 334 error)); |
337 } | 335 } |
(...skipping 21 matching lines...) Expand all Loading... | |
359 it != devices_.end(); | 357 it != devices_.end(); |
360 ++it) { | 358 ++it) { |
361 if (device_name.unique_id == it->second->device_name().unique_id) { | 359 if (device_name.unique_id == it->second->device_name().unique_id) { |
362 // We've found the device! | 360 // We've found the device! |
363 return true; | 361 return true; |
364 } | 362 } |
365 } | 363 } |
366 return false; | 364 return false; |
367 } | 365 } |
368 | 366 |
369 bool VideoCaptureManager::DeviceOpened( | 367 bool VideoCaptureManager::DeviceOpened(const StreamDeviceInfo& device_info) { |
370 const MediaCaptureDeviceInfo& device_info) { | |
371 DCHECK(IsOnCaptureDeviceThread()); | 368 DCHECK(IsOnCaptureDeviceThread()); |
372 | 369 |
373 for (VideoCaptureDevices::iterator it = devices_.begin(); | 370 for (VideoCaptureDevices::iterator it = devices_.begin(); |
374 it != devices_.end(); | 371 it != devices_.end(); |
375 it++) { | 372 it++) { |
376 if (device_info.device_id == it->second->device_name().unique_id) { | 373 if (device_info.device_id == it->second->device_name().unique_id) { |
377 return true; | 374 return true; |
378 } | 375 } |
379 } | 376 } |
380 return false; | 377 return false; |
381 } | 378 } |
382 | 379 |
383 } // namespace media | 380 } // namespace media |
Leandro Graciá Gil
2011/06/21 18:00:26
The namespace is media_stream.
mflodman1
2011/06/21 19:23:51
Done.
| |
OLD | NEW |