| Index: media/video/capture/video_capture_device_unittest.cc
|
| diff --git a/media/video/capture/video_capture_device_unittest.cc b/media/video/capture/video_capture_device_unittest.cc
|
| index 5a19d272c93d3eef65707bf92b21173bcfc0b0e2..586060f169fdac71b838effc7e976607e8f528ae 100644
|
| --- a/media/video/capture/video_capture_device_unittest.cc
|
| +++ b/media/video/capture/video_capture_device_unittest.cc
|
| @@ -2,8 +2,12 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/message_loop/message_loop.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +#include "base/run_loop.h"
|
| #include "base/synchronization/waitable_event.h"
|
| #include "base/test/test_timeouts.h"
|
| #include "base/threading/thread.h"
|
| @@ -65,8 +69,10 @@ class MockFrameObserver : public media::VideoCaptureDevice::EventHandler {
|
| MOCK_METHOD1(OnFrameInfo, void(const VideoCaptureCapability&));
|
| MOCK_METHOD1(OnFrameInfoChanged, void(const VideoCaptureCapability&));
|
|
|
| - explicit MockFrameObserver(base::WaitableEvent* wait_event)
|
| - : wait_event_(wait_event) {}
|
| + explicit MockFrameObserver(
|
| + base::Closure frame_cb)
|
| + : main_thread_(base::MessageLoopProxy::current()),
|
| + frame_cb_(frame_cb) {}
|
|
|
| virtual void OnError() OVERRIDE {
|
| OnErr();
|
| @@ -79,45 +85,40 @@ class MockFrameObserver : public media::VideoCaptureDevice::EventHandler {
|
| int rotation,
|
| bool flip_vert,
|
| bool flip_horiz) OVERRIDE {
|
| - wait_event_->Signal();
|
| + main_thread_->PostTask(FROM_HERE, frame_cb_);
|
| }
|
|
|
| virtual void OnIncomingCapturedVideoFrame(
|
| const scoped_refptr<media::VideoFrame>& frame,
|
| base::Time timestamp) OVERRIDE {
|
| - wait_event_->Signal();
|
| + main_thread_->PostTask(FROM_HERE, frame_cb_);
|
| }
|
|
|
| private:
|
| - base::WaitableEvent* wait_event_;
|
| + scoped_refptr<base::MessageLoopProxy> main_thread_;
|
| + base::Closure frame_cb_;
|
| };
|
|
|
| class VideoCaptureDeviceTest : public testing::Test {
|
| - public:
|
| - VideoCaptureDeviceTest(): wait_event_(false, false) { }
|
| -
|
| - void PostQuitTask() {
|
| - loop_->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
|
| - loop_->Run();
|
| - }
|
| -
|
| protected:
|
| + typedef media::VideoCaptureDevice::EventHandler EventHandler;
|
| +
|
| virtual void SetUp() {
|
| - frame_observer_.reset(new MockFrameObserver(&wait_event_));
|
| loop_.reset(new base::MessageLoopForUI());
|
| + frame_observer_.reset(new MockFrameObserver(loop_->QuitClosure()));
|
| #if defined(OS_ANDROID)
|
| media::VideoCaptureDeviceAndroid::RegisterVideoCaptureDevice(
|
| base::android::AttachCurrentThread());
|
| #endif
|
| }
|
|
|
| - virtual void TearDown() {
|
| + void WaitForCapturedFrame() {
|
| + loop_->Run();
|
| }
|
|
|
| #if defined(OS_WIN)
|
| base::win::ScopedCOMInitializer initialize_com_;
|
| #endif
|
| - base::WaitableEvent wait_event_;
|
| scoped_ptr<MockFrameObserver> frame_observer_;
|
| VideoCaptureDevice::Names names_;
|
| scoped_ptr<base::MessageLoop> loop_;
|
| @@ -163,15 +164,13 @@ TEST_F(VideoCaptureDeviceTest, CaptureVGA) {
|
| 0,
|
| false,
|
| ConstantResolutionVideoCaptureDevice);
|
| - device->Allocate(capture_format, frame_observer_.get());
|
| - device->Start();
|
| + device->AllocateAndStart(capture_format,
|
| + frame_observer_.PassAs<EventHandler>());
|
| // Get captured video frames.
|
| - PostQuitTask();
|
| - EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout()));
|
| + loop_->Run();
|
| EXPECT_EQ(rx_capability.width, 640);
|
| EXPECT_EQ(rx_capability.height, 480);
|
| - device->Stop();
|
| - device->DeAllocate();
|
| + device->StopAndDeAllocate();
|
| }
|
|
|
| TEST_F(VideoCaptureDeviceTest, Capture720p) {
|
| @@ -201,13 +200,11 @@ TEST_F(VideoCaptureDeviceTest, Capture720p) {
|
| 0,
|
| false,
|
| ConstantResolutionVideoCaptureDevice);
|
| - device->Allocate(capture_format, frame_observer_.get());
|
| - device->Start();
|
| + device->AllocateAndStart(capture_format,
|
| + frame_observer_.PassAs<EventHandler>());
|
| // Get captured video frames.
|
| - PostQuitTask();
|
| - EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout()));
|
| - device->Stop();
|
| - device->DeAllocate();
|
| + WaitForCapturedFrame();
|
| + device->StopAndDeAllocate();
|
| }
|
|
|
| TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
|
| @@ -235,8 +232,9 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
|
| 0,
|
| false,
|
| ConstantResolutionVideoCaptureDevice);
|
| - device->Allocate(capture_format, frame_observer_.get());
|
| - device->DeAllocate();
|
| + device->AllocateAndStart(capture_format,
|
| + frame_observer_.PassAs<EventHandler>());
|
| + device->StopAndDeAllocate();
|
| EXPECT_EQ(rx_capability.width, 640);
|
| EXPECT_EQ(rx_capability.height, 480);
|
| }
|
| @@ -247,58 +245,67 @@ TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) {
|
| DVLOG(1) << "No camera available. Exiting test.";
|
| return;
|
| }
|
| +
|
| + // First, do a number of very fast device start/stops.
|
| + for (int i = 0; i <= 5; i++) {
|
| + scoped_ptr<MockFrameObserver> frame_observer(
|
| + new MockFrameObserver(base::Bind(&base::DoNothing)));
|
| + scoped_ptr<VideoCaptureDevice> device(
|
| + VideoCaptureDevice::Create(names_.front()));
|
| + gfx::Size resolution;
|
| + if (i % 2) {
|
| + resolution = gfx::Size(640, 480);
|
| + } else {
|
| + resolution = gfx::Size(1280, 1024);
|
| + }
|
| + VideoCaptureCapability requested_format(
|
| + resolution.width(),
|
| + resolution.height(),
|
| + 30,
|
| + PIXEL_FORMAT_I420,
|
| + 0,
|
| + false,
|
| + ConstantResolutionVideoCaptureDevice);
|
| +
|
| + // The device (if it is an async implementation) may or may not get as far
|
| + // as the OnFrameInfo() step; we're intentionally not going to wait for it
|
| + // to get that far.
|
| + ON_CALL(*frame_observer, OnFrameInfo(_));
|
| + device->AllocateAndStart(requested_format,
|
| + frame_observer.PassAs<EventHandler>());
|
| + device->StopAndDeAllocate();
|
| + }
|
| +
|
| + // Finally, do a device start and wait for it to finish.
|
| + gfx::Size resolution;
|
| + VideoCaptureCapability requested_format(
|
| + 320,
|
| + 240,
|
| + 30,
|
| + PIXEL_FORMAT_I420,
|
| + 0,
|
| + false,
|
| + ConstantResolutionVideoCaptureDevice);
|
| +
|
| + base::RunLoop run_loop;
|
| + scoped_ptr<MockFrameObserver> frame_observer(
|
| + new MockFrameObserver(base::Bind(run_loop.QuitClosure())));
|
| scoped_ptr<VideoCaptureDevice> device(
|
| VideoCaptureDevice::Create(names_.front()));
|
| - ASSERT_TRUE(device.get() != NULL);
|
| - EXPECT_CALL(*frame_observer_, OnErr())
|
| - .Times(0);
|
| - // Get info about the new resolution.
|
| - VideoCaptureCapability rx_capability_1;
|
| - VideoCaptureCapability rx_capability_2;
|
| - VideoCaptureCapability capture_format_1(640,
|
| - 480,
|
| - 30,
|
| - PIXEL_FORMAT_I420,
|
| - 0,
|
| - false,
|
| - ConstantResolutionVideoCaptureDevice);
|
| - VideoCaptureCapability capture_format_2(1280,
|
| - 1024,
|
| - 30,
|
| - PIXEL_FORMAT_I420,
|
| - 0,
|
| - false,
|
| - ConstantResolutionVideoCaptureDevice);
|
| - VideoCaptureCapability capture_format_3(320,
|
| - 240,
|
| - 30,
|
| - PIXEL_FORMAT_I420,
|
| - 0,
|
| - false,
|
| - ConstantResolutionVideoCaptureDevice);
|
|
|
| - EXPECT_CALL(*frame_observer_, OnFrameInfo(_))
|
| - .WillOnce(SaveArg<0>(&rx_capability_1));
|
| - device->Allocate(capture_format_1, frame_observer_.get());
|
| - device->Start();
|
| - // Nothing shall happen.
|
| - device->Allocate(capture_format_2, frame_observer_.get());
|
| - device->DeAllocate();
|
| - // Allocate new size 320, 240
|
| - EXPECT_CALL(*frame_observer_, OnFrameInfo(_))
|
| - .WillOnce(SaveArg<0>(&rx_capability_2));
|
| - device->Allocate(capture_format_3, frame_observer_.get());
|
| -
|
| - device->Start();
|
| - // Get captured video frames.
|
| - PostQuitTask();
|
| - EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout()));
|
| - EXPECT_EQ(rx_capability_1.width, 640);
|
| - EXPECT_EQ(rx_capability_1.height, 480);
|
| - EXPECT_EQ(rx_capability_2.width, 320);
|
| - EXPECT_EQ(rx_capability_2.height, 240);
|
| - device->Stop();
|
| - device->DeAllocate();
|
| + // The device (if it is an async implementation) may or may not get as far
|
| + // as the OnFrameInfo() step; we're intentionally not going to wait for it
|
| + // to get that far.
|
| + VideoCaptureCapability final_format;
|
| + EXPECT_CALL(*frame_observer, OnFrameInfo(_))
|
| + .Times(1).WillOnce(SaveArg<0>(&final_format));
|
| + device->AllocateAndStart(requested_format,
|
| + frame_observer.PassAs<EventHandler>());
|
| + run_loop.Run(); // Waits for a frame.
|
| + device->StopAndDeAllocate();
|
| + device.reset();
|
| + EXPECT_EQ(final_format.width, 320);
|
| + EXPECT_EQ(final_format.height, 240);
|
| }
|
|
|
| TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) {
|
| @@ -325,16 +332,14 @@ TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) {
|
| 0,
|
| false,
|
| ConstantResolutionVideoCaptureDevice);
|
| - device->Allocate(capture_format, frame_observer_.get());
|
| -
|
| - device->Start();
|
| + device->AllocateAndStart(capture_format,
|
| + frame_observer_.PassAs<EventHandler>());
|
| // Get captured video frames.
|
| - PostQuitTask();
|
| - EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout()));
|
| + WaitForCapturedFrame();
|
| EXPECT_EQ(rx_capability.width, 640);
|
| EXPECT_EQ(rx_capability.height, 480);
|
| EXPECT_EQ(rx_capability.frame_rate, 30);
|
| - device->DeAllocate();
|
| + device->StopAndDeAllocate();
|
| }
|
|
|
| TEST_F(VideoCaptureDeviceTest, FakeCapture) {
|
| @@ -363,15 +368,13 @@ TEST_F(VideoCaptureDeviceTest, FakeCapture) {
|
| 0,
|
| false,
|
| ConstantResolutionVideoCaptureDevice);
|
| - device->Allocate(capture_format, frame_observer_.get());
|
| -
|
| - device->Start();
|
| - EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout()));
|
| + device->AllocateAndStart(capture_format,
|
| + frame_observer_.PassAs<EventHandler>());
|
| + WaitForCapturedFrame();
|
| EXPECT_EQ(rx_capability.width, 640);
|
| EXPECT_EQ(rx_capability.height, 480);
|
| EXPECT_EQ(rx_capability.frame_rate, 30);
|
| - device->Stop();
|
| - device->DeAllocate();
|
| + device->StopAndDeAllocate();
|
| }
|
|
|
| // Start the camera in 720p to capture MJPEG instead of a raw format.
|
| @@ -400,14 +403,12 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) {
|
| 0,
|
| false,
|
| ConstantResolutionVideoCaptureDevice);
|
| - device->Allocate(capture_format, frame_observer_.get());
|
| -
|
| - device->Start();
|
| + device->AllocateAndStart(capture_format,
|
| + frame_observer_.PassAs<EventHandler>());
|
| // Get captured video frames.
|
| - PostQuitTask();
|
| - EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_max_timeout()));
|
| + WaitForCapturedFrame();
|
| EXPECT_EQ(rx_capability.color, PIXEL_FORMAT_MJPEG);
|
| - device->DeAllocate();
|
| + device->StopAndDeAllocate();
|
| }
|
|
|
| TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) {
|
| @@ -432,22 +433,21 @@ TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) {
|
|
|
| EXPECT_CALL(*frame_observer_, OnErr())
|
| .Times(0);
|
| + int action_count = 200;
|
| + EXPECT_CALL(*frame_observer_, OnFrameInfoChanged(_))
|
| + .Times(AtLeast(action_count / 30));
|
|
|
| - device->Allocate(capture_format, frame_observer_.get());
|
| + device->AllocateAndStart(capture_format,
|
| + frame_observer_.PassAs<EventHandler>());
|
|
|
| // The amount of times the OnFrameInfoChanged gets called depends on how often
|
| // FakeDevice is supposed to change and what is its actual frame rate.
|
| // We set TimeWait to 200 action timeouts and this should be enough for at
|
| // least action_count/kFakeCaptureCapabilityChangePeriod calls.
|
| - int action_count = 200;
|
| - EXPECT_CALL(*frame_observer_, OnFrameInfoChanged(_))
|
| - .Times(AtLeast(action_count / 30));
|
| - device->Start();
|
| for (int i = 0; i < action_count; ++i) {
|
| - EXPECT_TRUE(wait_event_.TimedWait(TestTimeouts::action_timeout()));
|
| + WaitForCapturedFrame();
|
| }
|
| - device->Stop();
|
| - device->DeAllocate();
|
| + device->StopAndDeAllocate();
|
| }
|
|
|
| }; // namespace media
|
|
|