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" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
18 #include "base/strings/stringprintf.h" | |
18 #include "base/task_runner_util.h" | 19 #include "base/task_runner_util.h" |
19 #include "base/thread_task_runner_handle.h" | 20 #include "base/thread_task_runner_handle.h" |
20 #include "base/threading/sequenced_worker_pool.h" | 21 #include "base/threading/sequenced_worker_pool.h" |
21 #include "content/browser/media/capture/web_contents_video_capture_device.h" | 22 #include "content/browser/media/capture/web_contents_video_capture_device.h" |
22 #include "content/browser/media/media_internals.h" | 23 #include "content/browser/media/media_internals.h" |
23 #include "content/browser/renderer_host/media/video_capture_controller.h" | 24 #include "content/browser/renderer_host/media/video_capture_controller.h" |
24 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" | 25 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" |
25 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
26 #include "content/public/browser/desktop_media_id.h" | 27 #include "content/public/browser/desktop_media_id.h" |
27 #include "content/public/common/media_stream_request.h" | 28 #include "content/public/common/media_stream_request.h" |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 if (request->serial_id() == entry->serial_id) { | 290 if (request->serial_id() == entry->serial_id) { |
290 request->set_abort_start(); | 291 request->set_abort_start(); |
291 DVLOG(3) << "DoStopDevice, aborting start request for device " | 292 DVLOG(3) << "DoStopDevice, aborting start request for device " |
292 << entry->id << " serial_id = " << entry->serial_id; | 293 << entry->id << " serial_id = " << entry->serial_id; |
293 return; | 294 return; |
294 } | 295 } |
295 } | 296 } |
296 | 297 |
297 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id | 298 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id |
298 << " serial_id = " << entry->serial_id << "."; | 299 << " serial_id = " << entry->serial_id << "."; |
300 entry->video_capture_controller()->DoLogOnIOThread( | |
301 base::StringPrintf("Stopping device: id: %s\n", entry->id.c_str())); | |
302 | |
299 if (entry->video_capture_device()) { | 303 if (entry->video_capture_device()) { |
300 // |entry->video_capture_device| can be null if creating the device fails. | 304 // |entry->video_capture_device| can be null if creating the device fails. |
301 device_task_runner_->PostTask( | 305 device_task_runner_->PostTask( |
302 FROM_HERE, | 306 FROM_HERE, |
303 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 307 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
304 base::Passed(entry->ReleaseVideoCaptureDevice()))); | 308 base::Passed(entry->ReleaseVideoCaptureDevice()))); |
305 } | 309 } |
306 } | 310 } |
307 | 311 |
308 void VideoCaptureManager::HandleQueuedStartRequest() { | 312 void VideoCaptureManager::HandleQueuedStartRequest() { |
(...skipping 11 matching lines...) Expand all Loading... | |
320 DeviceEntries::iterator entry_it = std::find_if( | 324 DeviceEntries::iterator entry_it = std::find_if( |
321 devices_.begin(), devices_.end(), | 325 devices_.begin(), devices_.end(), |
322 [serial_id] (const DeviceEntry* e) { | 326 [serial_id] (const DeviceEntry* e) { |
323 return e->serial_id == serial_id; | 327 return e->serial_id == serial_id; |
324 }); | 328 }); |
325 DCHECK(entry_it != devices_.end()); | 329 DCHECK(entry_it != devices_.end()); |
326 DeviceEntry* entry = (*entry_it); | 330 DeviceEntry* entry = (*entry_it); |
327 | 331 |
328 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " | 332 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
329 << entry->id << " start id = " << entry->serial_id; | 333 << entry->id << " start id = " << entry->serial_id; |
330 base::PostTaskAndReplyWithResult( | 334 |
mcasas
2015/12/01 15:30:38
So my suggestion was to add here:
base::Callback<
nisse-chromium (ooo August 14)
2015/12/02 14:26:00
Done. Please have a look and see if it seems right
tommi (sloooow) - chröme
2015/12/02 15:01:27
This is good
| |
331 device_task_runner_.get(), | 335 switch (entry->stream_type) { |
332 FROM_HERE, | 336 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
333 base::Bind( | 337 // We look up the device id from the renderer in our local enumeration |
334 &VideoCaptureManager::DoStartDeviceOnDeviceThread, | 338 // since the renderer does not have all the information that might be |
335 this, | 339 // held in the browser-side VideoCaptureDevice::Name structure. |
336 request->session_id(), | 340 const media::VideoCaptureDeviceInfo* found = |
337 entry->id, | 341 FindDeviceInfoById(entry->id, devices_info_cache_); |
338 entry->stream_type, | 342 if (found) { |
339 request->params(), | 343 entry->video_capture_controller()->DoLogOnIOThread(base::StringPrintf( |
340 base::Passed(entry->video_capture_controller()->NewDeviceClient())), | 344 "Starting device: id: %s, name: %s, api: %s", |
341 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | 345 found->name.id().c_str(), found->name.GetNameAndModel().c_str(), |
342 request->serial_id())); | 346 found->name.GetCaptureApiTypeString())); |
347 | |
348 base::PostTaskAndReplyWithResult( | |
349 device_task_runner_.get(), FROM_HERE, | |
350 base::Bind( | |
351 &VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, this, | |
352 found->name, request->params(), | |
353 base::Passed( | |
354 entry->video_capture_controller()->NewDeviceClient())), | |
355 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | |
356 request->serial_id())); | |
357 } else { | |
358 // Errors from DoStartDeviceCaptureOnDeviceThread go via | |
359 // VideoCaptureDeviceClient::OnError, which needs some thread | |
360 // dancing to get errors processed on the IO thread. But since | |
361 // we're on that thread, we call VideoCaptureController | |
362 // methods directly. | |
363 const std::string log_message = base::StringPrintf( | |
364 "Error on %s:%d: device %s unknown. Maybe recently disconnected?", | |
365 __FILE__, __LINE__, entry->id.c_str()); | |
366 DLOG(ERROR) << log_message; | |
367 entry->video_capture_controller()->DoLogOnIOThread(log_message); | |
368 entry->video_capture_controller()->DoErrorOnIOThread(); | |
369 } | |
370 break; | |
371 } | |
372 case MEDIA_TAB_VIDEO_CAPTURE: { | |
373 base::PostTaskAndReplyWithResult( | |
374 device_task_runner_.get(), FROM_HERE, | |
375 base::Bind(&VideoCaptureManager::DoStartTabCaptureOnDeviceThread, | |
376 this, entry->id, request->params(), | |
377 base::Passed( | |
378 entry->video_capture_controller()->NewDeviceClient())), | |
379 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | |
380 request->serial_id())); | |
381 break; | |
382 } | |
383 case MEDIA_DESKTOP_VIDEO_CAPTURE: { | |
384 base::PostTaskAndReplyWithResult( | |
385 device_task_runner_.get(), FROM_HERE, | |
386 base::Bind(&VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, | |
387 this, entry->id, request->params(), | |
388 base::Passed( | |
389 entry->video_capture_controller()->NewDeviceClient())), | |
390 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | |
391 request->serial_id())); | |
392 | |
393 break; | |
394 } | |
395 default: { | |
396 NOTIMPLEMENTED(); | |
397 break; | |
398 } | |
399 } | |
343 } | 400 } |
344 | 401 |
345 void VideoCaptureManager::OnDeviceStarted( | 402 void VideoCaptureManager::OnDeviceStarted( |
346 int serial_id, | 403 int serial_id, |
347 scoped_ptr<media::VideoCaptureDevice> device) { | 404 scoped_ptr<media::VideoCaptureDevice> device) { |
348 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 405 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
349 DCHECK(serial_id == device_start_queue_.begin()->serial_id()); | 406 DCHECK(serial_id == device_start_queue_.begin()->serial_id()); |
350 DVLOG(3) << "OnDeviceStarted"; | 407 DVLOG(3) << "OnDeviceStarted"; |
351 if (device_start_queue_.front().abort_start()) { | 408 if (device_start_queue_.front().abort_start()) { |
352 // |device| can be null if creation failed in DoStartDeviceOnDeviceThread. | 409 // |device| can be null if creation failed in |
410 // DoStartDeviceCaptureOnDeviceThread. | |
353 // The device is no longer wanted. Stop the device again. | 411 // The device is no longer wanted. Stop the device again. |
354 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; | 412 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; |
355 media::VideoCaptureDevice* device_ptr = device.get(); | 413 media::VideoCaptureDevice* device_ptr = device.get(); |
356 base::Closure closure = | 414 base::Closure closure = |
357 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 415 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
358 base::Passed(&device)); | 416 base::Passed(&device)); |
359 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { | 417 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { |
360 // PostTask failed. The device must be stopped anyway. | 418 // PostTask failed. The device must be stopped anyway. |
361 device_ptr->StopAndDeAllocate(); | 419 device_ptr->StopAndDeAllocate(); |
362 } | 420 } |
(...skipping 13 matching lines...) Expand all Loading... | |
376 device_start_queue_.front().session_id(); | 434 device_start_queue_.front().session_id(); |
377 MaybePostDesktopCaptureWindowId(session_id); | 435 MaybePostDesktopCaptureWindowId(session_id); |
378 } | 436 } |
379 } | 437 } |
380 | 438 |
381 device_start_queue_.pop_front(); | 439 device_start_queue_.pop_front(); |
382 HandleQueuedStartRequest(); | 440 HandleQueuedStartRequest(); |
383 } | 441 } |
384 | 442 |
385 scoped_ptr<media::VideoCaptureDevice> | 443 scoped_ptr<media::VideoCaptureDevice> |
386 VideoCaptureManager::DoStartDeviceOnDeviceThread( | 444 VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( |
387 media::VideoCaptureSessionId session_id, | 445 const media::VideoCaptureDevice::Name& name, |
388 const std::string& id, | |
389 MediaStreamType stream_type, | |
390 const media::VideoCaptureParams& params, | 446 const media::VideoCaptureParams& params, |
391 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { | 447 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { |
392 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 448 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
393 DCHECK(IsOnDeviceThread()); | 449 DCHECK(IsOnDeviceThread()); |
394 | 450 |
395 scoped_ptr<media::VideoCaptureDevice> video_capture_device; | 451 scoped_ptr<media::VideoCaptureDevice> video_capture_device; |
396 switch (stream_type) { | 452 video_capture_device = video_capture_device_factory_->Create(name); |
397 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 453 |
398 // We look up the device id from the renderer in our local enumeration | 454 if (!video_capture_device) { |
399 // since the renderer does not have all the information that might be | 455 device_client->OnError(FROM_HERE, "Could not create capture device"); |
400 // held in the browser-side VideoCaptureDevice::Name structure. | 456 return nullptr; |
401 const media::VideoCaptureDeviceInfo* found = | 457 } |
402 FindDeviceInfoById(id, devices_info_cache_); | 458 |
403 if (found) { | 459 video_capture_device->AllocateAndStart(params, device_client.Pass()); |
404 video_capture_device = | 460 return video_capture_device.Pass(); |
405 video_capture_device_factory_->Create(found->name); | 461 } |
406 } | 462 |
407 break; | 463 scoped_ptr<media::VideoCaptureDevice> |
408 } | 464 VideoCaptureManager::DoStartTabCaptureOnDeviceThread( |
409 case MEDIA_TAB_VIDEO_CAPTURE: { | 465 const std::string& id, |
410 video_capture_device.reset( | 466 const media::VideoCaptureParams& params, |
411 WebContentsVideoCaptureDevice::Create(id)); | 467 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { |
412 break; | 468 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
413 } | 469 DCHECK(IsOnDeviceThread()); |
414 case MEDIA_DESKTOP_VIDEO_CAPTURE: { | 470 |
471 scoped_ptr<media::VideoCaptureDevice> video_capture_device; | |
472 video_capture_device.reset(WebContentsVideoCaptureDevice::Create(id)); | |
473 | |
474 if (!video_capture_device) { | |
475 device_client->OnError(FROM_HERE, "Could not create capture device"); | |
476 return nullptr; | |
477 } | |
478 | |
479 video_capture_device->AllocateAndStart(params, device_client.Pass()); | |
480 return video_capture_device.Pass(); | |
481 } | |
482 | |
483 scoped_ptr<media::VideoCaptureDevice> | |
484 VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread( | |
485 const std::string& id, | |
486 const media::VideoCaptureParams& params, | |
487 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { | |
488 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | |
489 DCHECK(IsOnDeviceThread()); | |
490 | |
491 scoped_ptr<media::VideoCaptureDevice> video_capture_device; | |
415 #if defined(ENABLE_SCREEN_CAPTURE) | 492 #if defined(ENABLE_SCREEN_CAPTURE) |
416 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); | 493 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); |
417 if (!desktop_id.is_null()) { | 494 if (!desktop_id.is_null()) { |
418 #if defined(USE_AURA) | 495 #if defined(USE_AURA) |
419 video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id); | 496 video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id); |
420 #endif | 497 #endif |
421 if (!video_capture_device) | 498 if (!video_capture_device) |
422 video_capture_device = DesktopCaptureDevice::Create(desktop_id); | 499 video_capture_device = DesktopCaptureDevice::Create(desktop_id); |
423 } | |
424 #endif // defined(ENABLE_SCREEN_CAPTURE) | 500 #endif // defined(ENABLE_SCREEN_CAPTURE) |
425 break; | |
426 } | |
427 default: { | |
428 NOTIMPLEMENTED(); | |
429 break; | |
430 } | |
431 } | 501 } |
mcasas
2015/12/01 15:30:38
l.500 should go after the closing bracket.
nisse-chromium (ooo August 14)
2015/12/02 14:25:59
Done.
| |
432 | 502 |
433 if (!video_capture_device) { | 503 if (!video_capture_device) { |
434 device_client->OnError(FROM_HERE, "Could not create capture device"); | 504 device_client->OnError(FROM_HERE, "Could not create capture device"); |
435 return nullptr; | 505 return nullptr; |
436 } | 506 } |
437 | 507 |
438 video_capture_device->AllocateAndStart(params, device_client.Pass()); | 508 video_capture_device->AllocateAndStart(params, device_client.Pass()); |
439 return video_capture_device.Pass(); | 509 return video_capture_device.Pass(); |
440 } | 510 } |
441 | 511 |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
859 DCHECK(IsOnDeviceThread()); | 929 DCHECK(IsOnDeviceThread()); |
860 #if defined(ENABLE_SCREEN_CAPTURE) | 930 #if defined(ENABLE_SCREEN_CAPTURE) |
861 DesktopCaptureDevice* desktop_device = | 931 DesktopCaptureDevice* desktop_device = |
862 static_cast<DesktopCaptureDevice*>(device); | 932 static_cast<DesktopCaptureDevice*>(device); |
863 desktop_device->SetNotificationWindowId(window_id); | 933 desktop_device->SetNotificationWindowId(window_id); |
864 VLOG(2) << "Screen capture notification window passed on device thread."; | 934 VLOG(2) << "Screen capture notification window passed on device thread."; |
865 #endif | 935 #endif |
866 } | 936 } |
867 | 937 |
868 } // namespace content | 938 } // namespace content |
OLD | NEW |