diff options
author | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-26 22:15:48 +0000 |
---|---|---|
committer | mcasas@chromium.org <mcasas@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-26 22:15:48 +0000 |
commit | 1eb3690e43b267aab781ca1d02633f31a75a56e4 (patch) | |
tree | ff40709066caaef9ce9a2a841797835c3d817318 /media | |
parent | 819c834ea60f3d9b0e069c6c9e794b274b5bafd8 (diff) | |
download | chromium_src-1eb3690e43b267aab781ca1d02633f31a75a56e4.zip chromium_src-1eb3690e43b267aab781ca1d02633f31a75a56e4.tar.gz chromium_src-1eb3690e43b267aab781ca1d02633f31a75a56e4.tar.bz2 |
Extract VideoCaptureDeviceFactory out of VideoCaptureDevice and use for File and FakeVCD.
VideoCaptureDeviceFactory is owned by VideoCaptureManager.
VideoCaptureManager gets a VCDF on construction. This
can be a real devices factory or a test one (Fake/File).
All VCM operations previously static are now made
through the Factory API regardless of the type.
The previous MSM::UseFakeDevice() disappears and
unittests MediaStreamDispatcherHostTest,
MediaStreamManagerTest, VideoCaptureHostTest,
add the --use-fake-device-for-media-stream flag
to command line and depend on MSM reacting to it
via injecting a fake factory to VCM on creation.
Those tests also retrieve a weak reference to the
Fake Factory to manipulate it.
FakeVideoCapture::SetFailNextCreate() and associated
member are removed, unused.
BUG= 323913
Review URL: https://codereview.chromium.org/235353002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266380 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/media.gyp | 6 | ||||
-rw-r--r-- | media/video/capture/fake_video_capture_device.cc | 85 | ||||
-rw-r--r-- | media/video/capture/fake_video_capture_device.h | 39 | ||||
-rw-r--r-- | media/video/capture/fake_video_capture_device_factory.cc | 51 | ||||
-rw-r--r-- | media/video/capture/fake_video_capture_device_factory.h | 44 | ||||
-rw-r--r-- | media/video/capture/file_video_capture_device.cc | 54 | ||||
-rw-r--r-- | media/video/capture/file_video_capture_device.h | 18 | ||||
-rw-r--r-- | media/video/capture/file_video_capture_device_factory.cc | 64 | ||||
-rw-r--r-- | media/video/capture/file_video_capture_device_factory.h | 31 | ||||
-rw-r--r-- | media/video/capture/video_capture_device_factory.cc | 33 | ||||
-rw-r--r-- | media/video/capture/video_capture_device_factory.h | 46 | ||||
-rw-r--r-- | media/video/capture/video_capture_device_unittest.cc | 28 |
12 files changed, 329 insertions, 170 deletions
diff --git a/media/media.gyp b/media/media.gyp index 420e6fe..c0a4aa4 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -460,8 +460,12 @@ 'video/capture/android/video_capture_device_factory_android.h', 'video/capture/fake_video_capture_device.cc', 'video/capture/fake_video_capture_device.h', + 'video/capture/fake_video_capture_device_factory.h', + 'video/capture/fake_video_capture_device_factory.cc', 'video/capture/file_video_capture_device.cc', 'video/capture/file_video_capture_device.h', + 'video/capture/file_video_capture_device_factory.h', + 'video/capture/file_video_capture_device_factory.cc', 'video/capture/linux/video_capture_device_linux.cc', 'video/capture/linux/video_capture_device_linux.h', 'video/capture/mac/avfoundation_glue.h', @@ -478,6 +482,8 @@ 'video/capture/video_capture.h', 'video/capture/video_capture_device.cc', 'video/capture/video_capture_device.h', + 'video/capture/video_capture_device_factory.cc', + 'video/capture/video_capture_device_factory.h', 'video/capture/video_capture_proxy.cc', 'video/capture/video_capture_proxy.h', 'video/capture/video_capture_types.cc', diff --git a/media/video/capture/fake_video_capture_device.cc b/media/video/capture/fake_video_capture_device.cc index 68dc912..302396a 100644 --- a/media/video/capture/fake_video_capture_device.cc +++ b/media/video/capture/fake_video_capture_device.cc @@ -17,77 +17,8 @@ namespace media { -static const int kFakeCaptureTimeoutMs = 50; static const int kFakeCaptureBeepCycle = 10; // Visual beep every 0.5s. static const int kFakeCaptureCapabilityChangePeriod = 30; -enum { kNumberOfFakeDevices = 2 }; - -bool FakeVideoCaptureDevice::fail_next_create_ = false; -base::subtle::Atomic32 FakeVideoCaptureDevice::number_of_devices_ = - kNumberOfFakeDevices; - -// static -size_t FakeVideoCaptureDevice::NumberOfFakeDevices(void) { - return number_of_devices_; -} - -// static -void FakeVideoCaptureDevice::GetDeviceNames(Names* const device_names) { - // Empty the name list. - device_names->erase(device_names->begin(), device_names->end()); - - int number_of_devices = base::subtle::NoBarrier_Load(&number_of_devices_); - for (int32 n = 0; n < number_of_devices; n++) { - Name name(base::StringPrintf("fake_device_%d", n), - base::StringPrintf("/dev/video%d", n)); - device_names->push_back(name); - } -} - -// static -void FakeVideoCaptureDevice::GetDeviceSupportedFormats( - const Name& device, - VideoCaptureFormats* supported_formats) { - - const size_t supported_sizes_length = 3; - const gfx::Size supported_sizes[] = {gfx::Size(320, 240), - gfx::Size(640, 480), - gfx::Size(1280, 720)}; - int frame_rate = 1000 / kFakeCaptureTimeoutMs; - supported_formats->clear(); - for (size_t i=0; i < supported_sizes_length; ++i) { - supported_formats->push_back(VideoCaptureFormat(supported_sizes[i], - frame_rate, - media::PIXEL_FORMAT_I420)); - } -} - -// static -VideoCaptureDevice* FakeVideoCaptureDevice::Create(const Name& device_name) { - if (fail_next_create_) { - fail_next_create_ = false; - return NULL; - } - int number_of_devices = base::subtle::NoBarrier_Load(&number_of_devices_); - for (int32 n = 0; n < number_of_devices; ++n) { - std::string possible_id = base::StringPrintf("/dev/video%d", n); - if (device_name.id().compare(possible_id) == 0) { - return new FakeVideoCaptureDevice(); - } - } - return NULL; -} - -// static -void FakeVideoCaptureDevice::SetFailNextCreate() { - fail_next_create_ = true; -} - -// static -void FakeVideoCaptureDevice::SetNumberOfFakeDevices(size_t number_of_devices) { - base::subtle::NoBarrier_AtomicExchange(&number_of_devices_, - number_of_devices); -} FakeVideoCaptureDevice::FakeVideoCaptureDevice() : capture_thread_("CaptureThread"), @@ -124,6 +55,14 @@ void FakeVideoCaptureDevice::StopAndDeAllocate() { capture_thread_.Stop(); } +void FakeVideoCaptureDevice::PopulateVariableFormatsRoster( + const VideoCaptureFormats& formats) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!capture_thread_.IsRunning()); + format_roster_ = formats; + format_roster_index_ = 0; +} + void FakeVideoCaptureDevice::OnAllocateAndStart( const VideoCaptureParams& params, scoped_ptr<VideoCaptureDevice::Client> client) { @@ -142,8 +81,6 @@ void FakeVideoCaptureDevice::OnAllocateAndStart( capture_format_.frame_size.SetSize(640, 480); else capture_format_.frame_size.SetSize(320, 240); - if (params.allow_resolution_change) - PopulateFormatRoster(); const size_t fake_frame_size = VideoFrame::AllocationSize(VideoFrame::I420, capture_format_.frame_size); fake_frame_.reset(new uint8[fake_frame_size]); @@ -250,10 +187,4 @@ void FakeVideoCaptureDevice::Reallocate() { fake_frame_.reset(new uint8[fake_frame_size]); } -void FakeVideoCaptureDevice::PopulateFormatRoster() { - DCHECK_EQ(capture_thread_.message_loop(), base::MessageLoop::current()); - GetDeviceSupportedFormats(Name(), &format_roster_); - format_roster_index_ = 0; -} - } // namespace media diff --git a/media/video/capture/fake_video_capture_device.h b/media/video/capture/fake_video_capture_device.h index 399a682..96264e8 100644 --- a/media/video/capture/fake_video_capture_device.h +++ b/media/video/capture/fake_video_capture_device.h @@ -20,34 +20,29 @@ namespace media { class MEDIA_EXPORT FakeVideoCaptureDevice : public VideoCaptureDevice { public: - static VideoCaptureDevice* Create(const Name& device_name); - virtual ~FakeVideoCaptureDevice(); - // Used for testing. This will make sure the next call to Create will - // return NULL; - static void SetFailNextCreate(); - static void SetNumberOfFakeDevices(size_t number_of_devices); - static size_t NumberOfFakeDevices(); + static const int kFakeCaptureTimeoutMs = 50; - static void GetDeviceNames(Names* device_names); - static void GetDeviceSupportedFormats(const Name& device, - VideoCaptureFormats* supported_formats); + FakeVideoCaptureDevice(); + virtual ~FakeVideoCaptureDevice(); // 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; - private: - FakeVideoCaptureDevice(); + // Sets the formats to use sequentially when the device is configured as + // variable capture resolution. Works only before AllocateAndStart() or + // after StopAndDeallocate(). + void PopulateVariableFormatsRoster(const VideoCaptureFormats& formats); + private: // Called on the |capture_thread_| only. void OnAllocateAndStart(const VideoCaptureParams& params, scoped_ptr<Client> client); void OnStopAndDeAllocate(); void OnCaptureTask(); void Reallocate(); - void PopulateFormatRoster(); // |thread_checker_| is used to check that destructor, AllocateAndStart() and // StopAndDeAllocate() are called in the correct thread that owns the object. @@ -61,18 +56,12 @@ class MEDIA_EXPORT FakeVideoCaptureDevice : public VideoCaptureDevice { VideoCaptureFormat capture_format_; // When the device is allowed to change resolution, this vector holds the - // available ones which are used in sequence, restarting at the end. These - // two members belong to and are only used in |capture_thread_|. + // available ones, used sequentially restarting at the end. These two members + // are initialised in PopulateFormatRoster() before |capture_thread_| is + // running and are subsequently read-only in that thread. std::vector<VideoCaptureFormat> format_roster_; int format_roster_index_; - static bool fail_next_create_; - // |number_of_devices_| is atomic since tests can call SetNumberOfFakeDevices - // on the IO thread to set |number_of_devices_|. The variable can be - // read from a separate thread. - // TODO(perkj): Make tests independent of global state. crbug/323913 - static base::subtle::Atomic32 number_of_devices_; - DISALLOW_COPY_AND_ASSIGN(FakeVideoCaptureDevice); }; diff --git a/media/video/capture/fake_video_capture_device_factory.cc b/media/video/capture/fake_video_capture_device_factory.cc new file mode 100644 index 0000000..79e528f --- /dev/null +++ b/media/video/capture/fake_video_capture_device_factory.cc @@ -0,0 +1,51 @@ +// 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/fake_video_capture_device_factory.h" + +#include "base/strings/stringprintf.h" +#include "media/video/capture/fake_video_capture_device.h" + +namespace media { + +FakeVideoCaptureDeviceFactory::FakeVideoCaptureDeviceFactory() + : number_of_devices_(1) { +} + +scoped_ptr<VideoCaptureDevice> FakeVideoCaptureDeviceFactory::Create( + const VideoCaptureDevice::Name& device_name) { + for (int n = 0; n < number_of_devices_; ++n) { + std::string possible_id = base::StringPrintf("/dev/video%d", n); + if (device_name.id().compare(possible_id) == 0) + return scoped_ptr<VideoCaptureDevice>(new FakeVideoCaptureDevice()); + } + return scoped_ptr<VideoCaptureDevice>(); +} + +void FakeVideoCaptureDeviceFactory::GetDeviceNames( + VideoCaptureDevice::Names* const device_names) { + DCHECK(device_names->empty()); + for (int n = 0; n < number_of_devices_; ++n) { + VideoCaptureDevice::Name name(base::StringPrintf("fake_device_%d", n), + base::StringPrintf("/dev/video%d", n)); + device_names->push_back(name); + } +} + +void FakeVideoCaptureDeviceFactory::GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) { + const int frame_rate = 1000 / FakeVideoCaptureDevice::kFakeCaptureTimeoutMs; + const gfx::Size supported_sizes[] = {gfx::Size(320, 240), + gfx::Size(640, 480), + gfx::Size(1280, 720)}; + supported_formats->clear(); + for (size_t i = 0; i < arraysize(supported_sizes); ++i) { + supported_formats->push_back(VideoCaptureFormat(supported_sizes[i], + frame_rate, + media::PIXEL_FORMAT_I420)); + } +} + +} // namespace media diff --git a/media/video/capture/fake_video_capture_device_factory.h b/media/video/capture/fake_video_capture_device_factory.h new file mode 100644 index 0000000..5c7312b --- /dev/null +++ b/media/video/capture/fake_video_capture_device_factory.h @@ -0,0 +1,44 @@ +// 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 fake VideoCaptureDeviceFactory class. + +#ifndef MEDIA_VIDEO_CAPTURE_FAKE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ +#define MEDIA_VIDEO_CAPTURE_FAKE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ + +#include "media/video/capture/video_capture_device_factory.h" + +namespace media { + +// Extension of VideoCaptureDeviceFactory to create and manipulate fake devices, +// not including file-based ones. +class MEDIA_EXPORT FakeVideoCaptureDeviceFactory : + public VideoCaptureDeviceFactory { + public: + FakeVideoCaptureDeviceFactory(); + virtual ~FakeVideoCaptureDeviceFactory() {} + + 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; + + void set_number_of_devices(int number_of_devices) { + DCHECK(thread_checker_.CalledOnValidThread()); + number_of_devices_ = number_of_devices; + } + int number_of_devices() { + DCHECK(thread_checker_.CalledOnValidThread()); + return number_of_devices_; + } + + private: + int number_of_devices_; +}; + +} // namespace media + +#endif // MEDIA_VIDEO_CAPTURE_FAKE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ diff --git a/media/video/capture/file_video_capture_device.cc b/media/video/capture/file_video_capture_device.cc index 1e1277c..84a2d15 100644 --- a/media/video/capture/file_video_capture_device.cc +++ b/media/video/capture/file_video_capture_device.cc @@ -7,18 +7,11 @@ #include <string> #include "base/bind.h" -#include "base/command_line.h" #include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" -#include "base/strings/sys_string_conversions.h" -#include "media/base/media_switches.h" - namespace media { -static const char kFileVideoCaptureDeviceName[] = - "/dev/placeholder-for-file-backed-fake-capture-device"; - static const int kY4MHeaderMaxSize = 200; static const char kY4MSimpleFrameDelimiter[] = "FRAME"; static const int kY4MSimpleFrameDelimiterSize = 6; @@ -110,7 +103,8 @@ void ParseY4MTags(const std::string& file_header, // format in |video_format|. Returns the index of the first byte of the first // video frame. // Restrictions: Only trivial per-frame headers are supported. -int64 ParseFileAndExtractVideoFormat( +// static +int64 FileVideoCaptureDevice::ParseFileAndExtractVideoFormat( base::File* file, media::VideoCaptureFormat* video_format) { std::string header(kY4MHeaderMaxSize, 0); @@ -125,52 +119,14 @@ int64 ParseFileAndExtractVideoFormat( // Opens a given file for reading, and returns the file to the caller, who is // responsible for closing it. -base::File OpenFileForRead(const base::FilePath& file_path) { +// static +base::File FileVideoCaptureDevice::OpenFileForRead( + const base::FilePath& file_path) { base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); CHECK(file.IsValid()) << file_path.value(); return file.Pass(); } -// Inspects the command line and retrieves the file path parameter. -base::FilePath GetFilePathFromCommandLine() { - base::FilePath command_line_file_path = - CommandLine::ForCurrentProcess()->GetSwitchValuePath( - switches::kUseFileForFakeVideoCapture); - CHECK(!command_line_file_path.empty()); - return command_line_file_path; -} - -void FileVideoCaptureDevice::GetDeviceNames(Names* const device_names) { - DCHECK(device_names->empty()); - base::FilePath command_line_file_path = GetFilePathFromCommandLine(); -#if defined(OS_WIN) - device_names->push_back( - Name(base::SysWideToUTF8(command_line_file_path.value()), - kFileVideoCaptureDeviceName)); -#else - device_names->push_back(Name(command_line_file_path.value(), - kFileVideoCaptureDeviceName)); -#endif // OS_WIN -} - -void FileVideoCaptureDevice::GetDeviceSupportedFormats( - const Name& device, - VideoCaptureFormats* supported_formats) { - base::File file = OpenFileForRead(GetFilePathFromCommandLine()); - VideoCaptureFormat capture_format; - ParseFileAndExtractVideoFormat(&file, &capture_format); - supported_formats->push_back(capture_format); -} - -VideoCaptureDevice* FileVideoCaptureDevice::Create(const Name& device_name) { -#if defined(OS_WIN) - return new FileVideoCaptureDevice( - base::FilePath(base::SysUTF8ToWide(device_name.name()))); -#else - return new FileVideoCaptureDevice(base::FilePath(device_name.name())); -#endif // OS_WIN -} - FileVideoCaptureDevice::FileVideoCaptureDevice(const base::FilePath& file_path) : capture_thread_("CaptureThread"), file_path_(file_path), diff --git a/media/video/capture/file_video_capture_device.h b/media/video/capture/file_video_capture_device.h index e5b65ce..e2e066b 100644 --- a/media/video/capture/file_video_capture_device.h +++ b/media/video/capture/file_video_capture_device.h @@ -25,13 +25,14 @@ namespace media { // Example videos can be found in http://media.xiph.org/video/derf. class MEDIA_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice { public: - // VideoCaptureDevice implementation, static methods. Create() returns a - // pointer to the object, fully owned by the caller. - // TODO(mcasas): Create() should return a scoped_ptr<> http://crbug.com/321613 - static VideoCaptureDevice* Create(const Name& device_name); - static void GetDeviceNames(Names* device_names); - static void GetDeviceSupportedFormats(const Name& device, - VideoCaptureFormats* supported_formats); + static int64 ParseFileAndExtractVideoFormat( + base::File* file, + media::VideoCaptureFormat* video_format); + static base::File OpenFileForRead(const base::FilePath& file_path); + + // Constructor of the class, with a fully qualified file path as input, which + // represents the Y4M video file to stream repeatedly. + explicit FileVideoCaptureDevice(const base::FilePath& file_path); // VideoCaptureDevice implementation, class methods. virtual ~FileVideoCaptureDevice(); @@ -41,9 +42,6 @@ class MEDIA_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice { virtual void StopAndDeAllocate() OVERRIDE; private: - // Constructor of the class, with a fully qualified file path as input, which - // represents the Y4M video file to stream repeatedly. - explicit FileVideoCaptureDevice(const base::FilePath& file_path); // Returns size in bytes of an I420 frame, not including possible paddings, // defined by |capture_format_|. int CalculateFrameSize(); diff --git a/media/video/capture/file_video_capture_device_factory.cc b/media/video/capture/file_video_capture_device_factory.cc new file mode 100644 index 0000000..dab9a51 --- /dev/null +++ b/media/video/capture/file_video_capture_device_factory.cc @@ -0,0 +1,64 @@ +// 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/file_video_capture_device_factory.h" + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/strings/sys_string_conversions.h" +#include "media/base/media_switches.h" +#include "media/video/capture/file_video_capture_device.h" + +namespace media { + +const char kFileVideoCaptureDeviceName[] = + "/dev/placeholder-for-file-backed-fake-capture-device"; + +// Inspects the command line and retrieves the file path parameter. +base::FilePath GetFilePathFromCommandLine() { + base::FilePath command_line_file_path = + CommandLine::ForCurrentProcess()->GetSwitchValuePath( + switches::kUseFileForFakeVideoCapture); + CHECK(!command_line_file_path.empty()); + return command_line_file_path; +} + +scoped_ptr<VideoCaptureDevice> FileVideoCaptureDeviceFactory::Create( + const VideoCaptureDevice::Name& device_name) { +#if defined(OS_WIN) + return scoped_ptr<VideoCaptureDevice>(new FileVideoCaptureDevice( + base::FilePath(base::SysUTF8ToWide(device_name.name())))); +#else + return scoped_ptr<VideoCaptureDevice>(new FileVideoCaptureDevice( + base::FilePath(device_name.name()))); +#endif +} + +void FileVideoCaptureDeviceFactory::GetDeviceNames( + VideoCaptureDevice::Names* const device_names) { + DCHECK(device_names->empty()); + base::FilePath command_line_file_path = GetFilePathFromCommandLine(); +#if defined(OS_WIN) + device_names->push_back(VideoCaptureDevice::Name( + base::SysWideToUTF8(command_line_file_path.value()), + kFileVideoCaptureDeviceName)); +#else + device_names->push_back(VideoCaptureDevice::Name( + command_line_file_path.value(), + kFileVideoCaptureDeviceName)); +#endif +} + +void FileVideoCaptureDeviceFactory::GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) { + base::File file = + FileVideoCaptureDevice::OpenFileForRead(GetFilePathFromCommandLine()); + VideoCaptureFormat capture_format; + FileVideoCaptureDevice::ParseFileAndExtractVideoFormat(&file, + &capture_format); + supported_formats->push_back(capture_format); +} + +} // namespace media diff --git a/media/video/capture/file_video_capture_device_factory.h b/media/video/capture/file_video_capture_device_factory.h new file mode 100644 index 0000000..986a266 --- /dev/null +++ b/media/video/capture/file_video_capture_device_factory.h @@ -0,0 +1,31 @@ +// 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. + +#ifndef MEDIA_VIDEO_CAPTURE_FILE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ +#define MEDIA_VIDEO_CAPTURE_FILE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ + +#include "media/video/capture/video_capture_device_factory.h" + +namespace media { + +// Extension of VideoCaptureDeviceFactory to create and manipulate file-backed +// fake devices. These devices play back video-only files as video capture +// input. +class MEDIA_EXPORT FileVideoCaptureDeviceFactory : + public VideoCaptureDeviceFactory { + public: + FileVideoCaptureDeviceFactory() {} + virtual ~FileVideoCaptureDeviceFactory() {} + + 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; +}; + +} // namespace media + +#endif // MEDIA_VIDEO_CAPTURE_FILE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ diff --git a/media/video/capture/video_capture_device_factory.cc b/media/video/capture/video_capture_device_factory.cc new file mode 100644 index 0000000..e63225d --- /dev/null +++ b/media/video/capture/video_capture_device_factory.cc @@ -0,0 +1,33 @@ +// 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/video_capture_device_factory.h" + +namespace media { + +VideoCaptureDeviceFactory::VideoCaptureDeviceFactory() { + thread_checker_.DetachFromThread(); +}; + +scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactory::Create( + const VideoCaptureDevice::Name& device_name) { + DCHECK(thread_checker_.CalledOnValidThread()); + return scoped_ptr<VideoCaptureDevice>( + VideoCaptureDevice::Create(device_name)); +} + +void VideoCaptureDeviceFactory::GetDeviceNames( + VideoCaptureDevice::Names* device_names) { + DCHECK(thread_checker_.CalledOnValidThread()); + VideoCaptureDevice::GetDeviceNames(device_names); +} + +void VideoCaptureDeviceFactory::GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats) { + DCHECK(thread_checker_.CalledOnValidThread()); + VideoCaptureDevice::GetDeviceSupportedFormats(device, supported_formats); +} + +} // namespace media diff --git a/media/video/capture/video_capture_device_factory.h b/media/video/capture/video_capture_device_factory.h new file mode 100644 index 0000000..ab58ad6 --- /dev/null +++ b/media/video/capture/video_capture_device_factory.h @@ -0,0 +1,46 @@ +// 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. + +#ifndef MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ +#define MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ + +#include "base/threading/thread_checker.h" +#include "media/video/capture/video_capture_device.h" + +namespace media { + +// VideoCaptureDeviceFactory is the base class for creation of video capture +// devices in the different platforms. VCDFs are created by MediaStreamManager +// on IO thread and plugged into VideoCaptureManager, who owns and operates them +// in Device Thread (a.k.a. Audio Thread). +class MEDIA_EXPORT VideoCaptureDeviceFactory { + public: + VideoCaptureDeviceFactory(); + virtual ~VideoCaptureDeviceFactory() {} + + // Creates a VideoCaptureDevice object. Returns NULL if something goes wrong. + virtual scoped_ptr<VideoCaptureDevice> Create( + const VideoCaptureDevice::Name& device_name); + + // Gets the names of all video capture devices connected to this computer. + virtual void GetDeviceNames(VideoCaptureDevice::Names* device_names); + + // Gets the supported formats of a particular device attached to the system. + // This method should be called before allocating or starting a device. In + // case format enumeration is not supported, or there was a problem, the + // formats array will be empty. + virtual void GetDeviceSupportedFormats( + const VideoCaptureDevice::Name& device, + VideoCaptureFormats* supported_formats); + + protected: + base::ThreadChecker thread_checker_; + + private: + DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceFactory); +}; + +} // namespace media + +#endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_H_ diff --git a/media/video/capture/video_capture_device_unittest.cc b/media/video/capture/video_capture_device_unittest.cc index afeced3..f079a1f 100644 --- a/media/video/capture/video_capture_device_unittest.cc +++ b/media/video/capture/video_capture_device_unittest.cc @@ -10,6 +10,7 @@ #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" @@ -28,7 +29,7 @@ #if defined(OS_MACOSX) // Mac/QTKit will always give you the size you ask for and this case will fail. #define MAYBE_AllocateBadSize DISABLED_AllocateBadSize -// We will always get ARGB from the Mac/QTKit implementation. +// We will always get YUYV from the Mac QTKit/AVFoundation implementations. #define MAYBE_CaptureMjpeg DISABLED_CaptureMjpeg #elif defined(OS_WIN) #define MAYBE_AllocateBadSize AllocateBadSize @@ -102,7 +103,8 @@ class VideoCaptureDeviceTest : public testing::Test { : loop_(new base::MessageLoop()), client_( new MockClient(base::Bind(&VideoCaptureDeviceTest::OnFrameCaptured, - base::Unretained(this)))) {} + base::Unretained(this)))), + video_capture_device_factory_(new FakeVideoCaptureDeviceFactory()) {} virtual void SetUp() { #if defined(OS_ANDROID) @@ -162,6 +164,7 @@ class VideoCaptureDeviceTest : public testing::Test { scoped_ptr<base::RunLoop> run_loop_; scoped_ptr<MockClient> client_; VideoCaptureFormat last_format_; + scoped_ptr<VideoCaptureDeviceFactory> video_capture_device_factory_; }; TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) { @@ -332,12 +335,12 @@ TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) { TEST_F(VideoCaptureDeviceTest, FakeCapture) { VideoCaptureDevice::Names names; - FakeVideoCaptureDevice::GetDeviceNames(&names); + video_capture_device_factory_->GetDeviceNames(&names); ASSERT_GT(static_cast<int>(names.size()), 0); scoped_ptr<VideoCaptureDevice> device( - FakeVideoCaptureDevice::Create(names.front())); + video_capture_device_factory_->Create(names.front())); ASSERT_TRUE(device); EXPECT_CALL(*client_, OnErr()) @@ -397,7 +400,7 @@ TEST_F(VideoCaptureDeviceTest, GetDeviceSupportedFormats) { TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) { VideoCaptureDevice::Names names; - FakeVideoCaptureDevice::GetDeviceNames(&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; @@ -407,9 +410,16 @@ TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) { ASSERT_GT(static_cast<int>(names.size()), 0); scoped_ptr<VideoCaptureDevice> device( - FakeVideoCaptureDevice::Create(names.front())); + 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; @@ -426,15 +436,15 @@ TEST_F(VideoCaptureDeviceTest, FakeCaptureVariableResolution) { TEST_F(VideoCaptureDeviceTest, FakeGetDeviceSupportedFormats) { VideoCaptureDevice::Names names; - FakeVideoCaptureDevice::GetDeviceNames(&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) { - FakeVideoCaptureDevice::GetDeviceSupportedFormats(*names_iterator, - &supported_formats); + 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); |