[PATCH 08/32] quartz: Fix flushing in dsound renderer

Maarten Lankhorst m.b.lankhorst at gmail.com
Sun May 30 12:17:26 CDT 2010


---
 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;
-- 
1.7.0.4


--------------090301030300050207000901--



More information about the wine-patches mailing list