[PATCH 5/7] winecoreaudio: Use the presence of stream to indicate the init state.

Huw Davies huw at codeweavers.com
Thu Nov 18 01:52:36 CST 2021


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/winecoreaudio.drv/mmdevdrv.c | 211 +++++++++++++-----------------
 1 file changed, 93 insertions(+), 118 deletions(-)

diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 1e678b08c5b..0abfebfb1a5 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -129,7 +129,6 @@ struct ACImpl {
     HANDLE event;
     float *vols;
 
-    BOOL initted;
     AudioDeviceID adevid;
     AudioObjectPropertyScope scope;
     HANDLE timer;
@@ -541,11 +540,6 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACImpl));
     if(!This)
         return E_OUTOFMEMORY;
-    This->stream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This->stream));
-    if(!This->stream){
-        HeapFree(GetProcessHeap(), 0, This);
-        return E_OUTOFMEMORY;
-    }
 
     This->IAudioClient3_iface.lpVtbl = &AudioClient3_Vtbl;
     This->IAudioRenderClient_iface.lpVtbl = &AudioRenderClient_Vtbl;
@@ -561,16 +555,12 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
     else if(dataflow == eCapture)
         This->scope = kAudioDevicePropertyScopeInput;
     else{
-        HeapFree(GetProcessHeap(), 0, This->stream);
         HeapFree(GetProcessHeap(), 0, This);
         return E_INVALIDARG;
     }
 
-    This->stream->lock = 0;
-
     hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient3_iface, &This->pUnkFTMarshal);
     if (FAILED(hr)) {
-        HeapFree(GetProcessHeap(), 0, This->stream);
         HeapFree(GetProcessHeap(), 0, This);
         return hr;
     }
@@ -637,29 +627,31 @@ static ULONG WINAPI AudioClient_Release(IAudioClient3 *iface)
                 WaitForSingleObject(event, INFINITE);
             CloseHandle(event);
         }
-        AudioOutputUnitStop(This->stream->unit);
-        AudioComponentInstanceDispose(This->stream->unit);
-        if(This->stream->converter)
-            AudioConverterDispose(This->stream->converter);
+        if (This->stream){
+            AudioOutputUnitStop(This->stream->unit);
+            AudioComponentInstanceDispose(This->stream->unit);
+            if(This->stream->converter)
+                AudioConverterDispose(This->stream->converter);
+            HeapFree(GetProcessHeap(), 0, This->stream->cap_buffer);
+            if(This->stream->local_buffer)
+                NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer,
+                                    &This->stream->local_buffer_size, MEM_RELEASE);
+            if(This->stream->tmp_buffer)
+                NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer,
+                                    &This->stream->tmp_buffer_size, MEM_RELEASE);
+            free(This->stream->wrap_buffer);
+            HeapFree(GetProcessHeap(), 0, This->stream->resamp_buffer);
+            CoTaskMemFree(This->stream->fmt);
+            HeapFree(GetProcessHeap(), 0, This->stream);
+        }
         if(This->session){
             EnterCriticalSection(&g_sessions_lock);
             list_remove(&This->entry);
             LeaveCriticalSection(&g_sessions_lock);
         }
         HeapFree(GetProcessHeap(), 0, This->vols);
-        HeapFree(GetProcessHeap(), 0, This->stream->cap_buffer);
-        if(This->stream->local_buffer)
-            NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer,
-                                &This->stream->local_buffer_size, MEM_RELEASE);
-        if(This->stream->tmp_buffer)
-            NtFreeVirtualMemory(GetCurrentProcess(), (void **)&This->stream->tmp_buffer,
-                                &This->stream->tmp_buffer_size, MEM_RELEASE);
-        free(This->stream->wrap_buffer);
-        HeapFree(GetProcessHeap(), 0, This->stream->resamp_buffer);
-        CoTaskMemFree(This->stream->fmt);
         IMMDevice_Release(This->parent);
         IUnknown_Release(This->pUnkFTMarshal);
-        HeapFree(GetProcessHeap(), 0, This->stream);
         HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
@@ -1176,6 +1168,7 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         const GUID *sessionguid)
 {
     ACImpl *This = impl_from_IAudioClient3(iface);
+    struct coreaudio_stream *stream;
     HRESULT hr;
     OSStatus sc;
     UINT32 i;
@@ -1235,40 +1228,42 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
 
     EnterCriticalSection(&g_sessions_lock);
 
-    if(This->initted){
+    if(This->stream){
         LeaveCriticalSection(&g_sessions_lock);
         return AUDCLNT_E_ALREADY_INITIALIZED;
     }
 
-    OSSpinLockLock(&This->stream->lock);
+    stream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*stream));
+    if(!stream){
+        LeaveCriticalSection(&g_sessions_lock);
+        return E_OUTOFMEMORY;
+    }
 
-    This->stream->fmt = clone_format(fmt);
-    if(!This->stream->fmt){
-        OSSpinLockUnlock(&This->stream->lock);
+    stream->fmt = clone_format(fmt);
+    if(!stream->fmt){
+        HeapFree(GetProcessHeap(), 0, stream);
         LeaveCriticalSection(&g_sessions_lock);
         return E_OUTOFMEMORY;
     }
 
-    This->stream->period_ms = period / 10000;
-    This->stream->period_frames = MulDiv(period, This->stream->fmt->nSamplesPerSec, 10000000);
+    stream->period_ms = period / 10000;
+    stream->period_frames = MulDiv(period, stream->fmt->nSamplesPerSec, 10000000);
 
-    This->stream->bufsize_frames = MulDiv(duration, fmt->nSamplesPerSec, 10000000);
+    stream->bufsize_frames = MulDiv(duration, fmt->nSamplesPerSec, 10000000);
     if(mode == AUDCLNT_SHAREMODE_EXCLUSIVE)
-        This->stream->bufsize_frames -= This->stream->bufsize_frames % This->stream->period_frames;
+        stream->bufsize_frames -= stream->bufsize_frames % stream->period_frames;
 
-    if(!(This->stream->unit = get_audiounit(This->dataflow, This->adevid))){
-        CoTaskMemFree(This->stream->fmt);
-        This->stream->fmt = NULL;
-        OSSpinLockUnlock(&This->stream->lock);
+    if(!(stream->unit = get_audiounit(This->dataflow, This->adevid))){
+        CoTaskMemFree(stream->fmt);
+        HeapFree(GetProcessHeap(), 0, stream);
         LeaveCriticalSection(&g_sessions_lock);
         return AUDCLNT_E_DEVICE_INVALIDATED;
     }
 
-    hr = ca_setup_audiounit(This->dataflow, This->stream->unit, This->stream->fmt, &This->stream->dev_desc, &This->stream->converter);
+    hr = ca_setup_audiounit(This->dataflow, stream->unit, stream->fmt, &stream->dev_desc, &stream->converter);
     if(FAILED(hr)){
-        CoTaskMemFree(This->stream->fmt);
-        This->stream->fmt = NULL;
-        OSSpinLockUnlock(&This->stream->lock);
+        CoTaskMemFree(stream->fmt);
+        HeapFree(GetProcessHeap(), 0, stream);
         LeaveCriticalSection(&g_sessions_lock);
         return hr;
     }
@@ -1280,15 +1275,13 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         input.inputProc = &ca_capture_cb;
         input.inputProcRefCon = This;
 
-        sc = AudioUnitSetProperty(This->stream->unit, kAudioOutputUnitProperty_SetInputCallback,
+        sc = AudioUnitSetProperty(stream->unit, kAudioOutputUnitProperty_SetInputCallback,
                 kAudioUnitScope_Output, 1, &input, sizeof(input));
         if(sc != noErr){
             WARN("Couldn't set callback: %x\n", (int)sc);
-            AudioConverterDispose(This->stream->converter);
-            This->stream->converter = NULL;
-            CoTaskMemFree(This->stream->fmt);
-            This->stream->fmt = NULL;
-            OSSpinLockUnlock(&This->stream->lock);
+            AudioConverterDispose(stream->converter);
+            CoTaskMemFree(stream->fmt);
+            HeapFree(GetProcessHeap(), 0, stream);
             LeaveCriticalSection(&g_sessions_lock);
             return osstatus_to_hresult(sc);
         }
@@ -1299,68 +1292,60 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
         input.inputProc = &ca_render_cb;
         input.inputProcRefCon = This;
 
-        sc = AudioUnitSetProperty(This->stream->unit, kAudioUnitProperty_SetRenderCallback,
+        sc = AudioUnitSetProperty(stream->unit, kAudioUnitProperty_SetRenderCallback,
                 kAudioUnitScope_Input, 0, &input, sizeof(input));
         if(sc != noErr){
             WARN("Couldn't set callback: %x\n", (int)sc);
-            CoTaskMemFree(This->stream->fmt);
-            This->stream->fmt = NULL;
-            OSSpinLockUnlock(&This->stream->lock);
+            CoTaskMemFree(stream->fmt);
+            HeapFree(GetProcessHeap(), 0, stream);
             LeaveCriticalSection(&g_sessions_lock);
             return osstatus_to_hresult(sc);
         }
     }
 
-    sc = AudioUnitInitialize(This->stream->unit);
+    sc = AudioUnitInitialize(stream->unit);
     if(sc != noErr){
         WARN("Couldn't initialize: %x\n", (int)sc);
-        if(This->stream->converter){
-            AudioConverterDispose(This->stream->converter);
-            This->stream->converter = NULL;
-        }
-        CoTaskMemFree(This->stream->fmt);
-        This->stream->fmt = NULL;
-        OSSpinLockUnlock(&This->stream->lock);
+        if(stream->converter)
+            AudioConverterDispose(stream->converter);
+        CoTaskMemFree(stream->fmt);
+        HeapFree(GetProcessHeap(), 0, stream);
         LeaveCriticalSection(&g_sessions_lock);
         return osstatus_to_hresult(sc);
     }
 
     /* we play audio continuously because AudioOutputUnitStart sometimes takes
      * a while to return */
-    sc = AudioOutputUnitStart(This->stream->unit);
+    sc = AudioOutputUnitStart(stream->unit);
     if(sc != noErr){
         WARN("Unit failed to start: %x\n", (int)sc);
-        if(This->stream->converter){
-            AudioConverterDispose(This->stream->converter);
-            This->stream->converter = NULL;
-        }
-        CoTaskMemFree(This->stream->fmt);
-        This->stream->fmt = NULL;
-        OSSpinLockUnlock(&This->stream->lock);
+        if(stream->converter)
+            AudioConverterDispose(stream->converter);
+        CoTaskMemFree(stream->fmt);
+        HeapFree(GetProcessHeap(), 0, stream);
         LeaveCriticalSection(&g_sessions_lock);
         return osstatus_to_hresult(sc);
     }
 
-    This->stream->local_buffer_size = This->stream->bufsize_frames * fmt->nBlockAlign;
-    NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&This->stream->local_buffer, 0,
-                            &This->stream->local_buffer_size, MEM_COMMIT, PAGE_READWRITE);
-    silence_buffer(This->stream, This->stream->local_buffer, This->stream->bufsize_frames);
+    stream->local_buffer_size = stream->bufsize_frames * fmt->nBlockAlign;
+    NtAllocateVirtualMemory(GetCurrentProcess(), (void **)&stream->local_buffer, 0,
+                            &stream->local_buffer_size, MEM_COMMIT, PAGE_READWRITE);
+    silence_buffer(stream, stream->local_buffer, stream->bufsize_frames);
 
     if(This->dataflow == eCapture){
-        This->stream->cap_bufsize_frames = MulDiv(duration, This->stream->dev_desc.mSampleRate, 10000000);
-        This->stream->cap_buffer = HeapAlloc(GetProcessHeap(), 0, This->stream->cap_bufsize_frames * This->stream->fmt->nBlockAlign);
+        stream->cap_bufsize_frames = MulDiv(duration, stream->dev_desc.mSampleRate, 10000000);
+        stream->cap_buffer = HeapAlloc(GetProcessHeap(), 0, stream->cap_bufsize_frames * stream->fmt->nBlockAlign);
     }
 
-    This->stream->share = mode;
+    stream->share = mode;
     This->flags = flags;
     This->channel_count = fmt->nChannels;
     This->period_ms = period / 10000;
 
     This->vols = HeapAlloc(GetProcessHeap(), 0, This->channel_count * sizeof(float));
     if(!This->vols){
-        CoTaskMemFree(This->stream->fmt);
-        This->stream->fmt = NULL;
-        OSSpinLockUnlock(&This->stream->lock);
+        CoTaskMemFree(stream->fmt);
+        HeapFree(GetProcessHeap(), 0, stream);
         LeaveCriticalSection(&g_sessions_lock);
         return E_OUTOFMEMORY;
     }
@@ -1371,22 +1356,20 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface,
     hr = get_audio_session(sessionguid, This->parent, fmt->nChannels,
             &This->session);
     if(FAILED(hr)){
-        CoTaskMemFree(This->stream->fmt);
-        This->stream->fmt = NULL;
+        CoTaskMemFree(stream->fmt);
+        HeapFree(GetProcessHeap(), 0, stream);
         HeapFree(GetProcessHeap(), 0, This->vols);
         This->vols = NULL;
-        OSSpinLockUnlock(&This->stream->lock);
         LeaveCriticalSection(&g_sessions_lock);
         return E_INVALIDARG;
     }
 
     list_add_tail(&This->session->clients, &This->entry);
 
-    ca_setvol(This, This->stream, -1);
+    ca_setvol(This, stream, -1);
 
-    This->initted = TRUE;
+    This->stream = stream;
 
-    OSSpinLockUnlock(&This->stream->lock);
     LeaveCriticalSection(&g_sessions_lock);
 
     return S_OK;
@@ -1402,12 +1385,10 @@ static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
     if(!frames)
         return E_POINTER;
 
-    OSSpinLockLock(&This->stream->lock);
-
-    if(!This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
+    if(!This->stream)
         return AUDCLNT_E_NOT_INITIALIZED;
-    }
+
+    OSSpinLockLock(&This->stream->lock);
 
     *frames = This->stream->bufsize_frames;
 
@@ -1484,12 +1465,10 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
     if(!out)
         return E_POINTER;
 
-    OSSpinLockLock(&This->stream->lock);
-
-    if(!This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
+    if(!This->stream)
         return AUDCLNT_E_NOT_INITIALIZED;
-    }
+
+    OSSpinLockLock(&This->stream->lock);
 
     addr.mScope = This->scope;
     addr.mSelector = kAudioDevicePropertyLatency;
@@ -1524,7 +1503,7 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
 static HRESULT AudioClient_GetCurrentPadding_nolock(ACImpl *This,
         UINT32 *numpad)
 {
-    if(!This->initted)
+    if(!This->stream)
         return AUDCLNT_E_NOT_INITIALIZED;
 
     if(This->dataflow == eCapture)
@@ -1546,6 +1525,9 @@ static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface,
     if(!numpad)
         return E_POINTER;
 
+    if(!This->stream)
+        return AUDCLNT_E_NOT_INITIALIZED;
+
     OSSpinLockLock(&This->stream->lock);
 
     hr = AudioClient_GetCurrentPadding_nolock(This, numpad);
@@ -1898,12 +1880,10 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface)
 
     TRACE("(%p)\n", This);
 
-    OSSpinLockLock(&This->stream->lock);
-
-    if(!This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
+    if(!This->stream)
         return AUDCLNT_E_NOT_INITIALIZED;
-    }
+
+    OSSpinLockLock(&This->stream->lock);
 
     if(This->stream->playing){
         OSSpinLockUnlock(&This->stream->lock);
@@ -1937,12 +1917,10 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient3 *iface)
 
     TRACE("(%p)\n", This);
 
-    OSSpinLockLock(&This->stream->lock);
-
-    if(!This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
+    if(!This->stream)
         return AUDCLNT_E_NOT_INITIALIZED;
-    }
+
+    OSSpinLockLock(&This->stream->lock);
 
     if(!This->stream->playing){
         OSSpinLockUnlock(&This->stream->lock);
@@ -1962,12 +1940,10 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient3 *iface)
 
     TRACE("(%p)\n", This);
 
-    OSSpinLockLock(&This->stream->lock);
-
-    if(!This->initted){
-        OSSpinLockUnlock(&This->stream->lock);
+    if(!This->stream)
         return AUDCLNT_E_NOT_INITIALIZED;
-    }
+
+    OSSpinLockLock(&This->stream->lock);
 
     if(This->stream->playing){
         OSSpinLockUnlock(&This->stream->lock);
@@ -2007,11 +1983,12 @@ static HRESULT WINAPI AudioClient_SetEventHandle(IAudioClient3 *iface,
     if(!event)
         return E_INVALIDARG;
 
+    if(!This->stream)
+        return AUDCLNT_E_NOT_INITIALIZED;
+
     EnterCriticalSection(&g_sessions_lock);
 
-    if(!This->initted)
-        hr = AUDCLNT_E_NOT_INITIALIZED;
-    else if(!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
+    if(!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
         hr = AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
     else if(This->event){
         FIXME("called twice\n");
@@ -2036,12 +2013,10 @@ static HRESULT WINAPI AudioClient_GetService(IAudioClient3 *iface, REFIID riid,
         return E_POINTER;
     *ppv = NULL;
 
-    EnterCriticalSection(&g_sessions_lock);
+    if(!This->stream)
+        return AUDCLNT_E_NOT_INITIALIZED;
 
-    if(!This->initted){
-        hr = AUDCLNT_E_NOT_INITIALIZED;
-        goto end;
-    }
+    EnterCriticalSection(&g_sessions_lock);
 
     if(IsEqualIID(riid, &IID_IAudioRenderClient)){
         if(This->dataflow != eRender){
-- 
2.23.0




More information about the wine-devel mailing list