Maarten Lankhorst : quartz: Keep track of the time in the video renderer.

Alexandre Julliard julliard at winehq.org
Tue Apr 29 08:54:36 CDT 2008


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

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Mon Apr 28 15:00:51 2008 -0700

quartz: Keep track of the time in the video renderer.

---

 dlls/quartz/videorenderer.c |   54 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c
index f009eda..db80b65 100644
--- a/dlls/quartz/videorenderer.c
+++ b/dlls/quartz/videorenderer.c
@@ -85,6 +85,7 @@ typedef struct VideoRendererImpl
     IUnknown * pUnkOuter;
     BOOL bUnkOuterValid;
     BOOL bAggregatable;
+    REFERENCE_TIME rtLastStop;
 } VideoRendererImpl;
 
 static LRESULT CALLBACK VideoWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
@@ -361,9 +362,26 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
 
     TRACE("%p %p\n", iface, pSample);
 
+    hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
+    if (FAILED(hr))
+        ERR("Cannot get sample time (%x)\n", hr);
+
+    if (This->rtLastStop != tStart)
+    {
+        if (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;
         return S_OK;
+    }
 
     hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
     if (FAILED(hr))
@@ -372,10 +390,6 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
         return hr;
     }
 
-    hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
-    if (FAILED(hr))
-        ERR("Cannot get sample time (%x)\n", hr);
-
     cbSrcStream = IMediaSample_GetActualDataLength(pSample);
 
     TRACE("val %p %ld\n", pbSrcStream, cbSrcStream);
@@ -393,6 +407,37 @@ static HRESULT VideoRenderer_Sample(LPVOID iface, IMediaSample * pSample)
     }
 #endif
 
+    if (This->pClock && This->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->pClock, &time);
+
+        trefstart = This->rtStreamStart;
+        trefstop = (REFERENCE_TIME)((double)(tStop - tStart) / This->pInputPin->dRate) + This->rtStreamStart;
+        delta = (LONG)((trefstart-time)/10000);
+        This->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: %lld ms trefstop: %lld ms!\n", time/10000, trefstop/10000);
+            This->rtLastStop = tStop;
+            return S_OK;
+        }
+    }
+    This->rtLastStop = tStop;
+
     VideoRenderer_SendSampleData(This, pbSrcStream, cbSrcStream);
 
     return S_OK;
@@ -464,6 +509,7 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv)
     pVideoRenderer->pClock = NULL;
     pVideoRenderer->init = 0;
     pVideoRenderer->AutoShow = 1;
+    pVideoRenderer->rtLastStop = -1;
     ZeroMemory(&pVideoRenderer->filterInfo, sizeof(FILTER_INFO));
 
     /* construct input pin */




More information about the wine-cvs mailing list