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

Unified 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: 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 side-by-side diff with in-line comments
Download patch
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);
}
}

Powered by Google App Engine
This is Rietveld 408576698