Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 MediaStreamType stream_type, | 106 MediaStreamType stream_type, |
| 107 const std::string& id, | 107 const std::string& id, |
| 108 scoped_ptr<VideoCaptureController> controller) | 108 scoped_ptr<VideoCaptureController> controller) |
| 109 : serial_id(g_device_start_id++), | 109 : serial_id(g_device_start_id++), |
| 110 stream_type(stream_type), | 110 stream_type(stream_type), |
| 111 id(id), | 111 id(id), |
| 112 video_capture_controller_(controller.Pass()) {} | 112 video_capture_controller_(controller.Pass()) {} |
| 113 | 113 |
| 114 VideoCaptureManager::DeviceEntry::~DeviceEntry() { | 114 VideoCaptureManager::DeviceEntry::~DeviceEntry() { |
| 115 DCHECK(thread_checker_.CalledOnValidThread()); | 115 DCHECK(thread_checker_.CalledOnValidThread()); |
| 116 // CHECK that the media::VideoCaptureDevice is not | |
|
miu
2015/02/06 21:51:47
s/media::VideoCaptureDevice/media::VideoCaptureDev
perkj_chrome
2015/02/09 08:27:41
I want to check that the entry does not own a medi
| |
| 117 // deleted on the wrong thread. | |
| 118 CHECK(video_capture_device_ == NULL); | |
|
Sergey Ulanov
2015/02/06 22:20:03
s/NULL/nullptr/, or CHECK(!video_capture_device_)
perkj_chrome
2015/02/09 08:27:41
ok. I am pretty sure the race is the problem that
| |
| 116 } | 119 } |
| 117 | 120 |
| 118 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice( | 121 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice( |
| 119 scoped_ptr<media::VideoCaptureDevice> device) { | 122 scoped_ptr<media::VideoCaptureDevice> device) { |
| 120 DCHECK(thread_checker_.CalledOnValidThread()); | 123 DCHECK(thread_checker_.CalledOnValidThread()); |
| 121 video_capture_device_.swap(device); | 124 video_capture_device_.swap(device); |
| 122 } | 125 } |
| 123 | 126 |
| 124 scoped_ptr<media::VideoCaptureDevice> | 127 scoped_ptr<media::VideoCaptureDevice> |
| 125 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() { | 128 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 352 // PostTask failed. The device must be stopped anyway. | 355 // PostTask failed. The device must be stopped anyway. |
| 353 device_ptr->StopAndDeAllocate(); | 356 device_ptr->StopAndDeAllocate(); |
| 354 } | 357 } |
| 355 } else { | 358 } else { |
| 356 DeviceEntries::iterator entry_it = std::find_if( | 359 DeviceEntries::iterator entry_it = std::find_if( |
| 357 devices_.begin(), devices_.end(), | 360 devices_.begin(), devices_.end(), |
| 358 [serial_id] (const DeviceEntry* e) { | 361 [serial_id] (const DeviceEntry* e) { |
| 359 return e->serial_id == serial_id; | 362 return e->serial_id == serial_id; |
| 360 }); | 363 }); |
| 361 DCHECK(entry_it != devices_.end()); | 364 DCHECK(entry_it != devices_.end()); |
| 362 DCHECK(!(*entry_it)->video_capture_device()); | 365 DeviceEntry* entry = *entry_it; |
| 363 (*entry_it)->SetVideoCaptureDevice(device.Pass()); | 366 DCHECK(!entry->video_capture_device()); |
| 367 entry->SetVideoCaptureDevice(device.Pass()); | |
| 368 | |
| 369 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | |
| 370 const media::VideoCaptureSessionId session_id = | |
| 371 device_start_queue_.front().session_id(); | |
| 372 MaybePostDesktopCaptureWindowId(session_id); | |
| 373 } | |
| 364 } | 374 } |
| 365 | 375 |
| 366 device_start_queue_.pop_front(); | 376 device_start_queue_.pop_front(); |
| 367 HandleQueuedStartRequest(); | 377 HandleQueuedStartRequest(); |
| 368 } | 378 } |
| 369 | 379 |
| 370 scoped_ptr<media::VideoCaptureDevice> | 380 scoped_ptr<media::VideoCaptureDevice> |
| 371 VideoCaptureManager::DoStartDeviceOnDeviceThread( | 381 VideoCaptureManager::DoStartDeviceOnDeviceThread( |
| 372 media::VideoCaptureSessionId session_id, | 382 media::VideoCaptureSessionId session_id, |
| 373 const std::string& id, | 383 const std::string& id, |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 401 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); | 411 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); |
| 402 #if defined(USE_AURA) | 412 #if defined(USE_AURA) |
| 403 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) { | 413 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) { |
| 404 video_capture_device.reset( | 414 video_capture_device.reset( |
| 405 DesktopCaptureDeviceAura::Create(desktop_id)); | 415 DesktopCaptureDeviceAura::Create(desktop_id)); |
| 406 } else | 416 } else |
| 407 #endif | 417 #endif |
| 408 if (desktop_id.type != DesktopMediaID::TYPE_NONE && | 418 if (desktop_id.type != DesktopMediaID::TYPE_NONE && |
| 409 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) { | 419 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) { |
| 410 video_capture_device = DesktopCaptureDevice::Create(desktop_id); | 420 video_capture_device = DesktopCaptureDevice::Create(desktop_id); |
| 411 if (notification_window_ids_.find(session_id) != | |
| 412 notification_window_ids_.end()) { | |
| 413 static_cast<DesktopCaptureDevice*>(video_capture_device.get()) | |
| 414 ->SetNotificationWindowId(notification_window_ids_[session_id]); | |
| 415 VLOG(2) << "Screen capture notification window passed for session " | |
| 416 << session_id; | |
| 417 } | |
| 418 } | 421 } |
| 419 #endif // defined(ENABLE_SCREEN_CAPTURE) | 422 #endif // defined(ENABLE_SCREEN_CAPTURE) |
| 420 break; | 423 break; |
| 421 } | 424 } |
| 422 default: { | 425 default: { |
| 423 NOTIMPLEMENTED(); | 426 NOTIMPLEMENTED(); |
| 424 break; | 427 break; |
| 425 } | 428 } |
| 426 } | 429 } |
| 427 | 430 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 } | 611 } |
| 609 return true; | 612 return true; |
| 610 } | 613 } |
| 611 | 614 |
| 612 void VideoCaptureManager::SetDesktopCaptureWindowId( | 615 void VideoCaptureManager::SetDesktopCaptureWindowId( |
| 613 media::VideoCaptureSessionId session_id, | 616 media::VideoCaptureSessionId session_id, |
| 614 gfx::NativeViewId window_id) { | 617 gfx::NativeViewId window_id) { |
| 615 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 618 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 616 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; | 619 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; |
| 617 | 620 |
| 621 notification_window_ids_[session_id] = window_id; | |
| 622 MaybePostDesktopCaptureWindowId(session_id); | |
| 623 } | |
| 624 | |
| 625 void VideoCaptureManager::MaybePostDesktopCaptureWindowId( | |
| 626 media::VideoCaptureSessionId session_id) { | |
| 618 SessionMap::iterator session_it = sessions_.find(session_id); | 627 SessionMap::iterator session_it = sessions_.find(session_id); |
| 619 if (session_it == sessions_.end()) { | 628 if (session_it == sessions_.end()) { |
| 620 VLOG(2) << "Session not found, will save the notification window."; | 629 return; |
| 621 device_task_runner_->PostTask( | 630 } |
| 622 FROM_HERE, | 631 |
| 623 base::Bind( | 632 if (notification_window_ids_.find(session_id) == |
| 624 &VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread, | 633 notification_window_ids_.end()) { |
| 625 this, | 634 DVLOG(2) << "Notification window id not set for screen capture."; |
| 626 session_id, | |
| 627 window_id)); | |
| 628 return; | 635 return; |
| 629 } | 636 } |
| 630 | 637 |
| 631 DeviceEntry* const existing_device = | 638 DeviceEntry* const existing_device = |
| 632 GetDeviceEntryForMediaStreamDevice(session_it->second); | 639 GetDeviceEntryForMediaStreamDevice(session_it->second); |
| 633 if (!existing_device) { | 640 if (!existing_device) { |
| 634 VLOG(2) << "Failed to find an existing device."; | 641 DVLOG(2) << "Failed to find an existing screen capture device."; |
| 635 return; | 642 return; |
| 636 } | 643 } |
| 637 | 644 |
| 645 if (!existing_device->video_capture_device()) { | |
| 646 DVLOG(2) << "Screen capture device not yet started."; | |
| 647 return; | |
| 648 } | |
| 649 | |
| 638 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); | 650 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); |
| 639 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); | 651 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); |
| 640 if (id.type == DesktopMediaID::TYPE_NONE || | 652 if (id.type == DesktopMediaID::TYPE_NONE || |
| 641 id.type == DesktopMediaID::TYPE_AURA_WINDOW) { | 653 id.type == DesktopMediaID::TYPE_AURA_WINDOW) { |
| 642 VLOG(2) << "Video capture device type mismatch."; | 654 VLOG(2) << "Video capture device type mismatch."; |
| 643 return; | 655 return; |
| 644 } | 656 } |
| 645 | 657 |
| 646 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to | 658 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to |
| 647 // the device_task_runner_. This is safe since the device is destroyed on the | 659 // the device_task_runner_. This is safe since the device is destroyed on the |
| 648 // device_task_runner_. | 660 // device_task_runner_. |
| 649 device_task_runner_->PostTask( | 661 device_task_runner_->PostTask( |
| 650 FROM_HERE, | 662 FROM_HERE, |
| 651 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, | 663 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, |
| 652 this, | 664 this, |
| 653 existing_device->video_capture_device(), | 665 existing_device->video_capture_device(), |
| 654 window_id)); | 666 notification_window_ids_[session_id])); |
|
Sergey Ulanov
2015/02/06 22:20:03
I think you also want to remove the value from not
perkj_chrome
2015/02/09 08:27:41
ok, so this will fix an old bug as well? It looks
| |
| 655 } | 667 } |
| 656 | 668 |
| 657 void VideoCaptureManager::DoStopDeviceOnDeviceThread( | 669 void VideoCaptureManager::DoStopDeviceOnDeviceThread( |
| 658 scoped_ptr<media::VideoCaptureDevice> device) { | 670 scoped_ptr<media::VideoCaptureDevice> device) { |
| 659 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); | 671 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
| 660 DCHECK(IsOnDeviceThread()); | 672 DCHECK(IsOnDeviceThread()); |
| 661 device->StopAndDeAllocate(); | 673 device->StopAndDeAllocate(); |
| 662 DVLOG(3) << "DoStopDeviceOnDeviceThread"; | 674 DVLOG(3) << "DoStopDeviceOnDeviceThread"; |
| 663 } | 675 } |
| 664 | 676 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 gfx::NativeViewId window_id) { | 854 gfx::NativeViewId window_id) { |
| 843 DCHECK(IsOnDeviceThread()); | 855 DCHECK(IsOnDeviceThread()); |
| 844 #if defined(ENABLE_SCREEN_CAPTURE) | 856 #if defined(ENABLE_SCREEN_CAPTURE) |
| 845 DesktopCaptureDevice* desktop_device = | 857 DesktopCaptureDevice* desktop_device = |
| 846 static_cast<DesktopCaptureDevice*>(device); | 858 static_cast<DesktopCaptureDevice*>(device); |
| 847 desktop_device->SetNotificationWindowId(window_id); | 859 desktop_device->SetNotificationWindowId(window_id); |
| 848 VLOG(2) << "Screen capture notification window passed on device thread."; | 860 VLOG(2) << "Screen capture notification window passed on device thread."; |
| 849 #endif | 861 #endif |
| 850 } | 862 } |
| 851 | 863 |
| 852 void VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread( | |
| 853 media::VideoCaptureSessionId session_id, | |
| 854 gfx::NativeViewId window_id) { | |
| 855 DCHECK(IsOnDeviceThread()); | |
| 856 DCHECK(notification_window_ids_.find(session_id) == | |
| 857 notification_window_ids_.end()); | |
| 858 notification_window_ids_[session_id] = window_id; | |
| 859 VLOG(2) << "Screen capture notification window saved for session " | |
| 860 << session_id << " on device thread."; | |
| 861 } | |
| 862 | |
| 863 } // namespace content | 864 } // namespace content |
| OLD | NEW |