From aeb0d050171456e33fa2d4a7bfc70f738df16f24 Mon Sep 17 00:00:00 2001 From: Jonas Kvinge Date: Thu, 15 Oct 2020 16:06:07 +0200 Subject: [PATCH] Add CoInitializeEx() to mmdevice finder and refactor code --- src/engine/mmdevicefinder.cpp | 107 ++++++++++++++-------------------- 1 file changed, 44 insertions(+), 63 deletions(-) diff --git a/src/engine/mmdevicefinder.cpp b/src/engine/mmdevicefinder.cpp index 8a952f275..e861d2c45 100644 --- a/src/engine/mmdevicefinder.cpp +++ b/src/engine/mmdevicefinder.cpp @@ -36,26 +36,8 @@ MMDeviceFinder::MMDeviceFinder() : DeviceFinder("mmdevice", { "wasapisink" }) {} QList MMDeviceFinder::ListDevices() { - HRESULT hr = S_OK; - - IMMDeviceEnumerator *enumerator = nullptr; - hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enumerator); - if (FAILED(hr)) { - return QList(); - } - - IMMDeviceCollection *collection = nullptr; - hr = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &collection); - if (FAILED(hr)) { - enumerator->Release(); - return QList(); - } - - UINT count; - hr = collection->GetCount(&count); - if (FAILED(hr)) { - collection->Release(); - enumerator->Release(); + HRESULT hr_coinit = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if (hr_coinit != S_OK && hr_coinit != S_FALSE) { return QList(); } @@ -65,51 +47,50 @@ QList MMDeviceFinder::ListDevices() { default_device.iconname = GuessIconName(default_device.description); devices.append(default_device); - for (ULONG i = 0 ; i < count ; i++) { - - IMMDevice *endpoint = nullptr; - hr = collection->Item(i, &endpoint); - if (FAILED(hr)) { return devices; } - - LPWSTR pwszid = nullptr; - hr = endpoint->GetId(&pwszid); - if (FAILED(hr)) { - endpoint->Release(); - continue; + IMMDeviceEnumerator *enumerator = nullptr; + HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&enumerator); + if (hr == S_OK) { + IMMDeviceCollection *collection = nullptr; + hr = enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &collection); + if (hr == S_OK) { + UINT count; + hr = collection->GetCount(&count); + if (hr == S_OK) { + for (ULONG i = 0 ; i < count ; i++) { + IMMDevice *endpoint = nullptr; + hr = collection->Item(i, &endpoint); + if (hr == S_OK) { + LPWSTR pwszid = nullptr; + hr = endpoint->GetId(&pwszid); + if (hr == S_OK) { + IPropertyStore *props = nullptr; + hr = endpoint->OpenPropertyStore(STGM_READ, &props); + if (hr == S_OK) { + PROPVARIANT var_name; + PropVariantInit(&var_name); + hr = props->GetValue(PKEY_Device_FriendlyName, &var_name); + if (hr == S_OK) { + Device device; + device.description = QString::fromWCharArray(var_name.pwszVal); + device.iconname = GuessIconName(device.description); + device.value = QString::fromStdWString(pwszid); + devices.append(device); + PropVariantClear(&var_name); + } + props->Release(); + } + CoTaskMemFree(pwszid); + } + endpoint->Release(); + } + } + } + collection->Release(); } - - IPropertyStore *props = nullptr; - hr = endpoint->OpenPropertyStore(STGM_READ, &props); - if (FAILED(hr)) { - CoTaskMemFree(pwszid); - endpoint->Release(); - continue; - } - - PROPVARIANT var_name; - PropVariantInit(&var_name); - hr = props->GetValue(PKEY_Device_FriendlyName, &var_name); - if (FAILED(hr)) { - props->Release(); - CoTaskMemFree(pwszid); - endpoint->Release(); - continue; - } - - Device device; - device.description = QString::fromWCharArray(var_name.pwszVal); - device.iconname = GuessIconName(device.description); - device.value = QString::fromStdWString(pwszid); - devices.append(device); - - PropVariantClear(&var_name); - props->Release(); - CoTaskMemFree(pwszid); - endpoint->Release(); - + enumerator->Release(); } - collection->Release(); - enumerator->Release(); + + if (hr_coinit == S_OK || hr_coinit == S_FALSE) CoUninitialize(); return devices;