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

Unified Diff: content/renderer/media/video_capture_impl_manager.cc

Issue 242013002: Refactor video capturing code in the render process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged Created 6 years, 8 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/renderer/media/video_capture_impl_manager.cc
diff --git a/content/renderer/media/video_capture_impl_manager.cc b/content/renderer/media/video_capture_impl_manager.cc
index 07460fb6283337fd43f53c40cfff45dfd89f6c68..62495fa649e53bafd7ab527f47007b4c18de7756 100644
--- a/content/renderer/media/video_capture_impl_manager.cc
+++ b/content/renderer/media/video_capture_impl_manager.cc
@@ -1,89 +1,120 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+//
+// Implementation notes about lifetime of VideoCaptureImpl.
+//
+// VideoCaptureImpl is an internal class visible only by this class.
+// Since it is an IO thread object we manage the lifetime of it manually.
+// It is first created on the render thread. We also post a task to
+// access it on the IO thread. It is accessed with Unretained() because
+// we delete it on the IO thread after all clients have stopped.
#include "content/renderer/media/video_capture_impl_manager.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
-#include "content/public/renderer/render_thread.h"
+#include "content/child/child_process.h"
#include "content/renderer/media/video_capture_impl.h"
#include "content/renderer/media/video_capture_message_filter.h"
#include "media/base/bind_to_current_loop.h"
namespace content {
-VideoCaptureHandle::VideoCaptureHandle(
- media::VideoCapture* impl, base::Closure destruction_cb)
- : impl_(impl), destruction_cb_(destruction_cb) {
-}
-
-VideoCaptureHandle::~VideoCaptureHandle() {
- destruction_cb_.Run();
-}
-
-void VideoCaptureHandle::StartCapture(
- EventHandler* handler,
- const media::VideoCaptureParams& params) {
- impl_->StartCapture(handler, params);
-}
-
-void VideoCaptureHandle::StopCapture(EventHandler* handler) {
- impl_->StopCapture(handler);
-}
-
-bool VideoCaptureHandle::CaptureStarted() {
- return impl_->CaptureStarted();
-}
-
-int VideoCaptureHandle::CaptureFrameRate() {
- return impl_->CaptureFrameRate();
-}
-
-void VideoCaptureHandle::GetDeviceSupportedFormats(
- const DeviceFormatsCallback& callback) {
- impl_->GetDeviceSupportedFormats(callback);
-}
-
-void VideoCaptureHandle::GetDeviceFormatsInUse(
- const DeviceFormatsInUseCallback& callback) {
- impl_->GetDeviceFormatsInUse(callback);
-}
-
VideoCaptureImplManager::VideoCaptureImplManager()
- : filter_(new VideoCaptureMessageFilter()),
+ : next_client_id_(0),
+ filter_(new VideoCaptureMessageFilter()),
weak_factory_(this) {
}
VideoCaptureImplManager::~VideoCaptureImplManager() {
DCHECK(thread_checker_.CalledOnValidThread());
+ if (devices_.empty())
+ return;
+ // Forcibly release all video capture resources.
+ for (VideoCaptureDeviceMap::iterator it = devices_.begin();
+ it != devices_.end(); ++it) {
+ VideoCaptureImpl* impl = it->second.second;
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 ChildProcess::current()->io_message_loop_proxy() i
Alpha Left Google 2014/04/23 18:48:33 MessageLoopProxy::current() is the IO message loop
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::DeInit,
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 why not DeInit+delete directly in-line here?
Alpha Left Google 2014/04/23 18:48:33 VCI is an IO thread only object. It is accessed vi
+ base::Unretained(impl)));
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 any "Unretained" use should be covered by an expla
Alpha Left Google 2014/04/23 18:48:33 I documented it at the top of this file.
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&base::DeletePointer<VideoCaptureImpl>, impl));
+ }
+ devices_.clear();
}
-scoped_ptr<VideoCaptureHandle> VideoCaptureImplManager::UseDevice(
+base::Closure VideoCaptureImplManager::UseDevice(
media::VideoCaptureSessionId id) {
DCHECK(thread_checker_.CalledOnValidThread());
- VideoCaptureImpl* video_capture_device = NULL;
+ VideoCaptureImpl* impl = NULL;
VideoCaptureDeviceMap::iterator it = devices_.find(id);
if (it == devices_.end()) {
- video_capture_device = CreateVideoCaptureImpl(id, filter_.get());
- devices_[id] =
- std::make_pair(1, linked_ptr<VideoCaptureImpl>(video_capture_device));
- video_capture_device->Init();
+ impl = CreateVideoCaptureImpl(id, filter_.get());
+ devices_[id] = std::make_pair(1, impl);
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 ditto why post instead of running in-line?
Alpha Left Google 2014/04/23 18:48:33 VCIM is render thread only. VideoCaptureImpl is IO
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::Init,
+ base::Unretained(impl)));
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 ditto Unretained
Alpha Left Google 2014/04/23 18:48:33 Please see comments at the top of this file.
} else {
++it->second.first;
- video_capture_device = it->second.second.get();
+ impl = it->second.second;
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 unused?
Alpha Left Google 2014/04/23 18:48:33 Removed.
}
+ return base::Bind(&VideoCaptureImplManager::UnrefDevice, this, id);
+}
- // This callback ensures UnrefDevice() happens on the render thread.
- return scoped_ptr<VideoCaptureHandle>(
- new VideoCaptureHandle(
- video_capture_device,
- media::BindToCurrentLoop(
- base::Bind(
- &VideoCaptureImplManager::UnrefDevice,
- weak_factory_.GetWeakPtr(),
- id))));
+base::Closure VideoCaptureImplManager::StartCapture(
+ media::VideoCaptureSessionId id,
+ const media::VideoCaptureParams& params,
+ const VideoCaptureStateUpdateCB& state_update_cb,
+ const VideoCaptureDeliverFrameCB& deliver_frame_cb) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ VideoCaptureDeviceMap::iterator it = devices_.find(id);
+ DCHECK(it != devices_.end());
+ VideoCaptureImpl* impl = it->second.second;
+
+ // This ID is used to identify a client of VideoCaptureImpl.
+ const int client_id = ++next_client_id_;
+
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
Ami GONE FROM CHROMIUM 2014/04/21 23:42:53 not reviewing the rest of this file since I hope y
Alpha Left Google 2014/04/23 18:48:33 I have changed the access pattern. Instead of VCI
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::StartCapture,
+ base::Unretained(impl),
+ client_id,
+ params,
+ state_update_cb,
+ deliver_frame_cb));
+ return base::Bind(&VideoCaptureImplManager::StopCapture, this,
+ client_id, id);
+}
+
+void VideoCaptureImplManager::GetDeviceSupportedFormats(
+ media::VideoCaptureSessionId id,
+ const VideoCaptureDeviceFormatsCB& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ VideoCaptureDeviceMap::iterator it = devices_.find(id);
+ DCHECK(it != devices_.end());
+ VideoCaptureImpl* impl = it->second.second;
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::GetDeviceSupportedFormats,
+ base::Unretained(impl), callback));
+}
+
+void VideoCaptureImplManager::GetDeviceFormatsInUse(
+ media::VideoCaptureSessionId id,
+ const VideoCaptureDeviceFormatsCB& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ VideoCaptureDeviceMap::iterator it = devices_.find(id);
+ DCHECK(it != devices_.end());
+ VideoCaptureImpl* impl = it->second.second;
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::GetDeviceFormatsInUse,
+ base::Unretained(impl), callback));
}
VideoCaptureImpl* VideoCaptureImplManager::CreateVideoCaptureImpl(
@@ -92,26 +123,50 @@ VideoCaptureImpl* VideoCaptureImplManager::CreateVideoCaptureImpl(
return new VideoCaptureImpl(id, filter);
}
+void VideoCaptureImplManager::StopCapture(
+ int client_id, media::VideoCaptureSessionId id) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ VideoCaptureDeviceMap::iterator it = devices_.find(id);
+ DCHECK(it != devices_.end());
+ VideoCaptureImpl* impl = it->second.second;
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::StopCapture,
+ base::Unretained(impl), client_id));
+}
+
void VideoCaptureImplManager::UnrefDevice(
media::VideoCaptureSessionId id) {
DCHECK(thread_checker_.CalledOnValidThread());
VideoCaptureDeviceMap::iterator it = devices_.find(id);
DCHECK(it != devices_.end());
+ VideoCaptureImpl* impl = it->second.second;
+ // Unref and destroy on the IO thread if there's no more client.
DCHECK(it->second.first);
--it->second.first;
if (!it->second.first) {
- VideoCaptureImpl* impl = it->second.second.release();
devices_.erase(id);
- impl->DeInit(base::Bind(&base::DeletePointer<VideoCaptureImpl>, impl));
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::DeInit,
+ base::Unretained(impl)));
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&base::DeletePointer<VideoCaptureImpl>, impl));
}
}
void VideoCaptureImplManager::SuspendDevices(bool suspend) {
DCHECK(thread_checker_.CalledOnValidThread());
for (VideoCaptureDeviceMap::iterator it = devices_.begin();
- it != devices_.end(); ++it)
- it->second.second->SuspendCapture(suspend);
+ it != devices_.end(); ++it) {
+ VideoCaptureImpl* impl = it->second.second;
+ ChildProcess::current()->io_message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&VideoCaptureImpl::SuspendCapture,
+ base::Unretained(impl), suspend));
+ }
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698