summaryrefslogtreecommitdiffhomepage
path: root/cv/video-property-page.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2018-01-04 08:23:27 +0100
committerStanislaw Halik <sthalik@misaki.pl>2018-01-04 08:23:27 +0100
commit4b517fccf19a8de4e517532dca2df11cca36f3eb (patch)
tree657189b7f8928d09c11c6a4ed76ef2985b684859 /cv/video-property-page.cpp
parent3a987e9ae9aa72f361bb7a549102cb66c5abd268 (diff)
cv: fixed ps3 eye dialog
Diffstat (limited to 'cv/video-property-page.cpp')
-rw-r--r--cv/video-property-page.cpp224
1 files changed, 92 insertions, 132 deletions
diff --git a/cv/video-property-page.cpp b/cv/video-property-page.cpp
index 0595f04a..66060caa 100644
--- a/cv/video-property-page.cpp
+++ b/cv/video-property-page.cpp
@@ -10,178 +10,141 @@
#ifdef _WIN32
#include "compat/camera-names.hpp"
+#include "compat/sleep.hpp"
+#include "compat/run-in-thread.hpp"
#include "opentrack-library-path.h"
#include <cstring>
-#include <QRegularExpression>
+#include <opencv2/videoio.hpp>
+
+#include <QApplication>
#include <QProcess>
+#include <QThread>
+#include <QMessageBox>
+
#include <QDebug>
-#include <QFile>
#include <dshow.h>
-#define CHECK(expr) if (FAILED(hr = (expr))) { qDebug() << QStringLiteral(#expr) << hr; goto done; }
-#define CHECK2(expr) if (!(expr)) { qDebug() << QStringLiteral(#expr); goto done; }
+#define CHECK(expr) if (FAILED(hr = (expr))) { qDebug() << QLatin1String(#expr) << hr; goto done; }
+#define CHECK2(expr) if (!(expr)) { qDebug() << QLatin1String(#expr); goto done; }
-bool video_property_page::show_from_capture(cv::VideoCapture& cap, int index)
+bool video_property_page::show_from_capture(cv::VideoCapture& cap, int /*index */)
{
- const QString name = get_camera_names().value(index, "");
-
- if (name == "PS3Eye Camera")
- {
- return QProcess::startDetached(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH "./amcap.exe");
- }
- else
- {
- cap.set(cv::CAP_PROP_SETTINGS, 0);
- return true;
- }
+ cap.set(cv::CAP_PROP_SETTINGS, 0);
+ return true;
}
-bool video_property_page::should_show_dialog(const QString& camera_name)
+struct prop_settings_worker final : QThread
{
- using re = QRegularExpression;
- static const re regexen[] =
- {
- //re("^PS3Eye Camera$"),
- re("^A4 TECH "),
- };
- bool avail = true;
- for (const re& r : regexen)
- {
- avail &= !r.match(camera_name).hasMatch();
- if (!avail)
- break;
- }
- return avail;
-}
+ prop_settings_worker(int idx);
+ ~prop_settings_worker() override;
+ void _open_prop_page();
+ void run() override;
-bool video_property_page::show(int id)
-{
- const QString name = get_camera_names().value(id, "");
+ cv::VideoCapture cap;
+ int _idx = -1;
+};
- if (name == "PS3Eye Camera")
- return QProcess::startDetached(OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH "./amcap.exe");
+prop_settings_worker::prop_settings_worker(int idx)
+{
+ if (cap.get(cv::CAP_PROP_SETTINGS) < 0 || 1)
+ run_in_thread_async(qApp, []() {
+ QMessageBox msg;
+ msg.setTextFormat(Qt::RichText);
+ msg.setWindowTitle("Camera properties");
+
+ static const char* uri = "https://github.com/opentrack/opencv/tree/fork";
+
+ msg.setText(QString("<p>Must use the opencv fork.</p>"
+ "<p>See &lt;<a href='%1'>%1</a>&gt;</p>").arg(uri));
+ msg.setStandardButtons(QMessageBox::Cancel);
+ msg.setIcon(QMessageBox::Warning);
+ msg.exec();
+ });
+ else if (cap.get(cv::CAP_PROP_SETTINGS > 0))
+ run_in_thread_async(qApp, []() {
+ QMessageBox::warning(nullptr,
+ "Camera properties",
+ "Dialog already opened",
+ QMessageBox::Cancel,
+ QMessageBox::NoButton);
+ });
else
{
- IBaseFilter* filter = NULL;
- bool ret = false;
-
- CHECK2(filter = get_device(id));
-
- ret = SUCCEEDED(ShowFilterPropertyPages(filter));
-
-done:
- if (filter)
- filter->Release();
-
- return ret;
+ _idx = idx;
+ // DON'T MOVE IT
+ // ps3 eye will reset to default settings if done from another thread
+ _open_prop_page();
}
}
-int video_property_page::ShowFilterPropertyPages(IBaseFilter* filter)
+void prop_settings_worker::_open_prop_page()
{
- ISpecifyPropertyPages* pProp = NULL;
- IUnknown* unk = NULL;
- CAUUID caGUID = { 0, NULL };
- FILTER_INFO FilterInfo = { {0}, NULL };
- HRESULT hr;
-
- CHECK(filter->QueryInterface(IID_ISpecifyPropertyPages, (void**)&pProp));
- CHECK(pProp->GetPages(&caGUID));
- CHECK(filter->QueryFilterInfo(&FilterInfo));
-
- filter->QueryInterface(IID_IUnknown, (void**)&unk);
-
- // OleInitialize, CoCreateInstance et al. don't help with ps3 eye.
-
- // cl-eye uses this
- // perhaps more than IBaseFilter* -> IUnknown* needs be passed to lplpUnk
- // and the OleCreatePropertyFrame equiv
-#if 0
- OCPFIPARAMS params;
- params.cbStructSize = sizeof(params);
- params.hWndOwner = GetActiveWindow();
- params.x = 0;
- params.y = 0;
- params.lpszCaption = L"camera props";
- params.cObjects = 1;
- params.lplpUnk = &unk;
- params.cPages = 1;
- //OleCreatePropertyFrameIndirect()
-#endif
+ cap.open(_idx);
- OleCreatePropertyFrame(
- NULL, // Parent window
- 0, 0, // Reserved
- FilterInfo.achName, // Caption for the dialog box
- 1, // Number of objects (just the filter)
- &unk, // Array of object pointers.
- caGUID.cElems, // Number of property pages
- caGUID.pElems, // Array of property page CLSIDs
- 0, // Locale identifier
- 0, NULL // Reserved
- );
+ if (cap.isOpened())
+ {
+ cv::Mat tmp;
-done:
- if (FilterInfo.pGraph)
- FilterInfo.pGraph->Release();
+ for (unsigned k = 0; k < 2000/50; k++)
+ {
+ if (cap.read(tmp))
+ goto ok;
+ portable::sleep(50);
+ }
+ }
- if (caGUID.pElems)
- CoTaskMemFree(caGUID.pElems);
+ qDebug() << "property-page: can't open camera";
+ _idx = -1;
- if (pProp)
- pProp->Release();
+ return;
- if (unk)
- unk->Release();
+ok:
+ portable::sleep(100);
- return hr;
+ qDebug() << "property-page: opening for" << _idx;
+ cap.set(cv::CAP_PROP_SETTINGS, 0);
}
-IBaseFilter* video_property_page::get_device(int id)
+prop_settings_worker::~prop_settings_worker()
{
- ICreateDevEnum* pSysDevEnum = NULL;
- IEnumMoniker* pEnumCat = NULL;
- IMoniker* pMoniker = NULL;
- IBaseFilter* filter = NULL;
- HRESULT hr;
+ if (_idx != -1)
+ {
+ // ax filter is race condition-prone
+ portable::sleep(250);
+ cap.release();
+ // idem
+ portable::sleep(250);
- CHECK(CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum));
- CHECK(pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0));
+ qDebug() << "property-page: closed" << _idx;
+ }
+}
- for (int i = 0; !filter && SUCCEEDED(pEnumCat->Next(1, &pMoniker, NULL)); pMoniker->Release(), i++)
+void prop_settings_worker::run()
+{
+ if (_idx != -1)
{
- if (i == id)
- {
- CHECK(pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&filter));
- break;
- }
+ while (cap.get(cv::CAP_PROP_SETTINGS) > 0)
+ portable::sleep(1000);
}
-done:
- if (pMoniker)
- pMoniker->Release();
-
- if (pEnumCat)
- pEnumCat->Release();
+ connect(this, &QThread::finished, this, &QObject::deleteLater);
+}
- if (pSysDevEnum)
- pSysDevEnum->Release();
+bool video_property_page::show(int idx)
+{
+ auto thread = new prop_settings_worker(idx);
+ thread->start();
- return filter;
+ return true;
}
#elif defined(__linux)
# include <QProcess>
# include "compat/camera-names.hpp"
-bool video_property_page::should_show_dialog(const QString&)
-{
- return true;
-}
-
bool video_property_page::show(int idx)
{
const QList<QString> camera_names(get_camera_names());
@@ -199,8 +162,5 @@ bool video_property_page::show_from_capture(cv::VideoCapture&, int idx)
#else
bool video_property_page::show(int) { return false; }
bool video_property_page::show_from_capture(cv::VideoCapture&, int) { return false; }
-bool video_property_page::should_show_dialog(const QString& camera_name)
-{
- return false;
-}
#endif
+