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

Andrew Eikum aeikum at codeweavers.com
Mon Nov 22 14:55:01 CST 2021


Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>

On Thu, Nov 18, 2021 at 07:52:36AM +0000, Huw Davies wrote:
> 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