=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: winecoreaudio: Fix AudioCaptureClient Get/ReleaseBuffer protocol.
Alexandre Julliard
julliard at winehq.org
Fri Jan 13 11:44:31 CST 2012
Module: wine
Branch: master
Commit: ee5f6f229e4504d9435af8e653b8080b0fbb0fa5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ee5f6f229e4504d9435af8e653b8080b0fbb0fa5
Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date: Sun Aug 21 23:35:11 2011 +0200
winecoreaudio: Fix AudioCaptureClient Get/ReleaseBuffer protocol.
---
dlls/winecoreaudio.drv/mmdevdrv.c | 56 +++++++++++++++++++++++--------------
1 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 5d69e3c..6161e51 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -1950,32 +1950,38 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
}
if(This->public_buffer){
- *data = This->public_buffer->mAudioData;
*frames =
This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign;
}else{
struct list *head = list_head(&This->avail_buffers);
if(!head){
- *data = NULL;
*frames = 0;
}else{
AQBuffer *buf = LIST_ENTRY(head, AQBuffer, entry);
This->public_buffer = buf->buf;
- *data = This->public_buffer->mAudioData;
*frames =
This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign;
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");
+ }
}
}
- *flags = 0;
- This->written_frames += *frames;
- This->inbuf_frames -= *frames;
- This->getbuf_last = 1;
-
- if(devpos || qpcpos)
- AudioClock_GetPosition_nolock(This, devpos, qpcpos);
+ if((This->getbuf_last = *frames)){
+ UINT64 pos;
+ *flags = 0;
+ *data = This->public_buffer->mAudioData;
+ if(devpos)
+ *devpos = This->written_frames;
+ if(qpcpos) /* fixme: qpc of recording time */
+ AudioClock_GetPosition_nolock(This, &pos, qpcpos);
+ }
OSSpinLockUnlock(&This->lock);
return *frames ? S_OK : AUDCLNT_S_BUFFER_EMPTY;
@@ -1985,34 +1991,42 @@ static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer(
IAudioCaptureClient *iface, UINT32 done)
{
ACImpl *This = impl_from_IAudioCaptureClient(iface);
- UINT32 pbuf_frames;
OSStatus sc;
TRACE("(%p)->(%u)\n", This, done);
OSSpinLockLock(&This->lock);
+ if(!done){
+ This->getbuf_last = 0;
+ OSSpinLockUnlock(&This->lock);
+ return S_OK;
+ }
+
if(!This->getbuf_last){
OSSpinLockUnlock(&This->lock);
return AUDCLNT_E_OUT_OF_ORDER;
}
- pbuf_frames = This->public_buffer->mAudioDataByteSize / This->fmt->nBlockAlign;
- if(done != 0 && done != pbuf_frames){
+ if(This->getbuf_last != done){
OSSpinLockUnlock(&This->lock);
return AUDCLNT_E_INVALID_SIZE;
}
- if(done){
- sc = AudioQueueEnqueueBuffer(This->aqueue, This->public_buffer,
- 0, NULL);
- if(sc != noErr)
- WARN("Unable to enqueue buffer: %lx\n", sc);
- This->public_buffer = NULL;
- }
-
+ This->written_frames += done;
+ This->inbuf_frames -= done;
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);
return S_OK;
More information about the wine-cvs
mailing list