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