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

Side by Side Diff: content/browser/renderer_host/media/video_capture_manager.cc

Issue 7192007: Adding error signalling from device to VideocaptureManager to relay up to MediaStream and WebKit. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Adding the gyp-files. Created 9 years, 6 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) 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
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
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
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
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.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698