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

Side by Side 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 unified diff | Download patch
OLDNEW
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 <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 111
112 VideoCaptureManager::VideoCaptureManager( 112 VideoCaptureManager::VideoCaptureManager(
113 scoped_ptr<media::VideoCaptureDeviceFactory> factory) 113 scoped_ptr<media::VideoCaptureDeviceFactory> factory)
114 : listener_(NULL), 114 : listener_(NULL),
115 new_capture_session_id_(1), 115 new_capture_session_id_(1),
116 video_capture_device_factory_(factory.Pass()) { 116 video_capture_device_factory_(factory.Pass()) {
117 } 117 }
118 118
119 VideoCaptureManager::~VideoCaptureManager() { 119 VideoCaptureManager::~VideoCaptureManager() {
120 DCHECK(devices_.empty()); 120 DCHECK(devices_.empty());
121 DCHECK(device_start_queue_.empty());
121 } 122 }
122 123
123 void VideoCaptureManager::Register( 124 void VideoCaptureManager::Register(
124 MediaStreamProviderListener* listener, 125 MediaStreamProviderListener* listener,
125 const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner) { 126 const scoped_refptr<base::SingleThreadTaskRunner>& device_task_runner) {
126 DCHECK_CURRENTLY_ON(BrowserThread::IO); 127 DCHECK_CURRENTLY_ON(BrowserThread::IO);
127 DCHECK(!listener_); 128 DCHECK(!listener_);
128 DCHECK(!device_task_runner_.get()); 129 DCHECK(!device_task_runner_.get());
129 listener_ = listener; 130 listener_ = listener;
130 device_task_runner_ = device_task_runner; 131 device_task_runner_ = device_task_runner;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 DestroyDeviceEntryIfNoClients(existing_device); 210 DestroyDeviceEntryIfNoClients(existing_device);
210 } 211 }
211 212
212 // Notify listeners asynchronously, and forget the session. 213 // Notify listeners asynchronously, and forget the session.
213 base::MessageLoop::current()->PostTask(FROM_HERE, 214 base::MessageLoop::current()->PostTask(FROM_HERE,
214 base::Bind(&VideoCaptureManager::OnClosed, this, session_it->second.type, 215 base::Bind(&VideoCaptureManager::OnClosed, this, session_it->second.type,
215 capture_session_id)); 216 capture_session_id));
216 sessions_.erase(session_it); 217 sessions_.erase(session_it);
217 } 218 }
218 219
220 // Creates a start request.
221 VideoCaptureManager::
222 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
223 DeviceEntry* device_entry,
224 media::VideoCaptureSessionId session_id,
225 const media::VideoCaptureParams& params)
226 : device_entry(device_entry),
227 session_id(session_id),
228 params(params) {
229 }
230
231 void VideoCaptureManager::QueueStartDevice(
232 media::VideoCaptureSessionId session_id,
233 DeviceEntry* entry,
234 const media::VideoCaptureParams& params) {
235 DCHECK_CURRENTLY_ON(BrowserThread::IO);
236 DCHECK(entry->video_capture_controller.get());
237 DVLOG(3) << "QueueStartDevice, device = " << entry->id;
238
239 device_start_queue_.push_back(
240 CaptureDeviceStartRequest(entry, session_id, params));
241 if (device_start_queue_.size() == 1) {
242 HandleQueuedStartRequest();
243 }
244 }
245
246 void VideoCaptureManager::DoStopDevice(DeviceEntry* entry, bool delete_entry) {
247 DCHECK_CURRENTLY_ON(BrowserThread::IO);
248 // Check if the start request has not yet been sent to the device thread.
249 // If so, delete the request.
250 if (device_start_queue_.size() > 1) {
251 for (DeviceStartQueue::iterator request = ++device_start_queue_.begin();
252 request != device_start_queue_.end(); ++request) {
253 if (request->device_entry->id == entry->id &&
254 request->device_entry->stream_type == entry->stream_type) {
255 device_start_queue_.erase(request);
256 DVLOG(3) << "DoStopDevice, erasing start request for device "
257 << entry->id << ".";
258 if (delete_entry) {
259 delete entry;
tommi (sloooow) - chröme 2014/12/15 16:25:05 can we use a scoped_ptr<> for this instead?
260 }
261 return;
262 }
263 }
264 }
265
266 DVLOG(3) << "DoStopDevice. Send stop request for device " << entry->id << ".";
267 if (delete_entry) {
tommi (sloooow) - chröme 2014/12/15 16:25:05 FYI - here there are two call sites + bindings for
268 device_task_runner_->PostTask(
269 FROM_HERE,
270 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
271 base::Owned(entry)));
272 } else {
273 device_task_runner_->PostTask(
274 FROM_HERE,
275 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
276 base::Unretained(entry)));
277 }
278 }
279
280 void VideoCaptureManager::HandleQueuedStartRequest() {
281 auto request = device_start_queue_.begin();
282 if (request == device_start_queue_.end())
283 return;
284
285 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = "
286 << request->device_entry->id;
287
288 device_task_runner_->PostTaskAndReply(
289 FROM_HERE,
290 base::Bind(
291 &VideoCaptureManager::DoStartDeviceOnDeviceThread,
292 this,
293 request->session_id,
294 request->device_entry,
295 request->params,
296 base::Passed(request->device_entry->video_capture_controller->
297 NewDeviceClient())),
298 base::Bind(&VideoCaptureManager::OnDeviceStarted, this));
299 }
300
301 void VideoCaptureManager::OnDeviceStarted() {
302 DCHECK_CURRENTLY_ON(BrowserThread::IO);
303 DVLOG(3) << "OnDeviceStarted";
304 device_start_queue_.pop_front();
305 HandleQueuedStartRequest();
306 }
307
219 void VideoCaptureManager::DoStartDeviceOnDeviceThread( 308 void VideoCaptureManager::DoStartDeviceOnDeviceThread(
220 media::VideoCaptureSessionId session_id, 309 media::VideoCaptureSessionId session_id,
221 DeviceEntry* entry, 310 DeviceEntry* entry,
222 const media::VideoCaptureParams& params, 311 const media::VideoCaptureParams& params,
223 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { 312 scoped_ptr<media::VideoCaptureDevice::Client> device_client) {
224 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); 313 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime");
225 DCHECK(IsOnDeviceThread()); 314 DCHECK(IsOnDeviceThread());
226 315
227 scoped_ptr<media::VideoCaptureDevice> video_capture_device; 316 scoped_ptr<media::VideoCaptureDevice> video_capture_device;
228 switch (entry->stream_type) { 317 switch (entry->stream_type) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 388 }
300 389
301 DCHECK(entry->video_capture_controller); 390 DCHECK(entry->video_capture_controller);
302 391
303 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); 392 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE);
304 393
305 // First client starts the device. 394 // First client starts the device.
306 if (entry->video_capture_controller->GetActiveClientCount() == 0) { 395 if (entry->video_capture_controller->GetActiveClientCount() == 0) {
307 DVLOG(1) << "VideoCaptureManager starting device (type = " 396 DVLOG(1) << "VideoCaptureManager starting device (type = "
308 << entry->stream_type << ", id = " << entry->id << ")"; 397 << entry->stream_type << ", id = " << entry->id << ")";
309 398 QueueStartDevice(session_id, entry, params);
310 device_task_runner_->PostTask(
311 FROM_HERE,
312 base::Bind(
313 &VideoCaptureManager::DoStartDeviceOnDeviceThread,
314 this,
315 session_id,
316 entry,
317 params,
318 base::Passed(entry->video_capture_controller->NewDeviceClient())));
319 } 399 }
320 // Run the callback first, as AddClient() may trigger OnFrameInfo(). 400 // Run the callback first, as AddClient() may trigger OnFrameInfo().
321 done_cb.Run(entry->video_capture_controller->GetWeakPtr()); 401 done_cb.Run(entry->video_capture_controller->GetWeakPtr());
322 entry->video_capture_controller->AddClient( 402 entry->video_capture_controller->AddClient(
323 client_id, client_handler, client_render_process, session_id, params); 403 client_id, client_handler, client_render_process, session_id, params);
324 } 404 }
325 405
326 void VideoCaptureManager::StopCaptureForClient( 406 void VideoCaptureManager::StopCaptureForClient(
327 VideoCaptureController* controller, 407 VideoCaptureController* controller,
328 VideoCaptureControllerID client_id, 408 VideoCaptureControllerID client_id,
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 // We only pause the MEDIA_DEVICE_VIDEO_CAPTURE entry to release camera to 465 // We only pause the MEDIA_DEVICE_VIDEO_CAPTURE entry to release camera to
386 // system. 466 // system.
387 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) 467 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE)
388 return; 468 return;
389 469
390 controller->PauseOrResumeClient(client_id, client_handler, true); 470 controller->PauseOrResumeClient(client_id, client_handler, true);
391 if (controller->GetActiveClientCount() != 0) 471 if (controller->GetActiveClientCount() != 0)
392 return; 472 return;
393 473
394 // There is no more client, release the camera. 474 // There is no more client, release the camera.
395 device_task_runner_->PostTask( 475 DoStopDevice(entry, false);
396 FROM_HERE,
397 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
398 base::Unretained(entry)));
399 } 476 }
400 477
401 void VideoCaptureManager::ResumeCaptureForClient( 478 void VideoCaptureManager::ResumeCaptureForClient(
402 media::VideoCaptureSessionId session_id, 479 media::VideoCaptureSessionId session_id,
403 const media::VideoCaptureParams& params, 480 const media::VideoCaptureParams& params,
404 VideoCaptureController* controller, 481 VideoCaptureController* controller,
405 VideoCaptureControllerID client_id, 482 VideoCaptureControllerID client_id,
406 VideoCaptureControllerEventHandler* client_handler) { 483 VideoCaptureControllerEventHandler* client_handler) {
407 DCHECK_CURRENTLY_ON(BrowserThread::IO); 484 DCHECK_CURRENTLY_ON(BrowserThread::IO);
408 DCHECK(controller); 485 DCHECK(controller);
409 DCHECK(client_handler); 486 DCHECK(client_handler);
410 487
411 DeviceEntry* entry = GetDeviceEntryForController(controller); 488 DeviceEntry* entry = GetDeviceEntryForController(controller);
412 if (!entry) { 489 if (!entry) {
413 NOTREACHED(); 490 NOTREACHED();
414 return; 491 return;
415 } 492 }
416 493
417 // We only pause/resume the MEDIA_DEVICE_VIDEO_CAPTURE entry. 494 // We only pause/resume the MEDIA_DEVICE_VIDEO_CAPTURE entry.
418 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) 495 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE)
419 return; 496 return;
420 497
421 controller->PauseOrResumeClient(client_id, client_handler, false); 498 controller->PauseOrResumeClient(client_id, client_handler, false);
422 if (controller->GetActiveClientCount() != 1) 499 if (controller->GetActiveClientCount() != 1)
423 return; 500 return;
424 501
425 // This is first active client, allocate the camera. 502 // This is first active client, allocate the camera.
426 device_task_runner_->PostTask( 503 QueueStartDevice(session_id, entry, params);
427 FROM_HERE,
428 base::Bind(
429 &VideoCaptureManager::DoStartDeviceOnDeviceThread,
430 this,
431 session_id,
432 entry,
433 params,
434 base::Passed(entry->video_capture_controller->NewDeviceClient())));
435 } 504 }
436 505
437 bool VideoCaptureManager::GetDeviceSupportedFormats( 506 bool VideoCaptureManager::GetDeviceSupportedFormats(
438 media::VideoCaptureSessionId capture_session_id, 507 media::VideoCaptureSessionId capture_session_id,
439 media::VideoCaptureFormats* supported_formats) { 508 media::VideoCaptureFormats* supported_formats) {
440 DCHECK_CURRENTLY_ON(BrowserThread::IO); 509 DCHECK_CURRENTLY_ON(BrowserThread::IO);
441 DCHECK(supported_formats->empty()); 510 DCHECK(supported_formats->empty());
442 511
443 SessionMap::iterator it = sessions_.find(capture_session_id); 512 SessionMap::iterator it = sessions_.find(capture_session_id);
444 if (it == sessions_.end()) 513 if (it == sessions_.end())
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 if (entry->video_capture_controller->GetClientCount() == 0) { 717 if (entry->video_capture_controller->GetClientCount() == 0) {
649 DVLOG(1) << "VideoCaptureManager stopping device (type = " 718 DVLOG(1) << "VideoCaptureManager stopping device (type = "
650 << entry->stream_type << ", id = " << entry->id << ")"; 719 << entry->stream_type << ", id = " << entry->id << ")";
651 720
652 // The DeviceEntry is removed from |devices_| immediately. The controller is 721 // The DeviceEntry is removed from |devices_| immediately. The controller is
653 // deleted immediately, and the device is freed asynchronously. After this 722 // deleted immediately, and the device is freed asynchronously. After this
654 // point, subsequent requests to open this same device ID will create a new 723 // point, subsequent requests to open this same device ID will create a new
655 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. 724 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice.
656 devices_.erase(entry); 725 devices_.erase(entry);
657 entry->video_capture_controller.reset(); 726 entry->video_capture_controller.reset();
658 device_task_runner_->PostTask( 727 DoStopDevice(entry, true);
659 FROM_HERE,
660 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this,
661 base::Owned(entry)));
662 } 728 }
663 } 729 }
664 730
665 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( 731 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry(
666 media::VideoCaptureSessionId capture_session_id) { 732 media::VideoCaptureSessionId capture_session_id) {
667 DCHECK_CURRENTLY_ON(BrowserThread::IO); 733 DCHECK_CURRENTLY_ON(BrowserThread::IO);
668 734
669 SessionMap::iterator session_it = sessions_.find(capture_session_id); 735 SessionMap::iterator session_it = sessions_.find(capture_session_id);
670 if (session_it == sessions_.end()) { 736 if (session_it == sessions_.end()) {
671 return NULL; 737 return NULL;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 gfx::NativeViewId window_id) { 786 gfx::NativeViewId window_id) {
721 DCHECK(IsOnDeviceThread()); 787 DCHECK(IsOnDeviceThread());
722 DCHECK(notification_window_ids_.find(session_id) == 788 DCHECK(notification_window_ids_.find(session_id) ==
723 notification_window_ids_.end()); 789 notification_window_ids_.end());
724 notification_window_ids_[session_id] = window_id; 790 notification_window_ids_[session_id] = window_id;
725 VLOG(2) << "Screen capture notification window saved for session " 791 VLOG(2) << "Screen capture notification window saved for session "
726 << session_id << " on device thread."; 792 << session_id << " on device thread.";
727 } 793 }
728 794
729 } // namespace content 795 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698