diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2016-05-22 12:52:36 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2016-05-22 13:29:44 +0200 |
commit | f65e2035abfbd2660ed91d7882a2bdcd9301db0a (patch) | |
tree | 3c7d7b3c648d8ed31f65174fc68c71adf9d1d36a | |
parent | c6819cfa0213a72be66c7e6c9808fd1b7ad9ce03 (diff) |
{compat,api}/camera: make CoInitializeEx use the right threading apartment
-rw-r--r-- | opentrack-compat/camera-names.cpp | 20 | ||||
-rw-r--r-- | opentrack/opencv-camera-dialog.hpp | 63 |
2 files changed, 56 insertions, 27 deletions
diff --git a/opentrack-compat/camera-names.cpp b/opentrack-compat/camera-names.cpp index 72bcf41a..ef5c159d 100644 --- a/opentrack-compat/camera-names.cpp +++ b/opentrack-compat/camera-names.cpp @@ -1,20 +1,18 @@ #include "camera-names.hpp" -#if defined(OPENTRACK_API) && defined(_WIN32) +#ifdef _WIN32 # define NO_DSHOW_STRSAFE # include <windows.h> # include <dshow.h> -#endif - -#if defined(OPENTRACK_API) && (defined(__unix) || defined(__linux) || defined(__APPLE__)) +#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 <fcntl.h> +# include <sys/ioctl.h> +# include <linux/videodev2.h> +# include <cerrno> #endif #include <QDebug> @@ -33,9 +31,9 @@ OPENTRACK_COMPAT_EXPORT QList<QString> get_camera_names() { #if defined(_WIN32) // Create the System Device Enumerator. HRESULT hr; - hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); + hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(hr)) - qDebug() << "failed CoInitializeEx" << hr; + qDebug() << "failed CoInitializeEx" << hr << GetLastError(); ICreateDevEnum *pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum); if (FAILED(hr)) @@ -110,4 +108,4 @@ OPENTRACK_COMPAT_EXPORT QList<QString> get_camera_names() { } #endif return ret; -}
\ No newline at end of file +} diff --git a/opentrack/opencv-camera-dialog.hpp b/opentrack/opencv-camera-dialog.hpp index 96c7a643..eac26bde 100644 --- a/opentrack/opencv-camera-dialog.hpp +++ b/opentrack/opencv-camera-dialog.hpp @@ -8,6 +8,8 @@ #pragma once +#if !defined(QT_MOC_RUN) + #include <QTimer> #include <QMutex> #include <QMutexLocker> @@ -15,30 +17,45 @@ #include "opentrack-compat/camera-names.hpp" #ifdef __linux -#include <QProcess> +# include <QProcess> +#else +# include "opentrack-compat/sleep.hpp" #endif -template<typename tracker> +#ifdef _WIN32 +# include <objbase.h> +# include <winerror.h> +# include <windows.h> +#endif + +static void init_com_threading(void) +{ + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if (FAILED(hr)) + qDebug() << "failed CoInitializeEx" << hr << "code" << GetLastError(); +} + +static void maybe_grab_frame(cv::VideoCapture& cap) +{ + for (int i = 0; i < 60; i++) + { + if (cap.grab()) + break; + portable::sleep(50); + } +} + class camera_dialog { -#ifdef __linux public: + inline virtual ~camera_dialog() {} +#ifdef __linux void open_camera_settings(cv::VideoCapture *, const QString &camera_name, QMutex *) { int idx = camera_name_to_index(camera_name); QProcess::startDetached("qv4l2", QStringList() << "-d" << ("/dev/video" + QString::number(idx))); } #else - cv::VideoCapture fake_capture; - QTimer t; - -private: - void delete_capture() - { - fake_capture.open(""); - } - -public: void open_camera_settings(cv::VideoCapture* cap, const QString& camera_name, QMutex* camera_mtx) { if (cap) @@ -47,6 +64,8 @@ public: if (cap->isOpened()) { + init_com_threading(); + maybe_grab_frame(*cap); cap->set(cv::CAP_PROP_SETTINGS, 1); return; } @@ -59,14 +78,26 @@ public: if (!t.isSingleShot()) QObject::connect(&t, &QTimer::timeout, [&]() -> void { delete_capture(); }); - t.setSingleShot(true); - t.setInterval(3000); - + init_com_threading(); fake_capture = cv::VideoCapture(camera_name_to_index(camera_name)); + maybe_grab_frame(fake_capture); fake_capture.set(cv::CAP_PROP_SETTINGS, 1); + + t.setSingleShot(true); + t.setInterval(5000); + // HACK: we're not notified when it's safe to close the capture t.start(); } +private: + cv::VideoCapture fake_capture; + QTimer t; + void delete_capture() + { + fake_capture.open(""); + } #endif }; +#endif + |