aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMatthew Gregan <[email protected]>2022-12-07 21:12:48 +1300
committerMatthew Gregan <[email protected]>2022-12-08 09:24:26 +1300
commit51728e55cd9e11088da414d6ae1e21ef10cd83de (patch)
tree05ad76f2c37ce894c21c0814e9b16aab8be41a34
parenteb8c4ff0605e304ccdf839a22d89312e152ad914 (diff)
downloadcubeb-51728e55cd9e11088da414d6ae1e21ef10cd83de.tar.gz
cubeb-51728e55cd9e11088da414d6ae1e21ef10cd83de.zip
wasapi: Avoid reconfiguring default output stream spuriously.
-rw-r--r--src/cubeb_wasapi.cpp32
1 files changed, 26 insertions, 6 deletions
diff --git a/src/cubeb_wasapi.cpp b/src/cubeb_wasapi.cpp
index 14ae226..c9ac8c2 100644
--- a/src/cubeb_wasapi.cpp
+++ b/src/cubeb_wasapi.cpp
@@ -97,6 +97,8 @@ namespace {
const int64_t LATENCY_NOT_AVAILABLE_YET = -1;
+const DWORD DEVICE_CHANGE_DEBOUNCE_MS = 250;
+
struct com_heap_ptr_deleter {
void operator()(void * ptr) const noexcept { CoTaskMemFree(ptr); }
};
@@ -696,7 +698,8 @@ public:
}
wasapi_endpoint_notification_client(HANDLE event, ERole role)
- : ref_count(1), reconfigure_event(event), role(role)
+ : ref_count(1), reconfigure_event(event), role(role),
+ last_device_change(timeGetTime())
{
}
@@ -705,17 +708,32 @@ public:
HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow flow, ERole role,
LPCWSTR device_id)
{
- LOG("endpoint: Audio device default changed.");
+ LOG("endpoint: Audio device default changed flow=%d role=%d "
+ "new_device_id=%ws.",
+ flow, role, device_id);
/* we only support a single stream type for now. */
if (flow != eRender || role != this->role) {
return S_OK;
}
- BOOL ok = SetEvent(reconfigure_event);
- if (!ok) {
- LOG("endpoint: SetEvent on reconfigure_event failed: %lx",
- GetLastError());
+ DWORD last_change_ms = timeGetTime() - last_device_change;
+ bool same_device = default_device_id && device_id &&
+ wcscmp(default_device_id.get(), device_id) == 0;
+ LOG("endpoint: Audio device default changed last_change=%u same_device=%d",
+ last_change_ms, same_device);
+ if (last_change_ms > DEVICE_CHANGE_DEBOUNCE_MS || !same_device) {
+ if (device_id) {
+ default_device_id.reset(_wcsdup(device_id));
+ } else {
+ default_device_id.reset();
+ }
+ BOOL ok = SetEvent(reconfigure_event);
+ LOG("endpoint: Audio device default changed: trigger reconfig");
+ if (!ok) {
+ LOG("endpoint: SetEvent on reconfigure_event failed: %lx",
+ GetLastError());
+ }
}
return S_OK;
@@ -754,6 +772,8 @@ private:
LONG ref_count;
HANDLE reconfigure_event;
ERole role;
+ std::unique_ptr<const wchar_t[]> default_device_id;
+ DWORD last_device_change;
};
namespace {