Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/stl_util.h" |
| 9 #include "content/browser/browser_thread.h" | 9 #include "content/browser/browser_thread.h" |
| 10 #include "content/browser/renderer_host/media/video_capture_controller.h" | |
| 11 #include "content/browser/renderer_host/media/video_capture_controller_event_han dler.h" | |
| 10 #include "media/video/capture/fake_video_capture_device.h" | 12 #include "media/video/capture/fake_video_capture_device.h" |
| 11 #include "media/video/capture/video_capture_device.h" | 13 #include "media/video/capture/video_capture_device.h" |
| 12 | 14 |
| 13 namespace media_stream { | 15 namespace media_stream { |
| 14 | 16 |
| 15 // Starting id for the first capture session. | 17 // Starting id for the first capture session. |
| 16 // VideoCaptureManager::kStartOpenSessionId is used as default id without | 18 // VideoCaptureManager::kStartOpenSessionId is used as default id without |
| 17 // explicitly calling open device. | 19 // explicitly calling open device. |
| 18 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 }; | 20 enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 }; |
| 19 | 21 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 31 // resolved, i.e. all code below this comment. | 33 // resolved, i.e. all code below this comment. |
| 32 // Temporary solution: close all open devices and delete them, after the | 34 // Temporary solution: close all open devices and delete them, after the |
| 33 // thread is stopped. | 35 // thread is stopped. |
| 34 DLOG_IF(ERROR, !devices_.empty()) << "VideoCaptureManager: Open devices!"; | 36 DLOG_IF(ERROR, !devices_.empty()) << "VideoCaptureManager: Open devices!"; |
| 35 for (VideoCaptureDevices::iterator it = devices_.begin(); | 37 for (VideoCaptureDevices::iterator it = devices_.begin(); |
| 36 it != devices_.end(); | 38 it != devices_.end(); |
| 37 ++it) { | 39 ++it) { |
| 38 it->second->DeAllocate(); | 40 it->second->DeAllocate(); |
| 39 delete it->second; | 41 delete it->second; |
| 40 } | 42 } |
| 43 STLDeleteContainerPairSecondPointers(controllers_.begin(), | |
|
scherkus (not reviewing)
2011/10/19 18:02:21
nit: STLDeleteValues() works here
wjia(left Chromium)
2011/10/21 00:56:13
Done.
| |
| 44 controllers_.end()); | |
| 41 } | 45 } |
| 42 | 46 |
| 43 void VideoCaptureManager::Register(MediaStreamProviderListener* listener) { | 47 void VideoCaptureManager::Register(MediaStreamProviderListener* listener) { |
| 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 45 DCHECK(!listener_); | 49 DCHECK(!listener_); |
| 46 listener_ = listener; | 50 listener_ = listener; |
| 47 } | 51 } |
| 48 | 52 |
| 49 void VideoCaptureManager::Unregister() { | 53 void VideoCaptureManager::Unregister() { |
| 50 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 | 190 |
| 187 PostOnClosed(capture_session_id); | 191 PostOnClosed(capture_session_id); |
| 188 } | 192 } |
| 189 | 193 |
| 190 void VideoCaptureManager::OnStart( | 194 void VideoCaptureManager::OnStart( |
| 191 const media::VideoCaptureParams capture_params, | 195 const media::VideoCaptureParams capture_params, |
| 192 media::VideoCaptureDevice::EventHandler* video_capture_receiver) { | 196 media::VideoCaptureDevice::EventHandler* video_capture_receiver) { |
| 193 DCHECK(IsOnCaptureDeviceThread()); | 197 DCHECK(IsOnCaptureDeviceThread()); |
| 194 DCHECK(video_capture_receiver != NULL); | 198 DCHECK(video_capture_receiver != NULL); |
| 195 | 199 |
| 196 // Solution for not using MediaStreamManager. | 200 media::VideoCaptureDevice* video_capture_device = |
| 197 // This session id won't be returned by Open(). | 201 GetDeviceInternal(capture_params.session_id); |
| 198 if (capture_params.session_id == kStartOpenSessionId) { | 202 if (!video_capture_device) { |
| 199 // Start() is called without using Open(), we need to open a device. | |
| 200 media::VideoCaptureDevice::Names device_names; | |
| 201 GetAvailableDevices(&device_names); | |
| 202 if (device_names.empty()) { | |
| 203 // No devices available. | |
| 204 video_capture_receiver->OnError(); | |
| 205 return; | |
| 206 } | |
| 207 StreamDeviceInfo device(kVideoCapture, | |
| 208 device_names.front().device_name, | |
| 209 device_names.front().unique_id, false); | |
| 210 | |
| 211 // Call OnOpen to open using the first device in the list. | |
| 212 OnOpen(capture_params.session_id, device); | |
| 213 } | |
| 214 | |
| 215 VideoCaptureDevices::iterator it = devices_.find(capture_params.session_id); | |
| 216 if (it == devices_.end()) { | |
| 217 // Invalid session id. | 203 // Invalid session id. |
| 218 video_capture_receiver->OnError(); | 204 video_capture_receiver->OnError(); |
| 219 return; | 205 return; |
| 220 } | 206 } |
| 221 media::VideoCaptureDevice* video_capture_device = it->second; | |
| 222 | 207 |
| 223 // Possible errors are signaled to video_capture_receiver by | 208 // Possible errors are signaled to video_capture_receiver by |
| 224 // video_capture_device. video_capture_receiver to perform actions. | 209 // video_capture_device. video_capture_receiver to perform actions. |
| 225 video_capture_device->Allocate(capture_params.width, capture_params.height, | 210 video_capture_device->Allocate(capture_params.width, capture_params.height, |
| 226 capture_params.frame_per_second, | 211 capture_params.frame_per_second, |
| 227 video_capture_receiver); | 212 video_capture_receiver); |
| 228 video_capture_device->Start(); | 213 video_capture_device->Start(); |
| 229 } | 214 } |
| 230 | 215 |
| 231 void VideoCaptureManager::OnStop( | 216 void VideoCaptureManager::OnStop( |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 363 for (VideoCaptureDevices::iterator it = devices_.begin(); | 348 for (VideoCaptureDevices::iterator it = devices_.begin(); |
| 364 it != devices_.end(); | 349 it != devices_.end(); |
| 365 it++) { | 350 it++) { |
| 366 if (device_info.device_id == it->second->device_name().unique_id) { | 351 if (device_info.device_id == it->second->device_name().unique_id) { |
| 367 return true; | 352 return true; |
| 368 } | 353 } |
| 369 } | 354 } |
| 370 return false; | 355 return false; |
| 371 } | 356 } |
| 372 | 357 |
| 358 void VideoCaptureManager::AddController( | |
| 359 const media::VideoCaptureParams& capture_params, | |
| 360 VideoCaptureControllerEventHandler* handler, | |
| 361 base::Callback<void(VideoCaptureController*)> added_cb) { | |
| 362 DCHECK(handler); | |
| 363 vc_device_thread_.message_loop()->PostTask( | |
| 364 FROM_HERE, | |
| 365 base::Bind(&VideoCaptureManager::DoAddControllerOnDeviceThread, | |
| 366 base::Unretained(this), capture_params, handler, added_cb)); | |
| 367 } | |
| 368 | |
| 369 void VideoCaptureManager::DoAddControllerOnDeviceThread( | |
| 370 const media::VideoCaptureParams capture_params, | |
| 371 VideoCaptureControllerEventHandler* handler, | |
| 372 base::Callback<void(VideoCaptureController*)> added_cb) { | |
| 373 DCHECK(IsOnCaptureDeviceThread()); | |
| 374 | |
| 375 media::VideoCaptureDevice* video_capture_device = | |
| 376 GetDeviceInternal(capture_params.session_id); | |
| 377 scoped_refptr<VideoCaptureController> ctrller = NULL; | |
| 378 if (video_capture_device) { | |
| 379 Controllers::iterator cit = controllers_.find(video_capture_device); | |
| 380 if (cit == controllers_.end()) { | |
| 381 ctrller = new VideoCaptureController(this); | |
| 382 controllers_[video_capture_device] = new Controller(ctrller, handler); | |
| 383 } else { | |
| 384 controllers_[video_capture_device]->handlers.push_front(handler); | |
| 385 ctrller = controllers_[video_capture_device]->controller; | |
| 386 } | |
| 387 } | |
| 388 added_cb.Run(ctrller); | |
| 389 } | |
| 390 | |
| 391 void VideoCaptureManager::RemoveController( | |
| 392 VideoCaptureController* controller, | |
| 393 VideoCaptureControllerEventHandler* handler) { | |
| 394 DCHECK(handler); | |
| 395 vc_device_thread_.message_loop()->PostTask( | |
| 396 FROM_HERE, | |
| 397 base::Bind(&VideoCaptureManager::DoRemoveControllerOnDeviceThread, | |
| 398 base::Unretained(this), | |
| 399 make_scoped_refptr(controller), | |
| 400 handler)); | |
| 401 } | |
| 402 | |
| 403 void VideoCaptureManager::DoRemoveControllerOnDeviceThread( | |
| 404 VideoCaptureController* controller, | |
| 405 VideoCaptureControllerEventHandler* handler) { | |
| 406 DCHECK(IsOnCaptureDeviceThread()); | |
| 407 | |
| 408 for (Controllers::iterator cit = controllers_.begin(); | |
| 409 cit != controllers_.end(); ++cit) { | |
| 410 if (controller == cit->second->controller) { | |
| 411 Handlers& handlers = cit->second->handlers; | |
| 412 for (Handlers::iterator hit = handlers.begin(); | |
| 413 hit != handlers.end(); ++hit) { | |
| 414 if ((*hit) == handler) { | |
| 415 handlers.erase(hit); | |
| 416 break; | |
| 417 } | |
| 418 } | |
| 419 if (handlers.size() == 0 && cit->second->ready_to_delete) { | |
| 420 delete cit->second; | |
| 421 controllers_.erase(cit); | |
| 422 } | |
| 423 return; | |
| 424 } | |
| 425 } | |
| 426 } | |
| 427 | |
| 428 void VideoCaptureManager::DeviceStatusFromController( | |
| 429 VideoCaptureController* controller, bool in_use) { | |
| 430 DCHECK(controller); | |
| 431 vc_device_thread_.message_loop()->PostTask( | |
| 432 FROM_HERE, base::Bind( | |
| 433 &VideoCaptureManager::DoDeviceStatusFromControllerOnDeviceThread, | |
| 434 base::Unretained(this), | |
| 435 make_scoped_refptr(controller), | |
| 436 in_use)); | |
| 437 } | |
| 438 | |
| 439 void VideoCaptureManager::DoDeviceStatusFromControllerOnDeviceThread( | |
| 440 VideoCaptureController* controller, bool in_use) { | |
| 441 DCHECK(IsOnCaptureDeviceThread()); | |
| 442 for (Controllers::iterator cit = controllers_.begin(); | |
| 443 cit != controllers_.end(); ++cit) { | |
| 444 if (controller == cit->second->controller) { | |
| 445 if (in_use) { | |
| 446 cit->second->ready_to_delete = false; | |
| 447 } else { | |
| 448 cit->second->ready_to_delete = true; | |
| 449 if (cit->second->handlers.size() == 0) { | |
| 450 delete cit->second; | |
| 451 controllers_.erase(cit); | |
| 452 } | |
| 453 } | |
| 454 return; | |
| 455 } | |
| 456 } | |
| 457 } | |
| 458 | |
| 459 media::VideoCaptureDevice* VideoCaptureManager::GetDeviceInternal( | |
| 460 int capture_session_id) { | |
| 461 DCHECK(IsOnCaptureDeviceThread()); | |
| 462 VideoCaptureDevices::iterator dit = devices_.find(capture_session_id); | |
| 463 if (dit != devices_.end()) { | |
| 464 return dit->second; | |
| 465 } | |
| 466 | |
| 467 // Solution for not using MediaStreamManager. | |
| 468 // This session id won't be returned by Open(). | |
| 469 if (capture_session_id == kStartOpenSessionId) { | |
| 470 media::VideoCaptureDevice::Names device_names; | |
| 471 GetAvailableDevices(&device_names); | |
| 472 if (device_names.empty()) { | |
| 473 // No devices available. | |
| 474 return NULL; | |
| 475 } | |
| 476 StreamDeviceInfo device(kVideoCapture, | |
| 477 device_names.front().device_name, | |
| 478 device_names.front().unique_id, false); | |
| 479 | |
| 480 // Call OnOpen to open using the first device in the list. | |
| 481 OnOpen(capture_session_id, device); | |
| 482 | |
| 483 VideoCaptureDevices::iterator dit = devices_.find(capture_session_id); | |
| 484 if (dit != devices_.end()) { | |
| 485 return dit->second; | |
| 486 } | |
| 487 } | |
| 488 return NULL; | |
| 489 } | |
| 490 | |
| 491 VideoCaptureManager::Controller::Controller( | |
| 492 VideoCaptureController* ctrller, | |
|
perkj_chrome
2011/10/17 08:39:43
nit: name?
wjia(left Chromium)
2011/10/21 00:56:13
Done.
| |
| 493 VideoCaptureControllerEventHandler* handler) | |
| 494 : controller(ctrller), | |
| 495 ready_to_delete(false) { | |
| 496 handlers.push_front(handler); | |
| 497 } | |
| 498 | |
| 499 VideoCaptureManager::Controller::~Controller() {} | |
| 500 | |
| 373 } // namespace media_stream | 501 } // namespace media_stream |
| OLD | NEW |