diff options
author | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 13:53:32 +0000 |
---|---|---|
committer | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-09 13:53:32 +0000 |
commit | 4669e6887f7c5d95e0c5f9a5346bd29fba0954ca (patch) | |
tree | e6868ecf6a2e6b91d591f3f884f4f9a939ccdba5 | |
parent | f6c52338609c76cf8b7b68fafd27834e48d10f90 (diff) | |
download | chromium_src-4669e6887f7c5d95e0c5f9a5346bd29fba0954ca.zip chromium_src-4669e6887f7c5d95e0c5f9a5346bd29fba0954ca.tar.gz chromium_src-4669e6887f7c5d95e0c5f9a5346bd29fba0954ca.tar.bz2 |
Mac Video Capture Device: split VCD into VCD and Factory.
VideoCaptureDeviceMac includes factory and non-factory parts.
This CL splits them into VideoCaptureDeviceMac and
VideoCaptureDeviceFactoryMac. The latter inherits the previous
class' static methods: Create(), GetDeviceNames() and
GetDeviceSupportedFormats().
All video factory code previously in MediaStreamManager is
moved into VideoCaptureFactory. This includes the use
of the flag |kUseFakeDeviceForMediaStream|.
This flag is moved correspondingly into media_switches.cc --
(but note that this flag is still used in MediaStreamManager for
the Fake Audio parts). File media_switches.cc is
included in several test files where the flag is used.
VideoCaptureDeviceTest is splitted as well into:
a) Tests that were exercising only the FakeVCD
(FakeVideoCaptureDeviceTest).
b) All other tests, that use the underlying OS webcam.
This VideoCaptureDeviceTest gets a Factory and uses it
instead of static methods.
A unit test is added to VCDFMac, doing little for the moment
but I'm planning to add support for testing at least the
blacklisting -- req from rsesek@ in another CL.
BUG=288562, 323913, 255552
Review URL: https://codereview.chromium.org/265263004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269271 0039d316-1c4b-4281-b951-d872f2087c98
31 files changed, 511 insertions, 246 deletions
diff --git a/chrome/browser/apps/speech_recognition_browsertest.cc b/chrome/browser/apps/speech_recognition_browsertest.cc index c0b8d33..7708dc7 100644 --- a/chrome/browser/apps/speech_recognition_browsertest.cc +++ b/chrome/browser/apps/speech_recognition_browsertest.cc @@ -5,6 +5,7 @@ #include "chrome/browser/apps/app_browsertest_util.h" #include "content/public/common/content_switches.h" #include "content/public/test/fake_speech_recognition_manager.h" +#include "media/base/media_switches.h" class SpeechRecognitionTest : public extensions::PlatformAppBrowserTest { public: diff --git a/chrome/browser/apps/web_view_browsertest.cc b/chrome/browser/apps/web_view_browsertest.cc index 8b96069..5f6fe38 100644 --- a/chrome/browser/apps/web_view_browsertest.cc +++ b/chrome/browser/apps/web_view_browsertest.cc @@ -31,6 +31,7 @@ #include "content/public/test/fake_speech_recognition_manager.h" #include "extensions/common/extension.h" #include "extensions/common/extensions_client.h" +#include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" diff --git a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc index 49cc42c..07c4f0b 100644 --- a/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc +++ b/chrome/browser/media/chrome_media_stream_infobar_browsertest.cc @@ -25,6 +25,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/common/media_stream_request.h" #include "content/public/test/browser_test_utils.h" +#include "media/base/media_switches.h" #include "net/test/spawned_test_server/spawned_test_server.h" diff --git a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc index a1e492e..d69dff0 100644 --- a/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc +++ b/chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc @@ -21,6 +21,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test_utils.h" +#include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/perf/perf_test.h" diff --git a/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc b/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc index 14e461f..28dfc7a 100644 --- a/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc +++ b/chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc @@ -8,6 +8,7 @@ #include "chrome/browser/media/webrtc_browsertest_common.h" #include "chrome/common/chrome_version_info.h" #include "content/public/common/content_switches.h" +#include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" static const char kMainWebrtcTestHtmlPage[] = diff --git a/chrome/test/ppapi/ppapi_test.cc b/chrome/test/ppapi/ppapi_test.cc index aefc4e9..2440949 100644 --- a/chrome/test/ppapi/ppapi_test.cc +++ b/chrome/test/ppapi/ppapi_test.cc @@ -25,6 +25,7 @@ #include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" +#include "media/base/media_switches.h" #include "net/base/filename_util.h" #include "net/base/test_data_directory.h" #include "ppapi/shared_impl/ppapi_switches.h" diff --git a/content/browser/media/webrtc_browsertest.cc b/content/browser/media/webrtc_browsertest.cc index 69fd5c0..912ec96 100644 --- a/content/browser/media/webrtc_browsertest.cc +++ b/content/browser/media/webrtc_browsertest.cc @@ -16,6 +16,7 @@ #include "content/shell/browser/shell.h" #include "content/test/webrtc_content_browsertest_base.h" #include "media/audio/audio_manager.h" +#include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" #if defined(OS_WIN) diff --git a/content/browser/media/webrtc_internals_browsertest.cc b/content/browser/media/webrtc_internals_browsertest.cc index 8e071c7..7b352d6 100644 --- a/content/browser/media/webrtc_internals_browsertest.cc +++ b/content/browser/media/webrtc_internals_browsertest.cc @@ -12,6 +12,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h" using std::string; diff --git a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc index 38a7f0a..cc8c226 100644 --- a/content/browser/renderer_host/media/audio_renderer_host_unittest.cc +++ b/content/browser/renderer_host/media/audio_renderer_host_unittest.cc @@ -18,6 +18,7 @@ #include "ipc/ipc_message_utils.h" #include "media/audio/audio_manager.h" #include "media/base/bind_to_current_loop.h" +#include "media/base/media_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc index a181899..603ec30 100644 --- a/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc @@ -26,6 +26,7 @@ #include "content/test/test_content_client.h" #include "ipc/ipc_message_macros.h" #include "media/audio/mock_audio_manager.h" +#include "media/base/media_switches.h" #include "media/video/capture/fake_video_capture_device_factory.h" #include "net/url_request/url_request_context.h" #include "testing/gmock/include/gmock/gmock.h" diff --git a/content/browser/renderer_host/media/media_stream_manager.cc b/content/browser/renderer_host/media/media_stream_manager.cc index 3cdb1ab..fe537d9 100644 --- a/content/browser/renderer_host/media/media_stream_manager.cc +++ b/content/browser/renderer_host/media/media_stream_manager.cc @@ -37,8 +37,7 @@ #include "media/audio/audio_parameters.h" #include "media/base/channel_layout.h" #include "media/base/media_switches.h" -#include "media/video/capture/fake_video_capture_device_factory.h" -#include "media/video/capture/file_video_capture_device_factory.h" +#include "media/video/capture/video_capture_device_factory.h" #include "url/gurl.h" #if defined(OS_WIN) @@ -1438,26 +1437,13 @@ void MediaStreamManager::InitializeDeviceManagersOnIOThread() { io_loop_ = base::MessageLoop::current(); io_loop_->AddDestructionObserver(this); - // Use a Fake Audio Device and Fake/File Video Device Factory if the command - // line flags are present, otherwise use a normal device factory. if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUseFakeDeviceForMediaStream)) { - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUseFileForFakeVideoCapture)) { - video_capture_manager_ = new VideoCaptureManager( - scoped_ptr<media::VideoCaptureDeviceFactory>( - new media::FileVideoCaptureDeviceFactory())); - } else { - video_capture_manager_ = new VideoCaptureManager( - scoped_ptr<media::VideoCaptureDeviceFactory>( - new media::FakeVideoCaptureDeviceFactory())); - } + switches::kUseFakeDeviceForMediaStream)) { audio_input_device_manager()->UseFakeDevice(); - } else { - video_capture_manager_ = new VideoCaptureManager( - scoped_ptr<media::VideoCaptureDeviceFactory>( - new media::VideoCaptureDeviceFactory())); } + + video_capture_manager_ = new VideoCaptureManager( + media::VideoCaptureDeviceFactory::CreateFactory()); video_capture_manager_->Register(this, device_task_runner_); } diff --git a/content/browser/renderer_host/media/media_stream_manager_unittest.cc b/content/browser/renderer_host/media/media_stream_manager_unittest.cc index 2da5a64..e01b945 100644 --- a/content/browser/renderer_host/media/media_stream_manager_unittest.cc +++ b/content/browser/renderer_host/media/media_stream_manager_unittest.cc @@ -16,6 +16,7 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "media/audio/audio_manager_base.h" #include "media/audio/fake_audio_log_factory.h" +#include "media/base/media_switches.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" 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 171d300..dd22a64 100644 --- a/content/browser/renderer_host/media/video_capture_host_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc @@ -27,6 +27,7 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "content/test/test_content_browser_client.h" #include "media/audio/audio_manager.h" +#include "media/base/media_switches.h" #include "media/base/video_frame.h" #include "media/video/capture/video_capture_types.h" #include "net/url_request/url_request_context.h" diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 589f694..c689caf 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -885,9 +885,6 @@ extern const char kUIPrioritizeInGpuProcess[] = // Overrides the preferred discardable memory implementation. const char kUseDiscardableMemory[] = "use-discardable-memory"; -// Use fake device for MediaStream to replace actual camera and microphone. -const char kUseFakeDeviceForMediaStream[] = "use-fake-device-for-media-stream"; - // Bypass the media stream infobar by selecting the default device for media // streams (e.g. WebRTC). Works with --use-fake-device-for-media-stream. const char kUseFakeUIForMediaStream[] = "use-fake-ui-for-media-stream"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index c8c97bca..d158186 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -247,7 +247,6 @@ extern const char kTraceStartupDuration[]; extern const char kTraceStartupFile[]; CONTENT_EXPORT extern const char kUIPrioritizeInGpuProcess[]; CONTENT_EXPORT extern const char kUseDiscardableMemory[]; -CONTENT_EXPORT extern const char kUseFakeDeviceForMediaStream[]; CONTENT_EXPORT extern const char kUseFakeUIForMediaStream[]; CONTENT_EXPORT extern const char kUseMobileUserAgent[]; extern const char kUtilityCmdPrefix[]; diff --git a/content/shell/DEPS b/content/shell/DEPS index 1d7524c..386f7d0 100644 --- a/content/shell/DEPS +++ b/content/shell/DEPS @@ -27,4 +27,7 @@ specific_include_rules = { "shell_views\.cc": [ "+ui/wm/test" ], + "content_browser_tests_android\.cc": [ + "+media/base" + ], } diff --git a/content/shell/android/browsertests_apk/content_browser_tests_android.cc b/content/shell/android/browsertests_apk/content_browser_tests_android.cc index d4dd0b2..9abc636 100644 --- a/content/shell/android/browsertests_apk/content_browser_tests_android.cc +++ b/content/shell/android/browsertests_apk/content_browser_tests_android.cc @@ -29,6 +29,7 @@ #include "content/shell/android/shell_jni_registrar.h" #include "content/shell/app/shell_main_delegate.h" #include "jni/ContentBrowserTestsActivity_jni.h" +#include "media/base/media_switches.h" #include "testing/android/native_test_util.h" using testing::native_test_util::ArgsToArgv; diff --git a/content/test/content_test_launcher.cc b/content/test/content_test_launcher.cc index d351e91..64e91f8 100644 --- a/content/test/content_test_launcher.cc +++ b/content/test/content_test_launcher.cc @@ -17,6 +17,7 @@ #include "content/public/test/content_test_suite_base.h" #include "content/shell/app/shell_main_delegate.h" #include "content/shell/common/shell_switches.h" +#include "media/base/media_switches.h" #include "testing/gtest/include/gtest/gtest.h" #if defined(OS_ANDROID) diff --git a/content/test/webrtc_content_browsertest_base.cc b/content/test/webrtc_content_browsertest_base.cc index e3f7191..5b0df6f 100644 --- a/content/test/webrtc_content_browsertest_base.cc +++ b/content/test/webrtc_content_browsertest_base.cc @@ -11,6 +11,7 @@ #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "media/base/media_switches.h" namespace content { diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 515c0bc..e7982da 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc @@ -40,6 +40,7 @@ const char kAlsaOutputDevice[] = "alsa-output-device"; // for experimentation purposes, in particular library load time issue, the // usage of this library can be enabled by using this flag. const char kEnableAVFoundation[] = "enable-avfoundation"; + // QTKit is the media capture API predecessor to AVFoundation, available up and // until Mac OS X 10.9 (despite being deprecated in this last one). This flag // is used for troubleshooting and testing, and forces QTKit in builds and @@ -85,6 +86,9 @@ const char kWaveOutBuffers[] = "waveout-buffers"; const char kUseCras[] = "use-cras"; #endif +// Use fake device for Media Stream to replace actual camera and microphone. +const char kUseFakeDeviceForMediaStream[] = "use-fake-device-for-media-stream"; + // Use a raw video file as fake video capture device. const char kUseFileForFakeVideoCapture[] = "use-file-for-fake-video-capture"; diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 90a25f4..a225a18 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h @@ -46,6 +46,7 @@ MEDIA_EXPORT extern const char kWaveOutBuffers[]; MEDIA_EXPORT extern const char kUseCras[]; #endif +MEDIA_EXPORT extern const char kUseFakeDeviceForMediaStream[]; MEDIA_EXPORT extern const char kUseFileForFakeVideoCapture[]; } // namespace switches diff --git a/media/media.gyp b/media/media.gyp index a799028..ddc91fa 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -52,7 +52,7 @@ 'type': '<(component)', 'dependencies': [ '../base/base.gyp:base', - '../base/base.gyp:base_i18n', + '../base/base.gyp:base_i18n', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../crypto/crypto.gyp:crypto', '../gpu/gpu.gyp:command_buffer_common', @@ -475,6 +475,8 @@ 'video/capture/mac/platform_video_capturing_mac.h', 'video/capture/mac/video_capture_device_avfoundation_mac.h', 'video/capture/mac/video_capture_device_avfoundation_mac.mm', + 'video/capture/mac/video_capture_device_factory_mac.h', + 'video/capture/mac/video_capture_device_factory_mac.mm', 'video/capture/mac/video_capture_device_mac.h', 'video/capture/mac/video_capture_device_mac.mm', 'video/capture/mac/video_capture_device_qtkit_mac.h', @@ -1063,6 +1065,7 @@ 'midi/usb_midi_descriptor_parser_unittest.cc', 'midi/usb_midi_input_stream_unittest.cc', 'midi/usb_midi_output_stream_unittest.cc', + 'video/capture/fake_video_capture_device_unittest.cc', 'video/capture/video_capture_device_unittest.cc', 'formats/common/offset_byte_queue_unittest.cc', 'formats/webm/cluster_builder.cc', @@ -1193,6 +1196,11 @@ ['OS=="win" and target_arch=="x64"', { 'msvs_disabled_warnings': [ 4267, ], }], + ['OS=="mac"', { + 'sources': [ + 'video/capture/mac/video_capture_device_factory_mac_unittest.mm', + ] + }], ], }, { diff --git a/media/video/capture/fake_video_capture_device_unittest.cc b/media/video/capture/fake_video_capture_device_unittest.cc new file mode 100644 index 0000000..9bbbe67 --- /dev/null +++ b/media/video/capture/fake_video_capture_device_unittest.cc @@ -0,0 +1,180 @@ +// Copyright 2014 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. + +#include "base/bind.h" +#include "base/memory/scoped_ptr.h" +#include "base/run_loop.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/fake_video_capture_device_factory.h" +#include "media/video/capture/video_capture_device.h" +#include "media/video/capture/video_capture_types.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; + +namespace media { + +class MockClient : public media::VideoCaptureDevice::Client { + public: + MOCK_METHOD2(ReserveOutputBuffer, + scoped_refptr<Buffer>(media::VideoFrame::Format format, + const gfx::Size& dimensions)); + MOCK_METHOD0(OnErr, void()); + + explicit MockClient(base::Callback<void(const VideoCaptureFormat&)> frame_cb) + : main_thread_(base::MessageLoopProxy::current()), frame_cb_(frame_cb) {} + + virtual void OnError(const std::string& error_message) OVERRIDE { + OnErr(); + } + + 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 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::SingleThreadTaskRunner> main_thread_; + base::Callback<void(const VideoCaptureFormat&)> frame_cb_; +}; + +class FakeVideoCaptureDeviceTest : public testing::Test { + protected: + typedef media::VideoCaptureDevice::Client Client; + + FakeVideoCaptureDeviceTest() + : loop_(new base::MessageLoop()), + client_(new MockClient( + base::Bind(&FakeVideoCaptureDeviceTest::OnFrameCaptured, + base::Unretained(this)))), + video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {} + + virtual void SetUp() { + } + + void OnFrameCaptured(const VideoCaptureFormat& format) { + last_format_ = format; + run_loop_->QuitClosure().Run(); + } + + void WaitForCapturedFrame() { + run_loop_.reset(new base::RunLoop()); + run_loop_->Run(); + } + + const VideoCaptureFormat& last_format() const { return last_format_; } + + VideoCaptureDevice::Names names_; + scoped_ptr<base::MessageLoop> loop_; + scoped_ptr<base::RunLoop> run_loop_; + scoped_ptr<MockClient> client_; + VideoCaptureFormat last_format_; + scoped_ptr<VideoCaptureDeviceFactory> video_capture_device_factory_; +}; + +TEST_F(FakeVideoCaptureDeviceTest, Capture) { + VideoCaptureDevice::Names names; + + video_capture_device_factory_->GetDeviceNames(&names); + + ASSERT_GT(static_cast<int>(names.size()), 0); + + scoped_ptr<VideoCaptureDevice> device( + video_capture_device_factory_->Create(names.front())); + ASSERT_TRUE(device); + + 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(); +} + +TEST_F(FakeVideoCaptureDeviceTest, GetDeviceSupportedFormats) { + VideoCaptureDevice::Names names; + video_capture_device_factory_->GetDeviceNames(&names); + + VideoCaptureFormats supported_formats; + VideoCaptureDevice::Names::iterator names_iterator; + + for (names_iterator = names.begin(); names_iterator != names.end(); + ++names_iterator) { + video_capture_device_factory_->GetDeviceSupportedFormats( + *names_iterator, &supported_formats); + EXPECT_EQ(supported_formats.size(), 3u); + EXPECT_EQ(supported_formats[0].frame_size.width(), 320); + EXPECT_EQ(supported_formats[0].frame_size.height(), 240); + 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(), 640); + EXPECT_EQ(supported_formats[1].frame_size.height(), 480); + EXPECT_EQ(supported_formats[1].pixel_format, media::PIXEL_FORMAT_I420); + EXPECT_GE(supported_formats[1].frame_rate, 20); + EXPECT_EQ(supported_formats[2].frame_size.width(), 1280); + EXPECT_EQ(supported_formats[2].frame_size.height(), 720); + EXPECT_EQ(supported_formats[2].pixel_format, media::PIXEL_FORMAT_I420); + EXPECT_GE(supported_formats[2].frame_rate, 20); + } +} + +TEST_F(FakeVideoCaptureDeviceTest, CaptureVariableResolution) { + VideoCaptureDevice::Names names; + + video_capture_device_factory_->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( + video_capture_device_factory_->Create(names.front())); + ASSERT_TRUE(device); + + // Configure the FakeVideoCaptureDevice to use all its formats as roster. + VideoCaptureFormats formats; + video_capture_device_factory_->GetDeviceSupportedFormats(names.front(), + &formats); + static_cast<FakeVideoCaptureDevice*>(device.get())-> + PopulateVariableFormatsRoster(formats); + + 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(); +} + +}; // namespace media diff --git a/media/video/capture/mac/video_capture_device_factory_mac.h b/media/video/capture/mac/video_capture_device_factory_mac.h new file mode 100644 index 0000000..a581925 --- /dev/null +++ b/media/video/capture/mac/video_capture_device_factory_mac.h @@ -0,0 +1,34 @@ +// Copyright 2014 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. + +// Implementation of a VideoCaptureDeviceFactory class for Mac. + +#ifndef MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_MAC_H_ +#define MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_MAC_H_ + +#include "media/video/capture/video_capture_device_factory.h" + +namespace media { + +// Extension of VideoCaptureDeviceFactory to create and manipulate Mac devices. +class MEDIA_EXPORT VideoCaptureDeviceFactoryMac : + public VideoCaptureDeviceFactory { + public: + VideoCaptureDeviceFactoryMac(); + virtual ~VideoCaptureDeviceFactoryMac() {} + + virtual scoped_ptr<VideoCaptureDevice> Create( + const VideoCaptureDevice::Name& device_name) OVERRIDE; + virtual void GetDeviceNames(VideoCaptureDevice::Names* device_names) OVERRIDE; + virtual void GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceFactoryMac); +}; + +} // namespace media + +#endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_MAC_H_ diff --git a/media/video/capture/mac/video_capture_device_factory_mac.mm b/media/video/capture/mac/video_capture_device_factory_mac.mm new file mode 100644 index 0000000..0e24203 --- /dev/null +++ b/media/video/capture/mac/video_capture_device_factory_mac.mm @@ -0,0 +1,125 @@ +// Copyright 2014 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. + +#include "media/video/capture/mac/video_capture_device_factory_mac.h" + +#import "media/video/capture/mac/avfoundation_glue.h" +#include "media/video/capture/mac/video_capture_device_mac.h" +#import "media/video/capture/mac/video_capture_device_avfoundation_mac.h" +#import "media/video/capture/mac/video_capture_device_qtkit_mac.h" + +namespace media { + +// Some devices are not correctly supported in AVFoundation, f.i. Blackmagic, +// see http://crbug.com/347371. The devices are identified by USB Vendor ID and +// by a characteristic substring of the name, usually the vendor's name. +const struct NameAndVid { + const char* vid; + const char* name; +} kBlacklistedCameras[] = { { "a82c", "Blackmagic" } }; + +// In device identifiers, the USB VID and PID are stored in 4 bytes each. +const size_t kVidPidSize = 4; + +VideoCaptureDeviceFactoryMac::VideoCaptureDeviceFactoryMac() { + thread_checker_.DetachFromThread(); +} + +scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryMac::Create( + const VideoCaptureDevice::Name& device_name) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_NE(device_name.capture_api_type(), + VideoCaptureDevice::Name::API_TYPE_UNKNOWN); + + VideoCaptureDevice::Names device_names; + GetDeviceNames(&device_names); + VideoCaptureDevice::Names::iterator it = device_names.begin(); + for (; it != device_names.end(); ++it) { + if (it->id() == device_name.id()) + break; + } + if (it == device_names.end()) + return scoped_ptr<VideoCaptureDevice>(); + + scoped_ptr<VideoCaptureDeviceMac> capture_device( + new VideoCaptureDeviceMac(device_name)); + if (!capture_device->Init(device_name.capture_api_type())) { + LOG(ERROR) << "Could not initialize VideoCaptureDevice."; + capture_device.reset(); + } + return scoped_ptr<VideoCaptureDevice>(capture_device.Pass()); +} + +void VideoCaptureDeviceFactoryMac::GetDeviceNames( + VideoCaptureDevice::Names* const device_names) { + DCHECK(thread_checker_.CalledOnValidThread()); + // Loop through all available devices and add to |device_names|. + NSDictionary* capture_devices; + if (AVFoundationGlue::IsAVFoundationSupported()) { + bool is_any_device_blacklisted = false; + DVLOG(1) << "Enumerating video capture devices using AVFoundation"; + capture_devices = [VideoCaptureDeviceAVFoundation deviceNames]; + std::string device_vid; + // Enumerate all devices found by AVFoundation, translate the info for each + // to class Name and add it to |device_names|. + for (NSString* key in capture_devices) { + VideoCaptureDevice::Name name( + [[capture_devices valueForKey:key] UTF8String], + [key UTF8String], VideoCaptureDevice::Name::AVFOUNDATION); + device_names->push_back(name); + // Extract the device's Vendor ID and compare to all blacklisted ones. + device_vid = name.GetModel().substr(0, kVidPidSize); + for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { + is_any_device_blacklisted |= + !strcasecmp(device_vid.c_str(), kBlacklistedCameras[i].vid); + if (is_any_device_blacklisted) + break; + } + } + // If there is any device blacklisted in the system, walk the QTKit device + // list and add those devices with a blacklisted name to the |device_names|. + // AVFoundation and QTKit device lists partially overlap, so add a "QTKit" + // prefix to the latter ones to distinguish them from the AVFoundation ones. + if (is_any_device_blacklisted) { + capture_devices = [VideoCaptureDeviceQTKit deviceNames]; + for (NSString* key in capture_devices) { + NSString* device_name = [capture_devices valueForKey:key]; + for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { + if ([device_name rangeOfString:@(kBlacklistedCameras[i].name) + options:NSCaseInsensitiveSearch].length != 0) { + DVLOG(1) << "Enumerated blacklisted " << [device_name UTF8String]; + VideoCaptureDevice::Name name( + "QTKit " + std::string([device_name UTF8String]), + [key UTF8String], VideoCaptureDevice::Name::QTKIT); + device_names->push_back(name); + } + } + } + } + } else { + DVLOG(1) << "Enumerating video capture devices using QTKit"; + capture_devices = [VideoCaptureDeviceQTKit deviceNames]; + for (NSString* key in capture_devices) { + VideoCaptureDevice::Name name( + [[capture_devices valueForKey:key] UTF8String], + [key UTF8String], VideoCaptureDevice::Name::QTKIT); + device_names->push_back(name); + } + } +} + +void VideoCaptureDeviceFactoryMac::GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (device.capture_api_type() == VideoCaptureDevice::Name::AVFOUNDATION) { + DVLOG(1) << "Enumerating video capture capabilities, AVFoundation"; + [VideoCaptureDeviceAVFoundation getDevice:device + supportedFormats:supported_formats]; + } else { + NOTIMPLEMENTED(); + } +} + +} // namespace media diff --git a/media/video/capture/mac/video_capture_device_factory_mac_unittest.mm b/media/video/capture/mac/video_capture_device_factory_mac_unittest.mm new file mode 100644 index 0000000..6aa23a9 --- /dev/null +++ b/media/video/capture/mac/video_capture_device_factory_mac_unittest.mm @@ -0,0 +1,42 @@ +// Copyright 2014 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. + +#include "base/command_line.h" +#include "media/base/media_switches.h" +#import "media/video/capture/mac/avfoundation_glue.h" +#include "media/video/capture/mac/video_capture_device_factory_mac.h" +#include "media/video/capture/mac/video_capture_device_mac.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { + +class VideoCaptureDeviceFactoryMacTest : public testing::Test { + virtual void SetUp() { + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kEnableAVFoundation); + } +}; + +TEST_F(VideoCaptureDeviceFactoryMacTest, ListDevicesAVFoundation) { + if (!AVFoundationGlue::IsAVFoundationSupported()) { + DVLOG(1) << "AVFoundation not supported, skipping test."; + return; + } + VideoCaptureDeviceFactoryMac video_capture_device_factory; + + VideoCaptureDevice::Names names; + video_capture_device_factory.GetDeviceNames(&names); + if (!names.size()) { + DVLOG(1) << "No camera available. Exiting test."; + return; + } + // There should be no blacklisted devices, i.e. QTKit. + std::string device_vid; + for (VideoCaptureDevice::Names::const_iterator it = names.begin(); + it != names.end(); ++it) { + EXPECT_EQ(it->capture_api_type(), VideoCaptureDevice::Name::AVFOUNDATION); + } +} + +}; // namespace media diff --git a/media/video/capture/mac/video_capture_device_mac.h b/media/video/capture/mac/video_capture_device_mac.h index 3b12d83..b28dacb 100644 --- a/media/video/capture/mac/video_capture_device_mac.h +++ b/media/video/capture/mac/video_capture_device_mac.h @@ -3,8 +3,9 @@ // found in the LICENSE file. // MacOSX implementation of generic VideoCaptureDevice, using either QTKit or -// AVFoundation as native capture API. QTKit is used in OSX versions 10.6 and -// previous, and AVFoundation is used in the rest. +// AVFoundation as native capture API. QTKit is available in all OSX versions, +// although namely deprecated in 10.9, and AVFoundation is available in versions +// 10.7 (Lion) and later. #ifndef MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_ #define MEDIA_VIDEO_CAPTURE_MAC_VIDEO_CAPTURE_DEVICE_MAC_H_ @@ -25,20 +26,20 @@ class SingleThreadTaskRunner; namespace media { -// Called by VideoCaptureManager to open, close and start, stop video capture -// devices. +// Called by VideoCaptureManager to open, close and start, stop Mac video +// capture devices. class VideoCaptureDeviceMac : public VideoCaptureDevice { public: explicit VideoCaptureDeviceMac(const Name& device_name); virtual ~VideoCaptureDeviceMac(); // VideoCaptureDevice implementation. - virtual void AllocateAndStart(const VideoCaptureParams& params, - scoped_ptr<VideoCaptureDevice::Client> client) - OVERRIDE; + virtual void AllocateAndStart( + const VideoCaptureParams& params, + scoped_ptr<VideoCaptureDevice::Client> client) OVERRIDE; virtual void StopAndDeAllocate() OVERRIDE; - bool Init(); + bool Init(VideoCaptureDevice::Name::CaptureApiType capture_api_type); // Called to deliver captured video frames. void ReceiveFrame(const uint8* video_frame, diff --git a/media/video/capture/mac/video_capture_device_mac.mm b/media/video/capture/mac/video_capture_device_mac.mm index bc3d541..5aacd26 100644 --- a/media/video/capture/mac/video_capture_device_mac.mm +++ b/media/video/capture/mac/video_capture_device_mac.mm @@ -22,14 +22,6 @@ const int kMaxFrameRate = 30; // In device identifiers, the USB VID and PID are stored in 4 bytes each. const size_t kVidPidSize = 4; -// Some devices are not correctly supported in AVFoundation, f.i. Blackmagic, -// see http://crbug.com/347371. The devices are identified by USB Vendor ID and -// by a characteristic substring of the name, usually the vendor's name. -const struct NameAndVid { - const char* vid; - const char* name; -} kBlacklistedCameras[] = { { "a82c", "Blackmagic" } }; - const struct Resolution { const int width; const int height; @@ -69,70 +61,26 @@ void GetBestMatchSupportedResolution(int* width, int* height) { *height = matched_height; } -//static +// TODO(mcasas): Remove the following static methods when they are no longer +// referenced from VideoCaptureDeviceFactory, i.e. when all OS platforms have +// splitted the VideoCaptureDevice into VideoCaptureDevice and +// VideoCaptureDeviceFactory. + +// static +VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { + NOTREACHED(); + return NULL; +} +// static void VideoCaptureDevice::GetDeviceNames(Names* device_names) { - // Loop through all available devices and add to |device_names|. - NSDictionary* capture_devices; - if (AVFoundationGlue::IsAVFoundationSupported()) { - bool is_any_device_blacklisted = false; - DVLOG(1) << "Enumerating video capture devices using AVFoundation"; - capture_devices = [VideoCaptureDeviceAVFoundation deviceNames]; - std::string device_vid; - // Enumerate all devices found by AVFoundation, translate the info for each - // to class Name and add it to |device_names|. - for (NSString* key in capture_devices) { - Name name([[capture_devices valueForKey:key] UTF8String], - [key UTF8String], Name::AVFOUNDATION); - device_names->push_back(name); - // Extract the device's Vendor ID and compare to all blacklisted ones. - device_vid = name.GetModel().substr(0, kVidPidSize); - for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { - is_any_device_blacklisted |= - !strcasecmp(device_vid.c_str(), kBlacklistedCameras[i].vid); - if (is_any_device_blacklisted) - break; - } - } - // If there is any device blacklisted in the system, walk the QTKit device - // list and add those devices with a blacklisted name to the |device_names|. - // AVFoundation and QTKit device lists partially overlap, so add a "QTKit" - // prefix to the latter ones to distinguish them from the AVFoundation ones. - if (is_any_device_blacklisted) { - capture_devices = [VideoCaptureDeviceQTKit deviceNames]; - for (NSString* key in capture_devices) { - NSString* device_name = [capture_devices valueForKey:key]; - for (size_t i = 0; i < arraysize(kBlacklistedCameras); ++i) { - if ([device_name rangeOfString:@(kBlacklistedCameras[i].name) - options:NSCaseInsensitiveSearch].length != 0) { - DVLOG(1) << "Enumerated blacklisted " << [device_name UTF8String]; - Name name("QTKit " + std::string([device_name UTF8String]), - [key UTF8String], Name::QTKIT); - device_names->push_back(name); - } - } - } - } - } else { - DVLOG(1) << "Enumerating video capture devices using QTKit"; - capture_devices = [VideoCaptureDeviceQTKit deviceNames]; - for (NSString* key in capture_devices) { - Name name([[capture_devices valueForKey:key] UTF8String], - [key UTF8String], Name::QTKIT); - device_names->push_back(name); - } - } + NOTREACHED(); } // static -void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device, - VideoCaptureFormats* formats) { - if (device.capture_api_type() == Name::AVFOUNDATION) { - DVLOG(1) << "Enumerating video capture capabilities, AVFoundation"; - [VideoCaptureDeviceAVFoundation getDevice:device - supportedFormats:formats]; - } else { - NOTIMPLEMENTED(); - } +void VideoCaptureDevice::GetDeviceSupportedFormats( + const Name& device, + VideoCaptureFormats* supported_formats) { + NOTREACHED(); } const std::string VideoCaptureDevice::Name::GetModel() const { @@ -150,17 +98,6 @@ const std::string VideoCaptureDevice::Name::GetModel() const { return id_vendor + ":" + id_product; } -VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { - VideoCaptureDeviceMac* capture_device = - new VideoCaptureDeviceMac(device_name); - if (!capture_device->Init()) { - LOG(ERROR) << "Could not initialize VideoCaptureDevice."; - delete capture_device; - capture_device = NULL; - } - return capture_device; -} - VideoCaptureDeviceMac::VideoCaptureDeviceMac(const Name& device_name) : device_name_(device_name), tried_to_square_pixels_(false), @@ -244,25 +181,12 @@ void VideoCaptureDeviceMac::StopAndDeAllocate() { tried_to_square_pixels_ = false; } -bool VideoCaptureDeviceMac::Init() { +bool VideoCaptureDeviceMac::Init( + VideoCaptureDevice::Name::CaptureApiType capture_api_type) { DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK_EQ(state_, kNotInitialized); - // TODO(mcasas): The following check might not be necessary; if the device has - // disappeared after enumeration and before coming here, opening would just - // fail but not necessarily produce a crash. - Names device_names; - GetDeviceNames(&device_names); - Names::iterator it = device_names.begin(); - for (; it != device_names.end(); ++it) { - if (it->id() == device_name_.id()) - break; - } - if (it == device_names.end()) - return false; - - DCHECK_NE(it->capture_api_type(), Name::API_TYPE_UNKNOWN); - if (it->capture_api_type() == Name::AVFOUNDATION) { + if (capture_api_type == Name::AVFOUNDATION) { capture_device_ = [[VideoCaptureDeviceAVFoundation alloc] initWithFrameReceiver:this]; } else { diff --git a/media/video/capture/video_capture_device_factory.cc b/media/video/capture/video_capture_device_factory.cc index e63225d..661900c 100644 --- a/media/video/capture/video_capture_device_factory.cc +++ b/media/video/capture/video_capture_device_factory.cc @@ -4,11 +4,47 @@ #include "media/video/capture/video_capture_device_factory.h" +#include "base/command_line.h" +#include "media/base/media_switches.h" +#include "media/video/capture/fake_video_capture_device_factory.h" +#include "media/video/capture/file_video_capture_device_factory.h" + +#if defined(OS_MACOSX) +#include "media/video/capture/mac/video_capture_device_factory_mac.h" +#endif + namespace media { +// static +scoped_ptr<VideoCaptureDeviceFactory> + VideoCaptureDeviceFactory::CreateFactory() { + const CommandLine* command_line = CommandLine::ForCurrentProcess(); + // Use a Fake or File Video Device Factory if the command line flags are + // present, otherwise use the normal, platform-dependent, device factory. + if (command_line->HasSwitch(switches::kUseFakeDeviceForMediaStream)) { + if (command_line->HasSwitch(switches::kUseFileForFakeVideoCapture)) { + return scoped_ptr<VideoCaptureDeviceFactory>(new + media::FileVideoCaptureDeviceFactory()); + } else { + return scoped_ptr<VideoCaptureDeviceFactory>(new + media::FakeVideoCaptureDeviceFactory()); + } + } else { +#if defined(OS_MACOSX) + return scoped_ptr<VideoCaptureDeviceFactory>(new + VideoCaptureDeviceFactoryMac()); +#else + return scoped_ptr<VideoCaptureDeviceFactory>(new + VideoCaptureDeviceFactory()); +#endif + } +} + VideoCaptureDeviceFactory::VideoCaptureDeviceFactory() { thread_checker_.DetachFromThread(); -}; +} + +VideoCaptureDeviceFactory::~VideoCaptureDeviceFactory() {} scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactory::Create( const VideoCaptureDevice::Name& device_name) { diff --git a/media/video/capture/video_capture_device_factory.h b/media/video/capture/video_capture_device_factory.h index ab58ad6..4a19e83 100644 --- a/media/video/capture/video_capture_device_factory.h +++ b/media/video/capture/video_capture_device_factory.h @@ -16,8 +16,10 @@ namespace media { // in Device Thread (a.k.a. Audio Thread). class MEDIA_EXPORT VideoCaptureDeviceFactory { public: + static scoped_ptr<VideoCaptureDeviceFactory> CreateFactory(); + VideoCaptureDeviceFactory(); - virtual ~VideoCaptureDeviceFactory() {} + virtual ~VideoCaptureDeviceFactory(); // Creates a VideoCaptureDevice object. Returns NULL if something goes wrong. virtual scoped_ptr<VideoCaptureDevice> Create( diff --git a/media/video/capture/video_capture_device_unittest.cc b/media/video/capture/video_capture_device_unittest.cc index f079a1f..e897d20 100644 --- a/media/video/capture/video_capture_device_unittest.cc +++ b/media/video/capture/video_capture_device_unittest.cc @@ -3,15 +3,12 @@ // found in the LICENSE file. #include "base/bind.h" -#include "base/bind_helpers.h" #include "base/memory/scoped_ptr.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/fake_video_capture_device_factory.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" @@ -53,11 +50,6 @@ #define MAYBE_CaptureMjpeg CaptureMjpeg #endif -using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Return; -using ::testing::AtLeast; - namespace media { class MockClient : public media::VideoCaptureDevice::Client { @@ -104,7 +96,8 @@ class VideoCaptureDeviceTest : public testing::Test { client_( new MockClient(base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, base::Unretained(this)))), - video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {} + video_capture_device_factory_( + VideoCaptureDeviceFactory::CreateFactory()) {} virtual void SetUp() { #if defined(OS_ANDROID) @@ -132,7 +125,7 @@ class VideoCaptureDeviceTest : public testing::Test { scoped_ptr<VideoCaptureDevice::Name> GetFirstDeviceNameSupportingPixelFormat( const VideoPixelFormat& pixel_format) { - VideoCaptureDevice::GetDeviceNames(&names_); + video_capture_device_factory_->GetDeviceNames(&names_); if (!names_.size()) { DVLOG(1) << "No camera available."; return scoped_ptr<VideoCaptureDevice::Name>(); @@ -141,8 +134,9 @@ class VideoCaptureDeviceTest : public testing::Test { for (names_iterator = names_.begin(); names_iterator != names_.end(); ++names_iterator) { VideoCaptureFormats supported_formats; - VideoCaptureDevice::GetDeviceSupportedFormats(*names_iterator, - &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) { @@ -174,22 +168,26 @@ TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) { ? 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", + VideoCaptureDevice::Name::AVFOUNDATION); #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); EXPECT_TRUE(device == NULL); } TEST_F(VideoCaptureDeviceTest, CaptureVGA) { - VideoCaptureDevice::GetDeviceNames(&names_); + video_capture_device_factory_->GetDeviceNames(&names_); if (!names_.size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); + video_capture_device_factory_->Create(names_.front())); ASSERT_TRUE(device); DVLOG(1) << names_.front().id(); @@ -210,14 +208,14 @@ TEST_F(VideoCaptureDeviceTest, CaptureVGA) { } TEST_F(VideoCaptureDeviceTest, Capture720p) { - VideoCaptureDevice::GetDeviceNames(&names_); + video_capture_device_factory_->GetDeviceNames(&names_); if (!names_.size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); + video_capture_device_factory_->Create(names_.front())); ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) @@ -235,13 +233,13 @@ TEST_F(VideoCaptureDeviceTest, Capture720p) { } TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { - VideoCaptureDevice::GetDeviceNames(&names_); + video_capture_device_factory_->GetDeviceNames(&names_); if (!names_.size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); + video_capture_device_factory_->Create(names_.front())); ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) @@ -260,7 +258,7 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { } TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) { - VideoCaptureDevice::GetDeviceNames(&names_); + video_capture_device_factory_->GetDeviceNames(&names_); if (!names_.size()) { DVLOG(1) << "No camera available. Exiting test."; return; @@ -270,7 +268,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); @@ -295,7 +293,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(); @@ -306,13 +304,13 @@ TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) { } TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { - VideoCaptureDevice::GetDeviceNames(&names_); + video_capture_device_factory_->GetDeviceNames(&names_); if (!names_.size()) { DVLOG(1) << "No camera available. Exiting test."; return; } scoped_ptr<VideoCaptureDevice> device( - VideoCaptureDevice::Create(names_.front())); + video_capture_device_factory_->Create(names_.front())); ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) @@ -332,33 +330,6 @@ TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { device->StopAndDeAllocate(); } -TEST_F(VideoCaptureDeviceTest, FakeCapture) { - VideoCaptureDevice::Names names; - - video_capture_device_factory_->GetDeviceNames(&names); - - ASSERT_GT(static_cast<int>(names.size()), 0); - - scoped_ptr<VideoCaptureDevice> device( - video_capture_device_factory_->Create(names.front())); - ASSERT_TRUE(device); - - 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) { scoped_ptr<VideoCaptureDevice::Name> name = @@ -367,7 +338,8 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { DVLOG(1) << "No camera supports MJPEG format. Exiting test."; return; } - scoped_ptr<VideoCaptureDevice> device(VideoCaptureDevice::Create(*name)); + scoped_ptr<VideoCaptureDevice> device( + video_capture_device_factory_->Create(*name)); ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) @@ -397,68 +369,4 @@ TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) { ASSERT_FALSE(name); } -TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) { - VideoCaptureDevice::Names names; - - video_capture_device_factory_->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( - video_capture_device_factory_->Create(names.front())); - ASSERT_TRUE(device); - - // Configure the FakeVideoCaptureDevice to use all its formats as roster. - VideoCaptureFormats formats; - video_capture_device_factory_->GetDeviceSupportedFormats(names.front(), - &formats); - static_cast<FakeVideoCaptureDevice*>(device.get())-> - PopulateVariableFormatsRoster(formats); - - 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; - video_capture_device_factory_->GetDeviceNames(&names); - - VideoCaptureFormats supported_formats; - VideoCaptureDevice::Names::iterator names_iterator; - - for (names_iterator = names.begin(); names_iterator != names.end(); - ++names_iterator) { - video_capture_device_factory_->GetDeviceSupportedFormats( - *names_iterator, &supported_formats); - EXPECT_EQ(supported_formats.size(), 3u); - EXPECT_EQ(supported_formats[0].frame_size.width(), 320); - EXPECT_EQ(supported_formats[0].frame_size.height(), 240); - 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(), 640); - EXPECT_EQ(supported_formats[1].frame_size.height(), 480); - EXPECT_EQ(supported_formats[1].pixel_format, media::PIXEL_FORMAT_I420); - EXPECT_GE(supported_formats[1].frame_rate, 20); - EXPECT_EQ(supported_formats[2].frame_size.width(), 1280); - EXPECT_EQ(supported_formats[2].frame_size.height(), 720); - EXPECT_EQ(supported_formats[2].pixel_format, media::PIXEL_FORMAT_I420); - EXPECT_GE(supported_formats[2].frame_rate, 20); - } -} - }; // namespace media |