diff options
Diffstat (limited to 'chromium/media/video/capture/video_capture_device_unittest.cc')
-rw-r--r-- | chromium/media/video/capture/video_capture_device_unittest.cc | 287 |
1 files changed, 143 insertions, 144 deletions
diff --git a/chromium/media/video/capture/video_capture_device_unittest.cc b/chromium/media/video/capture/video_capture_device_unittest.cc index 5e05ad4b4b2..afc6dff6aa5 100644 --- a/chromium/media/video/capture/video_capture_device_unittest.cc +++ b/chromium/media/video/capture/video_capture_device_unittest.cc @@ -4,22 +4,25 @@ #include "base/bind.h" #include "base/bind_helpers.h" +#include "base/memory/ref_counted.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" -#include "media/video/capture/fake_video_capture_device.h" #include "media/video/capture/video_capture_device.h" +#include "media/video/capture/video_capture_device_factory.h" #include "media/video/capture/video_capture_types.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_WIN) #include "base/win/scoped_com_initializer.h" -#include "media/video/capture/win/video_capture_device_mf_win.h" +#include "media/video/capture/win/video_capture_device_factory_win.h" +#endif + +#if defined(OS_MACOSX) +#include "media/video/capture/mac/video_capture_device_factory_mac.h" #endif #if defined(OS_ANDROID) @@ -30,7 +33,7 @@ #if defined(OS_MACOSX) // Mac/QTKit will always give you the size you ask for and this case will fail. #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize -// We will always get ARGB from the Mac/QTKit implementation. +// We will always get YUYV from the Mac QTKit/AVFoundation implementations. #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg #elif defined(OS_WIN) #define MAYBE_AllocateBadSize AllocateBadSize @@ -55,9 +58,7 @@ #endif using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Return; -using ::testing::AtLeast; +using ::testing::SaveArg; namespace media { @@ -71,32 +72,46 @@ class MockClient : public media::VideoCaptureDevice::Client { explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb) : main_thread_(base::MessageLoopProxy::current()), frame_cb_(frame_cb) {} - virtual void OnError() OVERRIDE { + virtual void OnError(const std::string& error_message) OVERRIDE { OnErr(); } - virtual void OnIncomingCapturedFrame(const uint8* data, - int length, - base::Time timestamp, - int rotation, - const VideoCaptureFormat& format) - OVERRIDE { + virtual void OnIncomingCapturedData(const uint8* data, + int length, + const VideoCaptureFormat& format, + int rotation, + base::TimeTicks timestamp) OVERRIDE { main_thread_->PostTask(FROM_HERE, base::Bind(frame_cb_, format)); } - virtual void OnIncomingCapturedBuffer(const scoped_refptr<Buffer>& buffer, - media::VideoFrame::Format format, - const gfx::Size& dimensions, - base::Time timestamp, - int frame_rate) OVERRIDE { + virtual void OnIncomingCapturedVideoFrame( + const scoped_refptr<Buffer>& buffer, + const media::VideoCaptureFormat& buffer_format, + const scoped_refptr<media::VideoFrame>& frame, + base::TimeTicks timestamp) OVERRIDE { NOTREACHED(); } private: - scoped_refptr<base::MessageLoopProxy> main_thread_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_; base::Callback<void(const VideoCaptureFormat&)> frame_cb_; }; +class DeviceEnumerationListener : + public base::RefCounted<DeviceEnumerationListener>{ + public: + MOCK_METHOD1(OnEnumeratedDevicesCallbackPtr, + void(media::VideoCaptureDevice::Names* names)); + // GMock doesn't support move-only arguments, so we use this forward method. + void OnEnumeratedDevicesCallback( + scoped_ptr<media::VideoCaptureDevice::Names> names) { + OnEnumeratedDevicesCallbackPtr(names.release()); + } + private: + friend class base::RefCounted<DeviceEnumerationListener>; + virtual ~DeviceEnumerationListener() {} +}; + class VideoCaptureDeviceTest : public testing::Test { protected: typedef media::VideoCaptureDevice::Client Client; @@ -105,7 +120,11 @@ class VideoCaptureDeviceTest : public testing::Test { : loop_(new base::MessageLoop()), client_( new MockClient(base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, - base::Unretained(this)))) {} + base::Unretained(this)))), + video_capture_device_factory_(VideoCaptureDeviceFactory::CreateFactory( + base::MessageLoopProxy::current())) { + device_enumeration_listener_ = new DeviceEnumerationListener(); + } virtual void SetUp() { #if defined(OS_ANDROID) @@ -129,43 +148,108 @@ class VideoCaptureDeviceTest : public testing::Test { run_loop_->Run(); } + scoped_ptr<media::VideoCaptureDevice::Names> EnumerateDevices() { + media::VideoCaptureDevice::Names* names; + EXPECT_CALL(*device_enumeration_listener_, + OnEnumeratedDevicesCallbackPtr(_)).WillOnce(SaveArg<0>(&names)); + + video_capture_device_factory_->EnumerateDeviceNames( + base::Bind(&DeviceEnumerationListener::OnEnumeratedDevicesCallback, + device_enumeration_listener_)); + base::MessageLoop::current()->RunUntilIdle(); + return scoped_ptr<media::VideoCaptureDevice::Names>(names); + } + const VideoCaptureFormat& last_format() const { return last_format_; } + scoped_ptr<VideoCaptureDevice::Name> GetFirstDeviceNameSupportingPixelFormat( + const VideoPixelFormat& pixel_format) { + names_ = EnumerateDevices(); + if (!names_->size()) { + DVLOG(1) << "No camera available."; + return scoped_ptr<VideoCaptureDevice::Name>(); + } + VideoCaptureDevice::Names::iterator names_iterator; + for (names_iterator = names_->begin(); names_iterator != names_->end(); + ++names_iterator) { + VideoCaptureFormats supported_formats; + video_capture_device_factory_->GetDeviceSupportedFormats( + *names_iterator, + &supported_formats); + VideoCaptureFormats::iterator formats_iterator; + for (formats_iterator = supported_formats.begin(); + formats_iterator != supported_formats.end(); ++formats_iterator) { + if (formats_iterator->pixel_format == pixel_format) { + return scoped_ptr<VideoCaptureDevice::Name>( + new VideoCaptureDevice::Name(*names_iterator)); + } + } + } + DVLOG(1) << "No camera can capture the format: " << pixel_format; + return scoped_ptr<VideoCaptureDevice::Name>(); + } + #if defined(OS_WIN) base::win::ScopedCOMInitializer initialize_com_; #endif - VideoCaptureDevice::Names names_; + scoped_ptr<VideoCaptureDevice::Names> names_; scoped_ptr<base::MessageLoop> loop_; scoped_ptr<base::RunLoop> run_loop_; scoped_ptr<MockClient> client_; + scoped_refptr<DeviceEnumerationListener> device_enumeration_listener_; VideoCaptureFormat last_format_; + scoped_ptr<VideoCaptureDeviceFactory> video_capture_device_factory_; }; TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) { #if defined(OS_WIN) VideoCaptureDevice::Name::CaptureApiType api_type = - VideoCaptureDeviceMFWin::PlatformSupported() + VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation() ? VideoCaptureDevice::Name::MEDIA_FOUNDATION : VideoCaptureDevice::Name::DIRECT_SHOW; VideoCaptureDevice::Name device_name("jibberish", "jibberish", api_type); +#elif defined(OS_MACOSX) + VideoCaptureDevice::Name device_name("jibberish", "jibberish", + VideoCaptureDeviceFactoryMac::PlatformSupportsAVFoundation() + ? VideoCaptureDevice::Name::AVFOUNDATION + : VideoCaptureDevice::Name::QTKIT); #else VideoCaptureDevice::Name device_name("jibberish", "jibberish"); #endif - VideoCaptureDevice* device = VideoCaptureDevice::Create(device_name); + scoped_ptr<VideoCaptureDevice> device = + video_capture_device_factory_->Create(device_name); +#if !defined(OS_MACOSX) EXPECT_TRUE(device == NULL); +#else + if (VideoCaptureDeviceFactoryMac::PlatformSupportsAVFoundation()) { + EXPECT_TRUE(device == NULL); + } else { + // The presence of the actual device is only checked on AllocateAndStart() + // and not on creation for QTKit API in Mac OS X platform. + EXPECT_CALL(*client_, OnErr()).Times(1); + + VideoCaptureParams capture_params; + capture_params.requested_format.frame_size.SetSize(640, 480); + capture_params.requested_format.frame_rate = 30; + capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; + capture_params.allow_resolution_change = false; + device->AllocateAndStart(capture_params, client_.PassAs<Client>()); + device->StopAndDeAllocate(); + } +#endif } TEST_F(VideoCaptureDeviceTest, CaptureVGA) { - VideoCaptureDevice::GetDeviceNames(&names_); - if (!names_.size()) { + names_ = EnumerateDevices(); + if (!names_->size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); - ASSERT_FALSE(device.get() == NULL); - DVLOG(1) << names_.front().id(); + video_capture_device_factory_->Create(names_->front())); + ASSERT_TRUE(device); + DVLOG(1) << names_->front().id(); EXPECT_CALL(*client_, OnErr()) .Times(0); @@ -184,15 +268,15 @@ TEST_F(VideoCaptureDeviceTest, CaptureVGA) { } TEST_F(VideoCaptureDeviceTest, Capture720p) { - VideoCaptureDevice::GetDeviceNames(&names_); - if (!names_.size()) { + names_ = EnumerateDevices(); + if (!names_->size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); - ASSERT_FALSE(device.get() == NULL); + video_capture_device_factory_->Create(names_->front())); + ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) .Times(0); @@ -209,14 +293,14 @@ TEST_F(VideoCaptureDeviceTest, Capture720p) { } TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { - VideoCaptureDevice::GetDeviceNames(&names_); - if (!names_.size()) { + names_ = EnumerateDevices(); + if (!names_->size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); - ASSERT_TRUE(device.get() != NULL); + video_capture_device_factory_->Create(names_->front())); + ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) .Times(0); @@ -234,8 +318,8 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { } TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) { - VideoCaptureDevice::GetDeviceNames(&names_); - if (!names_.size()) { + names_ = EnumerateDevices(); + if (!names_->size()) { DVLOG(1) << "No camera available. Exiting test."; return; } @@ -244,7 +328,7 @@ TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) { for (int i = 0; i <= 5; i++) { ResetWithNewClient(); scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); + video_capture_device_factory_->Create(names_->front())); gfx::Size resolution; if (i % 2) { resolution = gfx::Size(640, 480); @@ -269,7 +353,7 @@ TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) { ResetWithNewClient(); scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); + video_capture_device_factory_->Create(names_->front())); device->AllocateAndStart(capture_params, client_.PassAs<Client>()); WaitForCapturedFrame(); @@ -280,14 +364,14 @@ TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) { } TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { - VideoCaptureDevice::GetDeviceNames(&names_); - if (!names_.size()) { + names_ = EnumerateDevices(); + if (!names_->size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); - ASSERT_TRUE(device.get() != NULL); + video_capture_device_factory_->Create(names_->front())); + ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) .Times(0); @@ -306,43 +390,17 @@ TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { device->StopAndDeAllocate(); } -TEST_F(VideoCaptureDeviceTest, FakeCapture) { - VideoCaptureDevice::Names names; - - FakeVideoCaptureDevice::GetDeviceNames(&names); - - ASSERT_GT(static_cast<int>(names.size()), 0); - - scoped_ptr<VideoCaptureDevice> device( - FakeVideoCaptureDevice::Create(names.front())); - ASSERT_TRUE(device.get() != NULL); - - EXPECT_CALL(*client_, OnErr()) - .Times(0); - - VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(640, 480); - capture_params.requested_format.frame_rate = 30; - capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; - capture_params.allow_resolution_change = false; - device->AllocateAndStart(capture_params, client_.PassAs<Client>()); - WaitForCapturedFrame(); - EXPECT_EQ(last_format().frame_size.width(), 640); - EXPECT_EQ(last_format().frame_size.height(), 480); - EXPECT_EQ(last_format().frame_rate, 30); - device->StopAndDeAllocate(); -} - // Start the camera in 720p to capture MJPEG instead of a raw format. TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { - VideoCaptureDevice::GetDeviceNames(&names_); - if (!names_.size()) { - DVLOG(1) << "No camera available. Exiting test."; + scoped_ptr<VideoCaptureDevice::Name> name = + GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MJPEG); + if (!name) { + DVLOG(1) << "No camera supports MJPEG format. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); - ASSERT_TRUE(device.get() != NULL); + video_capture_device_factory_->Create(*name)); + ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) .Times(0); @@ -362,72 +420,13 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { } TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) { - VideoCaptureDevice::GetDeviceNames(&names_); - if (!names_.size()) { - DVLOG(1) << "No camera available. Exiting test."; - return; - } - VideoCaptureFormats supported_formats; - VideoCaptureDevice::Names::iterator names_iterator; - for (names_iterator = names_.begin(); names_iterator != names_.end(); - ++names_iterator) { - VideoCaptureDevice::GetDeviceSupportedFormats(*names_iterator, - &supported_formats); - // Nothing to test here since we cannot forecast the hardware capabilities. - } -} - -TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) { - VideoCaptureDevice::Names names; - - FakeVideoCaptureDevice::GetDeviceNames(&names); - VideoCaptureParams capture_params; - capture_params.requested_format.frame_size.SetSize(640, 480); - capture_params.requested_format.frame_rate = 30; - capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420; - capture_params.allow_resolution_change = true; - - ASSERT_GT(static_cast<int>(names.size()), 0); - - scoped_ptr<VideoCaptureDevice> device( - FakeVideoCaptureDevice::Create(names.front())); - ASSERT_TRUE(device.get() != NULL); - - EXPECT_CALL(*client_, OnErr()) - .Times(0); - int action_count = 200; - - device->AllocateAndStart(capture_params, client_.PassAs<Client>()); - - // We set TimeWait to 200 action timeouts and this should be enough for at - // least action_count/kFakeCaptureCapabilityChangePeriod calls. - for (int i = 0; i < action_count; ++i) { - WaitForCapturedFrame(); - } - device->StopAndDeAllocate(); -} - -TEST_F(VideoCaptureDeviceTest, FakeGetDeviceSupportedFormats) { - VideoCaptureDevice::Names names; - FakeVideoCaptureDevice::GetDeviceNames(&names); - - VideoCaptureFormats supported_formats; - VideoCaptureDevice::Names::iterator names_iterator; - - for (names_iterator = names.begin(); names_iterator != names.end(); - ++names_iterator) { - FakeVideoCaptureDevice::GetDeviceSupportedFormats(*names_iterator, - &supported_formats); - EXPECT_EQ(supported_formats.size(), 2u); - EXPECT_EQ(supported_formats[0].frame_size.width(), 640); - EXPECT_EQ(supported_formats[0].frame_size.height(), 480); - EXPECT_EQ(supported_formats[0].pixel_format, media::PIXEL_FORMAT_I420); - EXPECT_GE(supported_formats[0].frame_rate, 20); - EXPECT_EQ(supported_formats[1].frame_size.width(), 320); - EXPECT_EQ(supported_formats[1].frame_size.height(), 240); - EXPECT_EQ(supported_formats[1].pixel_format, media::PIXEL_FORMAT_I420); - EXPECT_GE(supported_formats[1].frame_rate, 20); - } + // Use PIXEL_FORMAT_MAX to iterate all device names for testing + // GetDeviceSupportedFormats(). + scoped_ptr<VideoCaptureDevice::Name> name = + GetFirstDeviceNameSupportingPixelFormat(PIXEL_FORMAT_MAX); + // Verify no camera returned for PIXEL_FORMAT_MAX. Nothing else to test here + // since we cannot forecast the hardware capabilities. + ASSERT_FALSE(name); } }; // namespace media |