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

This commit is contained in:
Andrew Eikum 2012-01-09 15:25:32 -06:00 committed by Alexandre Julliard
parent 9fb3e0fb62
commit 139e31bc00
1 changed files with 25 additions and 13 deletions

View File

@ -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 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
@ -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);