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 <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 Loading... | |
| 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 Loading... | |
| 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 |
| 219 void VideoCaptureManager::DoStartDeviceOnDeviceThread( | 220 VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( |
| 221 DeviceEntry* entry, | |
| 222 media::VideoCaptureSessionId session_id, | |
| 223 const media::VideoCaptureParams& params) | |
| 224 : entry(entry), | |
| 225 session_id(session_id), | |
| 226 params(params), | |
| 227 abort_start(false) { | |
| 228 } | |
| 229 | |
| 230 void VideoCaptureManager::QueueStartDevice( | |
| 220 media::VideoCaptureSessionId session_id, | 231 media::VideoCaptureSessionId session_id, |
| 221 DeviceEntry* entry, | 232 DeviceEntry* entry, |
| 233 const media::VideoCaptureParams& params) { | |
| 234 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 235 device_start_queue_.push_back( | |
| 236 CaptureDeviceStartRequest(entry, session_id, params)); | |
| 237 if (device_start_queue_.size() == 1) | |
| 238 HandleQueuedStartRequest(); | |
| 239 } | |
| 240 | |
| 241 void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) { | |
| 242 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 243 DCHECK(std::find(devices_.begin(), devices_.end(), entry) != devices_.end()); | |
| 244 | |
| 245 // Reverse iterate to find the last start request. This also avoids a problem | |
| 246 // where |entry| might get the same pointer value if it is deleted | |
| 247 // and recreated while we are waiting for the device to be started. | |
|
tommi (sloooow) - chröme
2014/12/17 14:46:12
ah... hmm.. maybe it's a good thing to use a seria
perkj_chrome
2014/12/18 12:15:32
Done.
| |
| 248 for (DeviceStartQueue::reverse_iterator request = | |
| 249 device_start_queue_.rbegin(); | |
| 250 request != device_start_queue_.rend(); ++request) { | |
| 251 if (request->entry == entry) { | |
| 252 request->abort_start = true; | |
| 253 DVLOG(3) << "DoStopDevice, aborting start request for device " | |
| 254 << entry->id << "." | |
|
tommi (sloooow) - chröme
2014/12/17 14:46:12
nit: align <<
perkj_chrome
2014/12/18 12:15:32
Done.
| |
| 255 return; | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 DVLOG(3) << "DoStopDevice. Send stop request for device " << entry->id << "."; | |
| 260 if (entry->video_capture_device.get()) { | |
| 261 // |entry->video_capture_device| can be null if creating the device fails. | |
| 262 device_task_runner_->PostTask( | |
| 263 FROM_HERE, | |
| 264 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | |
| 265 base::Passed(entry->video_capture_device.Pass()))); | |
| 266 } | |
| 267 } | |
| 268 | |
| 269 void VideoCaptureManager::HandleQueuedStartRequest() { | |
| 270 // Remove all start requests that have been aborted. | |
| 271 while(device_start_queue_.begin() != device_start_queue_.end() && | |
| 272 device_start_queue_.begin()->abort_start) { | |
| 273 device_start_queue_.pop_front(); | |
| 274 } | |
| 275 DeviceStartQueue::iterator request = device_start_queue_.begin(); | |
| 276 if (request == device_start_queue_.end()) | |
| 277 return; | |
| 278 | |
| 279 DeviceEntry* entry = request->entry; | |
| 280 DCHECK(std::find(devices_.begin(), devices_.end(), request->entry) != | |
| 281 devices_.end()); | |
| 282 | |
| 283 DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " | |
| 284 << entry->id; | |
| 285 base::PostTaskAndReplyWithResult( | |
| 286 device_task_runner_.get(), | |
| 287 FROM_HERE, | |
| 288 base::Bind( | |
| 289 &VideoCaptureManager::DoStartDeviceOnDeviceThread, | |
| 290 this, | |
| 291 request->session_id, | |
| 292 entry->id, | |
| 293 entry->stream_type, | |
| 294 request->params, | |
| 295 base::Passed(entry->video_capture_controller->NewDeviceClient())), | |
| 296 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, entry)); | |
| 297 } | |
| 298 | |
| 299 void VideoCaptureManager::OnDeviceStarted( | |
| 300 DeviceEntry* device_entry, | |
| 301 scoped_ptr<media::VideoCaptureDevice> device) { | |
| 302 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
| 303 DCHECK(device_entry == device_start_queue_.begin()->entry); | |
| 304 DVLOG(3) << "OnDeviceStarted"; | |
| 305 if (device_start_queue_.front().abort_start) { | |
| 306 // |device| can be null if creation failed in DoStartDeviceOnDeviceThread. | |
| 307 // The device is no longer wanted. Stop the device again. | |
| 308 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; | |
| 309 media::VideoCaptureDevice* device_ptr = device.get(); | |
| 310 base::Closure closure = | |
| 311 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | |
| 312 base::Passed(&device)); | |
| 313 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { | |
| 314 // PostTask failed. The device must be stopped anyway. | |
| 315 device_ptr->StopAndDeAllocate(); | |
| 316 } | |
| 317 } else { | |
| 318 DCHECK(std::find(devices_.begin(), devices_.end(), device_entry) != | |
| 319 devices_.end()); | |
| 320 device_entry->video_capture_device.swap(device); | |
| 321 } | |
| 322 | |
| 323 device_start_queue_.pop_front(); | |
| 324 HandleQueuedStartRequest(); | |
| 325 } | |
| 326 | |
| 327 scoped_ptr<media::VideoCaptureDevice> | |
| 328 VideoCaptureManager::DoStartDeviceOnDeviceThread( | |
| 329 media::VideoCaptureSessionId session_id, | |
| 330 const std::string& id, | |
| 331 MediaStreamType stream_type, | |
| 222 const media::VideoCaptureParams& params, | 332 const media::VideoCaptureParams& params, |
| 223 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { | 333 scoped_ptr<media::VideoCaptureDevice::Client> device_client) { |
| 224 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); | 334 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| 225 DCHECK(IsOnDeviceThread()); | 335 DCHECK(IsOnDeviceThread()); |
| 226 | 336 |
| 227 scoped_ptr<media::VideoCaptureDevice> video_capture_device; | 337 scoped_ptr<media::VideoCaptureDevice> video_capture_device; |
| 228 switch (entry->stream_type) { | 338 switch (stream_type) { |
| 229 case MEDIA_DEVICE_VIDEO_CAPTURE: { | 339 case MEDIA_DEVICE_VIDEO_CAPTURE: { |
| 230 // We look up the device id from the renderer in our local enumeration | 340 // We look up the device id from the renderer in our local enumeration |
| 231 // since the renderer does not have all the information that might be | 341 // since the renderer does not have all the information that might be |
| 232 // held in the browser-side VideoCaptureDevice::Name structure. | 342 // held in the browser-side VideoCaptureDevice::Name structure. |
| 233 media::VideoCaptureDeviceInfo* found = | 343 media::VideoCaptureDeviceInfo* found = |
| 234 FindDeviceInfoById(entry->id, devices_info_cache_); | 344 FindDeviceInfoById(id, devices_info_cache_); |
| 235 if (found) { | 345 if (found) { |
| 236 video_capture_device = | 346 video_capture_device = |
| 237 video_capture_device_factory_->Create(found->name); | 347 video_capture_device_factory_->Create(found->name); |
| 238 } | 348 } |
| 239 break; | 349 break; |
| 240 } | 350 } |
| 241 case MEDIA_TAB_VIDEO_CAPTURE: { | 351 case MEDIA_TAB_VIDEO_CAPTURE: { |
| 242 video_capture_device.reset( | 352 video_capture_device.reset( |
| 243 WebContentsVideoCaptureDevice::Create(entry->id)); | 353 WebContentsVideoCaptureDevice::Create(id)); |
| 244 break; | 354 break; |
| 245 } | 355 } |
| 246 case MEDIA_DESKTOP_VIDEO_CAPTURE: { | 356 case MEDIA_DESKTOP_VIDEO_CAPTURE: { |
| 247 #if defined(ENABLE_SCREEN_CAPTURE) | 357 #if defined(ENABLE_SCREEN_CAPTURE) |
| 248 DesktopMediaID id = DesktopMediaID::Parse(entry->id); | 358 DesktopMediaID desktop_id = DesktopMediaID::Parse(id); |
| 249 #if defined(USE_AURA) | 359 #if defined(USE_AURA) |
| 250 if (id.type == DesktopMediaID::TYPE_AURA_WINDOW) { | 360 if (desktop_id.type == DesktopMediaID::TYPE_AURA_WINDOW) { |
| 251 video_capture_device.reset(DesktopCaptureDeviceAura::Create(id)); | 361 video_capture_device.reset( |
| 362 DesktopCaptureDeviceAura::Create(desktop_id)); | |
| 252 } else | 363 } else |
| 253 #endif | 364 #endif |
| 254 if (id.type != DesktopMediaID::TYPE_NONE && | 365 if (desktop_id.type != DesktopMediaID::TYPE_NONE && |
| 255 id.type != DesktopMediaID::TYPE_AURA_WINDOW) { | 366 desktop_id.type != DesktopMediaID::TYPE_AURA_WINDOW) { |
| 256 video_capture_device = DesktopCaptureDevice::Create(id); | 367 video_capture_device = DesktopCaptureDevice::Create(desktop_id); |
| 257 if (notification_window_ids_.find(session_id) != | 368 if (notification_window_ids_.find(session_id) != |
| 258 notification_window_ids_.end()) { | 369 notification_window_ids_.end()) { |
| 259 static_cast<DesktopCaptureDevice*>(video_capture_device.get()) | 370 static_cast<DesktopCaptureDevice*>(video_capture_device.get()) |
| 260 ->SetNotificationWindowId(notification_window_ids_[session_id]); | 371 ->SetNotificationWindowId(notification_window_ids_[session_id]); |
| 261 VLOG(2) << "Screen capture notification window passed for session " | 372 VLOG(2) << "Screen capture notification window passed for session " |
| 262 << session_id; | 373 << session_id; |
| 263 } | 374 } |
| 264 } | 375 } |
| 265 #endif // defined(ENABLE_SCREEN_CAPTURE) | 376 #endif // defined(ENABLE_SCREEN_CAPTURE) |
| 266 break; | 377 break; |
| 267 } | 378 } |
| 268 default: { | 379 default: { |
| 269 NOTIMPLEMENTED(); | 380 NOTIMPLEMENTED(); |
| 270 break; | 381 break; |
| 271 } | 382 } |
| 272 } | 383 } |
| 273 | 384 |
| 274 if (!video_capture_device) { | 385 if (!video_capture_device) { |
| 275 device_client->OnError("Could not create capture device"); | 386 device_client->OnError("Could not create capture device"); |
| 276 return; | 387 return nullptr; |
| 277 } | 388 } |
| 278 | 389 |
| 279 video_capture_device->AllocateAndStart(params, device_client.Pass()); | 390 video_capture_device->AllocateAndStart(params, device_client.Pass()); |
| 280 entry->video_capture_device = video_capture_device.Pass(); | 391 return video_capture_device.Pass(); |
| 281 } | 392 } |
| 282 | 393 |
| 283 void VideoCaptureManager::StartCaptureForClient( | 394 void VideoCaptureManager::StartCaptureForClient( |
| 284 media::VideoCaptureSessionId session_id, | 395 media::VideoCaptureSessionId session_id, |
| 285 const media::VideoCaptureParams& params, | 396 const media::VideoCaptureParams& params, |
| 286 base::ProcessHandle client_render_process, | 397 base::ProcessHandle client_render_process, |
| 287 VideoCaptureControllerID client_id, | 398 VideoCaptureControllerID client_id, |
| 288 VideoCaptureControllerEventHandler* client_handler, | 399 VideoCaptureControllerEventHandler* client_handler, |
| 289 const DoneCB& done_cb) { | 400 const DoneCB& done_cb) { |
| 290 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 401 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 291 DVLOG(1) << "VideoCaptureManager::StartCaptureForClient, " | 402 DVLOG(1) << "VideoCaptureManager::StartCaptureForClient, " |
| 292 << params.requested_format.frame_size.ToString() << ", " | 403 << params.requested_format.frame_size.ToString() << ", " |
| 293 << params.requested_format.frame_rate << ", #" << session_id << ")"; | 404 << params.requested_format.frame_rate << ", #" << session_id << ")"; |
| 294 | 405 |
| 295 DeviceEntry* entry = GetOrCreateDeviceEntry(session_id); | 406 DeviceEntry* entry = GetOrCreateDeviceEntry(session_id); |
| 296 if (!entry) { | 407 if (!entry) { |
| 297 done_cb.Run(base::WeakPtr<VideoCaptureController>()); | 408 done_cb.Run(base::WeakPtr<VideoCaptureController>()); |
| 298 return; | 409 return; |
| 299 } | 410 } |
| 300 | 411 |
| 301 DCHECK(entry->video_capture_controller); | 412 DCHECK(entry->video_capture_controller); |
| 302 | 413 |
| 303 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); | 414 LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); |
| 304 | 415 |
| 305 // First client starts the device. | 416 // First client starts the device. |
| 306 if (entry->video_capture_controller->GetActiveClientCount() == 0) { | 417 if (entry->video_capture_controller->GetActiveClientCount() == 0) { |
| 307 DVLOG(1) << "VideoCaptureManager starting device (type = " | 418 DVLOG(1) << "VideoCaptureManager starting device (type = " |
| 308 << entry->stream_type << ", id = " << entry->id << ")"; | 419 << entry->stream_type << ", id = " << entry->id << ")"; |
| 309 | 420 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 } | 421 } |
| 320 // Run the callback first, as AddClient() may trigger OnFrameInfo(). | 422 // Run the callback first, as AddClient() may trigger OnFrameInfo(). |
| 321 done_cb.Run(entry->video_capture_controller->GetWeakPtr()); | 423 done_cb.Run(entry->video_capture_controller->GetWeakPtr()); |
| 322 entry->video_capture_controller->AddClient( | 424 entry->video_capture_controller->AddClient( |
| 323 client_id, client_handler, client_render_process, session_id, params); | 425 client_id, client_handler, client_render_process, session_id, params); |
| 324 } | 426 } |
| 325 | 427 |
| 326 void VideoCaptureManager::StopCaptureForClient( | 428 void VideoCaptureManager::StopCaptureForClient( |
| 327 VideoCaptureController* controller, | 429 VideoCaptureController* controller, |
| 328 VideoCaptureControllerID client_id, | 430 VideoCaptureControllerID client_id, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 // We only pause the MEDIA_DEVICE_VIDEO_CAPTURE entry to release camera to | 487 // We only pause the MEDIA_DEVICE_VIDEO_CAPTURE entry to release camera to |
| 386 // system. | 488 // system. |
| 387 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) | 489 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) |
| 388 return; | 490 return; |
| 389 | 491 |
| 390 controller->PauseOrResumeClient(client_id, client_handler, true); | 492 controller->PauseOrResumeClient(client_id, client_handler, true); |
| 391 if (controller->GetActiveClientCount() != 0) | 493 if (controller->GetActiveClientCount() != 0) |
| 392 return; | 494 return; |
| 393 | 495 |
| 394 // There is no more client, release the camera. | 496 // There is no more client, release the camera. |
| 395 device_task_runner_->PostTask( | 497 DoStopDevice(entry); |
| 396 FROM_HERE, | |
| 397 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | |
| 398 base::Unretained(entry))); | |
| 399 } | 498 } |
| 400 | 499 |
| 401 void VideoCaptureManager::ResumeCaptureForClient( | 500 void VideoCaptureManager::ResumeCaptureForClient( |
| 402 media::VideoCaptureSessionId session_id, | 501 media::VideoCaptureSessionId session_id, |
| 403 const media::VideoCaptureParams& params, | 502 const media::VideoCaptureParams& params, |
| 404 VideoCaptureController* controller, | 503 VideoCaptureController* controller, |
| 405 VideoCaptureControllerID client_id, | 504 VideoCaptureControllerID client_id, |
| 406 VideoCaptureControllerEventHandler* client_handler) { | 505 VideoCaptureControllerEventHandler* client_handler) { |
| 407 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 506 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 408 DCHECK(controller); | 507 DCHECK(controller); |
| 409 DCHECK(client_handler); | 508 DCHECK(client_handler); |
| 410 | 509 |
| 411 DeviceEntry* entry = GetDeviceEntryForController(controller); | 510 DeviceEntry* entry = GetDeviceEntryForController(controller); |
| 412 if (!entry) { | 511 if (!entry) { |
| 413 NOTREACHED(); | 512 NOTREACHED(); |
| 414 return; | 513 return; |
| 415 } | 514 } |
| 416 | 515 |
| 417 // We only pause/resume the MEDIA_DEVICE_VIDEO_CAPTURE entry. | 516 // We only pause/resume the MEDIA_DEVICE_VIDEO_CAPTURE entry. |
| 418 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) | 517 if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) |
| 419 return; | 518 return; |
| 420 | 519 |
| 421 controller->PauseOrResumeClient(client_id, client_handler, false); | 520 controller->PauseOrResumeClient(client_id, client_handler, false); |
| 422 if (controller->GetActiveClientCount() != 1) | 521 if (controller->GetActiveClientCount() != 1) |
| 423 return; | 522 return; |
| 424 | 523 |
| 425 // This is first active client, allocate the camera. | 524 // This is first active client, allocate the camera. |
| 426 device_task_runner_->PostTask( | 525 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 } | 526 } |
| 436 | 527 |
| 437 bool VideoCaptureManager::GetDeviceSupportedFormats( | 528 bool VideoCaptureManager::GetDeviceSupportedFormats( |
| 438 media::VideoCaptureSessionId capture_session_id, | 529 media::VideoCaptureSessionId capture_session_id, |
| 439 media::VideoCaptureFormats* supported_formats) { | 530 media::VideoCaptureFormats* supported_formats) { |
| 440 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 531 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 441 DCHECK(supported_formats->empty()); | 532 DCHECK(supported_formats->empty()); |
| 442 | 533 |
| 443 SessionMap::iterator it = sessions_.find(capture_session_id); | 534 SessionMap::iterator it = sessions_.find(capture_session_id); |
| 444 if (it == sessions_.end()) | 535 if (it == sessions_.end()) |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 510 } | 601 } |
| 511 | 602 |
| 512 device_task_runner_->PostTask( | 603 device_task_runner_->PostTask( |
| 513 FROM_HERE, | 604 FROM_HERE, |
| 514 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, | 605 base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, |
| 515 this, | 606 this, |
| 516 existing_device, | 607 existing_device, |
| 517 window_id)); | 608 window_id)); |
| 518 } | 609 } |
| 519 | 610 |
| 520 void VideoCaptureManager::DoStopDeviceOnDeviceThread(DeviceEntry* entry) { | 611 void VideoCaptureManager::DoStopDeviceOnDeviceThread( |
| 612 scoped_ptr<media::VideoCaptureDevice> device) { | |
| 521 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); | 613 SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
| 522 DCHECK(IsOnDeviceThread()); | 614 DCHECK(IsOnDeviceThread()); |
| 523 if (entry->video_capture_device) { | 615 device->StopAndDeAllocate(); |
| 524 entry->video_capture_device->StopAndDeAllocate(); | 616 DVLOG(3) << "DoStopDeviceOnDeviceThread"; |
| 525 } | |
| 526 entry->video_capture_device.reset(); | |
| 527 } | 617 } |
| 528 | 618 |
| 529 void VideoCaptureManager::OnOpened( | 619 void VideoCaptureManager::OnOpened( |
| 530 MediaStreamType stream_type, | 620 MediaStreamType stream_type, |
| 531 media::VideoCaptureSessionId capture_session_id) { | 621 media::VideoCaptureSessionId capture_session_id) { |
| 532 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 622 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 533 if (!listener_) { | 623 if (!listener_) { |
| 534 // Listener has been removed. | 624 // Listener has been removed. |
| 535 return; | 625 return; |
| 536 } | 626 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 736 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 647 // Removal of the last client stops the device. | 737 // Removal of the last client stops the device. |
| 648 if (entry->video_capture_controller->GetClientCount() == 0) { | 738 if (entry->video_capture_controller->GetClientCount() == 0) { |
| 649 DVLOG(1) << "VideoCaptureManager stopping device (type = " | 739 DVLOG(1) << "VideoCaptureManager stopping device (type = " |
| 650 << entry->stream_type << ", id = " << entry->id << ")"; | 740 << entry->stream_type << ", id = " << entry->id << ")"; |
| 651 | 741 |
| 652 // The DeviceEntry is removed from |devices_| immediately. The controller is | 742 // The DeviceEntry is removed from |devices_| immediately. The controller is |
| 653 // deleted immediately, and the device is freed asynchronously. After this | 743 // deleted immediately, and the device is freed asynchronously. After this |
| 654 // point, subsequent requests to open this same device ID will create a new | 744 // point, subsequent requests to open this same device ID will create a new |
| 655 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. | 745 // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. |
| 656 devices_.erase(entry); | 746 DoStopDevice(entry); |
| 657 entry->video_capture_controller.reset(); | 747 DeviceEntries::iterator device_it = std::find(devices_.begin(), |
| 658 device_task_runner_->PostTask( | 748 devices_.end(), |
| 659 FROM_HERE, | 749 entry); |
| 660 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 750 devices_.erase(device_it); |
| 661 base::Owned(entry))); | |
| 662 } | 751 } |
| 663 } | 752 } |
| 664 | 753 |
| 665 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( | 754 VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( |
| 666 media::VideoCaptureSessionId capture_session_id) { | 755 media::VideoCaptureSessionId capture_session_id) { |
| 667 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 756 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 668 | 757 |
| 669 SessionMap::iterator session_it = sessions_.find(capture_session_id); | 758 SessionMap::iterator session_it = sessions_.find(capture_session_id); |
| 670 if (session_it == sessions_.end()) { | 759 if (session_it == sessions_.end()) { |
| 671 return NULL; | 760 return NULL; |
| 672 } | 761 } |
| 673 const MediaStreamDevice& device_info = session_it->second; | 762 const MediaStreamDevice& device_info = session_it->second; |
| 674 | 763 |
| 675 // Check if another session has already opened this device. If so, just | 764 // Check if another session has already opened this device. If so, just |
| 676 // use that opened device. | 765 // use that opened device. |
| 677 DeviceEntry* const existing_device = | 766 DeviceEntry* const existing_device = |
| 678 GetDeviceEntryForMediaStreamDevice(device_info); | 767 GetDeviceEntryForMediaStreamDevice(device_info); |
| 679 if (existing_device) { | 768 if (existing_device) { |
| 680 DCHECK_EQ(device_info.type, existing_device->stream_type); | 769 DCHECK_EQ(device_info.type, existing_device->stream_type); |
| 681 return existing_device; | 770 return existing_device; |
| 682 } | 771 } |
| 683 | 772 |
| 684 const int max_buffers = device_info.type == MEDIA_TAB_VIDEO_CAPTURE ? | 773 const int max_buffers = device_info.type == MEDIA_TAB_VIDEO_CAPTURE ? |
| 685 kMaxNumberOfBuffersForTabCapture : kMaxNumberOfBuffers; | 774 kMaxNumberOfBuffersForTabCapture : kMaxNumberOfBuffers; |
| 686 scoped_ptr<VideoCaptureController> video_capture_controller( | 775 scoped_ptr<VideoCaptureController> video_capture_controller( |
| 687 new VideoCaptureController(max_buffers)); | 776 new VideoCaptureController(max_buffers)); |
| 688 DeviceEntry* new_device = new DeviceEntry(device_info.type, | 777 DeviceEntry* new_device = new DeviceEntry(device_info.type, |
| 689 device_info.id, | 778 device_info.id, |
| 690 video_capture_controller.Pass()); | 779 video_capture_controller.Pass()); |
| 691 devices_.insert(new_device); | 780 devices_.push_back(new_device); |
| 692 return new_device; | 781 return new_device; |
| 693 } | 782 } |
| 694 | 783 |
| 695 media::VideoCaptureDeviceInfo* VideoCaptureManager::FindDeviceInfoById( | 784 media::VideoCaptureDeviceInfo* VideoCaptureManager::FindDeviceInfoById( |
| 696 const std::string& id, | 785 const std::string& id, |
| 697 media::VideoCaptureDeviceInfos& device_vector) { | 786 media::VideoCaptureDeviceInfos& device_vector) { |
| 698 for (auto& it : device_vector) { | 787 for (auto& it : device_vector) { |
| 699 if (it.name.id() == id) | 788 if (it.name.id() == id) |
| 700 return &(it); | 789 return &(it); |
| 701 } | 790 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 720 gfx::NativeViewId window_id) { | 809 gfx::NativeViewId window_id) { |
| 721 DCHECK(IsOnDeviceThread()); | 810 DCHECK(IsOnDeviceThread()); |
| 722 DCHECK(notification_window_ids_.find(session_id) == | 811 DCHECK(notification_window_ids_.find(session_id) == |
| 723 notification_window_ids_.end()); | 812 notification_window_ids_.end()); |
| 724 notification_window_ids_[session_id] = window_id; | 813 notification_window_ids_[session_id] = window_id; |
| 725 VLOG(2) << "Screen capture notification window saved for session " | 814 VLOG(2) << "Screen capture notification window saved for session " |
| 726 << session_id << " on device thread."; | 815 << session_id << " on device thread."; |
| 727 } | 816 } |
| 728 | 817 |
| 729 } // namespace content | 818 } // namespace content |
| OLD | NEW |