wineoss.drv: Track number of frames reserved by client in capture direction.

This commit is contained in:
Andrew Eikum 2012-05-22 13:11:06 -05:00 committed by Alexandre Julliard
parent 99661c7ddf
commit 1c37857a18
1 changed files with 30 additions and 19 deletions

View File

@ -120,7 +120,6 @@ struct ACImpl {
UINT32 oss_bufsize_bytes, lcl_offs_frames; /* offs into local_buffer where valid data starts */ UINT32 oss_bufsize_bytes, lcl_offs_frames; /* offs into local_buffer where valid data starts */
BYTE *local_buffer, *tmp_buffer; BYTE *local_buffer, *tmp_buffer;
int buf_state;
LONG32 getbuf_last; /* <0 when using tmp_buffer */ LONG32 getbuf_last; /* <0 when using tmp_buffer */
HANDLE timer; HANDLE timer;
@ -132,12 +131,6 @@ struct ACImpl {
struct list entry; struct list entry;
}; };
enum BufferStates {
NOT_LOCKED = 0,
LOCKED_NORMAL, /* public buffer piece is from local_buffer */
LOCKED_WRAPPED /* public buffer piece is in tmp_buffer */
};
typedef struct _SessionMgr { typedef struct _SessionMgr {
IAudioSessionManager2 IAudioSessionManager2_iface; IAudioSessionManager2 IAudioSessionManager2_iface;
@ -1571,7 +1564,7 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient *iface)
return AUDCLNT_E_NOT_STOPPED; return AUDCLNT_E_NOT_STOPPED;
} }
if(This->buf_state != NOT_LOCKED || This->getbuf_last){ if(This->getbuf_last){
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return AUDCLNT_E_BUFFER_OPERATION_PENDING; return AUDCLNT_E_BUFFER_OPERATION_PENDING;
} }
@ -1928,7 +1921,6 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
UINT64 *qpcpos) UINT64 *qpcpos)
{ {
ACImpl *This = impl_from_IAudioCaptureClient(iface); ACImpl *This = impl_from_IAudioCaptureClient(iface);
HRESULT hr;
TRACE("(%p)->(%p, %p, %p, %p, %p)\n", This, data, frames, flags, TRACE("(%p)->(%p, %p, %p, %p, %p)\n", This, data, frames, flags,
devpos, qpcpos); devpos, qpcpos);
@ -1938,19 +1930,21 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
EnterCriticalSection(&This->lock); EnterCriticalSection(&This->lock);
if(This->buf_state != NOT_LOCKED){ if(This->getbuf_last){
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return AUDCLNT_E_OUT_OF_ORDER; return AUDCLNT_E_OUT_OF_ORDER;
} }
hr = IAudioCaptureClient_GetNextPacketSize(iface, frames); if(This->held_frames < This->period_frames){
if(FAILED(hr)){ *frames = 0;
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return hr; return AUDCLNT_S_BUFFER_EMPTY;
} }
*flags = 0; *flags = 0;
*frames = This->period_frames;
if(This->lcl_offs_frames + *frames > This->bufsize_frames){ if(This->lcl_offs_frames + *frames > This->bufsize_frames){
UINT32 chunk_bytes, offs_bytes, frames_bytes; UINT32 chunk_bytes, offs_bytes, frames_bytes;
if(This->tmp_buffer_frames < *frames){ if(This->tmp_buffer_frames < *frames){
@ -1976,10 +1970,16 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
*data = This->local_buffer + *data = This->local_buffer +
This->lcl_offs_frames * This->fmt->nBlockAlign; This->lcl_offs_frames * This->fmt->nBlockAlign;
This->buf_state = LOCKED_NORMAL; This->getbuf_last = *frames;
if(devpos || qpcpos) if(devpos)
IAudioClock_GetPosition(&This->IAudioClock_iface, devpos, qpcpos); *devpos = This->written_frames;
if(qpcpos){
LARGE_INTEGER stamp, freq;
QueryPerformanceCounter(&stamp);
QueryPerformanceFrequency(&freq);
*qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
}
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
@ -1995,16 +1995,27 @@ static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer(
EnterCriticalSection(&This->lock); EnterCriticalSection(&This->lock);
if(This->buf_state == NOT_LOCKED){ if(!done){
This->getbuf_last = 0;
LeaveCriticalSection(&This->lock);
return S_OK;
}
if(!This->getbuf_last){
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return AUDCLNT_E_OUT_OF_ORDER; return AUDCLNT_E_OUT_OF_ORDER;
} }
if(This->getbuf_last != done){
LeaveCriticalSection(&This->lock);
return AUDCLNT_E_INVALID_SIZE;
}
This->written_frames += done;
This->held_frames -= done; This->held_frames -= done;
This->lcl_offs_frames += done; This->lcl_offs_frames += done;
This->lcl_offs_frames %= This->bufsize_frames; This->lcl_offs_frames %= This->bufsize_frames;
This->getbuf_last = 0;
This->buf_state = NOT_LOCKED;
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);