To be merged after !2907.
-- v5: wineoss: Use mmdevapi's AudioClient's GetService. winecoreaudio: Use mmdevapi's AudioClient's GetService. winealsa: Use mmdevapi's AudioClient's GetService. winepulse: Move AudioClient's GetService into mmdevapi. winepulse: Lock sessions in AudioClient's GetService. wineoss: Use mmdevapi's session_wrapper_create. winecoreaudio: Use mmdevapi's session_wrapper_create. winealsa: Use mmdevapi's session_wrapper_create. winepulse: Move session_wrapper_create into mmdevapi. winepulse: Always initialize ref to 1 in session wrapper.
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winepulse.drv/mmdevdrv.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index def79d7f961..726ffeb86ad 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -1024,6 +1024,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, void **ppv) { ACImpl *This = impl_from_IAudioClient3(iface); + BOOLEAN add_ref = TRUE;
TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
@@ -1050,6 +1051,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, IsEqualIID(riid, &IID_IChannelAudioVolume) || IsEqualIID(riid, &IID_ISimpleAudioVolume)) { if (!This->session_wrapper) { + add_ref = FALSE; + This->session_wrapper = AudioSessionWrapper_Create(This); if (!This->session_wrapper) return E_OUTOFMEMORY; @@ -1063,7 +1066,8 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, }
if (*ppv) { - IUnknown_AddRef((IUnknown*)*ppv); + if (add_ref) + IUnknown_AddRef((IUnknown*)*ppv); return S_OK; }
@@ -1130,7 +1134,7 @@ static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client) ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl; ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl;
- ret->ref = !client; + ret->ref = 1;
ret->client = client; if (client) {
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/session.c | 28 ++++++++++++++++++++++++++++ dlls/winepulse.drv/mmdevdrv.c | 31 ++++--------------------------- 2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/dlls/mmdevapi/session.c b/dlls/mmdevapi/session.c index 81cea5b3482..e0625b59993 100644 --- a/dlls/mmdevapi/session.c +++ b/dlls/mmdevapi/session.c @@ -1,4 +1,9 @@ /* + * Copyright 2011-2012 Maarten Lankhorst + * Copyright 2010-2011 Maarten Lankhorst for CodeWeavers + * Copyright 2011 Andrew Eikum for CodeWeavers + * Copyright 2022 Huw Davies + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either @@ -545,3 +550,26 @@ const ISimpleAudioVolumeVtbl SimpleAudioVolume_Vtbl = simplevolume_SetMute, simplevolume_GetMute }; + +struct audio_session_wrapper *session_wrapper_create(struct audio_client *client) +{ + struct audio_session_wrapper *ret; + + ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct audio_session_wrapper)); + if (!ret) + return NULL; + + ret->IAudioSessionControl2_iface.lpVtbl = &AudioSessionControl2_Vtbl; + ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl; + ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl; + + ret->ref = 1; + ret->client = client; + + if (client) { + ret->session = client->session; + IAudioClient3_AddRef(&client->IAudioClient3_iface); + } + + return ret; +} diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 726ffeb86ad..04ec9a6498a 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -134,7 +134,8 @@ extern const IAudioClockVtbl AudioClock_Vtbl; extern const IAudioClock2Vtbl AudioClock2_Vtbl; extern const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl;
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client); +extern struct audio_session_wrapper *session_wrapper_create( + struct audio_client *client) DECLSPEC_HIDDEN;
static inline ACImpl *impl_from_IAudioClient3(IAudioClient3 *iface) { @@ -1053,7 +1054,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, if (!This->session_wrapper) { add_ref = FALSE;
- This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if (!This->session_wrapper) return E_OUTOFMEMORY; } @@ -1121,30 +1122,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = client_InitializeSharedAudioStream, };
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client) -{ - AudioSessionWrapper *ret; - - ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(AudioSessionWrapper)); - if (!ret) - return NULL; - - ret->IAudioSessionControl2_iface.lpVtbl = &AudioSessionControl2_Vtbl; - ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl; - ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl; - - ret->ref = 1; - - ret->client = client; - if (client) { - ret->session = client->session; - IAudioClient3_AddRef(&client->IAudioClient3_iface); - } - - return ret; -} - HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device, AudioSessionWrapper **out) { @@ -1154,7 +1131,7 @@ HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device if(FAILED(hr)) return hr;
- *out = AudioSessionWrapper_Create(NULL); + *out = session_wrapper_create(NULL); if(!*out) return E_OUTOFMEMORY;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winealsa.drv/mmdevdrv.c | 35 ++++++----------------------------- 1 file changed, 6 insertions(+), 29 deletions(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index 8961f1a3c1d..1eee5a8faa9 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -76,7 +76,8 @@ extern const IAudioClock2Vtbl AudioClock2_Vtbl; extern const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl; extern const IChannelAudioVolumeVtbl ChannelAudioVolume_Vtbl;
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client); +extern struct audio_session_wrapper *session_wrapper_create( + struct audio_client *client) DECLSPEC_HIDDEN;
void DECLSPEC_HIDDEN sessions_lock(void) { @@ -934,7 +935,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->IAudioStreamVolume_iface; }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ sessions_unlock(); return E_OUTOFMEMORY; @@ -945,7 +946,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->session_wrapper->IAudioSessionControl2_iface; }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ sessions_unlock(); return E_OUTOFMEMORY; @@ -956,7 +957,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->session_wrapper->IChannelAudioVolume_iface; }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ sessions_unlock(); return E_OUTOFMEMORY; @@ -1024,30 +1025,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = client_InitializeSharedAudioStream, };
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client) -{ - AudioSessionWrapper *ret; - - ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(AudioSessionWrapper)); - if(!ret) - return NULL; - - ret->IAudioSessionControl2_iface.lpVtbl = &AudioSessionControl2_Vtbl; - ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl; - ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl; - - ret->ref = 1; - - ret->client = client; - if(client){ - ret->session = client->session; - IAudioClient3_AddRef(&client->IAudioClient3_iface); - } - - return ret; -} - HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device, AudioSessionWrapper **out) { @@ -1057,7 +1034,7 @@ HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device if(FAILED(hr)) return hr;
- *out = AudioSessionWrapper_Create(NULL); + *out = session_wrapper_create(NULL); if(!*out) return E_OUTOFMEMORY;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winecoreaudio.drv/mmdevdrv.c | 35 ++++++------------------------- 1 file changed, 6 insertions(+), 29 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index 67bf7b122a4..196f2897b39 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -70,7 +70,8 @@ static CRITICAL_SECTION_DEBUG g_sessions_lock_debug = static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0, 0 }; static struct list g_sessions = LIST_INIT(g_sessions);
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client); +extern struct audio_session_wrapper *session_wrapper_create( + struct audio_client *client) DECLSPEC_HIDDEN;
void DECLSPEC_HIDDEN sessions_lock(void) { @@ -899,7 +900,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->IAudioStreamVolume_iface; }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ hr = E_OUTOFMEMORY; goto end; @@ -910,7 +911,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->session_wrapper->IAudioSessionControl2_iface; }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ hr = E_OUTOFMEMORY; goto end; @@ -921,7 +922,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->session_wrapper->IChannelAudioVolume_iface; }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ hr = E_OUTOFMEMORY; goto end; @@ -989,30 +990,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = client_InitializeSharedAudioStream, };
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client) -{ - AudioSessionWrapper *ret; - - ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(AudioSessionWrapper)); - if(!ret) - return NULL; - - ret->IAudioSessionControl2_iface.lpVtbl = &AudioSessionControl2_Vtbl; - ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl; - ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl; - - ret->ref = 1; - - ret->client = client; - if(client){ - ret->session = client->session; - IAudioClient3_AddRef(&client->IAudioClient3_iface); - } - - return ret; -} - HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device, AudioSessionWrapper **out) { @@ -1022,7 +999,7 @@ HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device if(FAILED(hr)) return hr;
- *out = AudioSessionWrapper_Create(NULL); + *out = session_wrapper_create(NULL); if(!*out) return E_OUTOFMEMORY;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/wineoss.drv/mmdevdrv.c | 37 +++++++------------------------------ 1 file changed, 7 insertions(+), 30 deletions(-)
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index c282fb88831..23a116f0c45 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -72,8 +72,6 @@ static CRITICAL_SECTION_DEBUG g_sessions_lock_debug = static CRITICAL_SECTION g_sessions_lock = { &g_sessions_lock_debug, -1, 0, 0, 0, 0 }; static struct list g_sessions = LIST_INIT(g_sessions);
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client); - static const IAudioClient3Vtbl AudioClient3_Vtbl; extern const IAudioRenderClientVtbl AudioRenderClient_Vtbl; extern const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl; @@ -84,6 +82,9 @@ extern const IAudioClock2Vtbl AudioClock2_Vtbl; extern const IAudioStreamVolumeVtbl AudioStreamVolume_Vtbl; extern const IChannelAudioVolumeVtbl ChannelAudioVolume_Vtbl;
+extern struct audio_session_wrapper *session_wrapper_create( + struct audio_client *client) DECLSPEC_HIDDEN; + void DECLSPEC_HIDDEN sessions_lock(void) { EnterCriticalSection(&g_sessions_lock); @@ -897,7 +898,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->IAudioStreamVolume_iface; }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ sessions_unlock(); return E_OUTOFMEMORY; @@ -908,7 +909,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->session_wrapper->IAudioSessionControl2_iface; }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ sessions_unlock(); return E_OUTOFMEMORY; @@ -919,7 +920,7 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, *ppv = &This->session_wrapper->IChannelAudioVolume_iface; }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){ if(!This->session_wrapper){ - This->session_wrapper = AudioSessionWrapper_Create(This); + This->session_wrapper = session_wrapper_create(This); if(!This->session_wrapper){ sessions_unlock(); return E_OUTOFMEMORY; @@ -987,30 +988,6 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = client_InitializeSharedAudioStream, };
-static AudioSessionWrapper *AudioSessionWrapper_Create(ACImpl *client) -{ - AudioSessionWrapper *ret; - - ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(AudioSessionWrapper)); - if(!ret) - return NULL; - - ret->IAudioSessionControl2_iface.lpVtbl = &AudioSessionControl2_Vtbl; - ret->ISimpleAudioVolume_iface.lpVtbl = &SimpleAudioVolume_Vtbl; - ret->IChannelAudioVolume_iface.lpVtbl = &ChannelAudioVolume_Vtbl; - - ret->ref = 1; - - ret->client = client; - if(client){ - ret->session = client->session; - IAudioClient3_AddRef(&client->IAudioClient3_iface); - } - - return ret; -} - HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device, AudioSessionWrapper **out) { @@ -1020,7 +997,7 @@ HRESULT WINAPI AUDDRV_GetAudioSessionWrapper(const GUID *guid, IMMDevice *device if(FAILED(hr)) return hr;
- *out = AudioSessionWrapper_Create(NULL); + *out = session_wrapper_create(NULL); if(!*out) return E_OUTOFMEMORY;
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winepulse.drv/mmdevdrv.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 04ec9a6498a..51b6d12d96b 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -1033,16 +1033,24 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, return E_POINTER; *ppv = NULL;
- if (!This->stream) + sessions_lock(); + + if (!This->stream) { + sessions_unlock(); return AUDCLNT_E_NOT_INITIALIZED; + }
if (IsEqualIID(riid, &IID_IAudioRenderClient)) { - if (This->dataflow != eRender) + if (This->dataflow != eRender) { + sessions_unlock(); return AUDCLNT_E_WRONG_ENDPOINT_TYPE; + } *ppv = &This->IAudioRenderClient_iface; } else if (IsEqualIID(riid, &IID_IAudioCaptureClient)) { - if (This->dataflow != eCapture) + if (This->dataflow != eCapture) { + sessions_unlock(); return AUDCLNT_E_WRONG_ENDPOINT_TYPE; + } *ppv = &This->IAudioCaptureClient_iface; } else if (IsEqualIID(riid, &IID_IAudioClock)) { *ppv = &This->IAudioClock_iface; @@ -1055,8 +1063,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, add_ref = FALSE;
This->session_wrapper = session_wrapper_create(This); - if (!This->session_wrapper) + if (!This->session_wrapper) { + sessions_unlock(); return E_OUTOFMEMORY; + } } if (IsEqualIID(riid, &IID_IAudioSessionControl)) *ppv = &This->session_wrapper->IAudioSessionControl2_iface; @@ -1069,9 +1079,12 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, if (*ppv) { if (add_ref) IUnknown_AddRef((IUnknown*)*ppv); + sessions_unlock(); return S_OK; }
+ sessions_unlock(); + FIXME("stub %s\n", debugstr_guid(riid)); return E_NOINTERFACE; }
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/client.c | 69 ++++++++++++++++++++++++++++++++++ dlls/winepulse.drv/mmdevdrv.c | 71 ++--------------------------------- 2 files changed, 72 insertions(+), 68 deletions(-)
diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index 87bc3fef0e5..c19de19c7fb 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -36,6 +36,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); extern void sessions_lock(void) DECLSPEC_HIDDEN; extern void sessions_unlock(void) DECLSPEC_HIDDEN;
+extern struct audio_session_wrapper *session_wrapper_create(struct audio_client *client) DECLSPEC_HIDDEN; + void set_stream_volumes(struct audio_client *This) { struct set_volumes_params params; @@ -194,6 +196,73 @@ const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl = capture_GetNextPacketSize };
+HRESULT WINAPI client_GetService(IAudioClient3 *iface, REFIID riid, void **ppv) +{ + struct audio_client *This = impl_from_IAudioClient3(iface); + BOOLEAN add_ref = TRUE; + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); + + if (!ppv) + return E_POINTER; + + *ppv = NULL; + + sessions_lock(); + + if (!This->stream) { + sessions_unlock(); + return AUDCLNT_E_NOT_INITIALIZED; + } + + if (IsEqualIID(riid, &IID_IAudioRenderClient)) { + if (This->dataflow != eRender) { + sessions_unlock(); + return AUDCLNT_E_WRONG_ENDPOINT_TYPE; + } + *ppv = &This->IAudioRenderClient_iface; + } else if (IsEqualIID(riid, &IID_IAudioCaptureClient)) { + if (This->dataflow != eCapture) { + sessions_unlock(); + return AUDCLNT_E_WRONG_ENDPOINT_TYPE; + } + *ppv = &This->IAudioCaptureClient_iface; + } else if (IsEqualIID(riid, &IID_IAudioClock)) { + *ppv = &This->IAudioClock_iface; + } else if (IsEqualIID(riid, &IID_IAudioStreamVolume)) { + *ppv = &This->IAudioStreamVolume_iface; + } else if (IsEqualIID(riid, &IID_IAudioSessionControl) || + IsEqualIID(riid, &IID_IChannelAudioVolume) || + IsEqualIID(riid, &IID_ISimpleAudioVolume)) { + if (!This->session_wrapper) { + add_ref = FALSE; + + This->session_wrapper = session_wrapper_create(This); + if (!This->session_wrapper) { + sessions_unlock(); + return E_OUTOFMEMORY; + } + } + if (IsEqualIID(riid, &IID_IAudioSessionControl)) + *ppv = &This->session_wrapper->IAudioSessionControl2_iface; + else if (IsEqualIID(riid, &IID_IChannelAudioVolume)) + *ppv = &This->session_wrapper->IChannelAudioVolume_iface; + else if (IsEqualIID(riid, &IID_ISimpleAudioVolume)) + *ppv = &This->session_wrapper->ISimpleAudioVolume_iface; + } + + if (*ppv) { + if (add_ref) + IUnknown_AddRef((IUnknown*)*ppv); + sessions_unlock(); + return S_OK; + } + + sessions_unlock(); + + return E_NOINTERFACE; +} + HRESULT WINAPI client_IsOffloadCapable(IAudioClient3 *iface, AUDIO_STREAM_CATEGORY category, BOOL *offload_capable) { diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 51b6d12d96b..19d4bd41c7a 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -1021,73 +1021,8 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface, return params.result; }
-static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, - void **ppv) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - BOOLEAN add_ref = TRUE; - - TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); - - if (!ppv) - return E_POINTER; - *ppv = NULL; - - sessions_lock(); - - if (!This->stream) { - sessions_unlock(); - return AUDCLNT_E_NOT_INITIALIZED; - } - - if (IsEqualIID(riid, &IID_IAudioRenderClient)) { - if (This->dataflow != eRender) { - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - *ppv = &This->IAudioRenderClient_iface; - } else if (IsEqualIID(riid, &IID_IAudioCaptureClient)) { - if (This->dataflow != eCapture) { - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - *ppv = &This->IAudioCaptureClient_iface; - } else if (IsEqualIID(riid, &IID_IAudioClock)) { - *ppv = &This->IAudioClock_iface; - } else if (IsEqualIID(riid, &IID_IAudioStreamVolume)) { - *ppv = &This->IAudioStreamVolume_iface; - } else if (IsEqualIID(riid, &IID_IAudioSessionControl) || - IsEqualIID(riid, &IID_IChannelAudioVolume) || - IsEqualIID(riid, &IID_ISimpleAudioVolume)) { - if (!This->session_wrapper) { - add_ref = FALSE; - - This->session_wrapper = session_wrapper_create(This); - if (!This->session_wrapper) { - sessions_unlock(); - return E_OUTOFMEMORY; - } - } - if (IsEqualIID(riid, &IID_IAudioSessionControl)) - *ppv = &This->session_wrapper->IAudioSessionControl2_iface; - else if (IsEqualIID(riid, &IID_IChannelAudioVolume)) - *ppv = &This->session_wrapper->IChannelAudioVolume_iface; - else if (IsEqualIID(riid, &IID_ISimpleAudioVolume)) - *ppv = &This->session_wrapper->ISimpleAudioVolume_iface; - } - - if (*ppv) { - if (add_ref) - IUnknown_AddRef((IUnknown*)*ppv); - sessions_unlock(); - return S_OK; - } - - sessions_unlock(); - - FIXME("stub %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} +extern HRESULT WINAPI client_GetService(IAudioClient3 *iface, REFIID riid, + void **ppv);
extern HRESULT WINAPI client_IsOffloadCapable(IAudioClient3 *iface, AUDIO_STREAM_CATEGORY category, BOOL *offload_capable); @@ -1126,7 +1061,7 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = AudioClient_Stop, AudioClient_Reset, AudioClient_SetEventHandle, - AudioClient_GetService, + client_GetService, client_IsOffloadCapable, client_SetClientProperties, client_GetBufferSizeLimits,
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winealsa.drv/mmdevdrv.c | 87 ++---------------------------------- 1 file changed, 3 insertions(+), 84 deletions(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index 1eee5a8faa9..b96eba1e0fe 100644 --- a/dlls/winealsa.drv/mmdevdrv.c +++ b/dlls/winealsa.drv/mmdevdrv.c @@ -895,89 +895,8 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface, return params.result; }
-static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, - void **ppv) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); - - if(!ppv) - return E_POINTER; - *ppv = NULL; - - sessions_lock(); - - if(!This->stream){ - sessions_unlock(); - return AUDCLNT_E_NOT_INITIALIZED; - } - - if(IsEqualIID(riid, &IID_IAudioRenderClient)){ - if(This->dataflow != eRender){ - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface); - *ppv = &This->IAudioRenderClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){ - if(This->dataflow != eCapture){ - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface); - *ppv = &This->IAudioCaptureClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioClock)){ - IAudioClock_AddRef(&This->IAudioClock_iface); - *ppv = &This->IAudioClock_iface; - }else if(IsEqualIID(riid, &IID_IAudioStreamVolume)){ - IAudioStreamVolume_AddRef(&This->IAudioStreamVolume_iface); - *ppv = &This->IAudioStreamVolume_iface; - }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface); - - *ppv = &This->session_wrapper->IAudioSessionControl2_iface; - }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface); - - *ppv = &This->session_wrapper->IChannelAudioVolume_iface; - }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface); - - *ppv = &This->session_wrapper->ISimpleAudioVolume_iface; - } - - if(*ppv){ - sessions_unlock(); - return S_OK; - } - - sessions_unlock(); - - FIXME("stub %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} +extern HRESULT WINAPI client_GetService(IAudioClient3 *iface, REFIID riid, + void **ppv);
extern HRESULT WINAPI client_IsOffloadCapable(IAudioClient3 *iface, AUDIO_STREAM_CATEGORY category, BOOL *offload_capable); @@ -1016,7 +935,7 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = AudioClient_Stop, AudioClient_Reset, AudioClient_SetEventHandle, - AudioClient_GetService, + client_GetService, client_IsOffloadCapable, client_SetClientProperties, client_GetBufferSizeLimits,
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/winecoreaudio.drv/mmdevdrv.c | 86 ++----------------------------- 1 file changed, 3 insertions(+), 83 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index 196f2897b39..dcd712c7c7a 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -861,88 +861,8 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface, return params.result; }
-static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, - void **ppv) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - HRESULT hr; - - TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); - - if(!ppv) - return E_POINTER; - *ppv = NULL; - - if(!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - sessions_lock(); - - if(IsEqualIID(riid, &IID_IAudioRenderClient)){ - if(This->dataflow != eRender){ - hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE; - goto end; - } - IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface); - *ppv = &This->IAudioRenderClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){ - if(This->dataflow != eCapture){ - hr = AUDCLNT_E_WRONG_ENDPOINT_TYPE; - goto end; - } - IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface); - *ppv = &This->IAudioCaptureClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioClock)){ - IAudioClock_AddRef(&This->IAudioClock_iface); - *ppv = &This->IAudioClock_iface; - }else if(IsEqualIID(riid, &IID_IAudioStreamVolume)){ - IAudioStreamVolume_AddRef(&This->IAudioStreamVolume_iface); - *ppv = &This->IAudioStreamVolume_iface; - }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - hr = E_OUTOFMEMORY; - goto end; - } - }else - IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface); - - *ppv = &This->session_wrapper->IAudioSessionControl2_iface; - }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - hr = E_OUTOFMEMORY; - goto end; - } - }else - IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface); - - *ppv = &This->session_wrapper->IChannelAudioVolume_iface; - }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - hr = E_OUTOFMEMORY; - goto end; - } - }else - ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface); - - *ppv = &This->session_wrapper->ISimpleAudioVolume_iface; - } - - if(*ppv) hr = S_OK; - else{ - FIXME("stub %s\n", debugstr_guid(riid)); - hr = E_NOINTERFACE; - } - -end: - sessions_unlock(); - return hr; -} +extern HRESULT WINAPI client_GetService(IAudioClient3 *iface, REFIID riid, + void **ppv);
extern HRESULT WINAPI client_IsOffloadCapable(IAudioClient3 *iface, AUDIO_STREAM_CATEGORY category, BOOL *offload_capable); @@ -981,7 +901,7 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = AudioClient_Stop, AudioClient_Reset, AudioClient_SetEventHandle, - AudioClient_GetService, + client_GetService, client_IsOffloadCapable, client_SetClientProperties, client_GetBufferSizeLimits,
From: Davide Beatrici git@davidebeatrici.dev
--- dlls/wineoss.drv/mmdevdrv.c | 87 ++----------------------------------- 1 file changed, 3 insertions(+), 84 deletions(-)
diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c index 23a116f0c45..188bf37aac9 100644 --- a/dlls/wineoss.drv/mmdevdrv.c +++ b/dlls/wineoss.drv/mmdevdrv.c @@ -858,89 +858,8 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface, return params.result; }
-static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid, - void **ppv) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - - TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); - - if(!ppv) - return E_POINTER; - *ppv = NULL; - - sessions_lock(); - - if(!This->stream){ - sessions_unlock(); - return AUDCLNT_E_NOT_INITIALIZED; - } - - if(IsEqualIID(riid, &IID_IAudioRenderClient)){ - if(This->dataflow != eRender){ - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - IAudioRenderClient_AddRef(&This->IAudioRenderClient_iface); - *ppv = &This->IAudioRenderClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioCaptureClient)){ - if(This->dataflow != eCapture){ - sessions_unlock(); - return AUDCLNT_E_WRONG_ENDPOINT_TYPE; - } - IAudioCaptureClient_AddRef(&This->IAudioCaptureClient_iface); - *ppv = &This->IAudioCaptureClient_iface; - }else if(IsEqualIID(riid, &IID_IAudioClock)){ - IAudioClock_AddRef(&This->IAudioClock_iface); - *ppv = &This->IAudioClock_iface; - }else if(IsEqualIID(riid, &IID_IAudioStreamVolume)){ - IAudioStreamVolume_AddRef(&This->IAudioStreamVolume_iface); - *ppv = &This->IAudioStreamVolume_iface; - }else if(IsEqualIID(riid, &IID_IAudioSessionControl)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - IAudioSessionControl2_AddRef(&This->session_wrapper->IAudioSessionControl2_iface); - - *ppv = &This->session_wrapper->IAudioSessionControl2_iface; - }else if(IsEqualIID(riid, &IID_IChannelAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - IChannelAudioVolume_AddRef(&This->session_wrapper->IChannelAudioVolume_iface); - - *ppv = &This->session_wrapper->IChannelAudioVolume_iface; - }else if(IsEqualIID(riid, &IID_ISimpleAudioVolume)){ - if(!This->session_wrapper){ - This->session_wrapper = session_wrapper_create(This); - if(!This->session_wrapper){ - sessions_unlock(); - return E_OUTOFMEMORY; - } - }else - ISimpleAudioVolume_AddRef(&This->session_wrapper->ISimpleAudioVolume_iface); - - *ppv = &This->session_wrapper->ISimpleAudioVolume_iface; - } - - if(*ppv){ - sessions_unlock(); - return S_OK; - } - - sessions_unlock(); - - FIXME("stub %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} +extern HRESULT WINAPI client_GetService(IAudioClient3 *iface, REFIID riid, + void **ppv);
extern HRESULT WINAPI client_IsOffloadCapable(IAudioClient3 *iface, AUDIO_STREAM_CATEGORY category, BOOL *offload_capable); @@ -979,7 +898,7 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = AudioClient_Stop, AudioClient_Reset, AudioClient_SetEventHandle, - AudioClient_GetService, + client_GetService, client_IsOffloadCapable, client_SetClientProperties, client_GetBufferSizeLimits,
On Mon Jun 5 21:58:11 2023 +0000, Davide Beatrici wrote:
This doesn't look right.
Note that the difference between the pulse and the other drivers is
that pulse's `GetService()` calls `AddRef()` in all success cases. More specifically, the other drivers call `AddRef()` only when the session wrapper already exists. I didn't catch that (and the tests didn't either apparently), sorry.
I think the other drivers do this in a more logical way - have the
session wrapper constructor return an object with `ref` set to one and don't `AddRef()` it in `GetService()`. Agreed.
I also added the logic to (un)lock sessions in a separate commit, as it was missing in `winepulse`.
Huw Davies (@huw) commented about dlls/winepulse.drv/mmdevdrv.c:
void **ppv)
{ ACImpl *This = impl_from_IAudioClient3(iface);
- BOOLEAN add_ref = TRUE;
I'm afraid I'm not a fan of this add_ref boolean. I'd prefer something like the current alsa driver's code with perhaps the grouping of the three session interfaces like it's currently done in the pulse driver and the moving of `sessions_unlock()` so it's called unconditionally near the end.
On Tue Jun 6 06:25:38 2023 +0000, Huw Davies wrote:
I'm afraid I'm not a fan of this add_ref boolean. I'd prefer something like the current alsa driver's code with perhaps the grouping of the three session interfaces like it's currently done in the pulse driver and the moving of `sessions_unlock()` so it's called unconditionally near the end.
No problem.