Andrew Eikum : wineoss.drv: Fix IAudioRenderClient::{Get, Release}Buffer protocol.

Alexandre Julliard julliard at winehq.org
Tue Jan 10 13:11:18 CST 2012


Module: wine
Branch: master
Commit: 139e31bc002e73bbb2e34268cae9e0918aaa4fef
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=139e31bc002e73bbb2e34268cae9e0918aaa4fef

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Mon Jan  9 15:25:32 2012 -0600

wineoss.drv: Fix IAudioRenderClient::{Get,Release}Buffer protocol.

---

 dlls/wineoss.drv/mmdevdrv.c |   38 +++++++++++++++++++++++++-------------
 1 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c
index bc4d952..aaa94ee 100644
--- a/dlls/wineoss.drv/mmdevdrv.c
+++ b/dlls/wineoss.drv/mmdevdrv.c
@@ -128,6 +128,7 @@ struct ACImpl {
 
     BYTE *local_buffer, *tmp_buffer;
     int buf_state;
+    long getbuf_last; /* <0 when using tmp_buffer */
     HANDLE timer;
 
     CRITICAL_SECTION lock;
@@ -1495,7 +1496,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;
     }
@@ -1689,15 +1690,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;
     }
@@ -1727,10 +1729,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);
@@ -1766,13 +1768,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 S_OK;
+    }
+
+    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 written_frames ? AUDCLNT_E_OUT_OF_ORDER : S_OK;
+        return AUDCLNT_E_INVALID_SIZE;
     }
 
-    if(This->buf_state == LOCKED_NORMAL)
+    if(This->getbuf_last >= 0)
         buffer = This->local_buffer + This->fmt->nBlockAlign *
           ((This->lcl_offs_frames + This->held_frames) % This->bufsize_frames);
     else
@@ -1782,7 +1794,7 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
         oss_silence_buffer(This, buffer, written_frames);
 
     if(This->held_frames){
-        if(This->buf_state == LOCKED_WRAPPED)
+        if(This->getbuf_last < 0)
             oss_wrap_buffer(This, buffer, written_frames);
 
         This->held_frames += written_frames;
@@ -1797,7 +1809,7 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
                 written_frames * This->fmt->nBlockAlign);
         if(w_bytes < 0){
             if(errno != EAGAIN){
-                This->buf_state = NOT_LOCKED;
+                This->getbuf_last = 0;
                 LeaveCriticalSection(&This->lock);
                 ERR("write failed: %d (%s)\n", errno, strerror(errno));
                 return E_FAIL;
@@ -1808,7 +1820,7 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
         This->inbuf_frames += w_frames;
 
         if(w_frames < written_frames){
-            if(This->buf_state == LOCKED_WRAPPED)
+            if(This->getbuf_last < 0)
                 oss_wrap_buffer(This, This->tmp_buffer + w_bytes,
                         written_frames - w_frames);
             else
@@ -1818,7 +1830,7 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
     }
 
     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