Alexandre Julliard : Revert "quartz: Clean up pullpin code."

Alexandre Julliard julliard at winehq.org
Mon May 5 14:28:22 CDT 2008


Module: wine
Branch: master
Commit: aac5fa3469057b52edad3b3994099a0d28304635
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=aac5fa3469057b52edad3b3994099a0d28304635

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon May  5 18:24:22 2008 +0200

Revert "quartz: Clean up pullpin code."

This reverts commit 3066116f76c0c44950fde3552485b37dce24d1f8.

---

 dlls/quartz/pin.c |  115 +++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 94 insertions(+), 21 deletions(-)

diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c
index 5f705d0..8619776 100644
--- a/dlls/quartz/pin.c
+++ b/dlls/quartz/pin.c
@@ -1233,7 +1233,6 @@ static HRESULT PullPin_Init(const IPinVtbl *PullPin_Vtbl, const PIN_INFO * pPinI
     pPinImpl->rtStop = ((LONGLONG)0x7fffffff << 32) | 0xffffffff;
     pPinImpl->dRate = 1.0;
     pPinImpl->state = Req_Die;
-    assert(pCustomRequest);
     pPinImpl->fnCustomRequest = pCustomRequest;
     pPinImpl->stop_playback = 1;
 
@@ -1400,6 +1399,44 @@ ULONG WINAPI PullPin_Release(IPin *iface)
     return refCount;
 }
 
+static HRESULT PullPin_Standard_Request(PullPin *This, BOOL start)
+{
+    REFERENCE_TIME rtSampleStart;
+    REFERENCE_TIME rtSampleStop;
+    IMediaSample *sample = NULL;
+    HRESULT hr;
+
+    TRACE("Requesting sample!\n");
+
+    if (start)
+        This->rtNext = This->rtCurrent;
+
+    if (This->rtNext >= This->rtStop)
+        /* Last sample has already been queued, request nothing more */
+        return S_OK;
+
+    hr = IMemAllocator_GetBuffer(This->pAlloc, &sample, NULL, NULL, 0);
+
+    if (SUCCEEDED(hr))
+    {
+        rtSampleStart = This->rtNext;
+        rtSampleStop = rtSampleStart + MEDIATIME_FROM_BYTES(IMediaSample_GetSize(sample));
+        if (rtSampleStop > This->rtStop)
+            rtSampleStop = MEDIATIME_FROM_BYTES(ALIGNUP(BYTES_FROM_MEDIATIME(This->rtStop), This->cbAlign));
+        hr = IMediaSample_SetTime(sample, &rtSampleStart, &rtSampleStop);
+
+        This->rtCurrent = This->rtNext;
+        This->rtNext = rtSampleStop;
+
+        if (SUCCEEDED(hr))
+            hr = IAsyncReader_Request(This->pReader, sample, 0);
+    }
+    if (FAILED(hr))
+        FIXME("Failed to queue sample : %08x\n", hr);
+
+    return hr;
+}
+
 static void CALLBACK PullPin_Flush(PullPin *This)
 {
     IMediaSample *pSample;
@@ -1408,8 +1445,6 @@ static void CALLBACK PullPin_Flush(PullPin *This)
     EnterCriticalSection(This->pin.pCritSec);
     if (This->pReader)
     {
-        SendFurther((IPin *)This, deliver_beginflush, NULL, NULL );
-
         /* Flush outstanding samples */
         IAsyncReader_BeginFlush(This->pReader);
         for (;;)
@@ -1422,12 +1457,13 @@ static void CALLBACK PullPin_Flush(PullPin *This)
                 break;
 
             assert(!IMediaSample_GetActualDataLength(pSample));
+            if (This->fnCustomRequest)
+                This->fnSampleProc(This->pin.pUserData, pSample, dwUser);
+
             IMediaSample_Release(pSample);
         }
 
         IAsyncReader_EndFlush(This->pReader);
-        SendFurther((IPin *)This, deliver_endflush, NULL, NULL );
-        This->fnCleanProc(This->pin.pUserData);
     }
     LeaveCriticalSection(This->pin.pCritSec);
 }
@@ -1454,7 +1490,10 @@ static void CALLBACK PullPin_Thread_Process(PullPin *This)
     }
 
     /* There is no sample in our buffer */
-    hr = This->fnCustomRequest(This->pin.pUserData);
+    if (!This->fnCustomRequest)
+        hr = PullPin_Standard_Request(This, TRUE);
+    else
+        hr = This->fnCustomRequest(This->pin.pUserData);
 
     if (FAILED(hr))
         ERR("Request error: %x\n", hr);
@@ -1471,18 +1510,46 @@ static void CALLBACK PullPin_Thread_Process(PullPin *This)
 
         hr = IAsyncReader_WaitForNext(This->pReader, 10000, &pSample, &dwUser);
 
-        if (SUCCEEDED(hr))
+        /* Calling fnCustomRequest is not specifically useful here: It can be handled inside fnSampleProc */
+        if (pSample && !This->fnCustomRequest)
+            hr = PullPin_Standard_Request(This, FALSE);
+
+        /* Return an empty sample on error to the implementation in case it does custom parsing, so it knows it's gone */
+        if (SUCCEEDED(hr) || (This->fnCustomRequest && pSample))
         {
             REFERENCE_TIME rtStart, rtStop;
+            BOOL rejected;
 
             IMediaSample_GetTime(pSample, &rtStart, &rtStop);
 
-            hr = This->fnSampleProc(This->pin.pUserData, pSample, dwUser);
+            do
+            {
+                hr = This->fnSampleProc(This->pin.pUserData, pSample, dwUser);
+
+                if (This->fnCustomRequest)
+                    break;
+
+                rejected = FALSE;
+                if (This->rtCurrent == rtStart)
+                {
+                    rejected = TRUE;
+                    TRACE("DENIED!\n");
+                    Sleep(10);
+                    /* Maybe it's transient? */
+                }
+                /* rtNext = rtCurrent, because the next sample is already queued */
+                else if (rtStop != This->rtCurrent && rtStop < This->rtStop)
+                {
+                    WARN("Position changed! rtStop: %u, rtCurrent: %u\n", (DWORD)BYTES_FROM_MEDIATIME(rtStop), (DWORD)BYTES_FROM_MEDIATIME(This->rtCurrent));
+                    PullPin_Flush(This);
+                    hr = PullPin_Standard_Request(This, TRUE);
+                }
+            } while (rejected && (This->rtCurrent < This->rtStop && hr == S_OK && !This->stop_playback));
         }
         else
         {
             /* FIXME: This is not well handled yet! */
-            ERR("Processing/wait error: %x\n", hr);
+            ERR("Processing error: %x\n", hr);
         }
 
         if (pSample)
@@ -1697,6 +1764,12 @@ HRESULT WINAPI PullPin_BeginFlush(IPin * iface)
     PullPin *This = (PullPin *)iface;
     TRACE("(%p)->()\n", This);
 
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        SendFurther( iface, deliver_beginflush, NULL, NULL );
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+
     EnterCriticalSection(&This->thread_lock);
     {
         PullPin_WaitForStateChange(This, INFINITE);
@@ -1706,14 +1779,15 @@ HRESULT WINAPI PullPin_BeginFlush(IPin * iface)
             PullPin_PauseProcessing(This);
             PullPin_WaitForStateChange(This, INFINITE);
         }
-
-        EnterCriticalSection(This->pin.pCritSec);
-        SendFurther( iface, deliver_beginflush, NULL, NULL );
-        LeaveCriticalSection(This->pin.pCritSec);
     }
-
     LeaveCriticalSection(&This->thread_lock);
 
+    EnterCriticalSection(This->pin.pCritSec);
+    {
+        This->fnCleanProc(This->pin.pUserData);
+    }
+    LeaveCriticalSection(This->pin.pCritSec);
+
     return S_OK;
 }
 
@@ -1728,18 +1802,17 @@ HRESULT WINAPI PullPin_EndFlush(IPin * iface)
         FILTER_STATE state;
         IBaseFilter_GetState(This->pin.pinInfo.pFilter, INFINITE, &state);
 
-        EnterCriticalSection(This->pin.pCritSec);
-        SendFurther( iface, deliver_endflush, NULL, NULL );
-        LeaveCriticalSection(This->pin.pCritSec);
-
         if (This->stop_playback && state == State_Running)
-        {
             PullPin_StartProcessing(This);
-            PullPin_WaitForStateChange(This, INFINITE);
-        }
+
+        PullPin_WaitForStateChange(This, INFINITE);
     }
     LeaveCriticalSection(&This->thread_lock);
 
+    EnterCriticalSection(This->pin.pCritSec);
+    SendFurther( iface, deliver_endflush, NULL, NULL );
+    LeaveCriticalSection(This->pin.pCritSec);
+
     return S_OK;
 }
 




More information about the wine-cvs mailing list