Index: media/video/capture/win/video_capture_device_factory_win.cc |
diff --git a/media/video/capture/win/video_capture_device_factory_win.cc b/media/video/capture/win/video_capture_device_factory_win.cc |
index 75ee59d3bf495be332468550d2bb9ef22a16ef5d..3ecd293d14438c432529e251bd9718b41e5288a4 100644 |
--- a/media/video/capture/win/video_capture_device_factory_win.cc |
+++ b/media/video/capture/win/video_capture_device_factory_win.cc |
@@ -22,6 +22,8 @@ |
using base::win::ScopedCoMem; |
using base::win::ScopedComPtr; |
using base::win::ScopedVariant; |
+using Name = media::VideoCaptureDevice::Name; |
+using Names = media::VideoCaptureDevice::Names; |
mcasas
2014/08/28 11:53:41
Comment: since Name is a nested class inside VCD,
|
namespace media { |
@@ -88,7 +90,7 @@ static bool EnumerateVideoDevicesMediaFoundation(IMFActivate*** devices, |
return SUCCEEDED(MFEnumDeviceSources(attributes, devices, count)); |
} |
-static void GetDeviceNamesDirectShow(VideoCaptureDevice::Names* device_names) { |
+static void GetDeviceNamesDirectShow(Names* device_names) { |
DCHECK(device_names); |
DVLOG(1) << " GetDeviceNamesDirectShow"; |
@@ -98,69 +100,81 @@ static void GetDeviceNamesDirectShow(VideoCaptureDevice::Names* device_names) { |
if (FAILED(hr)) |
return; |
- ScopedComPtr<IEnumMoniker> enum_moniker; |
- hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
- enum_moniker.Receive(), 0); |
- // CreateClassEnumerator returns S_FALSE on some Windows OS |
- // when no camera exist. Therefore the FAILED macro can't be used. |
- if (hr != S_OK) |
- return; |
- |
- device_names->clear(); |
+ static const struct{ |
+ CLSID class_id; |
+ Name::CaptureApiType capture_api_type; |
+ } kDirectShowFilterClasses[] = { |
+ { CLSID_VideoInputDeviceCategory, Name::DIRECT_SHOW }, |
+ { AM_KSCATEGORY_CROSSBAR, Name::DIRECT_SHOW_WDM} |
+ }; |
- // Name of a fake DirectShow filter that exist on computers with |
- // GTalk installed. |
- static const char kGoogleCameraAdapter[] = "google camera adapter"; |
- // Enumerate all video capture devices. |
- ScopedComPtr<IMoniker> moniker; |
- int index = 0; |
- while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { |
- ScopedComPtr<IPropertyBag> prop_bag; |
- hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); |
- if (FAILED(hr)) { |
- moniker.Release(); |
+ device_names->clear(); |
+ for (int class_index = 0; class_index < arraysize(kDirectShowFilterClasses); |
+ ++class_index) { |
+ ScopedComPtr<IEnumMoniker> enum_moniker; |
+ hr = dev_enum->CreateClassEnumerator( |
+ kDirectShowFilterClasses[class_index].class_id, |
+ enum_moniker.Receive(), |
+ 0); |
+ // CreateClassEnumerator returns S_FALSE on some Windows OS |
+ // when no camera exist. Therefore the FAILED macro can't be used. |
+ if (hr != S_OK) |
continue; |
- } |
- // Find the description or friendly name. |
- ScopedVariant name; |
- hr = prop_bag->Read(L"Description", name.Receive(), 0); |
- if (FAILED(hr)) |
- hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); |
- |
- if (SUCCEEDED(hr) && name.type() == VT_BSTR) { |
- // Ignore all VFW drivers and the special Google Camera Adapter. |
- // Google Camera Adapter is not a real DirectShow camera device. |
- // VFW are very old Video for Windows drivers that can not be used. |
- const wchar_t* str_ptr = V_BSTR(&name); |
- const int name_length = arraysize(kGoogleCameraAdapter) - 1; |
- |
- if ((wcsstr(str_ptr, L"(VFW)") == NULL) && |
- lstrlenW(str_ptr) < name_length || |
- (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length, |
- kGoogleCameraAdapter)))) { |
- std::string id; |
- std::string device_name(base::SysWideToUTF8(str_ptr)); |
- name.Reset(); |
- hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); |
- if (FAILED(hr) || name.type() != VT_BSTR) { |
- id = device_name; |
- } else { |
- DCHECK_EQ(name.type(), VT_BSTR); |
- id = base::SysWideToUTF8(V_BSTR(&name)); |
- } |
+ // Name of a fake DirectShow filter that exist on computers with |
+ // GTalk installed. |
+ static const char kGoogleCameraAdapter[] = "google camera adapter"; |
+ |
+ // Enumerate all video capture devices. |
+ ScopedComPtr<IMoniker> moniker; |
+ int index = 0; |
+ while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { |
+ ScopedComPtr<IPropertyBag> prop_bag; |
+ hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, |
+ prop_bag.ReceiveVoid()); |
+ if (FAILED(hr)) { |
+ moniker.Release(); |
+ continue; |
+ } |
- device_names->push_back(VideoCaptureDevice::Name(device_name, id, |
- VideoCaptureDevice::Name::DIRECT_SHOW)); |
+ // Find the description or friendly name. |
+ ScopedVariant name; |
+ hr = prop_bag->Read(L"Description", name.Receive(), 0); |
+ if (FAILED(hr)) |
+ hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); |
+ |
+ if (SUCCEEDED(hr) && name.type() == VT_BSTR) { |
+ // Ignore all VFW drivers and the special Google Camera Adapter. |
+ // Google Camera Adapter is not a real DirectShow camera device. |
+ // VFW are very old Video for Windows drivers that can not be used. |
+ const wchar_t* str_ptr = V_BSTR(&name); |
+ const int name_length = arraysize(kGoogleCameraAdapter) - 1; |
+ |
+ if ((wcsstr(str_ptr, L"(VFW)") == NULL) && |
+ lstrlenW(str_ptr) < name_length || |
+ (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length, |
+ kGoogleCameraAdapter)))) { |
+ std::string id; |
+ std::string device_name(base::SysWideToUTF8(str_ptr)); |
+ name.Reset(); |
+ hr = prop_bag->Read(L"DevicePath", name.Receive(), 0); |
+ if (FAILED(hr) || name.type() != VT_BSTR) { |
+ id = device_name; |
+ } else { |
+ DCHECK_EQ(name.type(), VT_BSTR); |
+ id = base::SysWideToUTF8(V_BSTR(&name)); |
+ } |
+ device_names->push_back(Name(device_name, id, |
+ kDirectShowFilterClasses[class_index].capture_api_type)); |
+ } |
} |
+ moniker.Release(); |
} |
- moniker.Release(); |
} |
} |
-static void GetDeviceNamesMediaFoundation( |
- VideoCaptureDevice::Names* device_names) { |
+static void GetDeviceNamesMediaFoundation(Names* device_names) { |
DVLOG(1) << " GetDeviceNamesMediaFoundation"; |
ScopedCoMem<IMFActivate*> devices; |
UINT32 count; |
@@ -179,10 +193,10 @@ static void GetDeviceNamesMediaFoundation( |
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, &id, |
&id_size); |
if (SUCCEEDED(hr)) { |
- device_names->push_back(VideoCaptureDevice::Name( |
+ device_names->push_back(Name( |
base::SysWideToUTF8(std::wstring(name, name_size)), |
base::SysWideToUTF8(std::wstring(id, id_size)), |
- VideoCaptureDevice::Name::MEDIA_FOUNDATION)); |
+ Name::MEDIA_FOUNDATION)); |
} |
} |
if (FAILED(hr)) |
@@ -191,9 +205,8 @@ static void GetDeviceNamesMediaFoundation( |
} |
} |
-static void GetDeviceSupportedFormatsDirectShow( |
- const VideoCaptureDevice::Name& device, |
- VideoCaptureFormats* formats) { |
+static void GetDeviceSupportedFormatsDirectShow(const Name& device, |
+ VideoCaptureFormats* formats) { |
DVLOG(1) << "GetDeviceSupportedFormatsDirectShow for " << device.name(); |
ScopedComPtr<ICreateDevEnum> dev_enum; |
HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, |
@@ -280,7 +293,7 @@ static void GetDeviceSupportedFormatsDirectShow( |
} |
static void GetDeviceSupportedFormatsMediaFoundation( |
- const VideoCaptureDevice::Name& device, |
+ const Name& device, |
VideoCaptureFormats* formats) { |
DVLOG(1) << "GetDeviceSupportedFormatsMediaFoundation for " << device.name(); |
ScopedComPtr<IMFMediaSource> source; |
@@ -371,11 +384,10 @@ VideoCaptureDeviceFactoryWin::VideoCaptureDeviceFactoryWin() { |
scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( |
- const VideoCaptureDevice::Name& device_name) { |
+ const Name& device_name) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
scoped_ptr<VideoCaptureDevice> device; |
- if (device_name.capture_api_type() == |
- VideoCaptureDevice::Name::MEDIA_FOUNDATION) { |
+ if (device_name.capture_api_type() == Name::MEDIA_FOUNDATION) { |
DCHECK(PlatformSupportsMediaFoundation()); |
device.reset(new VideoCaptureDeviceMFWin(device_name)); |
DVLOG(1) << " MediaFoundation Device: " << device_name.name(); |
@@ -387,8 +399,8 @@ scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( |
if (!static_cast<VideoCaptureDeviceMFWin*>(device.get())->Init(source)) |
device.reset(); |
} else { |
- DCHECK_EQ(device_name.capture_api_type(), |
- VideoCaptureDevice::Name::DIRECT_SHOW); |
+ DCHECK(device_name.capture_api_type() == Name::DIRECT_SHOW || |
+ device_name.capture_api_type() == Name::DIRECT_SHOW_WDM); |
device.reset(new VideoCaptureDeviceWin(device_name)); |
DVLOG(1) << " DirectShow Device: " << device_name.name(); |
if (!static_cast<VideoCaptureDeviceWin*>(device.get())->Init()) |
@@ -397,8 +409,7 @@ scoped_ptr<VideoCaptureDevice> VideoCaptureDeviceFactoryWin::Create( |
return device.Pass(); |
} |
-void VideoCaptureDeviceFactoryWin::GetDeviceNames( |
- VideoCaptureDevice::Names* device_names) { |
+void VideoCaptureDeviceFactoryWin::GetDeviceNames(Names* device_names) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
if (use_media_foundation_) |
GetDeviceNamesMediaFoundation(device_names); |
@@ -407,7 +418,7 @@ void VideoCaptureDeviceFactoryWin::GetDeviceNames( |
} |
void VideoCaptureDeviceFactoryWin::GetDeviceSupportedFormats( |
- const VideoCaptureDevice::Name& device, |
+ const Name& device, |
VideoCaptureFormats* formats) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
if (use_media_foundation_) |