Commit cf6c86f8 authored by mcasas@chromium.org's avatar mcasas@chromium.org

VideoCaptureDeviceWin: Extract class-static method into a Factory (both MF/DS)

This CL extends the separation Factory/device
initiated in the other CLs part of the bug. Aside
from code cleanup, it allows for better testing
(via dependency injection) of the factory parts
(this is specially important for blacklisted devices,
of which there are none in Win ATM). It can also
be used to modify the GetDeviceNames() method to
an asynchronous API.

Both VideoCaptureDeviceWin and VideoCaptureDeviceMFwin 
(using DirectShow and MediaFoundation APIs resp.),
have a number of static methods Create(),
GetDeviceNames() and GetDeviceSupportedFormats().
Plus, there are overarching versions of those
at the VideoCaptureDevice level, that do library
initialisation and appropriate forwarding to one
or the other implementation. This CL extracts all
of those class-static methods and moves them to
a single VideoCaptureDeviceFactoryWin.

ScopedMediaType, previously file-level data type
moves to the public def of VideoCaptureDeviceWin
since is used in the Factory.

Every file-static function and variable that could,
has been moved to the Factory file. Previous 
file-level static functions that are used in the
Factory and the VCD have been changed to VCD
static methods and used in both ends.

TBR= dalecurtis@chromium.org (media/media.gyp)

BUG=323913

Review URL: https://codereview.chromium.org/276383002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271800 0039d316-1c4b-4281-b951-d872f2087c98
parent 698d0288
...@@ -505,6 +505,8 @@ ...@@ -505,6 +505,8 @@
'video/capture/win/sink_filter_win.h', 'video/capture/win/sink_filter_win.h',
'video/capture/win/sink_input_pin_win.cc', 'video/capture/win/sink_input_pin_win.cc',
'video/capture/win/sink_input_pin_win.h', 'video/capture/win/sink_input_pin_win.h',
'video/capture/win/video_capture_device_factory_win.cc',
'video/capture/win/video_capture_device_factory_win.h',
'video/capture/win/video_capture_device_mf_win.cc', 'video/capture/win/video_capture_device_mf_win.cc',
'video/capture/win/video_capture_device_mf_win.h', 'video/capture/win/video_capture_device_mf_win.h',
'video/capture/win/video_capture_device_win.cc', 'video/capture/win/video_capture_device_win.cc',
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "media/video/capture/linux/video_capture_device_factory_linux.h" #include "media/video/capture/linux/video_capture_device_factory_linux.h"
#elif defined(OS_ANDROID) #elif defined(OS_ANDROID)
#include "media/video/capture/android/video_capture_device_factory_android.h" #include "media/video/capture/android/video_capture_device_factory_android.h"
#elif defined(OS_WIN)
#include "media/video/capture/win/video_capture_device_factory_win.h"
#endif #endif
namespace media { namespace media {
...@@ -46,6 +48,9 @@ scoped_ptr<VideoCaptureDeviceFactory> ...@@ -46,6 +48,9 @@ scoped_ptr<VideoCaptureDeviceFactory>
#elif defined(OS_ANDROID) #elif defined(OS_ANDROID)
return scoped_ptr<VideoCaptureDeviceFactory>(new return scoped_ptr<VideoCaptureDeviceFactory>(new
VideoCaptureDeviceFactoryAndroid()); VideoCaptureDeviceFactoryAndroid());
#elif defined(OS_WIN)
return scoped_ptr<VideoCaptureDeviceFactory>(new
VideoCaptureDeviceFactoryWin());
#else #else
return scoped_ptr<VideoCaptureDeviceFactory>(new return scoped_ptr<VideoCaptureDeviceFactory>(new
VideoCaptureDeviceFactory()); VideoCaptureDeviceFactory());
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#if defined(OS_WIN) #if defined(OS_WIN)
#include "base/win/scoped_com_initializer.h" #include "base/win/scoped_com_initializer.h"
#include "media/video/capture/win/video_capture_device_mf_win.h" #include "media/video/capture/win/video_capture_device_factory_win.h"
#endif #endif
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -165,7 +165,7 @@ class VideoCaptureDeviceTest : public testing::Test { ...@@ -165,7 +165,7 @@ class VideoCaptureDeviceTest : public testing::Test {
TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) { TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) {
#if defined(OS_WIN) #if defined(OS_WIN)
VideoCaptureDevice::Name::CaptureApiType api_type = VideoCaptureDevice::Name::CaptureApiType api_type =
VideoCaptureDeviceMFWin::PlatformSupported() VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation()
? VideoCaptureDevice::Name::MEDIA_FOUNDATION ? VideoCaptureDevice::Name::MEDIA_FOUNDATION
: VideoCaptureDevice::Name::DIRECT_SHOW; : VideoCaptureDevice::Name::DIRECT_SHOW;
VideoCaptureDevice::Name device_name("jibberish", "jibberish", api_type); VideoCaptureDevice::Name device_name("jibberish", "jibberish", api_type);
......
This diff is collapsed.
// 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 Windows platforms.
#ifndef MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_WIN_H_
#define MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_WIN_H_
#include "media/video/capture/video_capture_device_factory.h"
namespace media {
// Extension of VideoCaptureDeviceFactory to create and manipulate Windows
// devices, via either DirectShow or MediaFoundation APIs.
class MEDIA_EXPORT VideoCaptureDeviceFactoryWin :
public VideoCaptureDeviceFactory {
public:
static bool PlatformSupportsMediaFoundation();
VideoCaptureDeviceFactoryWin();
virtual ~VideoCaptureDeviceFactoryWin() {}
virtual scoped_ptr<VideoCaptureDevice> Create(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
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:
bool use_media_foundation_;
DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceFactoryWin);
};
} // namespace media
#endif // MEDIA_VIDEO_CAPTURE_VIDEO_CAPTURE_DEVICE_FACTORY_WIN_H_
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <mfapi.h> #include <mfapi.h>
#include <mferror.h> #include <mferror.h>
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
...@@ -20,7 +19,6 @@ using base::win::ScopedCoMem; ...@@ -20,7 +19,6 @@ using base::win::ScopedCoMem;
using base::win::ScopedComPtr; using base::win::ScopedComPtr;
namespace media { namespace media {
namespace {
// In Windows device identifiers, the USB VID and PID are preceded by the string // In Windows device identifiers, the USB VID and PID are preceded by the string
// "vid_" or "pid_". The identifiers are each 4 bytes long. // "vid_" or "pid_". The identifiers are each 4 bytes long.
...@@ -28,74 +26,7 @@ const char kVidPrefix[] = "vid_"; // Also contains '\0'. ...@@ -28,74 +26,7 @@ const char kVidPrefix[] = "vid_"; // Also contains '\0'.
const char kPidPrefix[] = "pid_"; // Also contains '\0'. const char kPidPrefix[] = "pid_"; // Also contains '\0'.
const size_t kVidPidSize = 4; const size_t kVidPidSize = 4;
class MFInitializerSingleton { static bool GetFrameSize(IMFMediaType* type, gfx::Size* frame_size) {
public:
MFInitializerSingleton() { MFStartup(MF_VERSION, MFSTARTUP_LITE); }
~MFInitializerSingleton() { MFShutdown(); }
};
static base::LazyInstance<MFInitializerSingleton> g_mf_initialize =
LAZY_INSTANCE_INITIALIZER;
void EnsureMFInit() {
g_mf_initialize.Get();
}
bool PrepareVideoCaptureAttributes(IMFAttributes** attributes, int count) {
EnsureMFInit();
if (FAILED(MFCreateAttributes(attributes, count)))
return false;
return SUCCEEDED((*attributes)->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID));
}
bool EnumerateVideoDevices(IMFActivate*** devices,
UINT32* count) {
ScopedComPtr<IMFAttributes> attributes;
if (!PrepareVideoCaptureAttributes(attributes.Receive(), 1))
return false;
return SUCCEEDED(MFEnumDeviceSources(attributes, devices, count));
}
bool CreateVideoCaptureDevice(const char* sym_link, IMFMediaSource** source) {
ScopedComPtr<IMFAttributes> attributes;
if (!PrepareVideoCaptureAttributes(attributes.Receive(), 2))
return false;
attributes->SetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
base::SysUTF8ToWide(sym_link).c_str());
return SUCCEEDED(MFCreateDeviceSource(attributes, source));
}
bool FormatFromGuid(const GUID& guid, VideoPixelFormat* format) {
struct {
const GUID& guid;
const VideoPixelFormat format;
} static const kFormatMap[] = {
{ MFVideoFormat_I420, PIXEL_FORMAT_I420 },
{ MFVideoFormat_YUY2, PIXEL_FORMAT_YUY2 },
{ MFVideoFormat_UYVY, PIXEL_FORMAT_UYVY },
{ MFVideoFormat_RGB24, PIXEL_FORMAT_RGB24 },
{ MFVideoFormat_ARGB32, PIXEL_FORMAT_ARGB },
{ MFVideoFormat_MJPG, PIXEL_FORMAT_MJPEG },
{ MFVideoFormat_YV12, PIXEL_FORMAT_YV12 },
};
for (int i = 0; i < arraysize(kFormatMap); ++i) {
if (kFormatMap[i].guid == guid) {
*format = kFormatMap[i].format;
return true;
}
}
return false;
}
bool GetFrameSize(IMFMediaType* type, gfx::Size* frame_size) {
UINT32 width32, height32; UINT32 width32, height32;
if (FAILED(MFGetAttributeSize(type, MF_MT_FRAME_SIZE, &width32, &height32))) if (FAILED(MFGetAttributeSize(type, MF_MT_FRAME_SIZE, &width32, &height32)))
return false; return false;
...@@ -103,9 +34,9 @@ bool GetFrameSize(IMFMediaType* type, gfx::Size* frame_size) { ...@@ -103,9 +34,9 @@ bool GetFrameSize(IMFMediaType* type, gfx::Size* frame_size) {
return true; return true;
} }
bool GetFrameRate(IMFMediaType* type, static bool GetFrameRate(IMFMediaType* type,
int* frame_rate_numerator, int* frame_rate_numerator,
int* frame_rate_denominator) { int* frame_rate_denominator) {
UINT32 numerator, denominator; UINT32 numerator, denominator;
if (FAILED(MFGetAttributeRatio(type, MF_MT_FRAME_RATE, &numerator, if (FAILED(MFGetAttributeRatio(type, MF_MT_FRAME_RATE, &numerator,
&denominator))|| &denominator))||
...@@ -117,15 +48,16 @@ bool GetFrameRate(IMFMediaType* type, ...@@ -117,15 +48,16 @@ bool GetFrameRate(IMFMediaType* type,
return true; return true;
} }
bool FillCapabilitiesFromType(IMFMediaType* type, static bool FillCapabilitiesFromType(IMFMediaType* type,
VideoCaptureCapabilityWin* capability) { VideoCaptureCapabilityWin* capability) {
GUID type_guid; GUID type_guid;
if (FAILED(type->GetGUID(MF_MT_SUBTYPE, &type_guid)) || if (FAILED(type->GetGUID(MF_MT_SUBTYPE, &type_guid)) ||
!GetFrameSize(type, &capability->supported_format.frame_size) || !GetFrameSize(type, &capability->supported_format.frame_size) ||
!GetFrameRate(type, !GetFrameRate(type,
&capability->frame_rate_numerator, &capability->frame_rate_numerator,
&capability->frame_rate_denominator) || &capability->frame_rate_denominator) ||
!FormatFromGuid(type_guid, &capability->supported_format.pixel_format)) { !VideoCaptureDeviceMFWin::FormatFromGuid(type_guid,
&capability->supported_format.pixel_format)) {
return false; return false;
} }
// Keep the integer version of the frame_rate for (potential) returns. // Keep the integer version of the frame_rate for (potential) returns.
...@@ -154,24 +86,6 @@ HRESULT FillCapabilities(IMFSourceReader* source, ...@@ -154,24 +86,6 @@ HRESULT FillCapabilities(IMFSourceReader* source,
return (hr == MF_E_NO_MORE_TYPES) ? S_OK : hr; return (hr == MF_E_NO_MORE_TYPES) ? S_OK : hr;
} }
bool LoadMediaFoundationDlls() {
static const wchar_t* const kMfDLLs[] = {
L"%WINDIR%\\system32\\mf.dll",
L"%WINDIR%\\system32\\mfplat.dll",
L"%WINDIR%\\system32\\mfreadwrite.dll",
};
for (int i = 0; i < arraysize(kMfDLLs); ++i) {
wchar_t path[MAX_PATH] = {0};
ExpandEnvironmentStringsW(kMfDLLs[i], path, arraysize(path));
if (!LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH))
return false;
}
return true;
}
} // namespace
class MFReaderCallback FINAL class MFReaderCallback FINAL
: public base::RefCountedThreadSafe<MFReaderCallback>, : public base::RefCountedThreadSafe<MFReaderCallback>,
...@@ -250,95 +164,29 @@ class MFReaderCallback FINAL ...@@ -250,95 +164,29 @@ class MFReaderCallback FINAL
}; };
// static // static
bool VideoCaptureDeviceMFWin::PlatformSupported() { bool VideoCaptureDeviceMFWin::FormatFromGuid(const GUID& guid,
// Even though the DLLs might be available on Vista, we get crashes VideoPixelFormat* format) {
// when running our tests on the build bots. struct {
if (base::win::GetVersion() < base::win::VERSION_WIN7) const GUID& guid;
return false; const VideoPixelFormat format;
} static const kFormatMap[] = {
static bool g_dlls_available = LoadMediaFoundationDlls(); { MFVideoFormat_I420, PIXEL_FORMAT_I420 },
return g_dlls_available; { MFVideoFormat_YUY2, PIXEL_FORMAT_YUY2 },
} { MFVideoFormat_UYVY, PIXEL_FORMAT_UYVY },
{ MFVideoFormat_RGB24, PIXEL_FORMAT_RGB24 },
// static { MFVideoFormat_ARGB32, PIXEL_FORMAT_ARGB },
void VideoCaptureDeviceMFWin::GetDeviceNames(Names* device_names) { { MFVideoFormat_MJPG, PIXEL_FORMAT_MJPEG },
ScopedCoMem<IMFActivate*> devices; { MFVideoFormat_YV12, PIXEL_FORMAT_YV12 },
UINT32 count; };
if (!EnumerateVideoDevices(&devices, &count))
return;
HRESULT hr; for (int i = 0; i < arraysize(kFormatMap); ++i) {
for (UINT32 i = 0; i < count; ++i) { if (kFormatMap[i].guid == guid) {
UINT32 name_size, id_size; *format = kFormatMap[i].format;
ScopedCoMem<wchar_t> name, id; return true;
if (SUCCEEDED(hr = devices[i]->GetAllocatedString(
MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &name, &name_size)) &&
SUCCEEDED(hr = devices[i]->GetAllocatedString(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id,
&id_size))) {
std::wstring name_w(name, name_size), id_w(id, id_size);
Name device(base::SysWideToUTF8(name_w), base::SysWideToUTF8(id_w),
Name::MEDIA_FOUNDATION);
device_names->push_back(device);
} else {
DLOG(WARNING) << "GetAllocatedString failed: " << std::hex << hr;
} }
devices[i]->Release();
} }
}
// static
void VideoCaptureDeviceMFWin::GetDeviceSupportedFormats(const Name& device,
VideoCaptureFormats* formats) {
ScopedComPtr<IMFMediaSource> source;
if (!CreateVideoCaptureDevice(device.id().c_str(), source.Receive()))
return;
HRESULT hr;
base::win::ScopedComPtr<IMFSourceReader> reader;
if (FAILED(hr = MFCreateSourceReaderFromMediaSource(source, NULL,
reader.Receive()))) {
DLOG(ERROR) << "MFCreateSourceReaderFromMediaSource: " << std::hex << hr;
return;
}
DWORD stream_index = 0;
ScopedComPtr<IMFMediaType> type;
while (SUCCEEDED(hr = reader->GetNativeMediaType(
MF_SOURCE_READER_FIRST_VIDEO_STREAM, stream_index, type.Receive()))) {
UINT32 width, height;
hr = MFGetAttributeSize(type, MF_MT_FRAME_SIZE, &width, &height);
if (FAILED(hr)) {
DLOG(ERROR) << "MFGetAttributeSize: " << std::hex << hr;
return;
}
VideoCaptureFormat capture_format;
capture_format.frame_size.SetSize(width, height);
UINT32 numerator, denominator;
hr = MFGetAttributeRatio(type, MF_MT_FRAME_RATE, &numerator, &denominator);
if (FAILED(hr)) {
DLOG(ERROR) << "MFGetAttributeSize: " << std::hex << hr;
return;
}
capture_format.frame_rate = denominator ? numerator / denominator : 0;
GUID type_guid;
hr = type->GetGUID(MF_MT_SUBTYPE, &type_guid);
if (FAILED(hr)) {
DLOG(ERROR) << "GetGUID: " << std::hex << hr;
return;
}
FormatFromGuid(type_guid, &capture_format.pixel_format);
type.Release();
formats->push_back(capture_format);
++stream_index;
DVLOG(1) << device.name() << " resolution: " return false;
<< capture_format.frame_size.ToString() << ", fps: "
<< capture_format.frame_rate << ", pixel format: "
<< capture_format.pixel_format;
}
} }
const std::string VideoCaptureDevice::Name::GetModel() const { const std::string VideoCaptureDevice::Name::GetModel() const {
...@@ -370,14 +218,11 @@ VideoCaptureDeviceMFWin::~VideoCaptureDeviceMFWin() { ...@@ -370,14 +218,11 @@ VideoCaptureDeviceMFWin::~VideoCaptureDeviceMFWin() {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
} }
bool VideoCaptureDeviceMFWin::Init() { bool VideoCaptureDeviceMFWin::Init(
const base::win::ScopedComPtr<IMFMediaSource>& source) {
DCHECK(CalledOnValidThread()); DCHECK(CalledOnValidThread());
DCHECK(!reader_); DCHECK(!reader_);
ScopedComPtr<IMFMediaSource> source;
if (!CreateVideoCaptureDevice(name_.id().c_str(), source.Receive()))
return false;
ScopedComPtr<IMFAttributes> attributes; ScopedComPtr<IMFAttributes> attributes;
MFCreateAttributes(attributes.Receive(), 1); MFCreateAttributes(attributes.Receive(), 1);
DCHECK(attributes); DCHECK(attributes);
......
...@@ -30,12 +30,13 @@ class MEDIA_EXPORT VideoCaptureDeviceMFWin ...@@ -30,12 +30,13 @@ class MEDIA_EXPORT VideoCaptureDeviceMFWin
: public base::NonThreadSafe, : public base::NonThreadSafe,
public VideoCaptureDevice { public VideoCaptureDevice {
public: public:
static bool FormatFromGuid(const GUID& guid, VideoPixelFormat* format);
explicit VideoCaptureDeviceMFWin(const Name& device_name); explicit VideoCaptureDeviceMFWin(const Name& device_name);
virtual ~VideoCaptureDeviceMFWin(); virtual ~VideoCaptureDeviceMFWin();
// Opens the device driver for this device. // Opens the device driver for this device.
// This function is used by the static VideoCaptureDevice::Create function. bool Init(const base::win::ScopedComPtr<IMFMediaSource>& source);
bool Init();
// VideoCaptureDevice implementation. // VideoCaptureDevice implementation.
virtual void AllocateAndStart(const VideoCaptureParams& params, virtual void AllocateAndStart(const VideoCaptureParams& params,
...@@ -43,18 +44,6 @@ class MEDIA_EXPORT VideoCaptureDeviceMFWin ...@@ -43,18 +44,6 @@ class MEDIA_EXPORT VideoCaptureDeviceMFWin
OVERRIDE; OVERRIDE;
virtual void StopAndDeAllocate() OVERRIDE; virtual void StopAndDeAllocate() OVERRIDE;
// Returns true iff the current platform supports the Media Foundation API
// and that the DLLs are available. On Vista this API is an optional download
// but the API is advertised as a part of Windows 7 and onwards. However,
// we've seen that the required DLLs are not available in some Win7
// distributions such as Windows 7 N and Windows 7 KN.
static bool PlatformSupported();
static void GetDeviceNames(Names* device_names);
static void GetDeviceSupportedFormats(const Name& device,
VideoCaptureFormats* formats);
// Captured new video data. // Captured new video data.
void OnIncomingCapturedData(const uint8* data, void OnIncomingCapturedData(const uint8* data,
int length, int length,
......
...@@ -33,10 +33,38 @@ class VideoCaptureDeviceWin ...@@ -33,10 +33,38 @@ class VideoCaptureDeviceWin
public VideoCaptureDevice, public VideoCaptureDevice,
public SinkFilterObserver { public SinkFilterObserver {
public: public:
// A utility class that wraps the AM_MEDIA_TYPE type and guarantees that
// we free the structure when exiting the scope. DCHECKing is also done to
// avoid memory leaks.
class ScopedMediaType {
public:
ScopedMediaType() : media_type_(NULL) {}
~ScopedMediaType() { Free(); }
AM_MEDIA_TYPE* operator->() { return media_type_; }
AM_MEDIA_TYPE* get() { return media_type_; }
void Free();
AM_MEDIA_TYPE** Receive();
private:
void FreeMediaType(AM_MEDIA_TYPE* mt);
void DeleteMediaType(AM_MEDIA_TYPE* mt);
AM_MEDIA_TYPE* media_type_;
};
static HRESULT GetDeviceFilter(const Name& device_name,
IBaseFilter** filter);
static bool PinMatchesCategory(IPin* pin, REFGUID category);
static base::win::ScopedComPtr<IPin> GetPin(IBaseFilter* filter,
PIN_DIRECTION pin_dir,
REFGUID category);
static VideoPixelFormat TranslateMediaSubtypeToPixelFormat(
const GUID& sub_type);
explicit VideoCaptureDeviceWin(const Name& device_name); explicit VideoCaptureDeviceWin(const Name& device_name);
virtual ~VideoCaptureDeviceWin(); virtual ~VideoCaptureDeviceWin();
// Opens the device driver for this device. // Opens the device driver for this device.
// This function is used by the static VideoCaptureDevice::Create function.
bool Init(); bool Init();
// VideoCaptureDevice implementation. // VideoCaptureDevice implementation.
...@@ -45,10 +73,6 @@ class VideoCaptureDeviceWin ...@@ -45,10 +73,6 @@ class VideoCaptureDeviceWin
scoped_ptr<VideoCaptureDevice::Client> client) OVERRIDE; scoped_ptr<VideoCaptureDevice::Client> client) OVERRIDE;
virtual void StopAndDeAllocate() OVERRIDE; virtual void StopAndDeAllocate() OVERRIDE;
static void GetDeviceNames(Names* device_names);
static void GetDeviceSupportedFormats(const Name& device,
VideoCaptureFormats* formats);
private: private:
enum InternalState { enum InternalState {
kIdle, // The device driver is opened but camera is not in use. kIdle, // The device driver is opened but camera is not in use.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment