summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 13:53:32 +0000
committermcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-09 13:53:32 +0000
commit4669e6887f7c5d95e0c5f9a5346bd29fba0954ca (patch)
treee6868ecf6a2e6b91d591f3f884f4f9a939ccdba5
parentf6c52338609c76cf8b7b68fafd27834e48d10f90 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/apps/speech_recognition_browsertest.cc1
-rw-r--r--chrome/browser/apps/web_view_browsertest.cc1
-rw-r--r--chrome/browser/media/chrome_media_stream_infobar_browsertest.cc1
-rw-r--r--chrome/browser/media/chrome_webrtc_audio_quality_browsertest.cc1
-rw-r--r--chrome/browser/media/chrome_webrtc_disable_encryption_flag_browsertest.cc1
-rw-r--r--chrome/test/ppapi/ppapi_test.cc1
-rw-r--r--content/browser/media/webrtc_browsertest.cc1
-rw-r--r--content/browser/media/webrtc_internals_browsertest.cc1
-rw-r--r--content/browser/renderer_host/media/audio_renderer_host_unittest.cc1
-rw-r--r--content/browser/renderer_host/media/media_stream_dispatcher_host_unittest.cc1
-rw-r--r--content/browser/renderer_host/media/media_stream_manager.cc24
-rw-r--r--content/browser/renderer_host/media/media_stream_manager_unittest.cc1
-rw-r--r--content/browser/renderer_host/media/video_capture_host_unittest.cc1
-rw-r--r--content/public/common/content_switches.cc3
-rw-r--r--content/public/common/content_switches.h1
-rw-r--r--content/shell/DEPS3
-rw-r--r--content/shell/android/browsertests_apk/content_browser_tests_android.cc1
-rw-r--r--content/test/content_test_launcher.cc1
-rw-r--r--content/test/webrtc_content_browsertest_base.cc1
-rw-r--r--media/base/media_switches.cc4
-rw-r--r--media/base/media_switches.h1
-rw-r--r--media/media.gyp10
-rw-r--r--media/video/capture/fake_video_capture_device_unittest.cc180
-rw-r--r--media/video/capture/mac/video_capture_device_factory_mac.h34
-rw-r--r--media/video/capture/mac/video_capture_device_factory_mac.mm125
-rw-r--r--media/video/capture/mac/video_capture_device_factory_mac_unittest.mm42
-rw-r--r--media/video/capture/mac/video_capture_device_mac.h17
-rw-r--r--media/video/capture/mac/video_capture_device_mac.mm114
-rw-r--r--media/video/capture/video_capture_device_factory.cc38
-rw-r--r--media/video/capture/video_capture_device_factory.h4
-rw-r--r--media/video/capture/video_capture_device_unittest.cc142
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