From 1c4a8bfb6668e9b925e227980c21a0fd019bdf9b Mon Sep 17 00:00:00 2001 From: Thad House Date: Thu, 2 Dec 2021 13:48:03 -0800 Subject: [PATCH] [cscore] Cleanup Windows USB camera impl (#3751) - Use wpiutil string conversion rather than codecvt (which is deprecated). - Force A function types. --- .../src/main/native/windows/UsbCameraImpl.cpp | 46 +++++++++++-------- .../native/windows/WindowsMessagePump.cpp | 16 +++---- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/cscore/src/main/native/windows/UsbCameraImpl.cpp b/cscore/src/main/native/windows/UsbCameraImpl.cpp index bf517160c0..1a416726e8 100644 --- a/cscore/src/main/native/windows/UsbCameraImpl.cpp +++ b/cscore/src/main/native/windows/UsbCameraImpl.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -25,7 +24,9 @@ #include #include #include +#include #include +#include #include #include @@ -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> utf8_conv; - m_widePath = utf8_conv.from_bytes(m_path.c_str()); + wpi::SmallVector 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(pHdr); + pDi = reinterpret_cast(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(parameter); + DEV_BROADCAST_DEVICEINTERFACE_A* pDi = + reinterpret_cast(parameter); m_path = pDi->dbcc_name; - std::wstring_convert> utf8_conv; - m_widePath = utf8_conv.from_bytes(m_path.c_str()); + wpi::SmallVector 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> utf8_conv; - m_widePath = utf8_conv.from_bytes(m_path.c_str()); + wpi::SmallVector wideStorage; + wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage); + m_widePath = std::wstring{wideStorage.data(), wideStorage.size()}; } DeviceDisconnect(); DeviceConnect(); @@ -1048,7 +1052,8 @@ std::vector EnumerateUsbCameras(CS_Status* status) { // Ensure we are initialized by grabbing the message pump // GetMessagePump(); - std::wstring_convert> utf8_conv; + wpi::SmallString<128> storage; + WCHAR buf[512]; ComPtr pAttributes; IMFActivate** ppDevices = nullptr; UINT32 count = 0; @@ -1080,14 +1085,19 @@ std::vector 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); diff --git a/cscore/src/main/native/windows/WindowsMessagePump.cpp b/cscore/src/main/native/windows/WindowsMessagePump.cpp index e0d78d7713..716edd91dc 100644 --- a/cscore/src/main/native/windows/WindowsMessagePump.cpp +++ b/cscore/src/main/native/windows/WindowsMessagePump.cpp @@ -89,7 +89,7 @@ static std::shared_ptr GetClassHolder() { WindowsMessagePump::WindowsMessagePump( std::function 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);