Maarten Lankhorst : quartz: Add GetCurrentPosition using the reference clock.

Alexandre Julliard julliard at winehq.org
Fri Mar 28 10:02:46 CDT 2008


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

Author: Maarten Lankhorst <m.b.lankhorst at gmail.com>
Date:   Thu Mar 27 16:28:51 2008 -0700

quartz: Add GetCurrentPosition using the reference clock.

---

 dlls/quartz/filtergraph.c       |   43 +++++++++++++++++++++++++++++++++++++-
 dlls/quartz/tests/filtergraph.c |   37 +++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 9b37594..4371a36 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -199,6 +199,8 @@ typedef struct _IFilterGraphImpl {
     BOOL bUnkOuterValid;
     BOOL bAggregatable;
     GUID timeformatseek;
+    LONGLONG start_time;
+    LONGLONG position;
 } IFilterGraphImpl;
 
 static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
@@ -1517,7 +1519,7 @@ static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter
 
     /* Explorer the graph from source filters to renderers, determine renderers
      * number and run filters from renderers to source filters */
-    This->nRenderers = 0;  
+    This->nRenderers = 0;
     ResetEvent(This->hEventCompletion);
 
     for(i = 0; i < This->nFilters; i++)
@@ -1567,6 +1569,13 @@ static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
     if (This->state == State_Running) return S_OK;
 
     EnterCriticalSection(&This->cs);
+    if (This->refClock)
+    {
+        IReferenceClock_GetTime(This->refClock, &This->start_time);
+        This->start_time += 500000;
+    }
+    else This->position = This->start_time = 0;
+
     SendFilterMessage(iface, SendRun);
     This->state = State_Running;
     LeaveCriticalSection(&This->cs);
@@ -1580,6 +1589,13 @@ static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
     if (This->state == State_Paused) return S_OK;
 
     EnterCriticalSection(&This->cs);
+    if (This->state == State_Running && This->refClock)
+    {
+        LONGLONG time = This->start_time;
+        IReferenceClock_GetTime(This->refClock, &time);
+        This->position += time - This->start_time;
+    }
+
     SendFilterMessage(iface, SendPause);
     This->state = State_Paused;
     LeaveCriticalSection(&This->cs);
@@ -1593,6 +1609,13 @@ static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
     if (This->state == State_Stopped) return S_OK;
 
     EnterCriticalSection(&This->cs);
+    if (This->state == State_Running && This->refClock)
+    {
+        LONGLONG time = This->start_time;
+        IReferenceClock_GetTime(This->refClock, &time);
+        This->position += time - This->start_time;
+    }
+
     if (This->state == State_Running) SendFilterMessage(iface, SendPause);
     SendFilterMessage(iface, SendStop);
     This->state = State_Stopped;
@@ -1952,8 +1975,23 @@ static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface,
 static HRESULT WINAPI MediaSeeking_GetCurrentPosition(IMediaSeeking *iface,
 						      LONGLONG *pCurrent) {
     ICOM_THIS_MULTI(IFilterGraphImpl, IMediaSeeking_vtbl, iface);
+    LONGLONG time = 0;
+
+    if (!pCurrent)
+        return E_POINTER;
 
-    FIXME("(%p/%p)->(%p): stub !!!\n", This, iface, pCurrent);
+    if (This->state == State_Running && This->refClock)
+    {
+        IReferenceClock_GetTime(This->refClock, &time);
+        if (time)
+            time += This->position - This->start_time;
+        if (time < This->position)
+            time = This->position;
+        *pCurrent = time;
+    }
+    else
+        *pCurrent = This->position;
+    TRACE("Time: %lld.%03lld\n", *pCurrent / 10000000, (*pCurrent / 10000)%1000);
 
     return S_OK;
 }
@@ -4933,6 +4971,7 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
     fimpl->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IFilterGraphImpl.cs");
     fimpl->nItfCacheEntries = 0;
     memcpy(&fimpl->timeformatseek, &TIME_FORMAT_MEDIA_TIME, sizeof(GUID));
+    fimpl->start_time = fimpl->position = 0;
 
     hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterMapper2, (LPVOID*)&fimpl->pFilterMapper2);
     if (FAILED(hr)) {
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index 2a2a806..efe12fc 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -172,6 +172,42 @@ static void test_graph_builder_addfilter(void)
 
     hr = IGraphBuilder_AddFilter(pgraph, pF, NULL);
     ok(hr == S_OK, "IGraphBuilder_AddFilter returned: %x\n", hr);
+    IMediaFilter_Release(pF);
+}
+
+static void test_mediacontrol(void)
+{
+    HRESULT hr;
+    LONGLONG pos = 0xdeadbeef;
+    IMediaSeeking *seeking = NULL;
+    IMediaFilter *filter = NULL;
+
+    IFilterGraph2_SetDefaultSyncSource(pgraph);
+    hr = IFilterGraph2_QueryInterface(pgraph, &IID_IMediaSeeking, (void**) &seeking);
+    ok(hr == S_OK, "QueryInterface IMediaControl failed: %08x\n", hr);
+    if (FAILED(hr))
+        return;
+
+    hr = IFilterGraph2_QueryInterface(pgraph, &IID_IMediaFilter, (void**) &filter);
+    ok(hr == S_OK, "QueryInterface IMediaFilter failed: %08x\n", hr);
+    if (FAILED(hr))
+    {
+        IUnknown_Release(seeking);
+        return;
+    }
+
+    hr = IMediaSeeking_GetCurrentPosition(seeking, &pos);
+    ok(hr == S_OK, "GetCurrentPosition failed: %08x\n", hr);
+    ok(pos == 0, "Position != 0 (%x%08x)\n", (DWORD)(pos >> 32), (DWORD)pos);
+
+    IMediaFilter_SetSyncSource(filter, NULL);
+    pos = 0xdeadbeef;
+    hr = IMediaSeeking_GetCurrentPosition(seeking, &pos);
+    ok(hr == S_OK, "GetCurrentPosition failed: %08x\n", hr);
+    ok(pos == 0, "Position != 0 (%x%08x)\n", (DWORD)(pos >> 32), (DWORD)pos);
+
+    IUnknown_Release(seeking);
+    IUnknown_Release(filter);
     releasefiltergraph();
 }
 
@@ -195,5 +231,6 @@ START_TEST(filtergraph)
     test_render_run();
     test_graph_builder();
     test_graph_builder_addfilter();
+    test_mediacontrol();
     test_filter_graph2();
 }




More information about the wine-cvs mailing list