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

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

Issue 801363002: Queue commands to the Os to start a video device. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix potential race when calling VideoCapture::Start->Pause Created 6 years 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
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/renderer_host/media/video_capture_manager.h" 5 #include "content/browser/renderer_host/media/video_capture_manager.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 111
112 VideoCaptureManager::VideoCaptureManager( 112 VideoCaptureManager::VideoCaptureManager(
113 scoped_ptr<media::VideoCaptureDeviceFactory> factory) 113 scoped_ptr<media::VideoCaptureDeviceFactory> factory)
114 : listener_(NULL), 114 : listener_(NULL),
115 new_capture_session_id_(1), 115 new_capture_session_id_(1),
116 video_capture_device_factory_(factory.Pass()) { 116 video_capture_device_factory_(factory.Pass()) {
117 } 117 }
118 118
119 VideoCaptureManager::~VideoCaptureManager() { 119 VideoCaptureManager::~VideoCaptureManager() {
120 DCHECK(devices_.empty()); 120 DCHECK(devices_.empty());
121 DCHECK(device_start_queue_.empty());
121 } 122 }
122 123
123 void VideoCaptureManager::Register( 124 void VideoCaptureManager::Register(
124 MediaStreamProviderListener* listener, 125 MediaStreamProviderListener* listener,
125 const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner) { 126 const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner) {
126 DCHECK_CURRENTLY_ON(BrowserThread::IO); 127 DCHECK_CURRENTLY_ON(BrowserThread::IO);
127 DCHECK(!listener_); 128 DCHECK(!listener_);
128 DCHECK(!device_task_runner_.get()); 129 DCHECK(!device_task_runner_.get());
129 listener_ = listener; 130 listener_ = listener;
130 device_task_runner_ = device_task_runner; 131 device_task_runner_ = device_task_runner;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 DestroyDeviceEntryIfNoClients(existing_device); 210 DestroyDeviceEntryIfNoClients(existing_device);
210 } 211 }
211 212
212 // Notify listeners asynchronously, and forget the session. 213 // Notify listeners asynchronously, and forget the session.
213 base::MessageLoop::current()->PostTask(FROM_HERE, 214 base::MessageLoop::current()->PostTask(FROM_HERE,
214 base::Bind(&VideoCaptureManager::OnClosed, this, session_it->second.type, 215 base::Bind(&VideoCaptureManager::OnClosed, this, session_it->second.type,
215 capture_session_id)); 216 capture_session_id));
216 sessions_.erase(session_it); 217 sessions_.erase(session_it);
217 } 218 }
218 219
219 void VideoCaptureManager::DoStartDeviceOnDeviceThread( 220 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest(
221 DeviceEntry* entry,
222 media::VideoCaptureSessionId session_id,
223 const media::VideoCaptureParams& params)
224 : entry(entry),
225 session_id(session_id),
226 params(params),
227 abort_start(false) {
228 }
229
230 void VideoCaptureManager::QueueStartDevice(
220 media::VideoCaptureSessionId session_id, 231 media::VideoCaptureSessionId session_id,
221 DeviceEntry* entry, 232 DeviceEntry* entry,
233 const media::VideoCaptureParams& params) {
234 DCHECK_CURRENTLY_ON(BrowserThread::IO);
235 device_start_queue_.push_back(
236 CaptureDeviceStartRequest(entry, session_id, params));
237 if (device_start_queue_.size() == 1)
238 HandleQueuedStartRequest();
239 }
240
241 void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) {
242 DCHECK_CURRENTLY_ON(BrowserThread::IO);
243 DCHECK(std::find(devices_.begin(), devices_.end(), entry) != devices_.end());
244
245 // Reverse iterate to find the last start request. This also avoids a problem
246 // where |entry| might get the same pointer value if it is deleted
247 // and recreated while we are waiting for the device to be started.
tommi (sloooow) - chröme 2014/12/17 14:46:12 ah... hmm.. maybe it's a good thing to use a seria
perkj_chrome 2014/12/18 12:15:32 Done.
248 for (DeviceStartQueue::reverse_iterator request =
249 device_start_queue_.rbegin();
250 request != device_start_queue_.rend(); ++request) {
251 if (request->entry == entry) {
252 request->abort_start = true;
253 DVLOG(3) << "DoStopDevice, aborting start request for device "
254 << entry->id << "."
tommi (sloooow) - chröme 2014/12/17 14:46:12 nit: align <<
perkj_chrome 2014/12/18 12:15:32 Done.
255 return;
256 }
257 }
258
259 DVLOG(3) << "DoStopDevice. Send stop request for device " << entry->id << ".";
260 if (entry->video_capture_device.get()) {
261 // |entry->video_capture_device| can be null if creating the device fails.
262 device_task_runner_->PostTask(
263 FROM_HERE,
264 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
265 base::Passed(entry->video_capture_device.Pass())));
266 }
267 }
268
269 void VideoCaptureManager::HandleQueuedStartRequest() {
270 // Remove all start requests that have been aborted.
271 while(device_start_queue_.begin() != device_start_queue_.end() &&
272 device_start_queue_.begin()->abort_start) {
273 device_start_queue_.pop_front();
274 }
275 DeviceStartQueue::iterator request = device_start_queue_.begin();
276 if (request == device_start_queue_.end())
277 return;
278
279 DeviceEntry* entry = request->entry;
280 DCHECK(std::find(devices_.begin(), devices_.end(), request->entry) !=
281 devices_.end());
282
283 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = "
284 << entry->id;
285 base::PostTaskAndReplyWithResult(
286 device_task_runner_.get(),
287 FROM_HERE,
288 base::Bind(
289 &VideoCaptureManager::DoStartDeviceOnDeviceThread,
290 this,
291 request->session_id,
292 entry->id,
293 entry->stream_type,
294 request->params,
295 base::Passed(entry->video_capture_controller->NewDeviceClient())),
296 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, entry));
297 }
298
299 void VideoCaptureManager::OnDeviceStarted(
300 DeviceEntry* device_entry,
301 scoped_ptr<media::VideoCaptureDevice> device) {
302 DCHECK_CURRENTLY_ON(BrowserThread::IO);
303 DCHECK(device_entry == device_start_queue_.begin()->entry);
304 DVLOG(3) << "OnDeviceStarted";
305 if (device_start_queue_.front().abort_start) {
306 // |device| can be null if creation failed in DoStartDeviceOnDeviceThread.
307 // The device is no longer wanted. Stop the device again.
308 DVLOG(3) << "OnDeviceStarted but start request have been aborted.";
309 media::VideoCaptureDevice* device_ptr = device.get();
310 base::Closure closure =
311 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
312 base::Passed(&device));
313 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) {
314 // PostTask failed. The device must be stopped anyway.
315 device_ptr->StopAndDeAllocate();
316 }
317 } else {
318 DCHECK(std::find(devices_.begin(), devices_.end(), device_entry) !=
319 devices_.end());
320 device_entry->video_capture_device.swap(device);
321 }
322
323 device_start_queue_.pop_front();
324 HandleQueuedStartRequest();
325 }
326
327 scoped_ptr<media::VideoCaptureDevice>
328 VideoCaptureManager::DoStartDeviceOnDeviceThread(
329 media::VideoCaptureSessionId session_id,
330 const std::string& id,
331 MediaStreamType stream_type,
222 const media::VideoCaptureParams& params, 332 const media::VideoCaptureParams& params,
223 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { 333 scoped_ptr<media::VideoCaptureDevice::Client> device_client) {
224 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); 334 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
225 DCHECK(IsOnDeviceThread()); 335 DCHECK(IsOnDeviceThread());
226 336
227 scoped_ptr<media::VideoCaptureDevice> video_capture_device; 337 scoped_ptr<media::VideoCaptureDevice> video_capture_device;
228 switch (entry->stream_type) { 338 switch (stream_type) {
229 case MEDIA_DEVICE_VIDEO_CAPTURE: { 339 case MEDIA_DEVICE_VIDEO_CAPTURE: {
230 // We look up the device id from the renderer in our local enumeration 340 // We look up the device id from the renderer in our local enumeration
231 // since the renderer does not have all the information that might be 341 // since the renderer does not have all the information that might be
232 // held in the browser-side VideoCaptureDevice::Name structure. 342 // held in the browser-side VideoCaptureDevice::Name structure.
233 media::VideoCaptureDeviceInfo* found = 343 media::VideoCaptureDeviceInfo* found =
234 FindDeviceInfoById(entry->id, devices_info_cache_); 344 FindDeviceInfoById(id, devices_info_cache_);
235 if (found) { 345 if (found) {
236 video_capture_device = 346 video_capture_device =
237 video_capture_device_factory_->Create(found->name); 347 video_capture_device_factory_->Create(found->name);
238 } 348 }
239 break; 349 break;
240 } 350 }
241 case MEDIA_TAB_VIDEO_CAPTURE: { 351 case MEDIA_TAB_VIDEO_CAPTURE: {
242 video_capture_device.reset( 352 video_capture_device.reset(
243 WebContentsVideoCaptureDevice::Create(entry->id)); 353 WebContentsVideoCaptureDevice::Create(id));
244 break; 354 break;
245 } 355 }
246 case MEDIA_DESKTOP_VIDEO_CAPTURE: { 356 case MEDIA_DESKTOP_VIDEO_CAPTURE: {
247 #if defined(ENABLE_SCREEN_CAPTURE) 357 #if defined(ENABLE_SCREEN_CAPTURE)
248 DesktopMediaID id = DesktopMediaID::Parse(entry->id); 358 DesktopMediaID desktop_id = DesktopMediaID::Parse(id);
249 #if defined(USE_AURA) 359 #if defined(USE_AURA)
250 if (id.type == DesktopMediaID::TYPE_AURA_WINDOW) { 360 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) {
251 video_capture_device.reset(DesktopCaptureDeviceAura::Create(id)); 361 video_capture_device.reset(
362 DesktopCaptureDeviceAura::Create(desktop_id));
252 } else 363 } else
253 #endif 364 #endif
254 if (id.type != DesktopMediaID::TYPE_NONE && 365 if (desktop_id.type != DesktopMediaID::TYPE_NONE &&
255 id.type != DesktopMediaID::TYPE_AURA_WINDOW) { 366 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) {
256 video_capture_device = DesktopCaptureDevice::Create(id); 367 video_capture_device = DesktopCaptureDevice::Create(desktop_id);
257 if (notification_window_ids_.find(session_id) != 368 if (notification_window_ids_.find(session_id) !=
258 notification_window_ids_.end()) { 369 notification_window_ids_.end()) {
259 static_cast<DesktopCaptureDevice*>(video_capture_device.get()) 370 static_cast<DesktopCaptureDevice*>(video_capture_device.get())
260 ->SetNotificationWindowId(notification_window_ids_[session_id]); 371 ->SetNotificationWindowId(notification_window_ids_[session_id]);
261 VLOG(2) << "Screen capture notification window passed for session " 372 VLOG(2) << "Screen capture notification window passed for session "
262 << session_id; 373 << session_id;
263 } 374 }
264 } 375 }
265 #endif // defined(ENABLE_SCREEN_CAPTURE) 376 #endif // defined(ENABLE_SCREEN_CAPTURE)
266 break; 377 break;
267 } 378 }
268 default: { 379 default: {
269 NOTIMPLEMENTED(); 380 NOTIMPLEMENTED();
270 break; 381 break;
271 } 382 }
272 } 383 }
273 384
274 if (!video_capture_device) { 385 if (!video_capture_device) {
275 device_client->OnError("Could not create capture device"); 386 device_client->OnError("Could not create capture device");
276 return; 387 return nullptr;
277 } 388 }
278 389
279 video_capture_device->AllocateAndStart(params, device_client.Pass()); 390 video_capture_device->AllocateAndStart(params, device_client.Pass());
280 entry->video_capture_device = video_capture_device.Pass(); 391 return video_capture_device.Pass();
281 } 392 }
282 393
283 void VideoCaptureManager::StartCaptureForClient( 394 void VideoCaptureManager::StartCaptureForClient(
284 media::VideoCaptureSessionId session_id, 395 media::VideoCaptureSessionId session_id,
285 const media::VideoCaptureParams& params, 396 const media::VideoCaptureParams& params,
286 base::ProcessHandle client_render_process, 397 base::ProcessHandle client_render_process,
287 VideoCaptureControllerID client_id, 398 VideoCaptureControllerID client_id,
288 VideoCaptureControllerEventHandler* client_handler, 399 VideoCaptureControllerEventHandler* client_handler,
289 const DoneCB& done_cb) { 400 const DoneCB& done_cb) {
290 DCHECK_CURRENTLY_ON(BrowserThread::IO); 401 DCHECK_CURRENTLY_ON(BrowserThread::IO);
291 DVLOG(1) << "VideoCaptureManager::StartCaptureForClient, " 402 DVLOG(1) << "VideoCaptureManager::StartCaptureForClient, "
292 << params.requested_format.frame_size.ToString() << ", " 403 << params.requested_format.frame_size.ToString() << ", "
293 << params.requested_format.frame_rate << ", #" << session_id << ")"; 404 << params.requested_format.frame_rate << ", #" << session_id << ")";
294 405
295 DeviceEntry* entry = GetOrCreateDeviceEntry(session_id); 406 DeviceEntry* entry = GetOrCreateDeviceEntry(session_id);
296 if (!entry) { 407 if (!entry) {
297 done_cb.Run(base::WeakPtr<VideoCaptureController>()); 408 done_cb.Run(base::WeakPtr<VideoCaptureController>());
298 return; 409 return;
299 } 410 }
300 411
301 DCHECK(entry->video_capture_controller); 412 DCHECK(entry->video_capture_controller);
302 413
303 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); 414 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE);
304 415
305 // First client starts the device. 416 // First client starts the device.
306 if (entry->video_capture_controller->GetActiveClientCount() == 0) { 417 if (entry->video_capture_controller->GetActiveClientCount() == 0) {
307 DVLOG(1) << "VideoCaptureManager starting device (type = " 418 DVLOG(1) << "VideoCaptureManager starting device (type = "
308 << entry->stream_type << ", id = " << entry->id << ")"; 419 << entry->stream_type << ", id = " << entry->id << ")";
309 420 QueueStartDevice(session_id, entry, params);
310 device_task_runner_->PostTask(
311 FROM_HERE,
312 base::Bind(
313 &VideoCaptureManager::DoStartDeviceOnDeviceThread,
314 this,
315 session_id,
316 entry,
317 params,
318 base::Passed(entry->video_capture_controller->NewDeviceClient())));
319 } 421 }
320 // Run the callback first, as AddClient() may trigger OnFrameInfo(). 422 // Run the callback first, as AddClient() may trigger OnFrameInfo().
321 done_cb.Run(entry->video_capture_controller->GetWeakPtr()); 423 done_cb.Run(entry->video_capture_controller->GetWeakPtr());
322 entry->video_capture_controller->AddClient( 424 entry->video_capture_controller->AddClient(
323 client_id, client_handler, client_render_process, session_id, params); 425 client_id, client_handler, client_render_process, session_id, params);
324 } 426 }
325 427
326 void VideoCaptureManager::StopCaptureForClient( 428 void VideoCaptureManager::StopCaptureForClient(
327 VideoCaptureController* controller, 429 VideoCaptureController* controller,
328 VideoCaptureControllerID client_id, 430 VideoCaptureControllerID client_id,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 // We only pause the MEDIA_DEVICE_VIDEO_CAPTURE entry to release camera to 487 // We only pause the MEDIA_DEVICE_VIDEO_CAPTURE entry to release camera to
386 // system. 488 // system.
387 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) 489 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE)
388 return; 490 return;
389 491
390 controller->PauseOrResumeClient(client_id, client_handler, true); 492 controller->PauseOrResumeClient(client_id, client_handler, true);
391 if (controller->GetActiveClientCount() != 0) 493 if (controller->GetActiveClientCount() != 0)
392 return; 494 return;
393 495
394 // There is no more client, release the camera. 496 // There is no more client, release the camera.
395 device_task_runner_->PostTask( 497 DoStopDevice(entry);
396 FROM_HERE,
397 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
398 base::Unretained(entry)));
399 } 498 }
400 499
401 void VideoCaptureManager::ResumeCaptureForClient( 500 void VideoCaptureManager::ResumeCaptureForClient(
402 media::VideoCaptureSessionId session_id, 501 media::VideoCaptureSessionId session_id,
403 const media::VideoCaptureParams& params, 502 const media::VideoCaptureParams& params,
404 VideoCaptureController* controller, 503 VideoCaptureController* controller,
405 VideoCaptureControllerID client_id, 504 VideoCaptureControllerID client_id,
406 VideoCaptureControllerEventHandler* client_handler) { 505 VideoCaptureControllerEventHandler* client_handler) {
407 DCHECK_CURRENTLY_ON(BrowserThread::IO); 506 DCHECK_CURRENTLY_ON(BrowserThread::IO);
408 DCHECK(controller); 507 DCHECK(controller);
409 DCHECK(client_handler); 508 DCHECK(client_handler);
410 509
411 DeviceEntry* entry = GetDeviceEntryForController(controller); 510 DeviceEntry* entry = GetDeviceEntryForController(controller);
412 if (!entry) { 511 if (!entry) {
413 NOTREACHED(); 512 NOTREACHED();
414 return; 513 return;
415 } 514 }
416 515
417 // We only pause/resume the MEDIA_DEVICE_VIDEO_CAPTURE entry. 516 // We only pause/resume the MEDIA_DEVICE_VIDEO_CAPTURE entry.
418 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) 517 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE)
419 return; 518 return;
420 519
421 controller->PauseOrResumeClient(client_id, client_handler, false); 520 controller->PauseOrResumeClient(client_id, client_handler, false);
422 if (controller->GetActiveClientCount() != 1) 521 if (controller->GetActiveClientCount() != 1)
423 return; 522 return;
424 523
425 // This is first active client, allocate the camera. 524 // This is first active client, allocate the camera.
426 device_task_runner_->PostTask( 525 QueueStartDevice(session_id, entry, params);
427 FROM_HERE,
428 base::Bind(
429 &VideoCaptureManager::DoStartDeviceOnDeviceThread,
430 this,
431 session_id,
432 entry,
433 params,
434 base::Passed(entry->video_capture_controller->NewDeviceClient())));
435 } 526 }
436 527
437 bool VideoCaptureManager::GetDeviceSupportedFormats( 528 bool VideoCaptureManager::GetDeviceSupportedFormats(
438 media::VideoCaptureSessionId capture_session_id, 529 media::VideoCaptureSessionId capture_session_id,
439 media::VideoCaptureFormats* supported_formats) { 530 media::VideoCaptureFormats* supported_formats) {
440 DCHECK_CURRENTLY_ON(BrowserThread::IO); 531 DCHECK_CURRENTLY_ON(BrowserThread::IO);
441 DCHECK(supported_formats->empty()); 532 DCHECK(supported_formats->empty());
442 533
443 SessionMap::iterator it = sessions_.find(capture_session_id); 534 SessionMap::iterator it = sessions_.find(capture_session_id);
444 if (it == sessions_.end()) 535 if (it == sessions_.end())
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 } 601 }
511 602
512 device_task_runner_->PostTask( 603 device_task_runner_->PostTask(
513 FROM_HERE, 604 FROM_HERE,
514 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, 605 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread,
515 this, 606 this,
516 existing_device, 607 existing_device,
517 window_id)); 608 window_id));
518 } 609 }
519 610
520 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) { 611 void VideoCaptureManager::DoStopDeviceOnDeviceThread(
612 scoped_ptr<media::VideoCaptureDevice> device) {
521 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); 613 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime");
522 DCHECK(IsOnDeviceThread()); 614 DCHECK(IsOnDeviceThread());
523 if (entry->video_capture_device) { 615 device->StopAndDeAllocate();
524 entry->video_capture_device->StopAndDeAllocate(); 616 DVLOG(3) << "DoStopDeviceOnDeviceThread";
525 }
526 entry->video_capture_device.reset();
527 } 617 }
528 618
529 void VideoCaptureManager::OnOpened( 619 void VideoCaptureManager::OnOpened(
530 MediaStreamType stream_type, 620 MediaStreamType stream_type,
531 media::VideoCaptureSessionId capture_session_id) { 621 media::VideoCaptureSessionId capture_session_id) {
532 DCHECK_CURRENTLY_ON(BrowserThread::IO); 622 DCHECK_CURRENTLY_ON(BrowserThread::IO);
533 if (!listener_) { 623 if (!listener_) {
534 // Listener has been removed. 624 // Listener has been removed.
535 return; 625 return;
536 } 626 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 DCHECK_CURRENTLY_ON(BrowserThread::IO); 736 DCHECK_CURRENTLY_ON(BrowserThread::IO);
647 // Removal of the last client stops the device. 737 // Removal of the last client stops the device.
648 if (entry->video_capture_controller->GetClientCount() == 0) { 738 if (entry->video_capture_controller->GetClientCount() == 0) {
649 DVLOG(1) << "VideoCaptureManager stopping device (type = " 739 DVLOG(1) << "VideoCaptureManager stopping device (type = "
650 << entry->stream_type << ", id = " << entry->id << ")"; 740 << entry->stream_type << ", id = " << entry->id << ")";
651 741
652 // The DeviceEntry is removed from |devices_| immediately. The controller is 742 // The DeviceEntry is removed from |devices_| immediately. The controller is
653 // deleted immediately, and the device is freed asynchronously. After this 743 // deleted immediately, and the device is freed asynchronously. After this
654 // point, subsequent requests to open this same device ID will create a new 744 // point, subsequent requests to open this same device ID will create a new
655 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. 745 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice.
656 devices_.erase(entry); 746 DoStopDevice(entry);
657 entry->video_capture_controller.reset(); 747 DeviceEntries::iterator device_it = std::find(devices_.begin(),
658 device_task_runner_->PostTask( 748 devices_.end(),
659 FROM_HERE, 749 entry);
660 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, 750 devices_.erase(device_it);
661 base::Owned(entry)));
662 } 751 }
663 } 752 }
664 753
665 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( 754 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
666 media::VideoCaptureSessionId capture_session_id) { 755 media::VideoCaptureSessionId capture_session_id) {
667 DCHECK_CURRENTLY_ON(BrowserThread::IO); 756 DCHECK_CURRENTLY_ON(BrowserThread::IO);
668 757
669 SessionMap::iterator session_it = sessions_.find(capture_session_id); 758 SessionMap::iterator session_it = sessions_.find(capture_session_id);
670 if (session_it == sessions_.end()) { 759 if (session_it == sessions_.end()) {
671 return NULL; 760 return NULL;
672 } 761 }
673 const MediaStreamDevice& device_info = session_it->second; 762 const MediaStreamDevice& device_info = session_it->second;
674 763
675 // Check if another session has already opened this device. If so, just 764 // Check if another session has already opened this device. If so, just
676 // use that opened device. 765 // use that opened device.
677 DeviceEntry* const existing_device = 766 DeviceEntry* const existing_device =
678 GetDeviceEntryForMediaStreamDevice(device_info); 767 GetDeviceEntryForMediaStreamDevice(device_info);
679 if (existing_device) { 768 if (existing_device) {
680 DCHECK_EQ(device_info.type, existing_device->stream_type); 769 DCHECK_EQ(device_info.type, existing_device->stream_type);
681 return existing_device; 770 return existing_device;
682 } 771 }
683 772
684 const int max_buffers = device_info.type == MEDIA_TAB_VIDEO_CAPTURE ? 773 const int max_buffers = device_info.type == MEDIA_TAB_VIDEO_CAPTURE ?
685 kMaxNumberOfBuffersForTabCapture : kMaxNumberOfBuffers; 774 kMaxNumberOfBuffersForTabCapture : kMaxNumberOfBuffers;
686 scoped_ptr<VideoCaptureController> video_capture_controller( 775 scoped_ptr<VideoCaptureController> video_capture_controller(
687 new VideoCaptureController(max_buffers)); 776 new VideoCaptureController(max_buffers));
688 DeviceEntry* new_device = new DeviceEntry(device_info.type, 777 DeviceEntry* new_device = new DeviceEntry(device_info.type,
689 device_info.id, 778 device_info.id,
690 video_capture_controller.Pass()); 779 video_capture_controller.Pass());
691 devices_.insert(new_device); 780 devices_.push_back(new_device);
692 return new_device; 781 return new_device;
693 } 782 }
694 783
695 media::VideoCaptureDeviceInfo* VideoCaptureManager::FindDeviceInfoById( 784 media::VideoCaptureDeviceInfo* VideoCaptureManager::FindDeviceInfoById(
696 const std::string& id, 785 const std::string& id,
697 media::VideoCaptureDeviceInfos& device_vector) { 786 media::VideoCaptureDeviceInfos& device_vector) {
698 for (auto& it : device_vector) { 787 for (auto& it : device_vector) {
699 if (it.name.id() == id) 788 if (it.name.id() == id)
700 return &(it); 789 return &(it);
701 } 790 }
(...skipping 18 matching lines...) Expand all
720 gfx::NativeViewId window_id) { 809 gfx::NativeViewId window_id) {
721 DCHECK(IsOnDeviceThread()); 810 DCHECK(IsOnDeviceThread());
722 DCHECK(notification_window_ids_.find(session_id) == 811 DCHECK(notification_window_ids_.find(session_id) ==
723 notification_window_ids_.end()); 812 notification_window_ids_.end());
724 notification_window_ids_[session_id] = window_id; 813 notification_window_ids_[session_id] = window_id;
725 VLOG(2) << "Screen capture notification window saved for session " 814 VLOG(2) << "Screen capture notification window saved for session "
726 << session_id << " on device thread."; 815 << session_id << " on device thread.";
727 } 816 }
728 817
729 } // namespace content 818 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698