Index: content/browser/renderer_host/media/video_capture_manager.cc |
=================================================================== |
--- content/browser/renderer_host/media/video_capture_manager.cc (revision 107671) |
+++ 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,17 @@ |
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; |
+ Controllers::iterator cit = controllers_.find(video_capture_device); |
+ if (cit != controllers_.end()) { |
+ cit->second->ready_to_delete = false; |
+ } |
// Possible errors are signaled to video_capture_receiver by |
// video_capture_device. video_capture_receiver to perform actions. |
@@ -240,6 +243,14 @@ |
// video_capture_device. video_capture_receiver to perform actions. |
video_capture_device->Stop(); |
video_capture_device->DeAllocate(); |
+ Controllers::iterator cit = controllers_.find(video_capture_device); |
+ if (cit != controllers_.end()) { |
+ cit->second->ready_to_delete = true; |
+ if (cit->second->handlers.size() == 0) { |
+ delete cit->second; |
+ controllers_.erase(cit); |
+ } |
+ } |
} |
if (!stopped_cb.is_null()) |
@@ -370,4 +381,106 @@ |
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; |
+ } |
+ } |
+} |
+ |
+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 |