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.
This commit is contained in:
Christian Costa 2004-12-16 14:25:15 +00:00 committed by Alexandre Julliard
parent b4bb1c931c
commit 1d90e4312f
5 changed files with 44 additions and 21 deletions

View File

@ -224,7 +224,8 @@ static ULONG WINAPI AVISplitter_Release(IBaseFilter * iface)
ULONG i; ULONG i;
DeleteCriticalSection(&This->csFilter); DeleteCriticalSection(&This->csFilter);
IReferenceClock_Release(This->pClock); if (This->pClock)
IReferenceClock_Release(This->pClock);
for (i = 0; i < This->cStreams + 1; i++) for (i = 0; i < This->cStreams + 1; i++)
IPin_Release(This->ppPins[i]); IPin_Release(This->ppPins[i]);
@ -385,7 +386,8 @@ static HRESULT WINAPI AVISplitter_GetSyncSource(IBaseFilter * iface, IReferenceC
EnterCriticalSection(&This->csFilter); EnterCriticalSection(&This->csFilter);
{ {
*ppClock = This->pClock; *ppClock = This->pClock;
IReferenceClock_AddRef(This->pClock); if (This->pClock)
IReferenceClock_AddRef(This->pClock);
} }
LeaveCriticalSection(&This->csFilter); LeaveCriticalSection(&This->csFilter);

View File

@ -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}; static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
IPropertyBag * pPropBagCat = NULL; IPropertyBag * pPropBagCat = NULL;
HRESULT hr; HRESULT hr;
VariantInit(pvar); VariantInit(pvar);
V_VT(pvar) = VT_BSTR; V_VT(pvar) = VT_BSTR;
@ -524,7 +524,7 @@ static HRESULT GetInternalConnections(IBaseFilter* pfilter, IPin* poutputpin, IP
HRESULT hr; HRESULT hr;
ULONG nb = 0; ULONG nb = 0;
TRACE("\n"); TRACE("(%p, %p, %p, %p)\n", pfilter, poutputpin, pppins, pnb);
hr = IPin_QueryInternalConnections(poutputpin, NULL, &nb); hr = IPin_QueryInternalConnections(poutputpin, NULL, &nb);
if (hr == S_OK) { if (hr == S_OK) {
/* Rendered input */ /* Rendered input */
@ -1167,7 +1167,7 @@ static HRESULT WINAPI Mediacontrol_Run(IMediaControl *iface) {
ResetEvent(This->hEventCompletion); ResetEvent(This->hEventCompletion);
return S_OK; return S_FALSE;
} }
static HRESULT WINAPI Mediacontrol_Pause(IMediaControl *iface) { static HRESULT WINAPI Mediacontrol_Pause(IMediaControl *iface) {

View File

@ -730,7 +730,7 @@ HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDI
} /* if succeeded */ } /* if succeeded */
LeaveCriticalSection(This->pin.pCritSec); LeaveCriticalSection(This->pin.pCritSec);
FIXME(" -- %lx\n", hr); TRACE(" -- %lx\n", hr);
return hr; return hr;
} }

View File

@ -111,16 +111,16 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) {
timeOut = INFINITE; timeOut = INFINITE;
goto outrefresh; goto outrefresh;
} }
/** First SingleShots Advice: sorted list */ /** 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 ... */ /** send event ... */
SetEvent((HANDLE) it->hEvent); SetEvent((HANDLE) it->hEvent);
/** ... and Release it */ /** ... and Release it */
QUARTZ_RemoveAviseEntryFromQueue(This, it); QUARTZ_RemoveAviseEntryFromQueue(This, it);
HeapFree(GetProcessHeap(), 0, 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) */ /** Now Periodics Advice: semi sorted list (sort cannot be used) */
for (it = This->pPeriodicAdvise; NULL != it; it = it->next) { for (it = This->pPeriodicAdvise; NULL != it; it = it->next) {
@ -129,10 +129,10 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) {
/** Release the semaphore ... */ /** Release the semaphore ... */
ReleaseSemaphore((HANDLE) it->hEvent, nPeriods, NULL); ReleaseSemaphore((HANDLE) it->hEvent, nPeriods, NULL);
/** ... and refresh time */ /** ... and refresh time */
it->rtBaseTime += it->rtIntervalTime; it->rtBaseTime += nPeriods * it->rtIntervalTime;
/*assert( it->rtBaseTime + it->rtIntervalTime < curTime );*/ /*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; if (timeOut > tmpTimeOut) timeOut = tmpTimeOut;
} }
@ -175,10 +175,20 @@ outofthread:
static BOOL SystemClockPostMessageToAdviseThread(SystemClockImpl* This, UINT iMsg) { static BOOL SystemClockPostMessageToAdviseThread(SystemClockImpl* This, UINT iMsg) {
if (FALSE == This->adviseThreadActive) { if (FALSE == This->adviseThreadActive) {
BOOL res;
This->adviseThread = CreateThread(NULL, 0, SystemClockAdviseThread, This, 0, &This->adviseThreadId); This->adviseThread = CreateThread(NULL, 0, SystemClockAdviseThread, This, 0, &This->adviseThreadId);
if (NULL == This->adviseThread) return FALSE; if (NULL == This->adviseThread) return FALSE;
SetThreadPriority(This->adviseThread, THREAD_PRIORITY_TIME_CRITICAL); SetThreadPriority(This->adviseThread, THREAD_PRIORITY_TIME_CRITICAL);
This->adviseThreadActive = TRUE; 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); return PostThreadMessageA(This->adviseThreadId, iMsg, 0, 0);
} }

View File

@ -27,6 +27,8 @@
#include "dshow.h" #include "dshow.h"
#include "control.h" #include "control.h"
static const WCHAR file[] = {'t','e','s','t','.','a','v','i',0};
IGraphBuilder* pgraph; IGraphBuilder* pgraph;
static void createfiltergraph() static void createfiltergraph()
@ -37,10 +39,8 @@ static void createfiltergraph()
ok(hr==S_OK, "Creating filtergraph returned: %lx\n", hr); ok(hr==S_OK, "Creating filtergraph returned: %lx\n", hr);
} }
#if 0
static void renderfile() static void renderfile()
{ {
WCHAR file[] = {'t','e','s','t','.','a','v','i',0};
HRESULT hr; HRESULT hr;
hr = IGraphBuilder_RenderFile(pgraph, file, NULL); 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); ok(hr==S_OK, "Cannot get IMediaControl interface returned: %lx\n", hr);
hr = IMediaControl_Run(pmc); 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() static void releasefiltergraph()
{ {
HRESULT hr; HRESULT hr;
hr = IGraphBuilder_Release(pgraph); 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) START_TEST(filtergraph)
{ {
HANDLE h;
CoInitialize(NULL); CoInitialize(NULL);
createfiltergraph(); createfiltergraph();
#if 0
renderfile(); h = CreateFileW(file, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
rungraph(); if (h != INVALID_HANDLE_VALUE) {
#endif CloseHandle(h);
renderfile();
rungraph();
}
releasefiltergraph(); releasefiltergraph();
} }