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