diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2019-05-06 03:52:45 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-05-06 03:53:01 +0200 |
commit | 31bab22b5ee7bc18ad4bdb2fb74ed4948a900cc0 (patch) | |
tree | 7532ffae7542002136e94f217fa3596787f0cc0a /compat/camera-names.cpp | |
parent | c246ff0280eda1a8ccdfdfb557037b7cea8ecc63 (diff) |
compat/camera-names: move to original location
Issue: #946
Diffstat (limited to 'compat/camera-names.cpp')
-rw-r--r-- | compat/camera-names.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/compat/camera-names.cpp b/compat/camera-names.cpp new file mode 100644 index 00000000..69926e5a --- /dev/null +++ b/compat/camera-names.cpp @@ -0,0 +1,106 @@ +#include "camera-names.hpp" + +#include <algorithm> +#include <iterator> + +#ifdef _WIN32 +# include <cwchar> +# define NO_DSHOW_STRSAFE +# include <dshow.h> +#elif defined(__unix) || defined(__linux) || defined(__APPLE__) +# include <unistd.h> +#endif + +#ifdef __linux +# include <fcntl.h> +# include <sys/ioctl.h> +# include <linux/videodev2.h> +# include <cerrno> +# include <cstring> +#endif + +#include <QDebug> + +int camera_name_to_index(const QString &name) +{ + auto list = get_camera_names(); + auto it = std::find(list.cbegin(), list.cend(), name); + if (it != list.cend()) + return std::distance(list.cbegin(), it); + + return -1; +} + +std::vector<QString> get_camera_names() +{ + std::vector<QString> ret; +#ifdef _WIN32 + // Create the System Device Enumerator. + HRESULT hr; + CoInitialize(nullptr); + ICreateDevEnum *pSysDevEnum = nullptr; + hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); + if (FAILED(hr)) + { + qDebug() << "failed CLSID_SystemDeviceEnum" << hr; + return ret; + } + // Obtain a class enumerator for the video compressor category. + IEnumMoniker *pEnumCat = nullptr; + hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0); + + if (hr == S_OK) { + // Enumerate the monikers. + IMoniker *pMoniker = nullptr; + ULONG cFetched; + while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK) + { + IPropertyBag *pPropBag; + hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag, (void **)&pPropBag); + if (SUCCEEDED(hr)) { + // To retrieve the filter's friendly name, do the following: + VARIANT var; + VariantInit(&var); + hr = pPropBag->Read(L"FriendlyName", &var, nullptr); + if (SUCCEEDED(hr)) + { + // Display the name in your UI somehow. + QString str((QChar*)var.bstrVal, int(std::wcslen(var.bstrVal))); + ret.push_back(str); + } + VariantClear(&var); + pPropBag->Release(); + } + pMoniker->Release(); + } + pEnumCat->Release(); + } + else + qDebug() << "failed CLSID_VideoInputDeviceCategory" << hr; + + pSysDevEnum->Release(); +#endif + +#ifdef __linux + for (int i = 0; i < 16; i++) { + char buf[32]; + snprintf(buf, sizeof(buf), "/dev/video%d", i); + + if (access(buf, R_OK | W_OK) == 0) { + int fd = open(buf, O_RDONLY); + if (fd == -1) + continue; + struct v4l2_capability video_cap; + if(ioctl(fd, VIDIOC_QUERYCAP, &video_cap) == -1) + { + qDebug() << "VIDIOC_QUERYCAP" << errno; + close(fd); + continue; + } + ret.push_back(QString((const char*)video_cap.card)); + close(fd); + } + } +#endif + return ret; +} |