diff options
author | wjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 03:41:43 +0000 |
---|---|---|
committer | wjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 03:41:43 +0000 |
commit | 5161efd189654e665fec35021b7f66e9815402ab (patch) | |
tree | 1e73eab7fe0b37a2754bea879419be98d5bb787c /content | |
parent | 16d6c12ef5d56237d4b60f62246887b36d87176c (diff) | |
download | chromium_src-5161efd189654e665fec35021b7f66e9815402ab.zip chromium_src-5161efd189654e665fec35021b7f66e9815402ab.tar.gz chromium_src-5161efd189654e665fec35021b7f66e9815402ab.tar.bz2 |
for readability review.
Review URL: https://chromiumcodereview.appspot.com/10451087
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146516 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/renderer/media/capture_video_decoder_unittest.cc | 3 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl.cc | 229 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl.h | 54 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl_unittest.cc | 3 |
4 files changed, 148 insertions, 141 deletions
diff --git a/content/renderer/media/capture_video_decoder_unittest.cc b/content/renderer/media/capture_video_decoder_unittest.cc index cd93f92..643fc50 100644 --- a/content/renderer/media/capture_video_decoder_unittest.cc +++ b/content/renderer/media/capture_video_decoder_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/bind.h" +#include "content/common/child_process.h" #include "content/renderer/media/capture_video_decoder.h" #include "content/renderer/media/video_capture_impl.h" #include "content/renderer/media/video_capture_impl_manager.h" @@ -103,6 +104,7 @@ class CaptureVideoDecoderTest : public ::testing::Test { read_cb_ = base::Bind(&CaptureVideoDecoderTest::FrameReady, base::Unretained(this)); + child_process_.reset(new ChildProcess()); vc_impl_.reset(new MockVideoCaptureImpl( kVideoStreamId, message_loop_proxy_, new VideoCaptureMessageFilter())); } @@ -159,6 +161,7 @@ class CaptureVideoDecoderTest : public ::testing::Test { // Fixture members. scoped_refptr<CaptureVideoDecoder> decoder_; scoped_refptr<MockVideoCaptureImplManager> vc_manager_; + scoped_ptr<ChildProcess> child_process_; scoped_ptr<MockVideoCaptureImpl> vc_impl_; media::MockStatisticsCB statistics_cb_object_; scoped_ptr<MessageLoop> message_loop_; diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index 1fa61a2..faa29d0 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc @@ -50,6 +50,7 @@ VideoCaptureImpl::VideoCaptureImpl( : VideoCapture(), message_filter_(filter), capture_message_loop_proxy_(capture_message_loop_proxy), + io_message_loop_proxy_(ChildProcess::current()->io_message_loop_proxy()), device_id_(0), video_type_(media::VideoCaptureCapability::kI420), device_info_available_(false), @@ -61,34 +62,22 @@ VideoCaptureImpl::VideoCaptureImpl( } VideoCaptureImpl::~VideoCaptureImpl() { - STLDeleteContainerPairSecondPointers(cached_dibs_.begin(), - cached_dibs_.end()); + STLDeleteValues(&cached_dibs_); } void VideoCaptureImpl::Init() { - io_message_loop_proxy_ = ChildProcess::current()->io_message_loop_proxy(); if (!io_message_loop_proxy_->BelongsToCurrentThread()) { io_message_loop_proxy_->PostTask(FROM_HERE, base::Bind(&VideoCaptureImpl::AddDelegateOnIOThread, base::Unretained(this))); - return; + } else { + AddDelegateOnIOThread(); } - - AddDelegateOnIOThread(); } void VideoCaptureImpl::DeInit(base::Closure task) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoDeInit, - base::Unretained(this), task)); -} - -void VideoCaptureImpl::DoDeInit(base::Closure task) { - if (state_ == video_capture::kStarted) - Send(new VideoCaptureHostMsg_Stop(device_id_)); - - io_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::RemoveDelegateOnIOThread, + base::Bind(&VideoCaptureImpl::DoDeInitOnCaptureThread, base::Unretained(this), task)); } @@ -98,19 +87,19 @@ void VideoCaptureImpl::StartCapture( DCHECK_EQ(capability.color, media::VideoCaptureCapability::kI420); capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoStartCapture, + base::Bind(&VideoCaptureImpl::DoStartCaptureOnCaptureThread, base::Unretained(this), handler, capability)); } void VideoCaptureImpl::StopCapture(media::VideoCapture::EventHandler* handler) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoStopCapture, + base::Bind(&VideoCaptureImpl::DoStopCaptureOnCaptureThread, base::Unretained(this), handler)); } void VideoCaptureImpl::FeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoFeedBuffer, + base::Bind(&VideoCaptureImpl::DoFeedBufferOnCaptureThread, base::Unretained(this), buffer)); } @@ -118,36 +107,45 @@ void VideoCaptureImpl::OnBufferCreated( base::SharedMemoryHandle handle, int length, int buffer_id) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoBufferCreated, + base::Bind(&VideoCaptureImpl::DoBufferCreatedOnCaptureThread, base::Unretained(this), handle, length, buffer_id)); } void VideoCaptureImpl::OnBufferReceived(int buffer_id, base::Time timestamp) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoBufferReceived, + base::Bind(&VideoCaptureImpl::DoBufferReceivedOnCaptureThread, base::Unretained(this), buffer_id, timestamp)); } void VideoCaptureImpl::OnStateChanged(video_capture::State state) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoStateChanged, + base::Bind(&VideoCaptureImpl::DoStateChangedOnCaptureThread, base::Unretained(this), state)); } void VideoCaptureImpl::OnDeviceInfoReceived( const media::VideoCaptureParams& device_info) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoDeviceInfoReceived, + base::Bind(&VideoCaptureImpl::DoDeviceInfoReceivedOnCaptureThread, base::Unretained(this), device_info)); } void VideoCaptureImpl::OnDelegateAdded(int32 device_id) { capture_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&VideoCaptureImpl::DoDelegateAdded, + base::Bind(&VideoCaptureImpl::DoDelegateAddedOnCaptureThread, base::Unretained(this), device_id)); } -void VideoCaptureImpl::DoStartCapture( +void VideoCaptureImpl::DoDeInitOnCaptureThread(base::Closure task) { + if (state_ == video_capture::kStarted) + Send(new VideoCaptureHostMsg_Stop(device_id_)); + + io_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&VideoCaptureImpl::RemoveDelegateOnIOThread, + base::Unretained(this), task)); +} + +void VideoCaptureImpl::DoStartCaptureOnCaptureThread( media::VideoCapture::EventHandler* handler, const media::VideoCaptureCapability& capability) { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); @@ -155,114 +153,88 @@ void VideoCaptureImpl::DoStartCapture( if (state_ == video_capture::kError) { handler->OnError(this, 1); handler->OnRemoved(this); - return; - } - - ClientInfo::iterator it1 = clients_pending_on_filter_.find(handler); - ClientInfo::iterator it2 = clients_pending_on_restart_.find(handler); - if (it1 != clients_pending_on_filter_.end() || - it2 != clients_pending_on_restart_.end() || - clients_.find(handler) != clients_.end() ) { + } else if ((clients_pending_on_filter_.find(handler) != + clients_pending_on_filter_.end()) || + (clients_pending_on_restart_.find(handler) != + clients_pending_on_restart_.end()) || + clients_.find(handler) != clients_.end() ) { // This client has started. - return; - } - - if (!device_id_) { + } else if (!device_id_) { clients_pending_on_filter_[handler] = capability; - return; - } - - handler->OnStarted(this); - if (state_ == video_capture::kStarted) { - if (capability.width > current_params_.width || - capability.height > current_params_.height) { - StopDevice(); - DVLOG(1) << "StartCapture: Got client with higher resolution (" - << capability.width << ", " << capability.height << ") " - << "after started, try to restart."; + } else { + handler->OnStarted(this); + if (state_ == video_capture::kStarted) { + if (capability.width > current_params_.width || + capability.height > current_params_.height) { + StopDevice(); + DVLOG(1) << "StartCapture: Got client with higher resolution (" + << capability.width << ", " << capability.height << ") " + << "after started, try to restart."; + clients_pending_on_restart_[handler] = capability; + } else { + if (device_info_available_) { + handler->OnDeviceInfoReceived(this, device_info_); + } + + clients_[handler] = capability; + } + } else if (state_ == video_capture::kStopping) { clients_pending_on_restart_[handler] = capability; - return; - } - - if (device_info_available_) { - handler->OnDeviceInfoReceived(this, device_info_); + DVLOG(1) << "StartCapture: Got new resolution (" + << capability.width << ", " << capability.height << ") " + << ", during stopping."; + } else { + clients_[handler] = capability; + DCHECK_EQ(1ul, clients_.size()); + video_type_ = capability.color; + current_params_.width = capability.width; + current_params_.height = capability.height; + current_params_.frame_per_second = capability.frame_rate; + DVLOG(1) << "StartCapture: starting with first resolution (" + << current_params_.width << "," << current_params_.height << ")"; + + StartCaptureInternal(); } - - clients_[handler] = capability; - return; } - - if (state_ == video_capture::kStopping) { - clients_pending_on_restart_[handler] = capability; - DVLOG(1) << "StartCapture: Got new resolution (" - << capability.width << ", " << capability.height << ") " - << ", during stopping."; - return; - } - - clients_[handler] = capability; - DCHECK_EQ(clients_.size(), 1ul); - video_type_ = capability.color; - current_params_.width = capability.width; - current_params_.height = capability.height; - current_params_.frame_per_second = capability.frame_rate; - DVLOG(1) << "StartCapture: starting with first resolution (" - << current_params_.width << ", " << current_params_.height << ")"; - - StartCaptureInternal(); } -void VideoCaptureImpl::DoStopCapture( +void VideoCaptureImpl::DoStopCaptureOnCaptureThread( media::VideoCapture::EventHandler* handler) { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); - ClientInfo::iterator it = clients_pending_on_filter_.find(handler); - if (it != clients_pending_on_filter_.end()) { - handler->OnStopped(this); - handler->OnRemoved(this); - clients_pending_on_filter_.erase(it); - return; - } - it = clients_pending_on_restart_.find(handler); - if (it != clients_pending_on_restart_.end()) { - handler->OnStopped(this); - handler->OnRemoved(this); - clients_pending_on_restart_.erase(it); - return; - } - - if (clients_.find(handler) == clients_.end()) - return; - - clients_.erase(handler); + // A handler can be in only one client list. + // If this handler is in any client list, we can just remove it from + // that client list and don't have to run the other following RemoveClient(). + RemoveClient(handler, &clients_pending_on_filter_) || + RemoveClient(handler, &clients_pending_on_restart_) || + RemoveClient(handler, &clients_); if (clients_.empty()) { DVLOG(1) << "StopCapture: No more client, stopping ..."; StopDevice(); } - handler->OnStopped(this); - handler->OnRemoved(this); } -void VideoCaptureImpl::DoFeedBuffer(scoped_refptr<VideoFrameBuffer> buffer) { +void VideoCaptureImpl::DoFeedBufferOnCaptureThread( + scoped_refptr<VideoFrameBuffer> buffer) { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); CachedDIB::iterator it; - for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) { + for (it = cached_dibs_.begin(); it != cached_dibs_.end(); ++it) { if (buffer == it->second->mapped_memory) break; } if (it != cached_dibs_.end() && it->second) { DCHECK_GT(it->second->references, 0); - it->second->references--; + --it->second->references; if (it->second->references == 0) { Send(new VideoCaptureHostMsg_BufferReady(device_id_, it->first)); } } } -void VideoCaptureImpl::DoBufferCreated( +void VideoCaptureImpl::DoBufferCreatedOnCaptureThread( base::SharedMemoryHandle handle, int length, int buffer_id) { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); @@ -284,7 +256,8 @@ void VideoCaptureImpl::DoBufferCreated( cached_dibs_[buffer_id] = dib_buffer; } -void VideoCaptureImpl::DoBufferReceived(int buffer_id, base::Time timestamp) { +void VideoCaptureImpl::DoBufferReceivedOnCaptureThread( + int buffer_id, base::Time timestamp) { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); if (state_ != video_capture::kStarted) { @@ -297,13 +270,14 @@ void VideoCaptureImpl::DoBufferReceived(int buffer_id, base::Time timestamp) { buffer = cached_dibs_[buffer_id]->mapped_memory; buffer->timestamp = timestamp; - for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { + for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) { it->first->OnBufferReady(this, buffer); } cached_dibs_[buffer_id]->references = clients_.size(); } -void VideoCaptureImpl::DoStateChanged(video_capture::State state) { +void VideoCaptureImpl::DoStateChangedOnCaptureThread( + video_capture::State state) { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); switch (state) { @@ -318,14 +292,14 @@ void VideoCaptureImpl::DoStateChanged(video_capture::State state) { break; case video_capture::kPaused: for (ClientInfo::iterator it = clients_.begin(); - it != clients_.end(); it++) { + it != clients_.end(); ++it) { it->first->OnPaused(this); } break; case video_capture::kError: DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; for (ClientInfo::iterator it = clients_.begin(); - it != clients_.end(); it++) { + it != clients_.end(); ++it) { // TODO(wjia): browser process would send error code. it->first->OnError(this, 1); it->first->OnRemoved(this); @@ -338,7 +312,7 @@ void VideoCaptureImpl::DoStateChanged(video_capture::State state) { } } -void VideoCaptureImpl::DoDeviceInfoReceived( +void VideoCaptureImpl::DoDeviceInfoReceivedOnCaptureThread( const media::VideoCaptureParams& device_info) { DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); DCHECK(!ClientHasDIB()); @@ -347,12 +321,12 @@ void VideoCaptureImpl::DoDeviceInfoReceived( device_info_ = device_info; device_info_available_ = true; - for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { + for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); ++it) { it->first->OnDeviceInfoReceived(this, device_info); } } -void VideoCaptureImpl::DoDelegateAdded(int32 device_id) { +void VideoCaptureImpl::DoDelegateAddedOnCaptureThread(int32 device_id) { DVLOG(1) << "DoDelegateAdded: device_id " << device_id; DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); @@ -384,18 +358,14 @@ void VideoCaptureImpl::RestartCapture() { int width = 0; int height = 0; for (ClientInfo::iterator it = clients_.begin(); - it != clients_.end(); it++) { - if (it->second.width > width) - width = it->second.width; - if (it->second.height > height) - height = it->second.height; + it != clients_.end(); ++it) { + width = std::max(width, it->second.width); + height = std::max(height, it->second.height); } for (ClientInfo::iterator it = clients_pending_on_restart_.begin(); it != clients_pending_on_restart_.end(); ) { - if (it->second.width > width) - width = it->second.width; - if (it->second.height > height) - height = it->second.height; + width = std::max(width, it->second.width); + height = std::max(height, it->second.height); clients_[it->first] = it->second; clients_pending_on_restart_.erase(it++); } @@ -431,11 +401,28 @@ void VideoCaptureImpl::Send(IPC::Message* message) { message_filter_.get(), message)); } -bool VideoCaptureImpl::ClientHasDIB() { - CachedDIB::iterator it; - for (it = cached_dibs_.begin(); it != cached_dibs_.end(); it++) { +bool VideoCaptureImpl::ClientHasDIB() const { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + for (CachedDIB::const_iterator it = cached_dibs_.begin(); + it != cached_dibs_.end(); ++it) { if (it->second->references > 0) return true; } return false; } + +bool VideoCaptureImpl::RemoveClient( + media::VideoCapture::EventHandler* handler, + ClientInfo* clients) { + DCHECK(capture_message_loop_proxy_->BelongsToCurrentThread()); + bool found = false; + + ClientInfo::iterator it = clients->find(handler); + if (it != clients->end()) { + handler->OnStopped(this); + handler->OnRemoved(this); + clients->erase(it); + found = true; + } + return found; +} diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h index d7439ec..381ecc2 100644 --- a/content/renderer/media/video_capture_impl.h +++ b/content/renderer/media/video_capture_impl.h @@ -6,6 +6,16 @@ // interfaces for clients to Start/Stop capture. It also communicates to clients // when buffer is ready, state of capture device is changed. +// VideoCaptureImpl is also a delegate of VideoCaptureMessageFilter which +// relays operation of capture device to browser process and receives response +// from browser process. + +// The media::VideoCapture and VideoCaptureMessageFilter::Delegate are +// asynchronous interfaces, which means callers can call those interfaces +// from any threads without worrying about thread safety. +// The |capture_message_loop_proxy_| is the working thread of VideoCaptureImpl. +// All non-const members are accessed only on that working thread. + #ifndef CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_ #define CONTENT_RENDERER_MEDIA_VIDEO_CAPTURE_IMPL_H_ @@ -51,27 +61,31 @@ class CONTENT_EXPORT VideoCaptureImpl friend class MockVideoCaptureImpl; struct DIBBuffer; + typedef std::map<media::VideoCapture::EventHandler*, + media::VideoCaptureCapability> ClientInfo; VideoCaptureImpl(media::VideoCaptureSessionId id, base::MessageLoopProxy* capture_message_loop_proxy, VideoCaptureMessageFilter* filter); virtual ~VideoCaptureImpl(); - void DoStartCapture(media::VideoCapture::EventHandler* handler, - const media::VideoCaptureCapability& capability); - void DoStopCapture(media::VideoCapture::EventHandler* handler); - void DoFeedBuffer(scoped_refptr<VideoFrameBuffer> buffer); - - void DoBufferCreated(base::SharedMemoryHandle handle, - int length, int buffer_id); - void DoBufferReceived(int buffer_id, base::Time timestamp); - void DoStateChanged(video_capture::State state); - void DoDeviceInfoReceived(const media::VideoCaptureParams& device_info); - void DoDelegateAdded(int32 device_id); + void DoStartCaptureOnCaptureThread( + media::VideoCapture::EventHandler* handler, + const media::VideoCaptureCapability& capability); + void DoStopCaptureOnCaptureThread(media::VideoCapture::EventHandler* handler); + void DoFeedBufferOnCaptureThread(scoped_refptr<VideoFrameBuffer> buffer); + + void DoBufferCreatedOnCaptureThread(base::SharedMemoryHandle handle, + int length, int buffer_id); + void DoBufferReceivedOnCaptureThread(int buffer_id, base::Time timestamp); + void DoStateChangedOnCaptureThread(video_capture::State state); + void DoDeviceInfoReceivedOnCaptureThread( + const media::VideoCaptureParams& device_info); + void DoDelegateAddedOnCaptureThread(int32 device_id); void Init(); void DeInit(base::Closure task); - void DoDeInit(base::Closure task); + void DoDeInitOnCaptureThread(base::Closure task); void StopDevice(); void RestartCapture(); void StartCaptureInternal(); @@ -80,19 +94,19 @@ class CONTENT_EXPORT VideoCaptureImpl virtual void Send(IPC::Message* message); // Helpers. - bool ClientHasDIB(); + bool ClientHasDIB() const; + bool RemoveClient(media::VideoCapture::EventHandler* handler, + ClientInfo* clients); - scoped_refptr<VideoCaptureMessageFilter> message_filter_; - scoped_refptr<base::MessageLoopProxy> capture_message_loop_proxy_; - scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; + const scoped_refptr<VideoCaptureMessageFilter> message_filter_; + const scoped_refptr<base::MessageLoopProxy> capture_message_loop_proxy_; + const scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_; int device_id_; - // Pool of DIBs. - typedef std::map<int /* buffer_id */, DIBBuffer*> CachedDIB; + // Pool of DIBs. The key is buffer_id. + typedef std::map<int, DIBBuffer*> CachedDIB; CachedDIB cached_dibs_; - typedef std::map<media::VideoCapture::EventHandler*, - media::VideoCaptureCapability> ClientInfo; ClientInfo clients_; ClientInfo clients_pending_on_filter_; diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc index 24644e3..2ea5adb 100644 --- a/content/renderer/media/video_capture_impl_unittest.cc +++ b/content/renderer/media/video_capture_impl_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/message_loop.h" +#include "content/common/child_process.h" #include "content/common/media/video_capture_messages.h" #include "content/renderer/media/video_capture_impl.h" #include "testing/gmock/include/gmock/gmock.h" @@ -103,6 +104,7 @@ class VideoCaptureImplTest : public ::testing::Test { message_loop_.reset(new MessageLoop(MessageLoop::TYPE_IO)); message_loop_proxy_ = base::MessageLoopProxy::current().get(); + child_process_.reset(new ChildProcess()); message_filter_ = new MockVideoCaptureMessageFilter; session_id_ = 1; @@ -121,6 +123,7 @@ class VideoCaptureImplTest : public ::testing::Test { protected: scoped_ptr<MessageLoop> message_loop_; scoped_refptr<base::MessageLoopProxy> message_loop_proxy_; + scoped_ptr<ChildProcess> child_process_; scoped_refptr<MockVideoCaptureMessageFilter> message_filter_; media::VideoCaptureSessionId session_id_; MockVideoCaptureImpl* video_capture_impl_; |