summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-01-26 10:14:34 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-01-26 12:13:38 +0100
commit58761c8d6fa2f64b85845ccd18f759f0ecc7e550 (patch)
tree5878eaaa3ce68e4971f7effddde3f9aa557da197
parentb29b8e48fe59f44fd28de5f6879730bcdf34a9dd (diff)
compat/camera-names: allow cameras with same name
Some users have multiple units of the same camera model connected at the same time. Allow selecting each of these individual units. Issue: #1415
-rw-r--r--compat/camera-names.cpp38
-rw-r--r--migration/20220126_00-camera-name.cpp79
2 files changed, 110 insertions, 7 deletions
diff --git a/compat/camera-names.cpp b/compat/camera-names.cpp
index 8eef6d61..c7e38544 100644
--- a/compat/camera-names.cpp
+++ b/compat/camera-names.cpp
@@ -2,6 +2,7 @@
#include <algorithm>
#include <iterator>
+#include <QRegularExpression>
#ifdef _WIN32
# include <cwchar>
@@ -41,6 +42,31 @@ int camera_name_to_index(const QString &name)
return -1;
}
+static QString prop_to_qstring(IPropertyBag* pPropBag, const wchar_t* name)
+{
+ QString ret{};
+ VARIANT var;
+ VariantInit(&var);
+ HRESULT hr = pPropBag->Read(name, &var, nullptr);
+ if (SUCCEEDED(hr))
+ ret = QString{(const QChar*)var.bstrVal, int(std::wcslen(var.bstrVal))};
+ VariantClear(&var);
+ return ret;
+}
+
+static QString device_path_from_qstring(const QString& str)
+{
+ // language=RegExp prefix=R"/( suffix=)/"
+ static const QRegularExpression regexp{R"/(#vid_([0-9a-f]{4})&pid_([0-9a-f]{4})&mi_([0-9a-f]{2})#([^#]+))/",
+ QRegularExpression::CaseInsensitiveOption};
+ auto match = regexp.match(str);
+ if (!match.hasMatch())
+ return {};
+ QString id = match.captured(4);
+ id.replace('&', '_');
+ return id;
+}
+
std::vector<std::tuple<QString, int>> get_camera_names()
{
std::vector<std::tuple<QString, int>> ret;
@@ -67,18 +93,16 @@ std::vector<std::tuple<QString, int>> get_camera_names()
{
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag, (void **)&pPropBag);
- if (SUCCEEDED(hr)) {
+ 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)));
+ QString str = prop_to_qstring(pPropBag, L"FriendlyName");
+ QString path = device_path_from_qstring(prop_to_qstring(pPropBag, L"DevicePath"));
+ if (!path.isNull())
+ str += QStringLiteral(" [%1]").arg(path);
ret.push_back({ str, (int)ret.size() });
}
- VariantClear(&var);
pPropBag->Release();
}
pMoniker->Release();
diff --git a/migration/20220126_00-camera-name.cpp b/migration/20220126_00-camera-name.cpp
new file mode 100644
index 00000000..adb6d718
--- /dev/null
+++ b/migration/20220126_00-camera-name.cpp
@@ -0,0 +1,79 @@
+#ifdef _WIN32
+#include "migration.hpp"
+#include "options/options.hpp"
+#include "compat/camera-names.hpp"
+
+using namespace migrations;
+using namespace options;
+
+#include "api/plugin-support.hpp"
+#include "compat/library-path.hpp"
+#include <tuple>
+#include <QString>
+
+static const std::tuple<const char*, const char*> modules[] = {
+ { "tracker-aruco", "camera-name" },
+ { "tracker-easy", "camera-name" },
+ { "neuralnet-tracker", "camera-name" },
+ { "tracker-pt", "camera-name" },
+};
+
+struct win32_camera_name : migration
+{
+ QString unique_date() const override
+ {
+ return "20220126_00";
+ }
+
+ QString name() const override
+ {
+ return "camera name";
+ }
+
+ bool should_run() const override
+ {
+ for (const auto& [name, prop] : modules)
+ {
+ bundle b { make_bundle(name) };
+ QString str = b->get_variant(prop).toString();
+ if (!str.isEmpty() && !str.contains(" ["))
+ return true;
+ }
+ return false;
+ }
+
+ void run() override
+ {
+ auto cameras = get_camera_names();
+
+ for (const auto& [bundle_name, prop] : modules)
+ {
+ bundle b { make_bundle(bundle_name) };
+ QString name = b->get_variant(prop).toString();
+ if (name.isEmpty() || name.contains(" ["))
+ continue;
+ auto full_name_of = [&](const QString& str) {
+ QString ret = str;
+ auto prefix = str + " [";
+ for (const auto& [x, _] : cameras)
+ {
+ if (x == str)
+ return str;
+ if (x.startsWith(prefix))
+ ret = x;
+ }
+ return ret;
+ };
+ auto full_name = full_name_of(name);
+ if (name != full_name)
+ {
+ b->store_kv(prop, full_name);
+ b->save();
+ }
+ }
+ }
+};
+
+OPENTRACK_MIGRATION(win32_camera_name)
+
+#endif