=?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