diff --git a/lib/3rdParty/CameraEnumerator/CameraEnumerator.vcxproj b/lib/3rdParty/CameraEnumerator/CameraEnumerator.vcxproj
new file mode 100644
index 0000000..3be56a7
--- /dev/null
+++ b/lib/3rdParty/CameraEnumerator/CameraEnumerator.vcxproj
@@ -0,0 +1,135 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ {50B7D4BF-E33B-41D0-AA89-76BBA57BF5CC}
+ Win32Proj
+ CameraEnumerator
+ 8.1
+
+
+
+ StaticLibrary
+ true
+ v140
+ Unicode
+
+
+ StaticLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+ StaticLibrary
+ true
+ v140
+ Unicode
+
+
+ StaticLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+ Windows
+
+
+
+
+
+
+ Level3
+ Disabled
+ _DEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+ Windows
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_LIB;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+ true
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/3rdParty/CameraEnumerator/CameraEnumerator.vcxproj.filters b/lib/3rdParty/CameraEnumerator/CameraEnumerator.vcxproj.filters
new file mode 100644
index 0000000..34c1b07
--- /dev/null
+++ b/lib/3rdParty/CameraEnumerator/CameraEnumerator.vcxproj.filters
@@ -0,0 +1,20 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lib/3rdParty/CameraEnumerator/DeviceEnumerator.cpp b/lib/3rdParty/CameraEnumerator/DeviceEnumerator.cpp
new file mode 100644
index 0000000..02f4776
--- /dev/null
+++ b/lib/3rdParty/CameraEnumerator/DeviceEnumerator.cpp
@@ -0,0 +1,121 @@
+#include "DeviceEnumerator.h"
+
+std::map DeviceEnumerator::getVideoDevicesMap() {
+ return getDevicesMap(CLSID_VideoInputDeviceCategory);
+}
+
+std::map DeviceEnumerator::getAudioDevicesMap() {
+ return getDevicesMap(CLSID_AudioInputDeviceCategory);
+}
+
+// Returns a map of id and devices that can be used
+std::map DeviceEnumerator::getDevicesMap(const GUID deviceClass)
+{
+ std::map deviceMap;
+
+ HRESULT hr = CoInitialize(nullptr);
+ if (FAILED(hr)) {
+ return deviceMap; // Empty deviceMap as an error
+ }
+
+ // Create the System Device Enumerator
+ ICreateDevEnum *pDevEnum;
+ 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;
+}
diff --git a/lib/3rdParty/CameraEnumerator/DeviceEnumerator.h b/lib/3rdParty/CameraEnumerator/DeviceEnumerator.h
new file mode 100644
index 0000000..6e4716c
--- /dev/null
+++ b/lib/3rdParty/CameraEnumerator/DeviceEnumerator.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include
+#include
+
+#pragma comment(lib, "strmiids")
+
+#include