mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
USB: Initialize COM before using Cubeb on Windows
This commit is contained in:
parent
190b525ca6
commit
521b32c253
@ -6,10 +6,18 @@
|
||||
#include "Host.h"
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/Error.h"
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/RedtapeWindows.h"
|
||||
#include <objbase.h>
|
||||
|
||||
#include "wil/resource.h"
|
||||
#endif
|
||||
|
||||
// Since the context gets used to populate the device list, that unfortunately means
|
||||
// we need locking around it, since the UI thread's gonna be saying hi. The settings
|
||||
// callbacks don't actually modify the context itself, though, only look at the
|
||||
@ -22,7 +30,24 @@ static std::mutex s_cubeb_context_mutex;
|
||||
|
||||
static cubeb* GetCubebContext(const char* backend = nullptr)
|
||||
{
|
||||
std::unique_lock lock(s_cubeb_context_mutex);
|
||||
std::lock_guard lock(s_cubeb_context_mutex);
|
||||
|
||||
#ifdef _WIN32
|
||||
// For enumeration, we need *any* COM context. multi- or single-threaded.
|
||||
// As COM is per-thread, initialize and tear it down every time.
|
||||
// Doing it only on 0 refcount is a bad idea, because the Cubeb context could be created on one thread, and destroyed on another.
|
||||
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
if (hr == RPC_E_CHANGED_MODE)
|
||||
{
|
||||
hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||
}
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Console.ErrorFmt("CoInitializeEx failed: {}", Error::CreateHResult(hr).GetDescription());
|
||||
return nullptr;
|
||||
}
|
||||
wil::unique_couninitialize_call uninit;
|
||||
#endif
|
||||
|
||||
if (!s_cubeb_context)
|
||||
{
|
||||
@ -41,12 +66,17 @@ static cubeb* GetCubebContext(const char* backend = nullptr)
|
||||
if (s_cubeb_context)
|
||||
s_cubeb_refcount++;
|
||||
|
||||
#ifdef _WIN32
|
||||
// ReleaseCubebContext will call CoUninitialize
|
||||
uninit.release();
|
||||
#endif
|
||||
|
||||
return s_cubeb_context;
|
||||
}
|
||||
|
||||
static void ReleaseCubebContext()
|
||||
{
|
||||
std::unique_lock lock(s_cubeb_context_mutex);
|
||||
std::lock_guard lock(s_cubeb_context_mutex);
|
||||
|
||||
pxAssert(s_cubeb_refcount > 0);
|
||||
if ((--s_cubeb_refcount) == 0)
|
||||
@ -59,6 +89,10 @@ static void ReleaseCubebContext()
|
||||
cubeb_destroy(s_cubeb_context);
|
||||
s_cubeb_context = nullptr;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
CoUninitialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
static cubeb_devid FindCubebDevice(const char* devname, bool input)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user