Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1776)

Unified Diff: content/browser/renderer_host/media/video_capture_manager.cc

Issue 8304017: enable video capture to support sharing across multiple renderer processes (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
« no previous file with comments | « content/browser/renderer_host/media/video_capture_manager.h ('k') | content/renderer/media/capture_video_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698