diff options
author | wjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-23 18:39:42 +0000 |
---|---|---|
committer | wjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-23 18:39:42 +0000 |
commit | d843cc13b385ed30100bfa0cd3b08897ca8cd8b9 (patch) | |
tree | 7805cc828612b296ebef94541b12bf14064e1785 | |
parent | 5f31c18bb4f01034c9b6076746cd98f56ab9c196 (diff) | |
download | chromium_src-d843cc13b385ed30100bfa0cd3b08897ca8cd8b9.zip chromium_src-d843cc13b385ed30100bfa0cd3b08897ca8cd8b9.tar.gz chromium_src-d843cc13b385ed30100bfa0cd3b08897ca8cd8b9.tar.bz2 |
fix a racing condition when renderer process requests StopCapture before host gets controller
fix a typo (thanks ihf@)
BUG=104581
TEST=trybots
Review URL: http://codereview.chromium.org/8549010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111373 0039d316-1c4b-4281-b951-d872f2087c98
17 files changed, 186 insertions, 132 deletions
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc index 51bfa5c..8d13f9d 100644 --- a/content/browser/renderer_host/media/video_capture_controller.cc +++ b/content/browser/renderer_host/media/video_capture_controller.cc @@ -68,7 +68,7 @@ VideoCaptureController::VideoCaptureController( : frame_info_available_(false), video_capture_manager_(video_capture_manager), device_in_use_(false), - state_(media::VideoCapture::kStopped) { + state_(video_capture::kStopped) { memset(¤t_params_, 0, sizeof(current_params_)); } @@ -89,7 +89,7 @@ void VideoCaptureController::StartCapture( const media::VideoCaptureParams& params) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // Signal error in case device is already in error state. - if (state_ == media::VideoCapture::kError) { + if (state_ == video_capture::kError) { event_handler->OnError(id); return; } @@ -102,7 +102,7 @@ void VideoCaptureController::StartCapture( ControllerClient* client = new ControllerClient(id, event_handler, render_process, params); // In case capture has been started, need to check different condtions. - if (state_ == media::VideoCapture::kStarted) { + if (state_ == video_capture::kStarted) { // This client has higher resolution than what is currently requested. // Need restart capturing. if (params.width > current_params_.width || @@ -110,7 +110,7 @@ void VideoCaptureController::StartCapture( video_capture_manager_->Stop(current_params_.session_id, base::Bind(&VideoCaptureController::OnDeviceStopped, this)); frame_info_available_ = false; - state_ = media::VideoCapture::kStopping; + state_ = video_capture::kStopping; pending_clients_.push_back(client); return; } @@ -127,7 +127,7 @@ void VideoCaptureController::StartCapture( // In case the device is in the middle of stopping, put the client in // pending queue. - if (state_ == media::VideoCapture::kStopping) { + if (state_ == video_capture::kStopping) { pending_clients_.push_back(client); return; } @@ -137,7 +137,7 @@ void VideoCaptureController::StartCapture( current_params_ = params; // Order the manager to start the actual capture. video_capture_manager_->Start(params, this); - state_ = media::VideoCapture::kStarted; + state_ = video_capture::kStarted; } void VideoCaptureController::StopCapture( @@ -197,7 +197,7 @@ void VideoCaptureController::StopCapture( video_capture_manager_->Stop(current_params_.session_id, base::Bind(&VideoCaptureController::OnDeviceStopped, this)); frame_info_available_ = false; - state_ = media::VideoCapture::kStopping; + state_ = video_capture::kStopping; } } @@ -235,7 +235,7 @@ void VideoCaptureController::ReturnBuffer( // When all buffers have been returned by clients and device has been // called to stop, check if restart is needed. This could happen when // some clients call StopCapture before returning all buffers. - if (!ClientHasDIB() && state_ == media::VideoCapture::kStopping) { + if (!ClientHasDIB() && state_ == video_capture::kStopping) { PostStopping(); } } @@ -342,7 +342,7 @@ void VideoCaptureController::DoIncomingCapturedFrameOnIOThread( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); int count = 0; - if (state_ == media::VideoCapture::kStarted) { + if (state_ == video_capture::kStarted) { for (ControllerClients::iterator client_it = controller_clients_.begin(); client_it != controller_clients_.end(); client_it++) { if ((*client_it)->report_ready_to_delete) @@ -362,7 +362,7 @@ void VideoCaptureController::DoIncomingCapturedFrameOnIOThread( void VideoCaptureController::DoErrorOnIOThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - state_ = media::VideoCapture::kError; + state_ = video_capture::kError; ControllerClients::iterator client_it; for (client_it = controller_clients_.begin(); client_it != controller_clients_.end(); client_it++) { @@ -396,7 +396,7 @@ void VideoCaptureController::DoFrameInfoOnIOThread( } // Check whether all DIBs were created successfully. if (!frames_created) { - state_ = media::VideoCapture::kError; + state_ = video_capture::kError; for (ControllerClients::iterator client_it = controller_clients_.begin(); client_it != controller_clients_.end(); client_it++) { (*client_it)->event_handler->OnError((*client_it)->controller_id); @@ -437,7 +437,7 @@ void VideoCaptureController::SendFrameInfoAndBuffers( // restarted. void VideoCaptureController::PostStopping() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - DCHECK_EQ(state_, media::VideoCapture::kStopping); + DCHECK_EQ(state_, video_capture::kStopping); // When clients still have some buffers, or device has not been stopped yet, // do nothing. @@ -450,7 +450,7 @@ void VideoCaptureController::PostStopping() { // No more client. Therefore the controller is stopped. if (controller_clients_.empty() && pending_clients_.empty()) { - state_ = media::VideoCapture::kStopped; + state_ = video_capture::kStopped; return; } @@ -476,7 +476,7 @@ void VideoCaptureController::PostStopping() { } // Request the manager to start the actual capture. video_capture_manager_->Start(current_params_, this); - state_ = media::VideoCapture::kStarted; + state_ = video_capture::kStarted; } bool VideoCaptureController::ClientHasDIB() { @@ -516,7 +516,7 @@ void VideoCaptureController::OnDeviceStopped() { void VideoCaptureController::DoDeviceStoppedOnIOThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); device_in_use_ = false; - if (state_ == media::VideoCapture::kStopping) { + if (state_ == video_capture::kStopping) { PostStopping(); } } diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h index b732552..aa7e470 100644 --- a/content/browser/renderer_host/media/video_capture_controller.h +++ b/content/browser/renderer_host/media/video_capture_controller.h @@ -25,6 +25,7 @@ #include "base/synchronization/lock.h" #include "base/task.h" #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h" +#include "content/common/media/video_capture.h" #include "media/video/capture/video_capture.h" #include "media/video/capture/video_capture_device.h" #include "media/video/capture/video_capture_types.h" @@ -131,7 +132,7 @@ class VideoCaptureController media_stream::VideoCaptureManager* video_capture_manager_; bool device_in_use_; - media::VideoCapture::State state_; + video_capture::State state_; DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureController); }; diff --git a/content/browser/renderer_host/media/video_capture_host.cc b/content/browser/renderer_host/media/video_capture_host.cc index a4a4738..026b40e 100644 --- a/content/browser/renderer_host/media/video_capture_host.cc +++ b/content/browser/renderer_host/media/video_capture_host.cc @@ -14,6 +14,29 @@ using content::BrowserThread; +struct VideoCaptureHost::Entry { + Entry() : state(video_capture::kStopped) {} + + Entry(VideoCaptureController* controller, video_capture::State state) + : controller(controller), + state(state) { + } + + ~Entry() {} + + scoped_refptr<VideoCaptureController> controller; + + // Record state of each VideoCaptureControllerID. + // There are 5 states: + // kStarting: host has requested a controller, but has not got it yet. + // kStarted: host got a controller and has called StartCapture. + // kStopping: renderer process requests StopCapture before host gets + // a controller. + // kStopped: host has called StopCapture. + // kError: an error occurred and capture is stopped consequently. + video_capture::State state; +}; + VideoCaptureHost::VideoCaptureHost( const content::ResourceContext* resource_context) : resource_context_(resource_context) { @@ -26,13 +49,14 @@ void VideoCaptureHost::OnChannelClosing() { // Since the IPC channel is gone, close all requested VideCaptureDevices. for (EntryMap::iterator it = entries_.begin(); it != entries_.end(); it++) { - VideoCaptureController* controller = it->second; - VideoCaptureControllerID controller_id(it->first); - controller->StopCapture(controller_id, this, true); - GetVideoCaptureManager()->RemoveController(controller, this); + VideoCaptureController* controller = it->second->controller; + if (controller) { + VideoCaptureControllerID controller_id(it->first); + controller->StopCapture(controller_id, this, true); + GetVideoCaptureManager()->RemoveController(controller, this); + } } - entries_.clear(); - entry_state_.clear(); + STLDeleteValues(&entries_); } void VideoCaptureHost::OnDestruct() const { @@ -105,15 +129,17 @@ void VideoCaptureHost::DoSendFilledBuffer( void VideoCaptureHost::DoHandleError(int device_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - Send(new VideoCaptureMsg_StateChanged(device_id, - media::VideoCapture::kError)); - VideoCaptureControllerID id(device_id); EntryMap::iterator it = entries_.find(id); - if (it != entries_.end()) { - VideoCaptureController* controller = it->second; - controller->StopCapture(id, this, false); - } + if (it == entries_.end() || it->second->state == video_capture::kError) + return; + + it->second->state = video_capture::kError; + Send(new VideoCaptureMsg_StateChanged(device_id, + video_capture::kError)); + + VideoCaptureController* controller = it->second->controller; + controller->StopCapture(id, this, false); } void VideoCaptureHost::DoSendFrameInfo(int device_id, @@ -128,7 +154,7 @@ void VideoCaptureHost::DoSendFrameInfo(int device_id, params.frame_per_second = frame_per_second; Send(new VideoCaptureMsg_DeviceInfo(device_id, params)); Send(new VideoCaptureMsg_StateChanged(device_id, - media::VideoCapture::kStarted)); + video_capture::kStarted)); } /////////////////////////////////////////////////////////////////////////////// @@ -152,9 +178,8 @@ void VideoCaptureHost::OnStartCapture(int device_id, DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); VideoCaptureControllerID controller_id(device_id); DCHECK(entries_.find(controller_id) == entries_.end()); - DCHECK(entry_state_.find(controller_id) == entry_state_.end()); - entry_state_[controller_id] = media::VideoCapture::kStarted; + entries_[controller_id] = new Entry(NULL, video_capture::kStarting); GetVideoCaptureManager()->AddController( params, this, base::Bind(&VideoCaptureHost::OnControllerAdded, this, device_id, params)); @@ -165,48 +190,61 @@ void VideoCaptureHost::OnControllerAdded( VideoCaptureController* controller) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&VideoCaptureHost::DoControllerAddedOnIOThreead, + base::Bind(&VideoCaptureHost::DoControllerAddedOnIOThread, this, device_id, params, make_scoped_refptr(controller))); } -void VideoCaptureHost::DoControllerAddedOnIOThreead( +void VideoCaptureHost::DoControllerAddedOnIOThread( int device_id, const media::VideoCaptureParams params, VideoCaptureController* controller) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); VideoCaptureControllerID controller_id(device_id); - DCHECK(entries_.find(controller_id) == entries_.end()); - DCHECK(entry_state_.find(controller_id) != entry_state_.end()); + EntryMap::iterator it = entries_.find(controller_id); + DCHECK(it != entries_.end()); if (controller == NULL) { Send(new VideoCaptureMsg_StateChanged(device_id, - media::VideoCapture::kError)); + video_capture::kError)); return; } - entries_.insert(std::make_pair(controller_id, controller)); - if (entry_state_[controller_id] == media::VideoCapture::kStarted) { + Entry* entry = it->second; + entry->controller = controller; + if (entry->state == video_capture::kStarting) { + entry->state = video_capture::kStarted; controller->StartCapture(controller_id, this, peer_handle(), params); - } else if (entry_state_[controller_id] == media::VideoCapture::kStopped) { - controller->StopCapture(controller_id, this, false); + } else if (entry->state == video_capture::kStopping) { + DoDeleteVideoCaptureController(controller_id); + } else { + NOTREACHED(); } } void VideoCaptureHost::OnStopCapture(int device_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); VideoCaptureControllerID controller_id(device_id); + EntryMap::iterator it = entries_.find(controller_id); - if (entry_state_.find(controller_id) == entry_state_.end()) { + if (it == entries_.end()) { // It does not exist. So it must have been stopped already. Send(new VideoCaptureMsg_StateChanged(device_id, - media::VideoCapture::kStopped)); + video_capture::kStopped)); + return; } - entry_state_[controller_id] = media::VideoCapture::kStopped; + Entry* entry = it->second; + if (entry->state == video_capture::kStopping || + entry->state == video_capture::kStopped || + entry->state == video_capture::kError) { + return; + } - EntryMap::iterator it = entries_.find(controller_id); - if (it != entries_.end()) { - scoped_refptr<VideoCaptureController> controller = it->second; + if (entry->controller) { + entry->state = video_capture::kStopped; + scoped_refptr<VideoCaptureController> controller = entry->controller; controller->StopCapture(controller_id, this, false); + } else { + entry->state = video_capture::kStopping; } } @@ -214,7 +252,7 @@ void VideoCaptureHost::OnPauseCapture(int device_id) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // Not used. Send(new VideoCaptureMsg_StateChanged(device_id, - media::VideoCapture::kError)); + video_capture::kError)); } void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id, int buffer_id) { @@ -223,7 +261,7 @@ void VideoCaptureHost::OnReceiveEmptyBuffer(int device_id, int buffer_id) { VideoCaptureControllerID controller_id(device_id); EntryMap::iterator it = entries_.find(controller_id); if (it != entries_.end()) { - scoped_refptr<VideoCaptureController> controller = it->second; + scoped_refptr<VideoCaptureController> controller = it->second->controller; controller->ReturnBuffer(controller_id, this, buffer_id); } } @@ -234,13 +272,15 @@ void VideoCaptureHost::DoDeleteVideoCaptureController( // Report that the device have successfully been stopped. Send(new VideoCaptureMsg_StateChanged(id.device_id, - media::VideoCapture::kStopped)); + video_capture::kStopped)); EntryMap::iterator it = entries_.find(id); if (it != entries_.end()) { - GetVideoCaptureManager()->RemoveController(it->second, this); + if (it->second->controller) { + GetVideoCaptureManager()->RemoveController(it->second->controller, this); + } + delete it->second; + entries_.erase(id); } - entries_.erase(id); - entry_state_.erase(id); } media_stream::VideoCaptureManager* VideoCaptureHost::GetVideoCaptureManager() { diff --git a/content/browser/renderer_host/media/video_capture_host.h b/content/browser/renderer_host/media/video_capture_host.h index 168c4f3..21710e6 100644 --- a/content/browser/renderer_host/media/video_capture_host.h +++ b/content/browser/renderer_host/media/video_capture_host.h @@ -91,7 +91,7 @@ class CONTENT_EXPORT VideoCaptureHost void OnControllerAdded( int device_id, const media::VideoCaptureParams& params, VideoCaptureController* controller); - void DoControllerAddedOnIOThreead( + void DoControllerAddedOnIOThread( int device_id, const media::VideoCaptureParams params, VideoCaptureController* controller); @@ -134,17 +134,11 @@ class CONTENT_EXPORT VideoCaptureHost // Helpers. media_stream::VideoCaptureManager* GetVideoCaptureManager(); - typedef std::map<VideoCaptureControllerID, - scoped_refptr<VideoCaptureController> > EntryMap; - // A map of VideoCaptureControllerID to VideoCaptureController - // objects that is currently active. + struct Entry; + typedef std::map<VideoCaptureControllerID, Entry*> EntryMap; + // A map of VideoCaptureControllerID to its state and VideoCaptureController. EntryMap entries_; - typedef std::map<VideoCaptureControllerID, - media::VideoCapture::State> EntryState; - // Record state of each VideoCaptureControllerID. - EntryState entry_state_; - // Used to get a pointer to VideoCaptureManager to start/stop capture devices. const content::ResourceContext* resource_context_; diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc index 56be837..f71b2d6 100644 --- a/content/browser/renderer_host/media/video_capture_host_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc @@ -88,7 +88,7 @@ class MockVideoCaptureHost : public VideoCaptureHost { MOCK_METHOD3(OnBufferFilled, void(int device_id, int buffer_id, base::Time timestamp)); MOCK_METHOD2(OnStateChanged, - void(int device_id, media::VideoCapture::State state)); + void(int device_id, video_capture::State state)); MOCK_METHOD1(OnDeviceInfo, void(int device_id)); // Use class DumpVideo to write I420 video to file. @@ -166,7 +166,7 @@ class MockVideoCaptureHost : public VideoCaptureHost { } void OnStateChangedDispatch(int device_id, - media::VideoCapture::State state) { + video_capture::State state) { OnStateChanged(device_id, state); } @@ -228,7 +228,7 @@ class VideoCaptureHostTest : public testing::Test { Mock::VerifyAndClearExpectations(host_); EXPECT_CALL(*host_, OnStateChanged(kDeviceId, - media::VideoCapture::kStopped)) + video_capture::kStopped)) .Times(AnyNumber()); // Simulate closing the IPC channel. @@ -279,7 +279,7 @@ class VideoCaptureHostTest : public testing::Test { // 2. Change state to started EXPECT_CALL(*host_, OnStateChanged(kDeviceId, - media::VideoCapture::kStarted)); + video_capture::kStarted)); // 3. Newly created buffers will arrive. EXPECT_CALL(*host_, OnNewBufferCreated(kDeviceId, _, _, _)) @@ -307,7 +307,7 @@ class VideoCaptureHostTest : public testing::Test { // 2. Change state to started EXPECT_CALL(*host_, OnStateChanged(kDeviceId, - media::VideoCapture::kStarted)); + video_capture::kStarted)); // 3. First filled buffer will arrive. EXPECT_CALL(*host_, OnBufferFilled(kDeviceId, _, _)) @@ -326,7 +326,7 @@ class VideoCaptureHostTest : public testing::Test { void StopCapture() { EXPECT_CALL(*host_, OnStateChanged(kDeviceId, - media::VideoCapture::kStopped)) + video_capture::kStopped)) .Times(AtLeast(1)); host_->OnStopCapture(kDeviceId); @@ -354,7 +354,7 @@ class VideoCaptureHostTest : public testing::Test { void SimulateError() { // Expect a change state to error state sent through IPC. EXPECT_CALL(*host_, OnStateChanged(kDeviceId, - media::VideoCapture::kError)) + video_capture::kError)) .Times(1); VideoCaptureControllerID id(kDeviceId); host_->OnError(id); @@ -392,7 +392,7 @@ TEST_F(VideoCaptureHostTest, StartCaptureErrorStop) { TEST_F(VideoCaptureHostTest, StartCaptureError) { EXPECT_CALL(*host_, OnStateChanged(kDeviceId, - media::VideoCapture::kStopped)) + video_capture::kStopped)) .Times(0); StartCapture(); NotifyPacketReady(); diff --git a/content/common/media/video_capture.h b/content/common/media/video_capture.h new file mode 100644 index 0000000..5c117e4 --- /dev/null +++ b/content/common/media/video_capture.h @@ -0,0 +1,27 @@ +// Copyright (c) 2011 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. +// +// This file contains commonly used definitions of video capture. + +#ifndef CONTENT_COMMON_MEDIA_VIDEO_CAPTURE_H_ +#define CONTENT_COMMON_MEDIA_VIDEO_CAPTURE_H_ + +namespace video_capture { + +// Current status of the video capture device. It's used by multiple classes +// in browser process and renderer process. +// Browser process sends information about the current capture state and +// error to the renderer process using this type. +enum State { + kStarting, + kStarted, + kPaused, + kStopping, + kStopped, + kError, +}; + +} // namespace video_capture + +#endif // CONTENT_COMMON_MEDIA_VIDEO_CAPTURE_H_ diff --git a/content/common/media/video_capture_messages.h b/content/common/media/video_capture_messages.h index 0112d85..855a7ad 100644 --- a/content/common/media/video_capture_messages.h +++ b/content/common/media/video_capture_messages.h @@ -3,13 +3,14 @@ // found in the LICENSE file. #include "base/shared_memory.h" +#include "content/common/media/video_capture.h" #include "content/public/common/common_param_traits.h" #include "ipc/ipc_message_macros.h" -#include "media/video/capture/video_capture.h" +#include "media/video/capture/video_capture_types.h" #define IPC_MESSAGE_START VideoCaptureMsgStart -IPC_ENUM_TRAITS(media::VideoCapture::State) +IPC_ENUM_TRAITS(video_capture::State) IPC_STRUCT_TRAITS_BEGIN(media::VideoCaptureParams) IPC_STRUCT_TRAITS_MEMBER(width) @@ -22,7 +23,7 @@ IPC_STRUCT_TRAITS_END() // Start/Pause/Stop. IPC_MESSAGE_CONTROL2(VideoCaptureMsg_StateChanged, int /* device id */, - media::VideoCapture::State /* new state */) + video_capture::State /* new state */) // Tell the renderer process that a new buffer is allocated for video capture. IPC_MESSAGE_CONTROL4(VideoCaptureMsg_NewBuffer, diff --git a/content/content_common.gypi b/content/content_common.gypi index 9003e29..aebdc44 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -178,6 +178,7 @@ 'common/media/media_stream_messages.h', 'common/media/media_stream_options.cc', 'common/media/media_stream_options.h', + 'common/media/video_capture.h', 'common/media/video_capture_messages.h', 'common/message_router.cc', 'common/message_router.h', diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index 27bcb98..a123d09 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc @@ -28,7 +28,7 @@ struct VideoCaptureImpl::DIBBuffer { }; bool VideoCaptureImpl::CaptureStarted() { - return state_ == kStarted; + return state_ == video_capture::kStarted; } int VideoCaptureImpl::CaptureWidth() { @@ -53,7 +53,7 @@ VideoCaptureImpl::VideoCaptureImpl( device_id_(0), video_type_(media::VideoFrame::I420), device_info_available_(false), - state_(kStopped) { + state_(video_capture::kStopped) { DCHECK(filter); memset(¤t_params_, 0, sizeof(current_params_)); current_params_.session_id = id; @@ -85,7 +85,7 @@ void VideoCaptureImpl::DeInit(base::Closure task) { } void VideoCaptureImpl::DoDeInit(base::Closure task) { - if (state_ == kStarted) + if (state_ == video_capture::kStarted) Send(new VideoCaptureHostMsg_Stop(device_id_)); base::MessageLoopProxy* io_message_loop_proxy = @@ -132,7 +132,7 @@ void VideoCaptureImpl::OnBufferReceived(int buffer_id, base::Time timestamp) { base::Unretained(this), buffer_id, timestamp)); } -void VideoCaptureImpl::OnStateChanged(const media::VideoCapture::State& state) { +void VideoCaptureImpl::OnStateChanged(video_capture::State state) { ml_proxy_->PostTask(FROM_HERE, base::Bind(&VideoCaptureImpl::DoStateChanged, base::Unretained(this), state)); @@ -156,7 +156,7 @@ void VideoCaptureImpl::DoStartCapture( const VideoCaptureCapability& capability) { DCHECK(ml_proxy_->BelongsToCurrentThread()); - if (state_ == kError) { + if (state_ == video_capture::kError) { handler->OnError(this, 1); handler->OnRemoved(this); return; @@ -177,7 +177,7 @@ void VideoCaptureImpl::DoStartCapture( } handler->OnStarted(this); - if (state_ == kStarted) { + if (state_ == video_capture::kStarted) { if (capability.width > current_params_.width || capability.height > current_params_.height) { StopDevice(); @@ -196,7 +196,7 @@ void VideoCaptureImpl::DoStartCapture( return; } - if (state_ == kStopping) { + if (state_ == video_capture::kStopping) { clients_pending_on_restart_[handler] = capability; DVLOG(1) << "StartCapture: Got new resolution (" << capability.width << ", " << capability.height << ") " @@ -290,7 +290,7 @@ void VideoCaptureImpl::DoBufferCreated( void VideoCaptureImpl::DoBufferReceived(int buffer_id, base::Time timestamp) { DCHECK(ml_proxy_->BelongsToCurrentThread()); - if (state_ != kStarted) { + if (state_ != video_capture::kStarted) { Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id)); return; } @@ -305,26 +305,26 @@ void VideoCaptureImpl::DoBufferReceived(int buffer_id, base::Time timestamp) { cached_dibs_[buffer_id]->references = clients_.size(); } -void VideoCaptureImpl::DoStateChanged(const media::VideoCapture::State& state) { +void VideoCaptureImpl::DoStateChanged(video_capture::State state) { DCHECK(ml_proxy_->BelongsToCurrentThread()); switch (state) { - case media::VideoCapture::kStarted: + case video_capture::kStarted: break; - case media::VideoCapture::kStopped: - state_ = kStopped; + case video_capture::kStopped: + state_ = video_capture::kStopped; DVLOG(1) << "OnStateChanged: stopped!, device_id = " << device_id_; STLDeleteValues(&cached_dibs_); if (!clients_.empty() || !clients_pending_on_restart_.empty()) RestartCapture(); break; - case media::VideoCapture::kPaused: + case video_capture::kPaused: for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { it->first->OnPaused(this); } break; - case media::VideoCapture::kError: + case video_capture::kError: DVLOG(1) << "OnStateChanged: error!, device_id = " << device_id_; for (ClientInfo::iterator it = clients_.begin(); it != clients_.end(); it++) { @@ -333,7 +333,7 @@ void VideoCaptureImpl::DoStateChanged(const media::VideoCapture::State& state) { it->first->OnRemoved(this); } clients_.clear(); - state_ = kError; + state_ = video_capture::kError; break; default: break; @@ -372,8 +372,8 @@ void VideoCaptureImpl::StopDevice() { DCHECK(ml_proxy_->BelongsToCurrentThread()); device_info_available_ = false; - if (state_ == kStarted) { - state_ = kStopping; + if (state_ == video_capture::kStarted) { + state_ = video_capture::kStopping; Send(new VideoCaptureHostMsg_Stop(device_id_)); current_params_.width = current_params_.height = 0; } @@ -381,7 +381,7 @@ void VideoCaptureImpl::StopDevice() { void VideoCaptureImpl::RestartCapture() { DCHECK(ml_proxy_->BelongsToCurrentThread()); - DCHECK_EQ(state_, kStopped); + DCHECK_EQ(state_, video_capture::kStopped); int width = 0; int height = 0; @@ -413,7 +413,7 @@ void VideoCaptureImpl::StartCaptureInternal() { DCHECK(device_id_); Send(new VideoCaptureHostMsg_Start(device_id_, current_params_)); - state_ = kStarted; + state_ = video_capture::kStarted; } void VideoCaptureImpl::AddDelegateOnIOThread() { diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h index b7df349..6175725 100644 --- a/content/renderer/media/video_capture_impl.h +++ b/content/renderer/media/video_capture_impl.h @@ -13,6 +13,7 @@ #include <map> #include "content/common/content_export.h" +#include "content/common/media/video_capture.h" #include "content/renderer/media/video_capture_message_filter.h" #include "media/video/capture/video_capture.h" @@ -37,7 +38,7 @@ class CONTENT_EXPORT VideoCaptureImpl virtual void OnBufferCreated(base::SharedMemoryHandle handle, int length, int buffer_id) OVERRIDE; virtual void OnBufferReceived(int buffer_id, base::Time timestamp) OVERRIDE; - virtual void OnStateChanged(const media::VideoCapture::State& state) OVERRIDE; + virtual void OnStateChanged(video_capture::State state) OVERRIDE; virtual void OnDeviceInfoReceived( const media::VideoCaptureParams& device_info) OVERRIDE; virtual void OnDelegateAdded(int32 device_id) OVERRIDE; @@ -62,7 +63,7 @@ class CONTENT_EXPORT VideoCaptureImpl void DoBufferCreated(base::SharedMemoryHandle handle, int length, int buffer_id); void DoBufferReceived(int buffer_id, base::Time timestamp); - void DoStateChanged(const media::VideoCapture::State& state); + void DoStateChanged(video_capture::State state); void DoDeviceInfoReceived(const media::VideoCaptureParams& device_info); void DoDelegateAdded(int32 device_id); @@ -104,7 +105,7 @@ class CONTENT_EXPORT VideoCaptureImpl media::VideoCaptureParams device_info_; bool device_info_available_; - State state_; + video_capture::State state_; DISALLOW_COPY_AND_ASSIGN(VideoCaptureImpl); }; diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc index d7d08705c..2297886 100644 --- a/content/renderer/media/video_capture_impl_unittest.cc +++ b/content/renderer/media/video_capture_impl_unittest.cc @@ -84,16 +84,14 @@ class VideoCaptureImplTest : public ::testing::Test { void DeviceStartCapture(int device_id, const media::VideoCaptureParams& params) { media::VideoCaptureParams device_info = params; - media::VideoCapture::State state = kStarted; OnDeviceInfoReceived(device_info); - OnStateChanged(state); + OnStateChanged(video_capture::kStarted); } void DevicePauseCapture(int device_id) {} void DeviceStopCapture(int device_id) { - media::VideoCapture::State state = kStopped; - OnStateChanged(state); + OnStateChanged(video_capture::kStopped); } void DeviceReceiveEmptyBuffer(int device_id, int buffer_id) {} diff --git a/content/renderer/media/video_capture_message_filter.cc b/content/renderer/media/video_capture_message_filter.cc index 08adfaa..2ec4110 100644 --- a/content/renderer/media/video_capture_message_filter.cc +++ b/content/renderer/media/video_capture_message_filter.cc @@ -104,7 +104,7 @@ void VideoCaptureMessageFilter::OnBufferReceived( void VideoCaptureMessageFilter::OnDeviceStateChanged( int device_id, - const media::VideoCapture::State& state) { + video_capture::State state) { Delegate* delegate = NULL; if (delegates_.find(device_id) != delegates_.end()) delegate = delegates_.find(device_id)->second; diff --git a/content/renderer/media/video_capture_message_filter.h b/content/renderer/media/video_capture_message_filter.h index b23ddc8..9edf742 100644 --- a/content/renderer/media/video_capture_message_filter.h +++ b/content/renderer/media/video_capture_message_filter.h @@ -15,6 +15,7 @@ #include "base/message_loop_proxy.h" #include "base/shared_memory.h" #include "content/common/content_export.h" +#include "content/common/media/video_capture.h" #include "ipc/ipc_channel_proxy.h" #include "media/video/capture/video_capture.h" @@ -32,7 +33,7 @@ class CONTENT_EXPORT VideoCaptureMessageFilter // Called when state of a video capture device has changed in the browser // process. - virtual void OnStateChanged(const media::VideoCapture::State& state) = 0; + virtual void OnStateChanged(video_capture::State state) = 0; // Called when device info is received from video capture device in the // browser process. @@ -82,7 +83,7 @@ class CONTENT_EXPORT VideoCaptureMessageFilter // State of browser process' video capture device has changed. void OnDeviceStateChanged(int device_id, - const media::VideoCapture::State& state); + video_capture::State state); // Receive device info from browser process. void OnDeviceInfoReceived(int device_id, diff --git a/content/renderer/media/video_capture_message_filter_unittest.cc b/content/renderer/media/video_capture_message_filter_unittest.cc index cbc3e06..f9dd1f6 100644 --- a/content/renderer/media/video_capture_message_filter_unittest.cc +++ b/content/renderer/media/video_capture_message_filter_unittest.cc @@ -31,7 +31,7 @@ class MockVideoCaptureDelegate : public VideoCaptureMessageFilter::Delegate { timestamp_ = timestamp; } - virtual void OnStateChanged(const media::VideoCapture::State& state) { + virtual void OnStateChanged(video_capture::State state) { state_changed_received_ = true; state_ = state; } @@ -57,7 +57,7 @@ class MockVideoCaptureDelegate : public VideoCaptureMessageFilter::Delegate { timestamp_ = base::Time(); state_changed_received_ = false; - state_ = media::VideoCapture::kError; + state_ = video_capture::kError; device_info_received_ = false; params_.width = 0; @@ -73,7 +73,7 @@ class MockVideoCaptureDelegate : public VideoCaptureMessageFilter::Delegate { base::Time received_buffer_ts() { return timestamp_; } bool state_changed_received() { return state_changed_received_; } - media::VideoCapture::State state() { return state_; } + video_capture::State state() { return state_; } bool device_info_receive() { return device_info_received_; } const media::VideoCaptureParams& received_device_info() { return params_; } @@ -90,7 +90,7 @@ class MockVideoCaptureDelegate : public VideoCaptureMessageFilter::Delegate { base::Time timestamp_; bool state_changed_received_; - media::VideoCapture::State state_; + video_capture::State state_; bool device_info_received_; media::VideoCaptureParams params_; @@ -117,9 +117,9 @@ TEST(VideoCaptureMessageFilterTest, Basic) { EXPECT_FALSE(delegate.state_changed_received()); filter->OnMessageReceived( VideoCaptureMsg_StateChanged(delegate.device_id(), - media::VideoCapture::kStarted)); + video_capture::kStarted)); EXPECT_TRUE(delegate.state_changed_received()); - EXPECT_TRUE(media::VideoCapture::kStarted == delegate.state()); + EXPECT_TRUE(video_capture::kStarted == delegate.state()); delegate.Reset(); // VideoCaptureMsg_NewBuffer @@ -185,7 +185,7 @@ TEST(VideoCaptureMessageFilterTest, Delegates) { EXPECT_FALSE(delegate2.state_changed_received()); filter->OnMessageReceived( VideoCaptureMsg_StateChanged(delegate1.device_id(), - media::VideoCapture::kStarted)); + video_capture::kStarted)); EXPECT_TRUE(delegate1.state_changed_received()); EXPECT_FALSE(delegate2.state_changed_received()); delegate1.Reset(); @@ -194,7 +194,7 @@ TEST(VideoCaptureMessageFilterTest, Delegates) { EXPECT_FALSE(delegate2.state_changed_received()); filter->OnMessageReceived( VideoCaptureMsg_StateChanged(delegate2.device_id(), - media::VideoCapture::kStarted)); + video_capture::kStarted)); EXPECT_FALSE(delegate1.state_changed_received()); EXPECT_TRUE(delegate2.state_changed_received()); delegate2.Reset(); @@ -204,14 +204,14 @@ TEST(VideoCaptureMessageFilterTest, Delegates) { EXPECT_FALSE(delegate1.state_changed_received()); filter->OnMessageReceived( VideoCaptureMsg_StateChanged(delegate1.device_id(), - media::VideoCapture::kStarted)); + video_capture::kStarted)); EXPECT_FALSE(delegate1.state_changed_received()); filter->RemoveDelegate(&delegate2); EXPECT_FALSE(delegate2.state_changed_received()); filter->OnMessageReceived( VideoCaptureMsg_StateChanged(delegate2.device_id(), - media::VideoCapture::kStarted)); + video_capture::kStarted)); EXPECT_FALSE(delegate2.state_changed_received()); message_loop.RunAllPending(); diff --git a/content/renderer/media/video_capture_module_impl.cc b/content/renderer/media/video_capture_module_impl.cc index 9231112..69a07c5 100644 --- a/content/renderer/media/video_capture_module_impl.cc +++ b/content/renderer/media/video_capture_module_impl.cc @@ -16,7 +16,7 @@ VideoCaptureModuleImpl::VideoCaptureModuleImpl( thread_("VideoCaptureModuleImpl"), stopped_event_(false, false), vc_manager_(vc_manager), - state_(media::VideoCapture::kStopped), + state_(video_capture::kStopped), width_(-1), height_(-1), frame_rate_(-1), @@ -76,7 +76,7 @@ WebRtc_Word32 VideoCaptureModuleImpl::StopCapture() { } bool VideoCaptureModuleImpl::CaptureStarted() { - return state_ == media::VideoCapture::kStarted; + return state_ == video_capture::kStarted; } WebRtc_Word32 VideoCaptureModuleImpl::CaptureSettings( @@ -128,7 +128,7 @@ void VideoCaptureModuleImpl::OnDeviceInfoReceived( void VideoCaptureModuleImpl::StartCaptureOnCaptureThread( const webrtc::VideoCaptureCapability& capability) { DCHECK(message_loop_proxy_->BelongsToCurrentThread()); - DCHECK_NE(state_, media::VideoCapture::kStarted); + DCHECK_NE(state_, video_capture::kStarted); DVLOG(1) << "StartCaptureOnCaptureThread: " << capability.width << ", " << capability.height; @@ -146,7 +146,7 @@ void VideoCaptureModuleImpl::StartCaptureInternal( width_ = capability.width; height_ = capability.height; frame_rate_ = capability.maxFPS; - state_ = media::VideoCapture::kStarted; + state_ = video_capture::kStarted; media::VideoCapture::VideoCaptureCapability cap; cap.width = capability.width; @@ -159,7 +159,7 @@ void VideoCaptureModuleImpl::StartCaptureInternal( void VideoCaptureModuleImpl::StopCaptureOnCaptureThread() { DCHECK(message_loop_proxy_->BelongsToCurrentThread()); - if (state_ != media::VideoCapture::kStarted) { + if (state_ != video_capture::kStarted) { DVLOG(1) << "Got a StopCapture while not started!!! "; return; } @@ -171,7 +171,7 @@ void VideoCaptureModuleImpl::StopCaptureOnCaptureThread() { // use-after-free, especially when StopCapture() is called from dtor. stopped_event_.Wait(); DVLOG(1) << "Capture Stopped!!! "; - state_ = media::VideoCapture::kStopped; + state_ = video_capture::kStopped; width_ = -1; height_ = -1; frame_rate_ = -1; @@ -182,7 +182,7 @@ void VideoCaptureModuleImpl::OnBufferReadyOnCaptureThread( scoped_refptr<media::VideoCapture::VideoFrameBuffer> buf) { DCHECK(message_loop_proxy_->BelongsToCurrentThread()); - if (state_ != media::VideoCapture::kStarted) + if (state_ != video_capture::kStarted) return; frameInfo_.width = buf->width; diff --git a/content/renderer/media/video_capture_module_impl.h b/content/renderer/media/video_capture_module_impl.h index d86727e..7e19be0 100644 --- a/content/renderer/media/video_capture_module_impl.h +++ b/content/renderer/media/video_capture_module_impl.h @@ -8,6 +8,7 @@ #include "base/compiler_specific.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" +#include "content/common/media/video_capture.h" #include "media/video/capture/video_capture.h" #include "third_party/webrtc/common_types.h" #include "third_party/webrtc/modules/video_capture/main/interface/video_capture_defines.h" @@ -70,7 +71,7 @@ class VideoCaptureModuleImpl base::WaitableEvent stopped_event_; // The video capture manager handles open/close of video capture devices. scoped_refptr<VideoCaptureImplManager> vc_manager_; - media::VideoCapture::State state_; + video_capture::State state_; WebRtc_UWord32 width_; WebRtc_UWord32 height_; WebRtc_Word32 frame_rate_; diff --git a/media/video/capture/video_capture.h b/media/video/capture/video_capture.h index 62d5d37..0af1abf 100644 --- a/media/video/capture/video_capture.h +++ b/media/video/capture/video_capture.h @@ -18,17 +18,6 @@ namespace media { class MEDIA_EXPORT VideoCapture { public: - // Current status of the video capture device in the browser process. Browser - // process sends information about the current capture state and error to the - // renderer process using this type. - enum State { - kStarted, - kPaused, - kStopped, - kStopping, - kError, - }; - // TODO(wjia): consider merging with media::VideoFrame if possible. class VideoFrameBuffer : public base::RefCountedThreadSafe<VideoFrameBuffer> { public: |