Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_manager.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc |
| index 617a8696deeacb2c2f8d0ef5e8ceb1b24416b5f7..ac999afa31d41c8b3aa8765afa84907efcd5fc53 100644 |
| --- a/content/browser/renderer_host/media/video_capture_manager.cc |
| +++ b/content/browser/renderer_host/media/video_capture_manager.cc |
| @@ -118,6 +118,7 @@ VideoCaptureManager::VideoCaptureManager( |
| VideoCaptureManager::~VideoCaptureManager() { |
| DCHECK(devices_.empty()); |
| + DCHECK(device_start_queue_.empty()); |
| } |
| void VideoCaptureManager::Register( |
| @@ -216,6 +217,94 @@ void VideoCaptureManager::Close(int capture_session_id) { |
| sessions_.erase(session_it); |
| } |
| +// Creates a start request. |
| +VideoCaptureManager:: |
| +CaptureDeviceStartRequest::CaptureDeviceStartRequest( |
|
tommi (sloooow) - chröme
2014/12/15 16:25:05
no need to wrap?
perkj_chrome
2014/12/16 20:15:05
media::VideoCaptureSessionId session_id, does not
tommi (sloooow) - chröme
2014/12/16 22:31:25
I meant the function:
VideoCaptureManager::Captur
|
| + DeviceEntry* device_entry, |
| + media::VideoCaptureSessionId session_id, |
| + const media::VideoCaptureParams& params) |
| + : device_entry(device_entry), |
| + session_id(session_id), |
| + params(params) { |
| +} |
| + |
| +void VideoCaptureManager::QueueStartDevice( |
| + media::VideoCaptureSessionId session_id, |
| + DeviceEntry* entry, |
| + const media::VideoCaptureParams& params) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK(entry->video_capture_controller.get()); |
| + DVLOG(3) << "QueueStartDevice, device = " << entry->id; |
| + |
| + device_start_queue_.push_back( |
| + CaptureDeviceStartRequest(entry, session_id, params)); |
| + if (device_start_queue_.size() == 1) { |
| + HandleQueuedStartRequest(); |
| + } |
| +} |
| + |
| +void VideoCaptureManager::DoStopDevice(DeviceEntry* entry, bool delete_entry) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + // Check if the start request has not yet been sent to the device thread. |
| + // If so, delete the request. |
| + if (device_start_queue_.size() > 1) { |
| + for (DeviceStartQueue::iterator request = ++device_start_queue_.begin(); |
| + request != device_start_queue_.end(); ++request) { |
| + if (request->device_entry->id == entry->id && |
| + request->device_entry->stream_type == entry->stream_type) { |
| + device_start_queue_.erase(request); |
| + DVLOG(3) << "DoStopDevice, erasing start request for device " |
| + << entry->id << "."; |
| + if (delete_entry) { |
| + delete entry; |
|
tommi (sloooow) - chröme
2014/12/15 16:25:05
can we use a scoped_ptr<> for this instead?
|
| + } |
| + return; |
| + } |
| + } |
| + } |
| + |
| + DVLOG(3) << "DoStopDevice. Send stop request for device " << entry->id << "."; |
| + if (delete_entry) { |
|
tommi (sloooow) - chröme
2014/12/15 16:25:05
FYI - here there are two call sites + bindings for
|
| + device_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| + base::Owned(entry))); |
| + } else { |
| + device_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| + base::Unretained(entry))); |
| + } |
| +} |
| + |
| +void VideoCaptureManager::HandleQueuedStartRequest() { |
| + auto request = device_start_queue_.begin(); |
| + if (request == device_start_queue_.end()) |
| + return; |
| + |
| + DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
| + << request->device_entry->id; |
| + |
| + device_task_runner_->PostTaskAndReply( |
| + FROM_HERE, |
| + base::Bind( |
| + &VideoCaptureManager::DoStartDeviceOnDeviceThread, |
| + this, |
| + request->session_id, |
| + request->device_entry, |
| + request->params, |
| + base::Passed(request->device_entry->video_capture_controller-> |
| + NewDeviceClient())), |
| + base::Bind(&VideoCaptureManager::OnDeviceStarted, this)); |
| +} |
| + |
| +void VideoCaptureManager::OnDeviceStarted() { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DVLOG(3) << "OnDeviceStarted"; |
| + device_start_queue_.pop_front(); |
| + HandleQueuedStartRequest(); |
| +} |
| + |
| void VideoCaptureManager::DoStartDeviceOnDeviceThread( |
| media::VideoCaptureSessionId session_id, |
| DeviceEntry* entry, |
| @@ -306,16 +395,7 @@ void VideoCaptureManager::StartCaptureForClient( |
| if (entry->video_capture_controller->GetActiveClientCount() == 0) { |
| DVLOG(1) << "VideoCaptureManager starting device (type = " |
| << entry->stream_type << ", id = " << entry->id << ")"; |
| - |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind( |
| - &VideoCaptureManager::DoStartDeviceOnDeviceThread, |
| - this, |
| - session_id, |
| - entry, |
| - params, |
| - base::Passed(entry->video_capture_controller->NewDeviceClient()))); |
| + QueueStartDevice(session_id, entry, params); |
| } |
| // Run the callback first, as AddClient() may trigger OnFrameInfo(). |
| done_cb.Run(entry->video_capture_controller->GetWeakPtr()); |
| @@ -392,10 +472,7 @@ void VideoCaptureManager::PauseCaptureForClient( |
| return; |
| // There is no more client, release the camera. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| - base::Unretained(entry))); |
| + DoStopDevice(entry, false); |
| } |
| void VideoCaptureManager::ResumeCaptureForClient( |
| @@ -423,15 +500,7 @@ void VideoCaptureManager::ResumeCaptureForClient( |
| return; |
| // This is first active client, allocate the camera. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind( |
| - &VideoCaptureManager::DoStartDeviceOnDeviceThread, |
| - this, |
| - session_id, |
| - entry, |
| - params, |
| - base::Passed(entry->video_capture_controller->NewDeviceClient()))); |
| + QueueStartDevice(session_id, entry, params); |
| } |
| bool VideoCaptureManager::GetDeviceSupportedFormats( |
| @@ -655,10 +724,7 @@ void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { |
| // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. |
| devices_.erase(entry); |
| entry->video_capture_controller.reset(); |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| - base::Owned(entry))); |
| + DoStopDevice(entry, true); |
| } |
| } |