Andrew Eikum : wineoss.drv: Fix IAudioRenderClient::{Get, Release}Buffer protocol.
Module: wine Branch: master Commit: 139e31bc002e73bbb2e34268cae9e0918aaa4fef URL: http://source.winehq.org/git/wine.git/?a=commit;h=139e31bc002e73bbb2e34268ca... Author: Andrew Eikum <aeikum(a)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);
participants (1)
-
Alexandre Julliard