From 4fe10945026a2be7353703b9b25b3f495a1871a1 Mon Sep 17 00:00:00 2001 From: Vladimir Sumarov Date: Tue, 9 Dec 2025 14:04:13 -0800 Subject: [PATCH 1/3] ensure mutex to be created when used --- source/dshow-enum.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/dshow-enum.cpp b/source/dshow-enum.cpp index cad65a1..8f26aad 100644 --- a/source/dshow-enum.cpp +++ b/source/dshow-enum.cpp @@ -510,7 +510,11 @@ static bool EnumExceptionVideoDevices(EnumDeviceCallback callback, void *param) return true; } -static recursive_mutex enumMutex; +static std::mutex &GetEnumMutex() +{ + static std::mutex m; + return m; +} static bool CheckForDLCallback(void *unused, IBaseFilter *filter, const wchar_t *deviceName, @@ -536,7 +540,7 @@ static void CheckForDecklinkVideo(bool activate) bool EnumDevices(const GUID &type, EnumDeviceCallback callback, void *param, bool activate) { - lock_guard lock(enumMutex); + lock_guard lock(GetEnumMutex()); ComPtr deviceEnum; ComPtr enumMoniker; ComPtr deviceInfo; From d4359e73d78cb58bd9a76504570a2784465d5fdb Mon Sep 17 00:00:00 2001 From: Vladimir Sumarov Date: Tue, 9 Dec 2025 16:29:25 -0800 Subject: [PATCH 2/3] restore recursive mutex --- source/dshow-enum.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/dshow-enum.cpp b/source/dshow-enum.cpp index 8f26aad..99dc3a2 100644 --- a/source/dshow-enum.cpp +++ b/source/dshow-enum.cpp @@ -510,9 +510,9 @@ static bool EnumExceptionVideoDevices(EnumDeviceCallback callback, void *param) return true; } -static std::mutex &GetEnumMutex() +static std::recursive_mutex &GetEnumMutex() { - static std::mutex m; + static std::recursive_mutex m; return m; } @@ -540,7 +540,7 @@ static void CheckForDecklinkVideo(bool activate) bool EnumDevices(const GUID &type, EnumDeviceCallback callback, void *param, bool activate) { - lock_guard lock(GetEnumMutex()); + lock_guard lock(GetEnumMutex()); ComPtr deviceEnum; ComPtr enumMoniker; ComPtr deviceInfo; From 018b20eb477e35f950ed5ee3a1f5483143282122 Mon Sep 17 00:00:00 2001 From: Vladimir Sumarov Date: Tue, 16 Dec 2025 16:49:56 -0800 Subject: [PATCH 3/3] potential fix for plugin init crash --- source/dshow-enum.cpp | 49 +++++++++++++++++++++++------------------- source/dshowencode.cpp | 4 ++-- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/source/dshow-enum.cpp b/source/dshow-enum.cpp index 99dc3a2..52812c5 100644 --- a/source/dshow-enum.cpp +++ b/source/dshow-enum.cpp @@ -451,16 +451,20 @@ static bool EnumDevice(const GUID &type, IMoniker *deviceInfo, hr = deviceInfo->BindToStorage(0, 0, IID_IPropertyBag, (void **)&propertyData); if (FAILED(hr)) - return true; + goto cleanup; - VARIANT deviceName, devicePath; + VARIANT deviceName; + VariantInit(&deviceName); deviceName.vt = VT_BSTR; + + VARIANT devicePath; + VariantInit(&devicePath); devicePath.vt = VT_BSTR; - devicePath.bstrVal = NULL; hr = propertyData->Read(L"FriendlyName", &deviceName, NULL); - if (FAILED(hr)) - return true; + if (FAILED(hr) || deviceName.vt != VT_BSTR || !deviceName.bstrVal) { + goto cleanup; + } /* workaround to a crash in decklink drivers; if no decklink device * is plugged in to the system, it will still try to enumerate the @@ -469,27 +473,30 @@ static bool EnumDevice(const GUID &type, IMoniker *deviceInfo, if (deviceName.bstrVal && type == CLSID_AudioInputDeviceCategory && wcsstr(deviceName.bstrVal, L"Decklink") != nullptr && !decklinkVideoPresent) { - return true; + goto cleanup; } - hr = propertyData->Read(L"DevicePath", &devicePath, NULL); + HRESULT hrPath; + const wchar_t *devPath; + hrPath = propertyData->Read(L"DevicePath", &devicePath, nullptr); + devPath = SUCCEEDED(hrPath) ? devicePath.bstrVal : nullptr; if (activate) { - hr = deviceInfo->BindToObject(NULL, 0, IID_IBaseFilter, - (void **)&filter); - if (SUCCEEDED(hr)) { + HRESULT hrObj = deviceInfo->BindToObject( + nullptr, 0, IID_IBaseFilter, (void **)&filter); + if (SUCCEEDED(hrObj)) { if (!callback(param, filter, deviceName.bstrVal, - devicePath.bstrVal)) - return false; + devPath)) + goto cleanup; } } else { - if (SUCCEEDED(hr)) { - if (!callback(param, NULL, deviceName.bstrVal, - devicePath.bstrVal)) - return false; - } + if (!callback(param, nullptr, deviceName.bstrVal, devPath)) + goto cleanup; } +cleanup: + VariantClear(&deviceName); + VariantClear(&devicePath); return true; } @@ -510,10 +517,8 @@ static bool EnumExceptionVideoDevices(EnumDeviceCallback callback, void *param) return true; } -static std::recursive_mutex &GetEnumMutex() -{ - static std::recursive_mutex m; - return m; +namespace { +static std::recursive_mutex g_enum_mutex; } static bool CheckForDLCallback(void *unused, IBaseFilter *filter, @@ -540,7 +545,7 @@ static void CheckForDecklinkVideo(bool activate) bool EnumDevices(const GUID &type, EnumDeviceCallback callback, void *param, bool activate) { - lock_guard lock(GetEnumMutex()); + std::lock_guard lock(g_enum_mutex); ComPtr deviceEnum; ComPtr enumMoniker; ComPtr deviceInfo; diff --git a/source/dshowencode.cpp b/source/dshowencode.cpp index 7882e0f..a4a04c9 100644 --- a/source/dshowencode.cpp +++ b/source/dshowencode.cpp @@ -93,7 +93,7 @@ static bool EnumVideoEncoder(vector &encoders, IBaseFilter *encoder, return true; id.name = deviceName; - id.path = devicePath; + id.path = devicePath ? devicePath : L""; encoders.push_back(id); (void)encoder; @@ -104,7 +104,7 @@ bool VideoEncoder::EnumEncoders(vector &encoders) { encoders.clear(); return EnumDevices(KSCATEGORY_ENCODER, - EnumDeviceCallback(EnumVideoEncoder), &encoders, true); + EnumDeviceCallback(EnumVideoEncoder), &encoders, false); } };