Commit ee5f6f22 authored by Jörg Höhle's avatar Jörg Höhle Committed by Alexandre Julliard

winecoreaudio: Fix AudioCaptureClient Get/ReleaseBuffer protocol.

parent 04cf4dc0
...@@ -1950,32 +1950,38 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface, ...@@ -1950,32 +1950,38 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
} }
if(This->public_buffer){ if(This->public_buffer){
*data = This->public_buffer->mAudioData;
*frames = *frames =
This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign; This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign;
}else{ }else{
struct list *head = list_head(&This->avail_buffers); struct list *head = list_head(&This->avail_buffers);
if(!head){ if(!head){
*data = NULL;
*frames = 0; *frames = 0;
}else{ }else{
AQBuffer *buf = LIST_ENTRY(head, AQBuffer, entry); AQBuffer *buf = LIST_ENTRY(head, AQBuffer, entry);
This->public_buffer = buf->buf; This->public_buffer = buf->buf;
*data = This->public_buffer->mAudioData;
*frames = *frames =
This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign; This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign;
list_remove(&buf->entry); list_remove(&buf->entry);
if(!*frames){
OSStatus sc = AudioQueueEnqueueBuffer(This->aqueue, This->public_buffer, 0, NULL);
if(sc != noErr)
ERR("Unable to enqueue buffer: %lx\n", sc);
This->public_buffer = NULL;
WARN("empty packet\n");
}
} }
} }
if((This->getbuf_last = *frames)){
UINT64 pos;
*flags = 0; *flags = 0;
This->written_frames += *frames; *data = This->public_buffer->mAudioData;
This->inbuf_frames -= *frames;
This->getbuf_last = 1;
if(devpos || qpcpos)
AudioClock_GetPosition_nolock(This, devpos, qpcpos);
if(devpos)
*devpos = This->written_frames;
if(qpcpos) /* fixme: qpc of recording time */
AudioClock_GetPosition_nolock(This, &pos, qpcpos);
}
OSSpinLockUnlock(&This->lock); OSSpinLockUnlock(&This->lock);
return *frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY; return *frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY;
...@@ -1985,34 +1991,42 @@ static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer( ...@@ -1985,34 +1991,42 @@ static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer(
IAudioCaptureClient *iface, UINT32 done) IAudioCaptureClient *iface, UINT32 done)
{ {
ACImpl *This = impl_from_IAudioCaptureClient(iface); ACImpl *This = impl_from_IAudioCaptureClient(iface);
UINT32 pbuf_frames;
OSStatus sc; OSStatus sc;
TRACE("(%p)->(%u)\n", This, done); TRACE("(%p)->(%u)\n", This, done);
OSSpinLockLock(&This->lock); OSSpinLockLock(&This->lock);
if(!done){
This->getbuf_last = 0;
OSSpinLockUnlock(&This->lock);
return S_OK;
}
if(!This->getbuf_last){ if(!This->getbuf_last){
OSSpinLockUnlock(&This->lock); OSSpinLockUnlock(&This->lock);
return AUDCLNT_E_OUT_OF_ORDER; return AUDCLNT_E_OUT_OF_ORDER;
} }
pbuf_frames = This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign; if(This->getbuf_last != done){
if(done != 0 && done != pbuf_frames){
OSSpinLockUnlock(&This->lock); OSSpinLockUnlock(&This->lock);
return AUDCLNT_E_INVALID_SIZE; return AUDCLNT_E_INVALID_SIZE;
} }
if(done){ This->written_frames += done;
sc = AudioQueueEnqueueBuffer(This->aqueue, This->public_buffer, This->inbuf_frames -= done;
0, NULL);
if(sc != noErr)
WARN("Unable to enqueue buffer: %lx\n", sc);
This->public_buffer = NULL;
}
This->getbuf_last = 0; This->getbuf_last = 0;
sc = AudioQueueEnqueueBuffer(This->aqueue, This->public_buffer, 0, NULL);
if(sc != noErr){
OSSpinLockUnlock(&This->lock);
/* fixme: can't zero public_buffer or we lose memory, but then
* GetBuffer will see that packet again and again. */
ERR("Unable to enqueue buffer: %lx\n", sc);
return AUDCLNT_E_DEVICE_INVALIDATED;
}
This->public_buffer = NULL;
OSSpinLockUnlock(&This->lock); OSSpinLockUnlock(&This->lock);
return S_OK; return S_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment