Maarten Lankhorst : quartz: Use quality control in video renderer.

Alexandre Julliard julliard at winehq.org
Wed Nov 10 11:09:39 CST 2010


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

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Tue Nov  9 23:42:50 2010 +0100

quartz: Use quality control in video renderer.

---

 dlls/quartz/videorenderer.c |   82 ++++++++++++-------------------------------
 1 files changed, 23 insertions(+), 59 deletions(-)

diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c
index 2ad75c4..bf0fa7b 100644
--- a/dlls/quartz/videorenderer.c
+++ b/dlls/quartz/videorenderer.c
@@ -91,7 +91,6 @@ typedef struct VideoRendererImpl
     IUnknown * pUnkOuter;
     BOOL bUnkOuterValid;
     BOOL bAggregatable;
-    REFERENCE_TIME rtLastStop;
     LONG WindowStyle;
 
     /* During pause we can hold a single sample, for use in GetCurrentImage */
@@ -383,27 +382,8 @@ static HRESULT WINAPI VideoRenderer_Receive(BaseInputPin* pin, IMediaSample * pS
     if (IMediaSample_GetMediaTime(pSample, &tStart, &tStop) == S_OK)
         MediaSeekingPassThru_RegisterMediaTime(This->seekthru_unk, tStart);
 
-    hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
-    if (FAILED(hr))
-        ERR("Cannot get sample time (%x)\n", hr);
-
-    if (This->rtLastStop != tStart && This->filter.state == State_Running)
-    {
-        LONG64 delta;
-        delta = tStart - This->rtLastStop;
-        if ((delta < -100000 || delta > 100000) &&
-            IMediaSample_IsDiscontinuity(pSample) == S_FALSE)
-            ERR("Unexpected discontinuity: Last: %u.%03u, tStart: %u.%03u\n",
-                (DWORD)(This->rtLastStop / 10000000),
-                (DWORD)((This->rtLastStop / 10000)%1000),
-                (DWORD)(tStart / 10000000), (DWORD)((tStart / 10000)%1000));
-        This->rtLastStop = tStart;
-    }
-
     /* Preroll means the sample isn't shown, this is used for key frames and things like that */
-    if (IMediaSample_IsPreroll(pSample) == S_OK)
-    {
-        This->rtLastStop = tStop;
+    if (IMediaSample_IsPreroll(pSample) == S_OK) {
         LeaveCriticalSection(&This->filter.csFilter);
         return S_OK;
     }
@@ -436,6 +416,7 @@ static HRESULT WINAPI VideoRenderer_Receive(BaseInputPin* pin, IMediaSample * pS
     SetEvent(This->hEvent);
     if (This->filter.state == State_Paused)
     {
+        VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
         This->sample_held = pSample;
         LeaveCriticalSection(&This->filter.csFilter);
         WaitForSingleObject(This->blocked, INFINITE);
@@ -452,44 +433,15 @@ static HRESULT WINAPI VideoRenderer_Receive(BaseInputPin* pin, IMediaSample * pS
             LeaveCriticalSection(&This->filter.csFilter);
             return VFW_E_WRONG_STATE;
         }
-    }
-
-    if (This->filter.pClock && This->filter.state == State_Running)
-    {
-        REFERENCE_TIME time, trefstart, trefstop;
-        LONG delta;
-
-        /* Perhaps I <SHOULD> use the reference clock AdviseTime function here
-         * I'm not going to! When I tried, it seemed to generate lag and
-         * it caused instability.
-         */
-        IReferenceClock_GetTime(This->filter.pClock, &time);
-
-        trefstart = This->filter.rtStreamStart;
-        trefstop = (REFERENCE_TIME)((double)(tStop - tStart) / This->pInputPin->pin.dRate) + This->filter.rtStreamStart;
-        delta = (LONG)((trefstart-time)/10000);
-        This->filter.rtStreamStart = trefstop;
-        This->rtLastStop = tStop;
-
-        if (delta > 0)
-        {
-            TRACE("Sleeping for %u ms\n", delta);
-            Sleep(delta);
-        }
-        else if (time > trefstop)
-        {
-            TRACE("Dropping sample: Time: %u.%03u ms trefstop: %u.%03u ms!\n",
-                  (DWORD)(time / 10000000), (DWORD)((time / 10000)%1000),
-                  (DWORD)(trefstop / 10000000), (DWORD)((trefstop / 10000)%1000) );
-            This->rtLastStop = tStop;
-            LeaveCriticalSection(&This->filter.csFilter);
-            return S_OK;
+    } else {
+        hr = QualityControlRender_WaitFor(&This->qcimpl, pSample, This->blocked);
+        if (hr == S_OK) {
+            QualityControlRender_BeginRender(&This->qcimpl);
+            VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
+            QualityControlRender_EndRender(&This->qcimpl);
         }
+        QualityControlRender_DoQOS(&This->qcimpl);
     }
-    This->rtLastStop = tStop;
-
-    VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
-
     LeaveCriticalSection(&This->filter.csFilter);
     return S_OK;
 }
@@ -601,7 +553,6 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
 
     pVideoRenderer->init = 0;
     pVideoRenderer->AutoShow = 1;
-    pVideoRenderer->rtLastStop = -1;
     ZeroMemory(&pVideoRenderer->SourceRect, sizeof(RECT));
     ZeroMemory(&pVideoRenderer->DestRect, sizeof(RECT));
     ZeroMemory(&pVideoRenderer->WindowPos, sizeof(RECT));
@@ -846,6 +797,17 @@ static HRESULT WINAPI VideoRenderer_Pause(IBaseFilter * iface)
     return S_OK;
 }
 
+static HRESULT WINAPI VideoRenderer_SetSyncSource(IBaseFilter *iface, IReferenceClock *clock) {
+    VideoRendererImpl *This = (VideoRendererImpl *)iface;
+    HRESULT hr;
+
+    EnterCriticalSection(&This->filter.csFilter);
+    QualityControlRender_SetClock(&This->qcimpl, clock);
+    hr = BaseFilterImpl_SetSyncSource(iface, clock);
+    LeaveCriticalSection(&This->filter.csFilter);
+    return hr;
+}
+
 static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
 {
     HRESULT hr = S_OK;
@@ -867,6 +829,7 @@ static HRESULT WINAPI VideoRenderer_Run(IBaseFilter * iface, REFERENCE_TIME tSta
 
         This->filter.rtStreamStart = tStart;
         This->filter.state = State_Running;
+        QualityControlRender_Start(&This->qcimpl, tStart);
     } else if (This->filter.filterInfo.pGraph) {
         IMediaEventSink *pEventSink;
         hr = IFilterGraph_QueryInterface(This->filter.filterInfo.pGraph, &IID_IMediaEventSink, (LPVOID*)&pEventSink);
@@ -925,7 +888,7 @@ static const IBaseFilterVtbl VideoRenderer_Vtbl =
     VideoRenderer_Pause,
     VideoRenderer_Run,
     VideoRenderer_GetState,
-    BaseFilterImpl_SetSyncSource,
+    VideoRenderer_SetSyncSource,
     BaseFilterImpl_GetSyncSource,
     BaseFilterImpl_EnumPins,
     VideoRenderer_FindPin,
@@ -984,6 +947,7 @@ static HRESULT WINAPI VideoRenderer_InputPin_EndFlush(IPin * iface)
     if (pVideoRenderer->filter.state == State_Paused)
         ResetEvent(pVideoRenderer->blocked);
 
+    QualityControlRender_Start(&pVideoRenderer->qcimpl, pVideoRenderer->filter.rtStreamStart);
     hr = BaseInputPinImpl_EndFlush(iface);
     LeaveCriticalSection(This->pin.pCritSec);
     MediaSeekingPassThru_ResetMediaTime(pVideoRenderer->seekthru_unk);




More information about the wine-cvs mailing list