winealsa: Fix AudioCaptureClient Get/ReleaseBuffer protocol.
This commit is contained in:
parent
8bf8bd9786
commit
18024afd97
|
@ -115,7 +115,6 @@ struct ACImpl {
|
|||
|
||||
HANDLE timer;
|
||||
BYTE *local_buffer, *tmp_buffer;
|
||||
int buf_state;
|
||||
long getbuf_last; /* <0 when using tmp_buffer */
|
||||
|
||||
CRITICAL_SECTION lock;
|
||||
|
@ -126,12 +125,6 @@ struct ACImpl {
|
|||
struct list entry;
|
||||
};
|
||||
|
||||
enum BufferStates {
|
||||
NOT_LOCKED = 0,
|
||||
LOCKED_NORMAL, /* public buffer piece is from local_buffer */
|
||||
LOCKED_WRAPPED /* public buffer piece is wrapped around, in tmp_buffer */
|
||||
};
|
||||
|
||||
typedef struct _SessionMgr {
|
||||
IAudioSessionManager2 IAudioSessionManager2_iface;
|
||||
|
||||
|
@ -1757,7 +1750,7 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient *iface)
|
|||
return AUDCLNT_E_NOT_STOPPED;
|
||||
}
|
||||
|
||||
if(This->buf_state != NOT_LOCKED || This->getbuf_last){
|
||||
if(This->getbuf_last){
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return AUDCLNT_E_BUFFER_OPERATION_PENDING;
|
||||
}
|
||||
|
@ -2127,7 +2120,6 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
|
|||
UINT64 *qpcpos)
|
||||
{
|
||||
ACImpl *This = impl_from_IAudioCaptureClient(iface);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)->(%p, %p, %p, %p, %p)\n", This, data, frames, flags,
|
||||
devpos, qpcpos);
|
||||
|
@ -2137,18 +2129,18 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
|
|||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
if(This->buf_state != NOT_LOCKED){
|
||||
if(This->getbuf_last){
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return AUDCLNT_E_OUT_OF_ORDER;
|
||||
}
|
||||
|
||||
hr = IAudioCaptureClient_GetNextPacketSize(iface, frames);
|
||||
if(FAILED(hr)){
|
||||
/* hr = GetNextPacketSize(iface, frames); */
|
||||
if(This->held_frames < This->mmdev_period_frames){
|
||||
*frames = 0;
|
||||
LeaveCriticalSection(&This->lock);
|
||||
return hr;
|
||||
return AUDCLNT_S_BUFFER_EMPTY;
|
||||
}
|
||||
|
||||
*flags = 0;
|
||||
*frames = This->mmdev_period_frames;
|
||||
|
||||
if(This->lcl_offs_frames + *frames > This->bufsize_frames){
|
||||
UINT32 chunk_bytes, offs_bytes, frames_bytes;
|
||||
|
@ -2175,10 +2167,17 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
|
|||
*data = This->local_buffer +
|
||||
This->lcl_offs_frames * This->fmt->nBlockAlign;
|
||||
|
||||
This->buf_state = LOCKED_NORMAL;
|
||||
This->getbuf_last = *frames;
|
||||
*flags = 0;
|
||||
|
||||
if(devpos || qpcpos)
|
||||
IAudioClock_GetPosition(&This->IAudioClock_iface, devpos, qpcpos);
|
||||
if(devpos)
|
||||
*devpos = This->written_frames;
|
||||
if(qpcpos){ /* fixme: qpc of recording time */
|
||||
LARGE_INTEGER stamp, freq;
|
||||
QueryPerformanceCounter(&stamp);
|
||||
QueryPerformanceFrequency(&freq);
|
||||
*qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
|
@ -2194,16 +2193,27 @@ static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer(
|
|||
|
||||
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);
|
||||
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->lcl_offs_frames += done;
|
||||
This->lcl_offs_frames %= This->bufsize_frames;
|
||||
|
||||
This->buf_state = NOT_LOCKED;
|
||||
This->getbuf_last = 0;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
|
@ -2217,7 +2227,16 @@ static HRESULT WINAPI AudioCaptureClient_GetNextPacketSize(
|
|||
|
||||
TRACE("(%p)->(%p)\n", This, frames);
|
||||
|
||||
return AudioClient_GetCurrentPadding(&This->IAudioClient_iface, frames);
|
||||
if(!frames)
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
*frames = This->held_frames < This->mmdev_period_frames ? 0 : This->mmdev_period_frames;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl =
|
||||
|
|
Loading…
Reference in New Issue