[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