Chromium Code Reviews| 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 |