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:
parent
b4bb1c931c
commit
1d90e4312f
|
@ -224,6 +224,7 @@ static ULONG WINAPI AVISplitter_Release(IBaseFilter * iface)
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
DeleteCriticalSection(&This->csFilter);
|
DeleteCriticalSection(&This->csFilter);
|
||||||
|
if (This->pClock)
|
||||||
IReferenceClock_Release(This->pClock);
|
IReferenceClock_Release(This->pClock);
|
||||||
|
|
||||||
for (i = 0; i < This->cStreams + 1; i++)
|
for (i = 0; i < This->cStreams + 1; i++)
|
||||||
|
@ -385,6 +386,7 @@ static HRESULT WINAPI AVISplitter_GetSyncSource(IBaseFilter * iface, IReferenceC
|
||||||
EnterCriticalSection(&This->csFilter);
|
EnterCriticalSection(&This->csFilter);
|
||||||
{
|
{
|
||||||
*ppClock = This->pClock;
|
*ppClock = This->pClock;
|
||||||
|
if (This->pClock)
|
||||||
IReferenceClock_AddRef(This->pClock);
|
IReferenceClock_AddRef(This->pClock);
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&This->csFilter);
|
LeaveCriticalSection(&This->csFilter);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,14 +113,14 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
|
h = CreateFileW(file, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (h != INVALID_HANDLE_VALUE) {
|
||||||
|
CloseHandle(h);
|
||||||
renderfile();
|
renderfile();
|
||||||
rungraph();
|
rungraph();
|
||||||
#endif
|
}
|
||||||
|
|
||||||
releasefiltergraph();
|
releasefiltergraph();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue