mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[cscore] Cleanup Windows USB camera impl (#3751)
- Use wpiutil string conversion rather than codecvt (which is deprecated). - Force A function types.
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
#include <windowsx.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <codecvt>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -25,7 +24,9 @@
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <opencv2/imgproc/imgproc.hpp>
|
||||
#include <wpi/ConvertUTF.h>
|
||||
#include <wpi/MemAlloc.h>
|
||||
#include <wpi/SmallString.h>
|
||||
#include <wpi/StringExtras.h>
|
||||
#include <wpi/timestamp.h>
|
||||
|
||||
@@ -72,8 +73,9 @@ UsbCameraImpl::UsbCameraImpl(std::string_view name, wpi::Logger& logger,
|
||||
Notifier& notifier, Telemetry& telemetry,
|
||||
std::string_view path)
|
||||
: SourceImpl{name, logger, notifier, telemetry}, m_path{path} {
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
m_widePath = utf8_conv.from_bytes(m_path.c_str());
|
||||
wpi::SmallVector<wchar_t, 128> wideStorage;
|
||||
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
|
||||
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
|
||||
m_deviceId = -1;
|
||||
StartMessagePump();
|
||||
}
|
||||
@@ -227,7 +229,7 @@ void UsbCameraImpl::PostRequestNewFrame() {
|
||||
|
||||
bool UsbCameraImpl::CheckDeviceChange(WPARAM wParam, DEV_BROADCAST_HDR* pHdr,
|
||||
bool* connected) {
|
||||
DEV_BROADCAST_DEVICEINTERFACE* pDi = NULL;
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A* pDi = NULL;
|
||||
|
||||
*connected = false;
|
||||
|
||||
@@ -240,9 +242,9 @@ bool UsbCameraImpl::CheckDeviceChange(WPARAM wParam, DEV_BROADCAST_HDR* pHdr,
|
||||
|
||||
// Compare the device name with the symbolic link.
|
||||
|
||||
pDi = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(pHdr);
|
||||
pDi = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE_A*>(pHdr);
|
||||
|
||||
if (_stricmp(m_path.c_str(), pDi->dbcc_name) == 0) {
|
||||
if (wpi::equals_lower(m_path, pDi->dbcc_name)) {
|
||||
if (wParam == DBT_DEVICEARRIVAL) {
|
||||
*connected = true;
|
||||
return true;
|
||||
@@ -411,11 +413,12 @@ LRESULT UsbCameraImpl::PumpMain(HWND hwnd, UINT uiMsg, WPARAM wParam,
|
||||
// If has device ID, use the device ID from the event
|
||||
// because of windows bug
|
||||
auto&& device = devices[m_deviceId];
|
||||
DEV_BROADCAST_DEVICEINTERFACE* pDi =
|
||||
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(parameter);
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A* pDi =
|
||||
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE_A*>(parameter);
|
||||
m_path = pDi->dbcc_name;
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
m_widePath = utf8_conv.from_bytes(m_path.c_str());
|
||||
wpi::SmallVector<wchar_t, 128> wideStorage;
|
||||
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
|
||||
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
|
||||
} else {
|
||||
// This device not found
|
||||
break;
|
||||
@@ -747,8 +750,9 @@ CS_StatusValue UsbCameraImpl::DeviceProcessCommand(
|
||||
{
|
||||
std::scoped_lock lock(m_mutex);
|
||||
m_path = msg->dataStr;
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
m_widePath = utf8_conv.from_bytes(m_path.c_str());
|
||||
wpi::SmallVector<wchar_t, 128> wideStorage;
|
||||
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
|
||||
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
|
||||
}
|
||||
DeviceDisconnect();
|
||||
DeviceConnect();
|
||||
@@ -1048,7 +1052,8 @@ std::vector<UsbCameraInfo> EnumerateUsbCameras(CS_Status* status) {
|
||||
// Ensure we are initialized by grabbing the message pump
|
||||
// GetMessagePump();
|
||||
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
|
||||
wpi::SmallString<128> storage;
|
||||
WCHAR buf[512];
|
||||
ComPtr<IMFAttributes> pAttributes;
|
||||
IMFActivate** ppDevices = nullptr;
|
||||
UINT32 count = 0;
|
||||
@@ -1080,14 +1085,19 @@ std::vector<UsbCameraInfo> EnumerateUsbCameras(CS_Status* status) {
|
||||
for (UINT32 i = 0; i < count; i++) {
|
||||
UsbCameraInfo info;
|
||||
info.dev = i;
|
||||
WCHAR buf[512];
|
||||
|
||||
UINT32 characters = 0;
|
||||
ppDevices[i]->GetString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, buf,
|
||||
sizeof(buf) / sizeof(WCHAR), NULL);
|
||||
info.name = utf8_conv.to_bytes(buf);
|
||||
sizeof(buf) / sizeof(WCHAR), &characters);
|
||||
storage.clear();
|
||||
wpi::sys::windows::UTF16ToUTF8(buf, characters, storage);
|
||||
info.name = storage.string();
|
||||
ppDevices[i]->GetString(
|
||||
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, buf,
|
||||
sizeof(buf) / sizeof(WCHAR), NULL);
|
||||
info.path = utf8_conv.to_bytes(buf);
|
||||
sizeof(buf) / sizeof(WCHAR), &characters);
|
||||
storage.clear();
|
||||
wpi::sys::windows::UTF16ToUTF8(buf, characters, storage);
|
||||
info.path = storage.string();
|
||||
|
||||
// Try to parse path from symbolic link
|
||||
ParseVidAndPid(info.path, &info.productId, &info.vendorId);
|
||||
|
||||
@@ -89,7 +89,7 @@ static std::shared_ptr<ClassHolder> GetClassHolder() {
|
||||
WindowsMessagePump::WindowsMessagePump(
|
||||
std::function<LRESULT(HWND, UINT, WPARAM, LPARAM)> callback) {
|
||||
m_callback = callback;
|
||||
auto handle = CreateEvent(NULL, true, false, NULL);
|
||||
auto handle = CreateEventA(NULL, true, false, NULL);
|
||||
m_mainThread = std::thread([=] { ThreadMain(handle); });
|
||||
auto waitResult = WaitForSingleObject(handle, 1000);
|
||||
if (waitResult == WAIT_OBJECT_0) {
|
||||
@@ -98,7 +98,7 @@ WindowsMessagePump::WindowsMessagePump(
|
||||
}
|
||||
|
||||
WindowsMessagePump::~WindowsMessagePump() {
|
||||
auto res = SendMessage(hwnd, WM_CLOSE, NULL, NULL);
|
||||
auto res = SendMessageA(hwnd, WM_CLOSE, NULL, NULL);
|
||||
if (m_mainThread.joinable())
|
||||
m_mainThread.join();
|
||||
}
|
||||
@@ -110,28 +110,28 @@ void WindowsMessagePump::ThreadMain(HANDLE eventHandle) {
|
||||
MFStartup(MF_VERSION);
|
||||
|
||||
auto classHolder = GetClassHolder();
|
||||
hwnd = CreateWindowEx(0, classHolder->class_name, "dummy_name", 0, 0, 0, 0, 0,
|
||||
HWND_MESSAGE, NULL, NULL, this);
|
||||
hwnd = CreateWindowExA(0, classHolder->class_name, "dummy_name", 0, 0, 0, 0,
|
||||
0, HWND_MESSAGE, NULL, NULL, this);
|
||||
|
||||
// Register for device notifications
|
||||
HDEVNOTIFY g_hdevnotify = NULL;
|
||||
HDEVNOTIFY g_hdevnotify2 = NULL;
|
||||
|
||||
DEV_BROADCAST_DEVICEINTERFACE di = {0};
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A di = {0};
|
||||
di.dbcc_size = sizeof(di);
|
||||
di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
di.dbcc_classguid = KSCATEGORY_CAPTURE;
|
||||
|
||||
g_hdevnotify =
|
||||
RegisterDeviceNotification(hwnd, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
RegisterDeviceNotificationA(hwnd, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
|
||||
DEV_BROADCAST_DEVICEINTERFACE di2 = {0};
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A di2 = {0};
|
||||
di2.dbcc_size = sizeof(di2);
|
||||
di2.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
di2.dbcc_classguid = KSCATEGORY_VIDEO_CAMERA;
|
||||
|
||||
g_hdevnotify2 =
|
||||
RegisterDeviceNotification(hwnd, &di2, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
RegisterDeviceNotificationA(hwnd, &di2, DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
|
||||
SetEvent(eventHandle);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user