=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: winealsa: Fix AudioRenderClient Get/ ReleaseBuffer protocol.
Alexandre Julliard
julliard at winehq.org
Tue Jan 10 13:11:18 CST 2012
Module: wine
Branch: master
Commit: 2b51d38d3cf5e2f4e14d905c9263b1222dad3ef2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=2b51d38d3cf5e2f4e14d905c9263b1222dad3ef2
Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date: Thu Jan 5 18:24:20 2012 +0100
winealsa: Fix AudioRenderClient Get/ReleaseBuffer protocol.
---
dlls/winealsa.drv/mmdevdrv.c | 33 ++++++++++++++++++++++-----------
1 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index a2a2a7d..29933e8 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -116,6 +116,7 @@ struct ACImpl {
HANDLE timer;
BYTE *local_buffer, *tmp_buffer;
int buf_state;
+ long getbuf_last; /* <0 when using tmp_buffer */
CRITICAL_SECTION lock;
@@ -1763,7 +1764,7 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient *iface)
return AUDCLNT_E_NOT_STOPPED;
}
- if(This->buf_state != NOT_LOCKED){
+ if(This->buf_state != NOT_LOCKED || This->getbuf_last){
LeaveCriticalSection(&This->lock);
return AUDCLNT_E_BUFFER_OPERATION_PENDING;
}
@@ -1964,16 +1965,16 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
if(!data)
return E_POINTER;
+ *data = NULL;
EnterCriticalSection(&This->lock);
- if(This->buf_state != NOT_LOCKED){
+ if(This->getbuf_last){
LeaveCriticalSection(&This->lock);
return AUDCLNT_E_OUT_OF_ORDER;
}
if(!frames){
- This->buf_state = LOCKED_NORMAL;
LeaveCriticalSection(&This->lock);
return S_OK;
}
@@ -2003,10 +2004,10 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
This->tmp_buffer_frames = frames;
}
*data = This->tmp_buffer;
- This->buf_state = LOCKED_WRAPPED;
+ This->getbuf_last = -frames;
}else{
*data = This->local_buffer + write_pos * This->fmt->nBlockAlign;
- This->buf_state = LOCKED_NORMAL;
+ This->getbuf_last = frames;
}
LeaveCriticalSection(&This->lock);
@@ -2042,13 +2043,23 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
EnterCriticalSection(&This->lock);
- if(This->buf_state == NOT_LOCKED || !written_frames){
- This->buf_state = NOT_LOCKED;
+ if(!written_frames){
+ This->getbuf_last = 0;
LeaveCriticalSection(&This->lock);
- return written_frames ? AUDCLNT_E_OUT_OF_ORDER : S_OK;
+ return S_OK;
}
- if(This->buf_state == LOCKED_NORMAL)
+ if(!This->getbuf_last){
+ LeaveCriticalSection(&This->lock);
+ return AUDCLNT_E_OUT_OF_ORDER;
+ }
+
+ if(written_frames > (This->getbuf_last >= 0 ? This->getbuf_last : -This->getbuf_last)){
+ LeaveCriticalSection(&This->lock);
+ return AUDCLNT_E_INVALID_SIZE;
+ }
+
+ if(This->getbuf_last >= 0)
buffer = This->local_buffer + This->fmt->nBlockAlign *
((This->lcl_offs_frames + This->held_frames) % This->bufsize_frames);
else
@@ -2061,12 +2072,12 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
memset(buffer, 0, written_frames * This->fmt->nBlockAlign);
}
- if(This->buf_state == LOCKED_WRAPPED)
+ if(This->getbuf_last < 0)
alsa_wrap_buffer(This, buffer, written_frames);
This->held_frames += written_frames;
This->written_frames += written_frames;
- This->buf_state = NOT_LOCKED;
+ This->getbuf_last = 0;
LeaveCriticalSection(&This->lock);
More information about the wine-cvs
mailing list