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); |
} |
} |