diff options
author | wjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-05 20:33:03 +0000 |
---|---|---|
committer | wjia@chromium.org <wjia@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-05 20:33:03 +0000 |
commit | 8c6844fc33ef1d2fc49b57e4b2187c1855d271cb (patch) | |
tree | 1441c349a07eb48fd8fa76871d0ed6276e9aa05e /content/renderer | |
parent | 015a0830d770bad838d50c4a86293e43ace61168 (diff) | |
download | chromium_src-8c6844fc33ef1d2fc49b57e4b2187c1855d271cb.zip chromium_src-8c6844fc33ef1d2fc49b57e4b2187c1855d271cb.tar.gz chromium_src-8c6844fc33ef1d2fc49b57e4b2187c1855d271cb.tar.bz2 |
Add more tests for VideoCaptureImpl.
VideoCapture events are defined more restrictly now:
Without error, StartCapture will result in one and only one OnStarted event for each client, one and only one OnDeviceInfoReceived event for master client, at least one OnDeviceInfoReceived event for regular client.
Without error, StopCapture will result in one and only one OnStopped/OnRemoved event pair for each client.
In case of error, all clients receive OnError/OnRemoved event pair.
After OnRemoved event is sent to client, VideoCaptureImpl will never call that client.
BUG=none
TEST=trybots
Review URL: http://codereview.chromium.org/8138013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104167 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer')
-rw-r--r-- | content/renderer/media/video_capture_impl.cc | 48 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl.h | 4 | ||||
-rw-r--r-- | content/renderer/media/video_capture_impl_unittest.cc | 206 |
3 files changed, 228 insertions, 30 deletions
diff --git a/content/renderer/media/video_capture_impl.cc b/content/renderer/media/video_capture_impl.cc index 875dd4f..4cca466 100644 --- a/content/renderer/media/video_capture_impl.cc +++ b/content/renderer/media/video_capture_impl.cc @@ -141,11 +141,9 @@ void VideoCaptureImpl::DoStartCapture( const VideoCaptureCapability& capability) { DCHECK(ml_proxy_->BelongsToCurrentThread()); - ClientInfo::iterator it = pending_clients_.find(handler); - - if (it != pending_clients_.end()) { - handler->OnError(this, 1); - handler->OnRemoved(this); + if (pending_clients_.find(handler) != pending_clients_.end() || + clients_.find(handler) != clients_.end() ) { + // This client has started. return; } @@ -154,13 +152,18 @@ void VideoCaptureImpl::DoStartCapture( return; } - if (capability.resolution_fixed && master_clients_.size() && - (capability.width != current_params_.width || - capability.height != current_params_.height)) { - // Can't have 2 master clients with different resolutions. - handler->OnError(this, 1); - handler->OnRemoved(this); - return; + if (capability.resolution_fixed && master_clients_.size()) { + bool matches_current_params = + CapabilityMatchesParameters(capability, current_params_); + bool matches_new_params = + CapabilityMatchesParameters(capability, new_params_); + if ((state_ == kStarted && !matches_current_params) || + (state_ == kStopping && !matches_new_params)) { + // Can't have 2 master clients with different resolutions. + handler->OnError(this, 1); + handler->OnRemoved(this); + return; + } } handler->OnStarted(this); @@ -168,8 +171,6 @@ void VideoCaptureImpl::DoStartCapture( if (capability.resolution_fixed) { master_clients_.push_back(handler); if (master_clients_.size() > 1) { - // TODO(wjia): OnStarted might be called twice if VideoCaptureImpl will - // receive kStarted from browser process later. if (device_info_available_) handler->OnDeviceInfoReceived(this, device_info_); return; @@ -179,9 +180,7 @@ void VideoCaptureImpl::DoStartCapture( if (state_ == kStarted) { // Take the resolution of master client. if (capability.resolution_fixed && - (capability.width != current_params_.width || - capability.height != current_params_.height || - capability.max_fps != current_params_.frame_per_second)) { + !CapabilityMatchesParameters(capability, current_params_)) { new_params_.width = capability.width; new_params_.height = capability.height; new_params_.frame_per_second = capability.max_fps; @@ -189,9 +188,8 @@ void VideoCaptureImpl::DoStartCapture( << new_params_.width << ", " << new_params_.height << ") " << "during started, try to restart."; StopDevice(); - } else { - if (device_info_available_) - handler->OnDeviceInfoReceived(this, device_info_); + } else if (device_info_available_) { + handler->OnDeviceInfoReceived(this, device_info_); } return; } @@ -391,6 +389,8 @@ void VideoCaptureImpl::DoStateChanged(const media::VideoCapture::State& state) { void VideoCaptureImpl::DoDeviceInfoReceived( const media::VideoCaptureParams& device_info) { DCHECK(ml_proxy_->BelongsToCurrentThread()); + if (state_ != kStarted) + return; device_info_ = device_info; device_info_available_ = true; @@ -466,3 +466,11 @@ void VideoCaptureImpl::Send(IPC::Message* message) { NewRunnableMethod(message_filter_.get(), &VideoCaptureMessageFilter::Send, message)); } + +bool VideoCaptureImpl::CapabilityMatchesParameters( + const VideoCaptureCapability& capability, + const media::VideoCaptureParams& params) { + return (capability.width == params.width && + capability.height == params.height && + capability.max_fps == params.frame_per_second); +} diff --git a/content/renderer/media/video_capture_impl.h b/content/renderer/media/video_capture_impl.h index 8e3f690..a250eb0 100644 --- a/content/renderer/media/video_capture_impl.h +++ b/content/renderer/media/video_capture_impl.h @@ -87,6 +87,10 @@ class CONTENT_EXPORT VideoCaptureImpl void RemoveDelegateOnIOThread(Task* task); virtual void Send(IPC::Message* message); + // Helpers. + bool CapabilityMatchesParameters(const VideoCaptureCapability& capability, + const media::VideoCaptureParams& params); + scoped_refptr<VideoCaptureMessageFilter> message_filter_; scoped_refptr<base::MessageLoopProxy> ml_proxy_; int device_id_; diff --git a/content/renderer/media/video_capture_impl_unittest.cc b/content/renderer/media/video_capture_impl_unittest.cc index 1dd7ae1..43c7aa8 100644 --- a/content/renderer/media/video_capture_impl_unittest.cc +++ b/content/renderer/media/video_capture_impl_unittest.cc @@ -3,19 +3,19 @@ // found in the LICENSE file. #include "base/message_loop.h" +#include "content/common/media/video_capture_messages.h" #include "content/renderer/media/video_capture_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using ::testing::_; +using ::testing::AtLeast; using ::testing::Return; -#define DEFAULT_CAPABILITY {176, 144, 30, 0, media::VideoFrame::I420, \ +#define DEFAULT_CAPABILITY_REGULAR {176, 144, 30, 0, media::VideoFrame::I420, \ false, false } - -ACTION(DeleteMessage) { - delete arg0; -} +#define DEFAULT_CAPABILITY_MASTER {320, 240, 20, 0, media::VideoFrame::I420, \ + false, true } class MockVideoCaptureMessageFilter : public VideoCaptureMessageFilter { public: @@ -62,7 +62,41 @@ class VideoCaptureImplTest : public ::testing::Test { } virtual ~MockVideoCaptureImpl() {} - MOCK_METHOD1(Send, void(IPC::Message* message)); + // Override Send() to mimic device to send events. + void Send(IPC::Message* message) { + CHECK(message); + + // In this method, messages are sent to the according handlers as if + // we are the device. + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(MockVideoCaptureImpl, *message) + IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Start, DeviceStartCapture) + IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Pause, DevicePauseCapture) + IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_Stop, DeviceStopCapture) + IPC_MESSAGE_HANDLER(VideoCaptureHostMsg_BufferReady, + DeviceReceiveEmptyBuffer) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + EXPECT_TRUE(handled); + delete message; + } + + void DeviceStartCapture(int device_id, + const media::VideoCaptureParams& params) { + media::VideoCaptureParams device_info = params; + media::VideoCapture::State state = kStarted; + OnDeviceInfoReceived(device_info); + OnStateChanged(state); + } + + void DevicePauseCapture(int device_id) {} + + void DeviceStopCapture(int device_id) { + media::VideoCapture::State state = kStopped; + OnStateChanged(state); + } + + void DeviceReceiveEmptyBuffer(int device_id, int buffer_id) {} }; VideoCaptureImplTest() { @@ -96,23 +130,175 @@ class VideoCaptureImplTest : public ::testing::Test { }; TEST_F(VideoCaptureImplTest, Simple) { - // Execute SetCapture() and StopCapture(). + // Execute SetCapture() and StopCapture() for one client. + scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient); + media::VideoCapture::VideoCaptureCapability capability = + DEFAULT_CAPABILITY_REGULAR; + + EXPECT_CALL(*client, OnStarted(_)) + .WillOnce(Return()); + EXPECT_CALL(*client, OnDeviceInfoReceived(_,_)) + .WillOnce(Return()); + + video_capture_impl_->StartCapture(client.get(), capability); + message_loop_->RunAllPending(); + + EXPECT_CALL(*client, OnStopped(_)) + .WillOnce(Return()); + EXPECT_CALL(*client, OnRemoved(_)) + .WillOnce(Return()); + video_capture_impl_->StopCapture(client.get()); + message_loop_->RunAllPending(); +} + +TEST_F(VideoCaptureImplTest, TwoClientsInSequence) { + // Execute SetCapture() and StopCapture() for 2 clients in sequence. scoped_ptr<MockVideoCaptureClient> client(new MockVideoCaptureClient); - media::VideoCapture::VideoCaptureCapability capability = DEFAULT_CAPABILITY; + media::VideoCapture::VideoCaptureCapability capability = + DEFAULT_CAPABILITY_REGULAR; - EXPECT_CALL(*video_capture_impl_, Send(_)) - .WillRepeatedly(DeleteMessage()); + EXPECT_CALL(*client, OnStarted(_)) + .WillOnce(Return()); + EXPECT_CALL(*client, OnDeviceInfoReceived(_,_)) + .WillOnce(Return()); + + video_capture_impl_->StartCapture(client.get(), capability); + message_loop_->RunAllPending(); + + EXPECT_CALL(*client, OnStopped(_)) + .WillOnce(Return()); + EXPECT_CALL(*client, OnRemoved(_)) + .WillOnce(Return()); + + video_capture_impl_->StopCapture(client.get()); + message_loop_->RunAllPending(); EXPECT_CALL(*client, OnStarted(_)) .WillOnce(Return()); + EXPECT_CALL(*client, OnDeviceInfoReceived(_,_)) + .WillOnce(Return()); video_capture_impl_->StartCapture(client.get(), capability); message_loop_->RunAllPending(); EXPECT_CALL(*client, OnStopped(_)) .WillOnce(Return()); + EXPECT_CALL(*client, OnRemoved(_)) + .WillOnce(Return()); video_capture_impl_->StopCapture(client.get()); message_loop_->RunAllPending(); } + +TEST_F(VideoCaptureImplTest, MasterAndRegular) { + // Execute SetCapture() and StopCapture() for 2 clients simultaneously. + // The master client starts first and stops first. + scoped_ptr<MockVideoCaptureClient> client_regular(new MockVideoCaptureClient); + scoped_ptr<MockVideoCaptureClient> client_master(new MockVideoCaptureClient); + media::VideoCapture::VideoCaptureCapability capability_regular = + DEFAULT_CAPABILITY_REGULAR; + media::VideoCapture::VideoCaptureCapability capability_master = + DEFAULT_CAPABILITY_MASTER; + + EXPECT_CALL(*client_master, OnStarted(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master, OnDeviceInfoReceived(_,_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnStarted(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnDeviceInfoReceived(_,_)) + .WillOnce(Return()); + + video_capture_impl_->StartCapture(client_master.get(), capability_master); + video_capture_impl_->StartCapture(client_regular.get(), capability_regular); + message_loop_->RunAllPending(); + + EXPECT_CALL(*client_master, OnStopped(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master, OnRemoved(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnStopped(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnRemoved(_)) + .WillOnce(Return()); + + video_capture_impl_->StopCapture(client_master.get()); + video_capture_impl_->StopCapture(client_regular.get()); + message_loop_->RunAllPending(); +} + +TEST_F(VideoCaptureImplTest, RegularAndMaster) { + // Execute SetCapture() and StopCapture() for 2 clients simultaneously. + // The regular client starts first and stops first. + scoped_ptr<MockVideoCaptureClient> client_regular(new MockVideoCaptureClient); + scoped_ptr<MockVideoCaptureClient> client_master(new MockVideoCaptureClient); + media::VideoCapture::VideoCaptureCapability capability_regular = + DEFAULT_CAPABILITY_REGULAR; + media::VideoCapture::VideoCaptureCapability capability_master = + DEFAULT_CAPABILITY_MASTER; + + EXPECT_CALL(*client_master, OnStarted(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master, OnDeviceInfoReceived(_,_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnStarted(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnDeviceInfoReceived(_,_)) + .Times(AtLeast(1)) + .WillRepeatedly(Return()); + + video_capture_impl_->StartCapture(client_regular.get(), capability_regular); + video_capture_impl_->StartCapture(client_master.get(), capability_master); + message_loop_->RunAllPending(); + + EXPECT_CALL(*client_master, OnStopped(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master, OnRemoved(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnStopped(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_regular, OnRemoved(_)) + .WillOnce(Return()); + + video_capture_impl_->StopCapture(client_regular.get()); + video_capture_impl_->StopCapture(client_master.get()); + message_loop_->RunAllPending(); +} + +TEST_F(VideoCaptureImplTest, Master1AndMaster2) { + // Execute SetCapture() and StopCapture() for 2 master clients simultaneously. + // The two clients have different resolution. The second client is expected to + // recevie an error. + scoped_ptr<MockVideoCaptureClient> client_master1(new MockVideoCaptureClient); + scoped_ptr<MockVideoCaptureClient> client_master2(new MockVideoCaptureClient); + media::VideoCapture::VideoCaptureCapability capability1 = + DEFAULT_CAPABILITY_MASTER; + media::VideoCapture::VideoCaptureCapability capability2 = + DEFAULT_CAPABILITY_MASTER; + capability2.width++; + + EXPECT_CALL(*client_master1, OnStarted(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master1, OnDeviceInfoReceived(_,_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master2, OnError(_,_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master2, OnRemoved(_)) + .WillOnce(Return()); + + video_capture_impl_->StartCapture(client_master1.get(), capability1); + video_capture_impl_->StartCapture(client_master2.get(), capability2); + message_loop_->RunAllPending(); + + EXPECT_CALL(*client_master1, OnStopped(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master1, OnRemoved(_)) + .WillOnce(Return()); + EXPECT_CALL(*client_master2, OnStopped(_)) + .Times(0); + + video_capture_impl_->StopCapture(client_master1.get()); + video_capture_impl_->StopCapture(client_master2.get()); + message_loop_->RunAllPending(); +} |