summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-05-22 12:52:36 +0200
committerStanislaw Halik <sthalik@misaki.pl>2016-05-22 13:29:44 +0200
commitf65e2035abfbd2660ed91d7882a2bdcd9301db0a (patch)
tree3c7d7b3c648d8ed31f65174fc68c71adf9d1d36a
parentc6819cfa0213a72be66c7e6c9808fd1b7ad9ce03 (diff)
{compat,api}/camera: make CoInitializeEx use the right threading apartment
-rw-r--r--opentrack-compat/camera-names.cpp20
-rw-r--r--opentrack/opencv-camera-dialog.hpp63
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
+