| Index: content/browser/renderer_host/media/video_capture_manager.cc
|
| ===================================================================
|
| --- content/browser/renderer_host/media/video_capture_manager.cc (revision 106642)
|
| +++ content/browser/renderer_host/media/video_capture_manager.cc (working copy)
|
| @@ -5,8 +5,10 @@
|
| #include "content/browser/renderer_host/media/video_capture_manager.h"
|
|
|
| #include "base/bind.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| +#include "base/stl_util.h"
|
| #include "content/browser/browser_thread.h"
|
| +#include "content/browser/renderer_host/media/video_capture_controller.h"
|
| +#include "content/browser/renderer_host/media/video_capture_controller_event_handler.h"
|
| #include "media/video/capture/fake_video_capture_device.h"
|
| #include "media/video/capture/video_capture_device.h"
|
|
|
| @@ -17,6 +19,21 @@
|
| // explicitly calling open device.
|
| enum { kFirstSessionId = VideoCaptureManager::kStartOpenSessionId + 1 };
|
|
|
| +struct VideoCaptureManager::Controller {
|
| + Controller(
|
| + VideoCaptureController* vc_controller,
|
| + VideoCaptureControllerEventHandler* handler)
|
| + : controller(vc_controller),
|
| + ready_to_delete(false) {
|
| + handlers.push_front(handler);
|
| + }
|
| + ~Controller() {}
|
| +
|
| + scoped_refptr<VideoCaptureController> controller;
|
| + bool ready_to_delete;
|
| + Handlers handlers;
|
| +};
|
| +
|
| VideoCaptureManager::VideoCaptureManager()
|
| : vc_device_thread_("VideoCaptureManagerThread"),
|
| listener_(NULL),
|
| @@ -38,6 +55,7 @@
|
| it->second->DeAllocate();
|
| delete it->second;
|
| }
|
| + STLDeleteValues(&controllers_);
|
| }
|
|
|
| void VideoCaptureManager::Register(MediaStreamProviderListener* listener) {
|
| @@ -193,32 +211,13 @@
|
| DCHECK(IsOnCaptureDeviceThread());
|
| DCHECK(video_capture_receiver != NULL);
|
|
|
| - // Solution for not using MediaStreamManager.
|
| - // This session id won't be returned by Open().
|
| - if (capture_params.session_id == kStartOpenSessionId) {
|
| - // Start() is called without using Open(), we need to open a device.
|
| - media::VideoCaptureDevice::Names device_names;
|
| - GetAvailableDevices(&device_names);
|
| - if (device_names.empty()) {
|
| - // No devices available.
|
| - video_capture_receiver->OnError();
|
| - return;
|
| - }
|
| - StreamDeviceInfo device(kVideoCapture,
|
| - device_names.front().device_name,
|
| - device_names.front().unique_id, false);
|
| -
|
| - // Call OnOpen to open using the first device in the list.
|
| - OnOpen(capture_params.session_id, device);
|
| - }
|
| -
|
| - VideoCaptureDevices::iterator it = devices_.find(capture_params.session_id);
|
| - if (it == devices_.end()) {
|
| + media::VideoCaptureDevice* video_capture_device =
|
| + GetDeviceInternal(capture_params.session_id);
|
| + if (!video_capture_device) {
|
| // Invalid session id.
|
| video_capture_receiver->OnError();
|
| return;
|
| }
|
| - media::VideoCaptureDevice* video_capture_device = it->second;
|
|
|
| // Possible errors are signaled to video_capture_receiver by
|
| // video_capture_device. video_capture_receiver to perform actions.
|
| @@ -370,4 +369,137 @@
|
| return false;
|
| }
|
|
|
| +void VideoCaptureManager::AddController(
|
| + const media::VideoCaptureParams& capture_params,
|
| + VideoCaptureControllerEventHandler* handler,
|
| + base::Callback<void(VideoCaptureController*)> added_cb) {
|
| + DCHECK(handler);
|
| + vc_device_thread_.message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&VideoCaptureManager::DoAddControllerOnDeviceThread,
|
| + base::Unretained(this), capture_params, handler, added_cb));
|
| +}
|
| +
|
| +void VideoCaptureManager::DoAddControllerOnDeviceThread(
|
| + const media::VideoCaptureParams capture_params,
|
| + VideoCaptureControllerEventHandler* handler,
|
| + base::Callback<void(VideoCaptureController*)> added_cb) {
|
| + DCHECK(IsOnCaptureDeviceThread());
|
| +
|
| + media::VideoCaptureDevice* video_capture_device =
|
| + GetDeviceInternal(capture_params.session_id);
|
| + scoped_refptr<VideoCaptureController> ctrller = NULL;
|
| + if (video_capture_device) {
|
| + Controllers::iterator cit = controllers_.find(video_capture_device);
|
| + if (cit == controllers_.end()) {
|
| + ctrller = new VideoCaptureController(this);
|
| + controllers_[video_capture_device] = new Controller(ctrller, handler);
|
| + } else {
|
| + controllers_[video_capture_device]->handlers.push_front(handler);
|
| + ctrller = controllers_[video_capture_device]->controller;
|
| + }
|
| + }
|
| + added_cb.Run(ctrller);
|
| +}
|
| +
|
| +void VideoCaptureManager::RemoveController(
|
| + VideoCaptureController* controller,
|
| + VideoCaptureControllerEventHandler* handler) {
|
| + DCHECK(handler);
|
| + vc_device_thread_.message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&VideoCaptureManager::DoRemoveControllerOnDeviceThread,
|
| + base::Unretained(this),
|
| + make_scoped_refptr(controller),
|
| + handler));
|
| +}
|
| +
|
| +void VideoCaptureManager::DoRemoveControllerOnDeviceThread(
|
| + VideoCaptureController* controller,
|
| + VideoCaptureControllerEventHandler* handler) {
|
| + DCHECK(IsOnCaptureDeviceThread());
|
| +
|
| + for (Controllers::iterator cit = controllers_.begin();
|
| + cit != controllers_.end(); ++cit) {
|
| + if (controller == cit->second->controller) {
|
| + Handlers& handlers = cit->second->handlers;
|
| + for (Handlers::iterator hit = handlers.begin();
|
| + hit != handlers.end(); ++hit) {
|
| + if ((*hit) == handler) {
|
| + handlers.erase(hit);
|
| + break;
|
| + }
|
| + }
|
| + if (handlers.size() == 0 && cit->second->ready_to_delete) {
|
| + delete cit->second;
|
| + controllers_.erase(cit);
|
| + }
|
| + return;
|
| + }
|
| + }
|
| +}
|
| +
|
| +void VideoCaptureManager::DeviceStatusFromController(
|
| + VideoCaptureController* controller, bool in_use) {
|
| + DCHECK(controller);
|
| + vc_device_thread_.message_loop()->PostTask(
|
| + FROM_HERE, base::Bind(
|
| + &VideoCaptureManager::DoDeviceStatusFromControllerOnDeviceThread,
|
| + base::Unretained(this),
|
| + make_scoped_refptr(controller),
|
| + in_use));
|
| +}
|
| +
|
| +void VideoCaptureManager::DoDeviceStatusFromControllerOnDeviceThread(
|
| + VideoCaptureController* controller, bool in_use) {
|
| + DCHECK(IsOnCaptureDeviceThread());
|
| + for (Controllers::iterator cit = controllers_.begin();
|
| + cit != controllers_.end(); ++cit) {
|
| + if (controller == cit->second->controller) {
|
| + if (in_use) {
|
| + cit->second->ready_to_delete = false;
|
| + } else {
|
| + cit->second->ready_to_delete = true;
|
| + if (cit->second->handlers.size() == 0) {
|
| + delete cit->second;
|
| + controllers_.erase(cit);
|
| + }
|
| + }
|
| + return;
|
| + }
|
| + }
|
| +}
|
| +
|
| +media::VideoCaptureDevice* VideoCaptureManager::GetDeviceInternal(
|
| + int capture_session_id) {
|
| + DCHECK(IsOnCaptureDeviceThread());
|
| + VideoCaptureDevices::iterator dit = devices_.find(capture_session_id);
|
| + if (dit != devices_.end()) {
|
| + return dit->second;
|
| + }
|
| +
|
| + // Solution for not using MediaStreamManager.
|
| + // This session id won't be returned by Open().
|
| + if (capture_session_id == kStartOpenSessionId) {
|
| + media::VideoCaptureDevice::Names device_names;
|
| + GetAvailableDevices(&device_names);
|
| + if (device_names.empty()) {
|
| + // No devices available.
|
| + return NULL;
|
| + }
|
| + StreamDeviceInfo device(kVideoCapture,
|
| + device_names.front().device_name,
|
| + device_names.front().unique_id, false);
|
| +
|
| + // Call OnOpen to open using the first device in the list.
|
| + OnOpen(capture_session_id, device);
|
| +
|
| + VideoCaptureDevices::iterator dit = devices_.find(capture_session_id);
|
| + if (dit != devices_.end()) {
|
| + return dit->second;
|
| + }
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| } // namespace media_stream
|
|
|