Module: wine Branch: master Commit: 3658bf2367e6054ebdf0dd584e09b464a9c1a58c URL: http://source.winehq.org/git/wine.git/?a=commit;h=3658bf2367e6054ebdf0dd584e...
Author: Maarten Lankhorst m.b.lankhorst@gmail.com Date: Sun May 30 19:17:26 2010 +0200
quartz: Fix flushing in dsound renderer.
---
dlls/quartz/dsoundrender.c | 68 +++++++++++++++++++++++++++----------------- 1 files changed, 42 insertions(+), 26 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index b327c00..8631cd5 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -72,6 +72,7 @@ typedef struct DSoundRenderImpl
DWORD last_play_pos; DWORD play_loops; + DWORD in_loop;
REFERENCE_TIME play_time; MediaSeekingImpl mediaSeeking; @@ -199,9 +200,20 @@ static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *d buf_free = This->buf_size - This->write_pos + play_pos;
/* Wait for enough of the buffer to empty before filling it */ - if(buf_free < This->buf_size/4) + if(buf_free < This->buf_size/20) { - Sleep(50); + DWORD ret; + This->in_loop = 1; + LeaveCriticalSection(&This->csFilter); + ret = WaitForSingleObject(This->blocked, 50); + if (ret != WAIT_TIMEOUT) + ERR("%x\n", ret); + EnterCriticalSection(&This->csFilter); + This->in_loop = 0; + if (This->pInputPin->flushing) + return VFW_E_WRONG_STATE; + if (This->state == State_Stopped) + return VFW_E_WRONG_STATE; continue; }
@@ -296,8 +308,6 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) } }
- SetEvent(This->state_change); - hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { @@ -325,6 +335,7 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample)
if (This->state == State_Paused) { + SetEvent(This->state_change); LeaveCriticalSection(&This->csFilter); WaitForSingleObject(This->blocked, INFINITE); EnterCriticalSection(&This->csFilter); @@ -360,6 +371,7 @@ static HRESULT DSoundRender_Sample(LPVOID iface, IMediaSample * pSample) #endif
hr = DSoundRender_SendSampleData(This, pbSrcStream, cbSrcStream); + SetEvent(This->state_change); LeaveCriticalSection(&This->csFilter); return hr; } @@ -651,6 +663,7 @@ static HRESULT WINAPI DSoundRender_Run(IBaseFilter * iface, REFERENCE_TIME tStar ResetEvent(This->state_change); This->pInputPin->end_of_stream = 0; } + ResetEvent(This->blocked);
This->state = State_Running; } @@ -964,16 +977,39 @@ static HRESULT WINAPI DSoundRender_InputPin_BeginFlush(IPin * iface) InputPin *This = (InputPin *)iface; DSoundRenderImpl *pFilter = (DSoundRenderImpl *)This->pin.pinInfo.pFilter; HRESULT hr; - LPBYTE buffer; - DWORD size;
TRACE("\n");
EnterCriticalSection(This->pin.pCritSec); hr = InputPin_BeginFlush(iface); + SetEvent(pFilter->blocked); + LeaveCriticalSection(This->pin.pCritSec); + + return hr; +} + +static HRESULT WINAPI DSoundRender_InputPin_EndFlush(IPin * iface) +{ + InputPin *This = (InputPin *)iface; + DSoundRenderImpl *pFilter = (DSoundRenderImpl *)This->pin.pinInfo.pFilter; + HRESULT hr; + + TRACE("\n"); + + EnterCriticalSection(This->pin.pCritSec); + if (pFilter->in_loop) { + ResetEvent(pFilter->state_change); + LeaveCriticalSection(This->pin.pCritSec); + WaitForSingleObject(pFilter->state_change, -1); + EnterCriticalSection(This->pin.pCritSec); + } + if (pFilter->state != State_Stopped) + ResetEvent(pFilter->blocked);
if (pFilter->dsbuffer) { + LPBYTE buffer; + DWORD size; IDirectSoundBuffer_Stop(pFilter->dsbuffer);
/* Force a reset */ @@ -986,27 +1022,7 @@ static HRESULT WINAPI DSoundRender_InputPin_BeginFlush(IPin * iface) memset(buffer, 0, size); IDirectSoundBuffer_Unlock(pFilter->dsbuffer, buffer, size, NULL, 0); } - - if (pFilter->state == State_Paused) - SetEvent(pFilter->blocked); - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -static HRESULT WINAPI DSoundRender_InputPin_EndFlush(IPin * iface) -{ - InputPin *This = (InputPin *)iface; - DSoundRenderImpl *pFilter = (DSoundRenderImpl *)This->pin.pinInfo.pFilter; - HRESULT hr; - - TRACE("\n"); - - EnterCriticalSection(This->pin.pCritSec); hr = InputPin_EndFlush(iface); - - if (pFilter->state == State_Paused) - SetEvent(pFilter->blocked); LeaveCriticalSection(This->pin.pCritSec);
return hr;