From 1d90e4312f715469be67dd450890eb28162fa686 Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Thu, 16 Dec 2004 14:25:15 +0000 Subject: [PATCH] Many fixes to the system clock implementation. Ensure there is a clock before doing any AddRef or Release in the AVI splitter. Improved tests a bit. Misc fixes and traces clean-up. --- dlls/quartz/avisplit.c | 6 ++++-- dlls/quartz/filtergraph.c | 6 +++--- dlls/quartz/pin.c | 2 +- dlls/quartz/systemclock.c | 20 +++++++++++++++----- dlls/quartz/tests/filtergraph.c | 31 +++++++++++++++++++++---------- 5 files changed, 44 insertions(+), 21 deletions(-) diff --git a/dlls/quartz/avisplit.c b/dlls/quartz/avisplit.c index 2a3910075d8..644ce7a19dc 100644 --- a/dlls/quartz/avisplit.c +++ b/dlls/quartz/avisplit.c @@ -224,7 +224,8 @@ static ULONG WINAPI AVISplitter_Release(IBaseFilter * iface) ULONG i; DeleteCriticalSection(&This->csFilter); - IReferenceClock_Release(This->pClock); + if (This->pClock) + IReferenceClock_Release(This->pClock); for (i = 0; i < This->cStreams + 1; i++) IPin_Release(This->ppPins[i]); @@ -385,7 +386,8 @@ static HRESULT WINAPI AVISplitter_GetSyncSource(IBaseFilter * iface, IReferenceC EnterCriticalSection(&This->csFilter); { *ppClock = This->pClock; - IReferenceClock_AddRef(This->pClock); + if (This->pClock) + IReferenceClock_AddRef(This->pClock); } LeaveCriticalSection(&This->csFilter); diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 1f5664686c4..cc5b63e7e08 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -495,7 +495,7 @@ static HRESULT GetFilterInfo(IMoniker* pMoniker, GUID* pclsid, VARIANT* pvar) static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; IPropertyBag * pPropBagCat = NULL; HRESULT hr; - + VariantInit(pvar); V_VT(pvar) = VT_BSTR; @@ -524,7 +524,7 @@ static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* poutputpin, IP HRESULT hr; ULONG nb = 0; - TRACE("\n"); + TRACE("(%p, %p, %p, %p)\n", pfilter, poutputpin, pppins, pnb); hr = IPin_QueryInternalConnections(poutputpin, NULL, &nb); if (hr == S_OK) { /* Rendered input */ @@ -1167,7 +1167,7 @@ static HRESULT WINAPI Mediacontrol_Run(IMediaControl *iface) { ResetEvent(This->hEventCompletion); - return S_OK; + return S_FALSE; } static HRESULT WINAPI Mediacontrol_Pause(IMediaControl *iface) { diff --git a/dlls/quartz/pin.c b/dlls/quartz/pin.c index 812cf936514..7a5500a1fcd 100644 --- a/dlls/quartz/pin.c +++ b/dlls/quartz/pin.c @@ -730,7 +730,7 @@ HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDI } /* if succeeded */ LeaveCriticalSection(This->pin.pCritSec); - FIXME(" -- %lx\n", hr); + TRACE(" -- %lx\n", hr); return hr; } diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c index 83535eb3731..db0f127e6aa 100644 --- a/dlls/quartz/systemclock.c +++ b/dlls/quartz/systemclock.c @@ -111,16 +111,16 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { timeOut = INFINITE; goto outrefresh; } - + /** First SingleShots Advice: sorted list */ - for (it = This->pSingleShotAdvise; NULL != it && it->rtBaseTime <= curTime; it = it->next) { + for (it = This->pSingleShotAdvise; NULL != it && (it->rtBaseTime + it->rtIntervalTime) <= curTime; it = it->next) { /** send event ... */ SetEvent((HANDLE) it->hEvent); /** ... and Release it */ QUARTZ_RemoveAviseEntryFromQueue(This, it); HeapFree(GetProcessHeap(), 0, it); } - if (NULL != it) timeOut = (DWORD) (curTime - (it->rtBaseTime + it->rtIntervalTime)); + if (NULL != it) timeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000; /** Now Periodics Advice: semi sorted list (sort cannot be used) */ for (it = This->pPeriodicAdvise; NULL != it; it = it->next) { @@ -129,10 +129,10 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) { /** Release the semaphore ... */ ReleaseSemaphore((HANDLE) it->hEvent, nPeriods, NULL); /** ... and refresh time */ - it->rtBaseTime += it->rtIntervalTime; + it->rtBaseTime += nPeriods * it->rtIntervalTime; /*assert( it->rtBaseTime + it->rtIntervalTime < curTime );*/ } - tmpTimeOut = (DWORD) (curTime - (it->rtBaseTime + it->rtIntervalTime)); + tmpTimeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000; if (timeOut > tmpTimeOut) timeOut = tmpTimeOut; } @@ -175,10 +175,20 @@ outofthread: static BOOL SystemClockPostMessageToAdviseThread(SystemClockImpl* This, UINT iMsg) { if (FALSE == This->adviseThreadActive) { + BOOL res; This->adviseThread = CreateThread(NULL, 0, SystemClockAdviseThread, This, 0, &This->adviseThreadId); if (NULL == This->adviseThread) return FALSE; SetThreadPriority(This->adviseThread, THREAD_PRIORITY_TIME_CRITICAL); This->adviseThreadActive = TRUE; + while(1) { + res = PostThreadMessageA(This->adviseThreadId, iMsg, 0, 0); + /* Let the thread creates its message queue (with MsgWaitForMultipleObjects call) by yielding and retrying */ + if (!res && (GetLastError() == ERROR_INVALID_THREAD_ID)) + Sleep(0); + else + break; + } + return res; } return PostThreadMessageA(This->adviseThreadId, iMsg, 0, 0); } diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index 4a1ce50d587..969fa7d0851 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -27,6 +27,8 @@ #include "dshow.h" #include "control.h" +static const WCHAR file[] = {'t','e','s','t','.','a','v','i',0}; + IGraphBuilder* pgraph; static void createfiltergraph() @@ -37,10 +39,8 @@ static void createfiltergraph() ok(hr==S_OK, "Creating filtergraph returned: %lx\n", hr); } -#if 0 static void renderfile() { - WCHAR file[] = {'t','e','s','t','.','a','v','i',0}; HRESULT hr; hr = IGraphBuilder_RenderFile(pgraph, file, NULL); @@ -56,27 +56,38 @@ static void rungraph() ok(hr==S_OK, "Cannot get IMediaControl interface returned: %lx\n", hr); hr = IMediaControl_Run(pmc); - ok(hr==S_OK, "Cannot run the graph returned: %lx\n", hr); + ok(hr==S_FALSE, "Cannot run the graph returned: %lx\n", hr); - Sleep(20000); + Sleep(20000); + + hr = IMediaControl_Stop(pmc); + ok(hr==S_OK, "Cannot stop the graph returned: %lx\n", hr); + + hr = IMediaControl_Release(pmc); + ok(hr==1, "Releasing mediacontrol returned: %lx\n", hr); } -#endif static void releasefiltergraph() { HRESULT hr; hr = IGraphBuilder_Release(pgraph); - ok(hr==S_OK, "Releasing filtergraph returned: %lx\n", hr); + ok(hr==0, "Releasing filtergraph returned: %lx\n", hr); } START_TEST(filtergraph) { + HANDLE h; + CoInitialize(NULL); createfiltergraph(); -#if 0 - renderfile(); - rungraph(); -#endif + + h = CreateFileW(file, 0, 0, NULL, OPEN_EXISTING, 0, NULL); + if (h != INVALID_HANDLE_VALUE) { + CloseHandle(h); + renderfile(); + rungraph(); + } + releasefiltergraph(); }