mirror of
https://gitcode.com/gh_mirrors/ope/OpenFace.git
synced 2026-05-14 19:27:56 +00:00
Adding camera enumerator project for getting ready for GUI
This commit is contained in:
123
lib/3rdParty/CameraEnumerator/DeviceEnumerator.cpp
vendored
Normal file
123
lib/3rdParty/CameraEnumerator/DeviceEnumerator.cpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
#include "DeviceEnumerator.h"
|
||||
#include <iostream>
|
||||
|
||||
std::map<int, Device> DeviceEnumerator::getVideoDevicesMap() {
|
||||
return getDevicesMap(CLSID_VideoInputDeviceCategory);
|
||||
}
|
||||
|
||||
std::map<int, Device> DeviceEnumerator::getAudioDevicesMap() {
|
||||
return getDevicesMap(CLSID_AudioInputDeviceCategory);
|
||||
}
|
||||
|
||||
// Returns a map of id and devices that can be used
|
||||
std::map<int, Device> DeviceEnumerator::getDevicesMap(const GUID deviceClass)
|
||||
{
|
||||
std::map<int, Device> deviceMap;
|
||||
|
||||
// TODO add back? Calling from C# seems to not need this
|
||||
//HRESULT hr = CoInitialize(nullptr);
|
||||
//if (FAILED(hr)) {
|
||||
// return deviceMap; // Empty deviceMap as an error
|
||||
//}
|
||||
|
||||
// Create the System Device Enumerator
|
||||
ICreateDevEnum *pDevEnum;
|
||||
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pDevEnum));
|
||||
|
||||
// If succeeded, create an enumerator for the category
|
||||
IEnumMoniker *pEnum = NULL;
|
||||
if (SUCCEEDED(hr)) {
|
||||
hr = pDevEnum->CreateClassEnumerator(deviceClass, &pEnum, 0);
|
||||
if (hr == S_FALSE) {
|
||||
hr = VFW_E_NOT_FOUND;
|
||||
}
|
||||
pDevEnum->Release();
|
||||
}
|
||||
|
||||
// Now we check if the enumerator creation succeeded
|
||||
int deviceId = -1;
|
||||
if (SUCCEEDED(hr)) {
|
||||
// Fill the map with id and friendly device name
|
||||
IMoniker *pMoniker = NULL;
|
||||
while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
|
||||
|
||||
IPropertyBag *pPropBag;
|
||||
HRESULT hr = pMoniker->BindToStorage(0, 0, IID_PPV_ARGS(&pPropBag));
|
||||
if (FAILED(hr)) {
|
||||
pMoniker->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create variant to hold data
|
||||
VARIANT var;
|
||||
VariantInit(&var);
|
||||
|
||||
std::string deviceName;
|
||||
std::string devicePath;
|
||||
|
||||
// Read FriendlyName or Description
|
||||
hr = pPropBag->Read(L"Description", &var, 0); // Read description
|
||||
if (FAILED(hr)) {
|
||||
// If description fails, try with the friendly name
|
||||
hr = pPropBag->Read(L"FriendlyName", &var, 0);
|
||||
}
|
||||
// If still fails, continue with next device
|
||||
if (FAILED(hr)) {
|
||||
VariantClear(&var);
|
||||
continue;
|
||||
}
|
||||
// Convert to string
|
||||
else {
|
||||
deviceName = ConvertBSTRToMBS(var.bstrVal);
|
||||
}
|
||||
|
||||
VariantClear(&var); // We clean the variable in order to read the next value
|
||||
|
||||
// We try to read the DevicePath
|
||||
hr = pPropBag->Read(L"DevicePath", &var, 0);
|
||||
if (FAILED(hr)) {
|
||||
VariantClear(&var);
|
||||
continue; // If it fails we continue with next device
|
||||
}
|
||||
else {
|
||||
devicePath = ConvertBSTRToMBS(var.bstrVal);
|
||||
}
|
||||
|
||||
// We populate the map
|
||||
deviceId++;
|
||||
Device currentDevice;
|
||||
currentDevice.id = deviceId;
|
||||
currentDevice.deviceName = deviceName;
|
||||
currentDevice.devicePath = devicePath;
|
||||
deviceMap[deviceId] = currentDevice;
|
||||
|
||||
}
|
||||
pEnum->Release();
|
||||
}
|
||||
CoUninitialize();
|
||||
return deviceMap;
|
||||
}
|
||||
|
||||
/*
|
||||
This two methods were taken from
|
||||
https://stackoverflow.com/questions/6284524/bstr-to-stdstring-stdwstring-and-vice-versa
|
||||
*/
|
||||
|
||||
std::string DeviceEnumerator::ConvertBSTRToMBS(BSTR bstr)
|
||||
{
|
||||
int wslen = ::SysStringLen(bstr);
|
||||
return ConvertWCSToMBS((wchar_t*)bstr, wslen);
|
||||
}
|
||||
|
||||
std::string DeviceEnumerator::ConvertWCSToMBS(const wchar_t* pstr, long wslen)
|
||||
{
|
||||
int len = ::WideCharToMultiByte(CP_ACP, 0, pstr, wslen, NULL, 0, NULL, NULL);
|
||||
|
||||
std::string dblstr(len, '\0');
|
||||
len = ::WideCharToMultiByte(CP_ACP, 0 /* no flags */,
|
||||
pstr, wslen /* not necessary NULL-terminated */,
|
||||
&dblstr[0], len,
|
||||
NULL, NULL /* no default char */);
|
||||
|
||||
return dblstr;
|
||||
}
|
||||
Reference in New Issue
Block a user