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

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

Issue 24133002: Make VideoCaptureController single-threaded and not ref counted. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix a memory leak Created 7 years, 3 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_controller.cc
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index dbafeba49223d38b2edec3f738977f6241e8898c..772b412c324d1dc14faab95ea9f77ca81c342ce6 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -94,13 +94,31 @@ struct VideoCaptureController::ControllerClient {
};
VideoCaptureController::VideoCaptureController()
- : chopped_width_(0),
- chopped_height_(0),
- frame_info_available_(false),
- state_(VIDEO_CAPTURE_STATE_STARTED) {
+ : frame_info_available_(false),
+ state_(VIDEO_CAPTURE_STATE_STARTED),
+ weak_ptr_factory_(this) {
memset(&current_params_, 0, sizeof(current_params_));
}
+VideoCaptureController::VideoCaptureDeviceClient::VideoCaptureDeviceClient(
+ const base::WeakPtr<VideoCaptureController>& controller)
+ : controller_(controller),
+ chopped_width_(0),
+ chopped_height_(0) {}
+
+VideoCaptureController::VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {}
+
+base::WeakPtr<VideoCaptureController> VideoCaptureController::AsWeakPtr() {
+ return weak_ptr_factory_.GetWeakPtr();
+}
+
+scoped_ptr<media::VideoCaptureDevice::EventHandler>
+VideoCaptureController::NewDeviceClient() {
+ scoped_ptr<media::VideoCaptureDevice::EventHandler> result(
+ new VideoCaptureDeviceClient(this->AsWeakPtr()));
+ return result.Pass();
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 l.117-119 are equiv to return make_scoped_ptr(new
ncarter (slow) 2013/09/14 00:07:24 Actually, clang throws a hissy fit on that. Becaus
+}
+
void VideoCaptureController::AddClient(
const VideoCaptureControllerID& id,
VideoCaptureControllerEventHandler* event_handler,
@@ -165,8 +183,7 @@ int VideoCaptureController::RemoveClient(
return session_id;
}
-void VideoCaptureController::StopSession(
- int session_id) {
+void VideoCaptureController::StopSession(int session_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DVLOG(1) << "VideoCaptureController::StopSession, id " << session_id;
@@ -198,20 +215,17 @@ void VideoCaptureController::ReturnBuffer(
buffer_pool_->RelinquishConsumerHold(buffer_id, 1);
}
-scoped_refptr<media::VideoFrame> VideoCaptureController::ReserveOutputBuffer() {
- base::AutoLock lock(buffer_pool_lock_);
- if (!buffer_pool_.get())
- return NULL;
+scoped_refptr<media::VideoFrame>
+VideoCaptureController::VideoCaptureDeviceClient::ReserveOutputBuffer() {
return buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
frame_info_.height),
0);
}
-// Implements VideoCaptureDevice::EventHandler.
// OnIncomingCapturedFrame is called the thread running the capture device.
// I.e.- DirectShow thread on windows and v4l2_thread on Linux.
#if !defined(OS_IOS) && !defined(OS_ANDROID)
-void VideoCaptureController::OnIncomingCapturedFrame(
+void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
const uint8* data,
int length,
base::Time timestamp,
@@ -220,14 +234,10 @@ void VideoCaptureController::OnIncomingCapturedFrame(
bool flip_horiz) {
TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
- scoped_refptr<media::VideoFrame> dst;
- {
- base::AutoLock lock(buffer_pool_lock_);
- if (!buffer_pool_.get())
- return;
- dst = buffer_pool_->ReserveI420VideoFrame(
- gfx::Size(frame_info_.width, frame_info_.height), rotation);
- }
+ if (!buffer_pool_.get())
+ return;
+ scoped_refptr<media::VideoFrame> dst = buffer_pool_->ReserveI420VideoFrame(
+ gfx::Size(frame_info_.width, frame_info_.height), rotation);
if (!dst.get())
return;
@@ -336,12 +346,12 @@ void VideoCaptureController::OnIncomingCapturedFrame(
BrowserThread::IO,
FROM_HERE,
base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
- this,
+ controller_,
dst,
timestamp));
}
#else
-void VideoCaptureController::OnIncomingCapturedFrame(
+void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedFrame(
const uint8* data,
int length,
base::Time timestamp,
@@ -354,15 +364,12 @@ void VideoCaptureController::OnIncomingCapturedFrame(
TRACE_EVENT0("video", "VideoCaptureController::OnIncomingCapturedFrame");
- scoped_refptr<media::VideoFrame> dst;
- {
- base::AutoLock lock(buffer_pool_lock_);
- if (!buffer_pool_.get())
- return;
- dst = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
- frame_info_.height),
- rotation);
- }
+ if (!buffer_pool_)
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 There's a crbug to not need to defend against this
ncarter (slow) 2013/09/14 00:07:24 Yes. I've added the TODO to a different place in t
+ return;
+ scoped_refptr<media::VideoFrame> dst =
+ buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
+ frame_info_.height),
+ rotation);
if (!dst.get())
return;
@@ -426,39 +433,37 @@ void VideoCaptureController::OnIncomingCapturedFrame(
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
- this, dst, timestamp));
+ controller_, dst, timestamp));
}
#endif // #if !defined(OS_IOS) && !defined(OS_ANDROID)
// OnIncomingCapturedVideoFrame is called the thread running the capture device.
Ami GONE FROM CHROMIUM 2013/09/13 21:17:59 english
ncarter (slow) 2013/09/14 00:07:24 Deleted and elaborated the class comment.
-void VideoCaptureController::OnIncomingCapturedVideoFrame(
+void
+VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
const scoped_refptr<media::VideoFrame>& frame,
base::Time timestamp) {
- scoped_refptr<media::VideoFrame> target;
- {
- base::AutoLock lock(buffer_pool_lock_);
-
- if (!buffer_pool_.get())
- return;
-
- // If this is a frame that belongs to the buffer pool, we can forward it
- // directly to the IO thread and be done.
- if (buffer_pool_->RecognizeReservedBuffer(
- frame->shared_memory_handle()) >= 0) {
- BrowserThread::PostTask(BrowserThread::IO,
- FROM_HERE,
- base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
- this, frame, timestamp));
- return;
- }
- // Otherwise, this is a frame that belongs to the caller, and we must copy
- // it to a frame from the buffer pool.
- target = buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
- frame_info_.height),
- 0);
+ if (!buffer_pool_)
+ return;
+
+ // If this is a frame that belongs to the buffer pool, we can forward it
+ // directly to the IO thread and be done.
+ if (buffer_pool_->RecognizeReservedBuffer(
+ frame->shared_memory_handle()) >= 0) {
+ BrowserThread::PostTask(BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
+ controller_, frame, timestamp));
+ return;
}
+ // Otherwise, this is a frame that belongs to the caller, and we must copy
+ // it to a frame from the buffer pool.
+ scoped_refptr<media::VideoFrame> target =
+ buffer_pool_->ReserveI420VideoFrame(gfx::Size(frame_info_.width,
+ frame_info_.height),
+ 0);
+
if (!target.get())
return;
@@ -545,18 +550,18 @@ void VideoCaptureController::OnIncomingCapturedVideoFrame(
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&VideoCaptureController::DoIncomingCapturedFrameOnIOThread,
- this, target, timestamp));
+ controller_, target, timestamp));
}
-void VideoCaptureController::OnError() {
+void VideoCaptureController::VideoCaptureDeviceClient::OnError() {
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
- base::Bind(&VideoCaptureController::DoErrorOnIOThread, this));
+ base::Bind(&VideoCaptureController::DoErrorOnIOThread, controller_));
}
-void VideoCaptureController::OnFrameInfo(
+void VideoCaptureController::VideoCaptureDeviceClient::OnFrameInfo(
const media::VideoCaptureCapability& info) {
- frame_info_= info;
+ frame_info_ = info;
// Handle cases when |info| has odd numbers for width/height.
if (info.width & 1) {
--frame_info_.width;
@@ -570,17 +575,35 @@ void VideoCaptureController::OnFrameInfo(
} else {
chopped_height_ = 0;
}
+
+ DCHECK(!buffer_pool_.get());
+
+ buffer_pool_ = new VideoCaptureBufferPool(
+ media::VideoFrame::AllocationSize(
+ media::VideoFrame::I420,
+ gfx::Size(frame_info_.width, frame_info_.height)),
+ kNoOfBuffers);
+
+ // Check whether all buffers were created successfully.
+ if (!buffer_pool_->Allocate()) {
+ // Transition to the error state.
+ buffer_pool_ = NULL;
+ OnError();
+ return;
+ }
+
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
- base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, this));
+ base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, controller_,
+ frame_info_, buffer_pool_));
}
-void VideoCaptureController::OnFrameInfoChanged(
+void VideoCaptureController::VideoCaptureDeviceClient::OnFrameInfoChanged(
const media::VideoCaptureCapability& info) {
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&VideoCaptureController::DoFrameInfoChangedOnIOThread,
- this, info));
+ controller_, info));
}
VideoCaptureController::~VideoCaptureController() {
@@ -621,7 +644,9 @@ void VideoCaptureController::DoIncomingCapturedFrameOnIOThread(
buffer_pool_->HoldForConsumers(buffer_id, count);
}
-void VideoCaptureController::DoFrameInfoOnIOThread() {
+void VideoCaptureController::DoFrameInfoOnIOThread(
+ const media::VideoCaptureCapability& frame_info,
+ const scoped_refptr<VideoCaptureBufferPool>& buffer_pool) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(!buffer_pool_.get()) << "Frame info should happen only once.";
@@ -629,24 +654,9 @@ void VideoCaptureController::DoFrameInfoOnIOThread() {
if (state_ != VIDEO_CAPTURE_STATE_STARTED)
return;
- scoped_refptr<VideoCaptureBufferPool> buffer_pool =
- new VideoCaptureBufferPool(
- media::VideoFrame::AllocationSize(
- media::VideoFrame::I420,
- gfx::Size(frame_info_.width, frame_info_.height)),
- kNoOfBuffers);
-
- // Check whether all buffers were created successfully.
- if (!buffer_pool->Allocate()) {
- DoErrorOnIOThread();
- return;
- }
-
- {
- base::AutoLock lock(buffer_pool_lock_);
- buffer_pool_ = buffer_pool;
- }
+ frame_info_ = frame_info;
frame_info_available_ = true;
+ buffer_pool_ = buffer_pool;
for (ControllerClients::iterator client_it = controller_clients_.begin();
client_it != controller_clients_.end(); ++client_it) {

Powered by Google App Engine
This is Rietveld 408576698