| 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 // DCHECK that this DeviceEntry does not still own a |
| 117 // media::VideoCaptureDevice. media::VideoCaptureDevice must be deleted on |
| 118 // the device thread. |
| 119 DCHECK(video_capture_device_ == nullptr); |
| 116 } | 120 } |
| 117 | 121 |
| 118 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice( | 122 void VideoCaptureManager::DeviceEntry::SetVideoCaptureDevice( |
| 119 scoped_ptr<media::VideoCaptureDevice> device) { | 123 scoped_ptr<media::VideoCaptureDevice> device) { |
| 120 DCHECK(thread_checker_.CalledOnValidThread()); | 124 DCHECK(thread_checker_.CalledOnValidThread()); |
| 121 video_capture_device_.swap(device); | 125 video_capture_device_.swap(device); |
| 122 } | 126 } |
| 123 | 127 |
| 124 scoped_ptr<media::VideoCaptureDevice> | 128 scoped_ptr<media::VideoCaptureDevice> |
| 125 VideoCaptureManager::DeviceEntry::ReleaseVideoCaptureDevice() { | 129 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. | 356 // PostTask failed. The device must be stopped anyway. |
| 353 device_ptr->StopAndDeAllocate(); | 357 device_ptr->StopAndDeAllocate(); |
| 354 } | 358 } |
| 355 } else { | 359 } else { |
| 356 DeviceEntries::iterator entry_it = std::find_if( | 360 DeviceEntries::iterator entry_it = std::find_if( |
| 357 devices_.begin(), devices_.end(), | 361 devices_.begin(), devices_.end(), |
| 358 [serial_id] (const DeviceEntry* e) { | 362 [serial_id] (const DeviceEntry* e) { |
| 359 return e->serial_id == serial_id; | 363 return e->serial_id == serial_id; |
| 360 }); | 364 }); |
| 361 DCHECK(entry_it != devices_.end()); | 365 DCHECK(entry_it != devices_.end()); |
| 362 DCHECK(!(*entry_it)->video_capture_device()); | 366 DeviceEntry* entry = *entry_it; |
| 363 (*entry_it)->SetVideoCaptureDevice(device.Pass()); | 367 DCHECK(!entry->video_capture_device()); |
| 368 entry->SetVideoCaptureDevice(device.Pass()); |
| 369 |
| 370 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| 371 const media::VideoCaptureSessionId session_id = |
| 372 device_start_queue_.front().session_id(); |
| 373 MaybePostDesktopCaptureWindowId(session_id); |
| 374 } |
| 364 } | 375 } |
| 365 | 376 |
| 366 device_start_queue_.pop_front(); | 377 device_start_queue_.pop_front(); |
| 367 HandleQueuedStartRequest(); | 378 HandleQueuedStartRequest(); |
| 368 } | 379 } |
| 369 | 380 |
| 370 scoped_ptr<media::VideoCaptureDevice> | 381 scoped_ptr<media::VideoCaptureDevice> |
| 371 VideoCaptureManager::DoStartDeviceOnDeviceThread( | 382 VideoCaptureManager::DoStartDeviceOnDeviceThread( |
| 372 media::VideoCaptureSessionId session_id, | 383 media::VideoCaptureSessionId session_id, |
| 373 const std::string& id, | 384 const std::string& id, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 401 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); | 412 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); |
| 402 #if defined(USE_AURA) | 413 #if defined(USE_AURA) |
| 403 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) { | 414 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) { |
| 404 video_capture_device.reset( | 415 video_capture_device.reset( |
| 405 DesktopCaptureDeviceAura::Create(desktop_id)); | 416 DesktopCaptureDeviceAura::Create(desktop_id)); |
| 406 } else | 417 } else |
| 407 #endif | 418 #endif |
| 408 if (desktop_id.type != DesktopMediaID::TYPE_NONE && | 419 if (desktop_id.type != DesktopMediaID::TYPE_NONE && |
| 409 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) { | 420 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) { |
| 410 video_capture_device = DesktopCaptureDevice::Create(desktop_id); | 421 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 } | 422 } |
| 419 #endif // defined(ENABLE_SCREEN_CAPTURE) | 423 #endif // defined(ENABLE_SCREEN_CAPTURE) |
| 420 break; | 424 break; |
| 421 } | 425 } |
| 422 default: { | 426 default: { |
| 423 NOTIMPLEMENTED(); | 427 NOTIMPLEMENTED(); |
| 424 break; | 428 break; |
| 425 } | 429 } |
| 426 } | 430 } |
| 427 | 431 |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 } | 612 } |
| 609 return true; | 613 return true; |
| 610 } | 614 } |
| 611 | 615 |
| 612 void VideoCaptureManager::SetDesktopCaptureWindowId( | 616 void VideoCaptureManager::SetDesktopCaptureWindowId( |
| 613 media::VideoCaptureSessionId session_id, | 617 media::VideoCaptureSessionId session_id, |
| 614 gfx::NativeViewId window_id) { | 618 gfx::NativeViewId window_id) { |
| 615 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 619 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 616 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; | 620 VLOG(2) << "SetDesktopCaptureWindowId called for session " << session_id; |
| 617 | 621 |
| 622 notification_window_ids_[session_id] = window_id; |
| 623 MaybePostDesktopCaptureWindowId(session_id); |
| 624 } |
| 625 |
| 626 void VideoCaptureManager::MaybePostDesktopCaptureWindowId( |
| 627 media::VideoCaptureSessionId session_id) { |
| 618 SessionMap::iterator session_it = sessions_.find(session_id); | 628 SessionMap::iterator session_it = sessions_.find(session_id); |
| 619 if (session_it == sessions_.end()) { | 629 if (session_it == sessions_.end()) { |
| 620 VLOG(2) << "Session not found, will save the notification window."; | |
| 621 device_task_runner_->PostTask( | |
| 622 FROM_HERE, | |
| 623 base::Bind( | |
| 624 &VideoCaptureManager::SaveDesktopCaptureWindowIdOnDeviceThread, | |
| 625 this, | |
| 626 session_id, | |
| 627 window_id)); | |
| 628 return; | 630 return; |
| 629 } | 631 } |
| 630 | 632 |
| 631 DeviceEntry* const existing_device = | 633 DeviceEntry* const existing_device = |
| 632 GetDeviceEntryForMediaStreamDevice(session_it->second); | 634 GetDeviceEntryForMediaStreamDevice(session_it->second); |
| 633 if (!existing_device) { | 635 if (!existing_device) { |
| 634 VLOG(2) << "Failed to find an existing device."; | 636 DVLOG(2) << "Failed to find an existing screen capture device."; |
| 635 return; | 637 return; |
| 636 } | 638 } |
| 637 | 639 |
| 640 if (!existing_device->video_capture_device()) { |
| 641 DVLOG(2) << "Screen capture device not yet started."; |
| 642 return; |
| 643 } |
| 644 |
| 638 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); | 645 DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); |
| 639 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); | 646 DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); |
| 640 if (id.type == DesktopMediaID::TYPE_NONE || | 647 if (id.type == DesktopMediaID::TYPE_NONE || |
| 641 id.type == DesktopMediaID::TYPE_AURA_WINDOW) { | 648 id.type == DesktopMediaID::TYPE_AURA_WINDOW) { |
| 642 VLOG(2) << "Video capture device type mismatch."; | 649 VLOG(2) << "Video capture device type mismatch."; |
| 643 return; | 650 return; |
| 644 } | 651 } |
| 645 | 652 |
| 653 auto window_id_it = notification_window_ids_.find(session_id); |
| 654 if (window_id_it == notification_window_ids_.end()) { |
| 655 DVLOG(2) << "Notification window id not set for screen capture."; |
| 656 return; |
| 657 } |
| 658 |
| 646 // Post |existing_device->video_capture_device| to the VideoCaptureDevice to | 659 // 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 | 660 // the device_task_runner_. This is safe since the device is destroyed on the |
| 648 // device_task_runner_. | 661 // device_task_runner_. |
| 649 device_task_runner_->PostTask( | 662 device_task_runner_->PostTask( |
| 650 FROM_HERE, | 663 FROM_HERE, |
| 651 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, | 664 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, |
| 652 this, | 665 this, |
| 653 existing_device->video_capture_device(), | 666 existing_device->video_capture_device(), |
| 654 window_id)); | 667 window_id_it->second)); |
| 668 |
| 669 notification_window_ids_.erase(window_id_it); |
| 655 } | 670 } |
| 656 | 671 |
| 657 void VideoCaptureManager::DoStopDeviceOnDeviceThread( | 672 void VideoCaptureManager::DoStopDeviceOnDeviceThread( |
| 658 scoped_ptr<media::VideoCaptureDevice> device) { | 673 scoped_ptr<media::VideoCaptureDevice> device) { |
| 659 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); | 674 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
| 660 DCHECK(IsOnDeviceThread()); | 675 DCHECK(IsOnDeviceThread()); |
| 661 device->StopAndDeAllocate(); | 676 device->StopAndDeAllocate(); |
| 662 DVLOG(3) << "DoStopDeviceOnDeviceThread"; | 677 DVLOG(3) << "DoStopDeviceOnDeviceThread"; |
| 663 } | 678 } |
| 664 | 679 |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 gfx::NativeViewId window_id) { | 857 gfx::NativeViewId window_id) { |
| 843 DCHECK(IsOnDeviceThread()); | 858 DCHECK(IsOnDeviceThread()); |
| 844 #if defined(ENABLE_SCREEN_CAPTURE) | 859 #if defined(ENABLE_SCREEN_CAPTURE) |
| 845 DesktopCaptureDevice* desktop_device = | 860 DesktopCaptureDevice* desktop_device = |
| 846 static_cast<DesktopCaptureDevice*>(device); | 861 static_cast<DesktopCaptureDevice*>(device); |
| 847 desktop_device->SetNotificationWindowId(window_id); | 862 desktop_device->SetNotificationWindowId(window_id); |
| 848 VLOG(2) << "Screen capture notification window passed on device thread."; | 863 VLOG(2) << "Screen capture notification window passed on device thread."; |
| 849 #endif | 864 #endif |
| 850 } | 865 } |
| 851 | 866 |
| 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 | 867 } // namespace content |
| OLD | NEW |