Fixed some broken macros.
Added some stubs.
Implemeted undocumented APIs.
Implemented many methods in IMediaFilter, IMediaControl and
IReferenceClock.
Started Implementing IMemoryAllocator.
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in
index 6ce20a3..3b0240a 100644
--- a/dlls/quartz/Makefile.in
+++ b/dlls/quartz/Makefile.in
@@ -10,6 +10,7 @@
C_SRCS = \
amerror.c \
+ amundoc.c \
complist.c \
devenum.c \
devmon.c \
@@ -40,6 +41,7 @@
memalloc.c \
monprop.c \
regsvr.c \
+ seekpass.c \
sysclock.c
@MAKE_DLL_RULES@
diff --git a/dlls/quartz/amundoc.c b/dlls/quartz/amundoc.c
new file mode 100644
index 0000000..bf00ad1
--- /dev/null
+++ b/dlls/quartz/amundoc.c
@@ -0,0 +1,55 @@
+#include "config.h"
+
+#include <math.h>
+#include "windef.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+/***********************************************************************
+ * AmpFactorToDB (QUARTZ.@)
+ *
+ * undocumented.
+ * converting from Amp to dB?
+ *
+ */
+LONG WINAPI QUARTZ_AmpFactorToDB( LONG amp )
+{
+ LONG dB;
+
+ FIXME( "(%08ld): undocumented API.\n", amp );
+
+ if ( amp <= 0 || amp > 65536 )
+ return 0;
+
+ dB = (LONG)(2000.0 * log10((double)amp / 65536.0) + 0.5);
+ if ( dB >= 0 ) dB = 0;
+ if ( dB < -10000 ) dB = -10000;
+
+ return dB;
+}
+
+/***********************************************************************
+ * DBToAmpFactor (QUARTZ.@)
+ *
+ * undocumented.
+ * converting from dB to Amp?
+ */
+LONG WINAPI QUARTZ_DBToAmpFactor( LONG dB )
+{
+ LONG amp;
+
+ FIXME( "(%08ld): undocumented API.\n", dB );
+
+ if ( dB >= 0 )
+ return 65535;
+ if ( dB < -10000 )
+ return 0;
+
+ amp = (LONG)(pow(10.0,dB / 2000.0) * 65536.0 + 0.5);
+ if ( amp <= 0 ) amp = 1;
+ if ( amp >= 65536 ) amp = 65535;
+
+ return amp;
+}
+
diff --git a/dlls/quartz/fgraph.c b/dlls/quartz/fgraph.c
index 29ff724..fc6116a 100644
--- a/dlls/quartz/fgraph.c
+++ b/dlls/quartz/fgraph.c
@@ -79,6 +79,10 @@
CFilterGraph_THIS(punk,unk);
int i;
+ /* At first, call Stop. */
+ IMediaControl_Stop( CFilterGraph_IMediaControl(This) );
+ IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
+
i = 0;
while ( FGRAPH_Init[i].pInit != NULL )
{
diff --git a/dlls/quartz/fgraph.h b/dlls/quartz/fgraph.h
index e06551c..d038f6d 100644
--- a/dlls/quartz/fgraph.h
+++ b/dlls/quartz/fgraph.h
@@ -120,6 +120,9 @@
CRITICAL_SECTION m_csGraphVersion;
LONG m_lGraphVersion;
/* IMediaControl fields. */
+ /* IMediaFilter fields. */
+ CRITICAL_SECTION m_csGraphState;
+ FILTER_STATE m_stateGraph; /* must NOT accessed directly! */
/* IMediaEvent fields. */
HANDLE m_hMediaEvent;
/* IMediaEventSink fields. */
@@ -133,6 +136,9 @@
#define CFilterGraph_THIS(iface,member) CFilterGraph* This = ((CFilterGraph*)(((char*)iface)-offsetof(CFilterGraph,member)))
#define CFilterGraph_IPersist(th) ((IPersist*)&((th)->persist))
#define CFilterGraph_IDispatch(th) ((IDispatch*)&((th)->disp))
+#define CFilterGraph_IFilterGraph2(th) ((IFilterGraph2*)&((th)->fgraph))
+#define CFilterGraph_IMediaFilter(th) ((IMediaFilter*)&((th)->mediafilter))
+#define CFilterGraph_IMediaControl(th) ((IMediaControl*)&((th)->mediacontrol))
HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj);
diff --git a/dlls/quartz/ifmap.c b/dlls/quartz/ifmap.c
index 8d420d0..8905cc1 100644
--- a/dlls/quartz/ifmap.c
+++ b/dlls/quartz/ifmap.c
@@ -90,8 +90,11 @@
return hr;
/* FIXME */
- return IFilterMapper_RegisterFilter(iface,
- *pclsidMedia,lpwszName,0x60000000);
+ /* this doesn't work. */
+ /* return IFilterMapper_RegisterFilter(iface,
+ *pclsidMedia,lpwszName,0x60000000); */
+
+ return E_NOTIMPL;
}
static HRESULT WINAPI
@@ -136,7 +139,10 @@
FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
/* FIXME */
- return IFilterMapper_UnregisterFilter(iface,clsidMedia);
+ /* this doesn't work. */
+ /* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
+
+ return E_NOTIMPL;
}
static HRESULT WINAPI
diff --git a/dlls/quartz/ifmap3.c b/dlls/quartz/ifmap3.c
index b706ab4..44093da 100644
--- a/dlls/quartz/ifmap3.c
+++ b/dlls/quartz/ifmap3.c
@@ -80,7 +80,15 @@
debugstr_w(lpwszInst),
debugstr_guid(rclsidFilter));
- return E_NOTIMPL;
+ if ( pclsidCategory == NULL )
+ pclsidCategory = &CLSID_LegacyAmFilterCategory;
+
+ /* FIXME */
+ return QUARTZ_RegisterAMovieFilter(
+ pclsidCategory,
+ rclsidFilter,
+ NULL, 0,
+ NULL, lpwszInst, FALSE );
}
@@ -94,7 +102,25 @@
ppMoniker,debugstr_guid(pclsidCategory),
debugstr_w(lpwszInst),pRF2 );
- return E_NOTIMPL;
+ if ( lpName == NULL || pRF2 == NULL )
+ return E_POINTER;
+
+ if ( ppMoniker != NULL )
+ {
+ FIXME( "ppMoniker != NULL - not implemented!\n" );
+ return E_NOTIMPL;
+ }
+
+ if ( pclsidCategory == NULL )
+ pclsidCategory = &CLSID_LegacyAmFilterCategory;
+
+ /* FIXME!! - all members in REGFILTER2 are ignored ! */
+
+ return QUARTZ_RegisterAMovieFilter(
+ pclsidCategory,
+ rclsidFilter,
+ NULL, 0,
+ lpName, lpwszInst, TRUE );
}
diff --git a/dlls/quartz/imcntl.c b/dlls/quartz/imcntl.c
index 67bb2fa..52b653c 100644
--- a/dlls/quartz/imcntl.c
+++ b/dlls/quartz/imcntl.c
@@ -14,6 +14,7 @@
#include "winerror.h"
#include "wine/obj_base.h"
#include "wine/obj_oleaut.h"
+#include "oleauto.h"
#include "strmif.h"
#include "control.h"
#include "uuids.h"
@@ -102,9 +103,10 @@
{
CFilterGraph_THIS(iface,mediacontrol);
- FIXME("(%p)->()\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ return IMediaFilter_Run( CFilterGraph_IMediaFilter(This),
+ (REFERENCE_TIME)0 );
}
static HRESULT WINAPI
@@ -112,19 +114,36 @@
{
CFilterGraph_THIS(iface,mediacontrol);
- FIXME("(%p)->()\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ return IMediaFilter_Pause( CFilterGraph_IMediaFilter(This) );
}
static HRESULT WINAPI
IMediaControl_fnStop(IMediaControl* iface)
{
CFilterGraph_THIS(iface,mediacontrol);
+ HRESULT hr;
+ FILTER_STATE fs;
- FIXME("(%p)->()\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ hr = IMediaControl_GetState(iface,INFINITE,(OAFilterState*)&fs);
+ if ( SUCCEEDED(hr) && fs == State_Running )
+ {
+ hr = IMediaControl_Pause(iface);
+ if ( SUCCEEDED(hr) )
+ hr = IMediaControl_GetState(iface,INFINITE,(OAFilterState*)&fs);
+ }
+
+ if ( SUCCEEDED(hr) && fs == State_Paused )
+ {
+ hr = IMediaFilter_Stop(CFilterGraph_IMediaFilter(This));
+ if ( SUCCEEDED(hr) )
+ hr = IMediaControl_GetState(iface,INFINITE,(OAFilterState*)&fs);
+ }
+
+ return hr;
}
static HRESULT WINAPI
@@ -132,19 +151,34 @@
{
CFilterGraph_THIS(iface,mediacontrol);
- FIXME("(%p)->()\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ return IMediaFilter_GetState( CFilterGraph_IMediaFilter(This), (DWORD)lTimeOut, (FILTER_STATE*)pFilterState );
}
static HRESULT WINAPI
IMediaControl_fnRenderFile(IMediaControl* iface,BSTR bstrFileName)
{
CFilterGraph_THIS(iface,mediacontrol);
+ UINT uLen;
+ WCHAR* pwszName;
+ HRESULT hr;
- FIXME("(%p)->()\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ uLen = SysStringLen(bstrFileName);
+ pwszName = (WCHAR*)QUARTZ_AllocMem( sizeof(WCHAR) * (uLen+1) );
+ if ( pwszName == NULL )
+ return E_OUTOFMEMORY;
+ memcpy( pwszName, bstrFileName, sizeof(WCHAR)*uLen );
+ pwszName[uLen] = (WCHAR)0;
+
+ hr = IFilterGraph2_RenderFile(
+ CFilterGraph_IFilterGraph2(This), pwszName, NULL );
+
+ QUARTZ_FreeMem( pwszName );
+
+ return hr;
}
static HRESULT WINAPI
@@ -182,9 +216,9 @@
{
CFilterGraph_THIS(iface,mediacontrol);
- FIXME("(%p)->()\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ return IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
}
diff --git a/dlls/quartz/imem.c b/dlls/quartz/imem.c
index 7053fea..4dc0d67 100644
--- a/dlls/quartz/imem.c
+++ b/dlls/quartz/imem.c
@@ -57,9 +57,40 @@
IMemAllocator_fnSetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pPropReq,ALLOCATOR_PROPERTIES* pPropActual)
{
CMemoryAllocator_THIS(iface,memalloc);
+ long padding;
- FIXME( "(%p)->() stub!\n", This );
- return E_NOTIMPL;
+ TRACE( "(%p)->(%p,%p)\n", This, pPropReq, pPropActual );
+
+ if ( pPropReq == NULL || pPropActual == NULL )
+ return E_POINTER;
+ if ( pPropReq->cBuffers < 0 ||
+ pPropReq->cbBuffer < 0 ||
+ pPropReq->cbAlign < 0 ||
+ pPropReq->cbPrefix < 0 )
+ return E_INVALIDARG;
+
+ if ( ( pPropReq->cbAlign & (pPropReq->cbAlign-1) ) != 0 )
+ return E_INVALIDARG;
+
+ EnterCriticalSection( &This->csMem );
+
+ This->prop.cBuffers = pPropReq->cBuffers;
+ This->prop.cbBuffer = pPropReq->cbBuffer;
+ This->prop.cbAlign = pPropReq->cbAlign;
+ This->prop.cbPrefix = pPropReq->cbPrefix;
+
+ if ( This->prop.cbAlign == 0 )
+ This->prop.cbAlign = 1;
+ padding = This->prop.cbAlign -
+ ( (This->prop.cbBuffer+This->prop.cbPrefix) % This->prop.cbAlign );
+
+ This->prop.cbBuffer += padding;
+
+ memcpy( pPropActual, &This->prop, sizeof(ALLOCATOR_PROPERTIES) );
+
+ LeaveCriticalSection( &This->csMem );
+
+ return NOERROR;
}
static HRESULT WINAPI
@@ -67,8 +98,18 @@
{
CMemoryAllocator_THIS(iface,memalloc);
- FIXME( "(%p)->() stub!\n", This );
- return E_NOTIMPL;
+ TRACE( "(%p)->(%p)\n", This, pProp );
+
+ if ( pProp == NULL )
+ return E_POINTER;
+
+ EnterCriticalSection( &This->csMem );
+
+ memcpy( pProp, &This->prop, sizeof(ALLOCATOR_PROPERTIES) );
+
+ LeaveCriticalSection( &This->csMem );
+
+ return NOERROR;
}
static HRESULT WINAPI
@@ -129,12 +170,21 @@
HRESULT CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma )
{
TRACE("(%p)\n",pma);
+
ICOM_VTBL(&pma->memalloc) = &imemalloc;
+ ZeroMemory( &pma->prop, sizeof(pma->prop) );
+
+ InitializeCriticalSection( &pma->csMem );
+
return NOERROR;
}
void CMemoryAllocator_UninitIMemAllocator( CMemoryAllocator* pma )
{
TRACE("(%p)\n",pma);
+
+ IMemAllocator_Decommit( (IMemAllocator*)(&pma->memalloc) );
+
+ DeleteCriticalSection( &pma->csMem );
}
diff --git a/dlls/quartz/imfilter.c b/dlls/quartz/imfilter.c
index 2c7e94a..0e0a4e5 100644
--- a/dlls/quartz/imfilter.c
+++ b/dlls/quartz/imfilter.c
@@ -17,6 +17,7 @@
#include "strmif.h"
#include "control.h"
#include "uuids.h"
+#include "vfwmsgs.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
@@ -25,6 +26,46 @@
#include "fgraph.h"
+#define WINE_QUARTZ_POLL_INTERVAL 10
+
+/*****************************************************************************/
+
+static
+HRESULT CFilterGraph_PollGraphState(
+ CFilterGraph* This,
+ FILTER_STATE* pState)
+{
+ HRESULT hr;
+ QUARTZ_CompListItem* pItem;
+ IBaseFilter* pFilter;
+
+ hr = S_OK;
+
+ EnterCriticalSection( &This->m_csGraphState );
+ QUARTZ_CompList_Lock( This->m_pFilterList );
+
+ pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
+
+ while ( pItem != NULL )
+ {
+ pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
+ hr = IBaseFilter_GetState( pFilter, (DWORD)0, pState );
+ if ( hr != S_OK )
+ break;
+
+ pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
+ }
+
+ QUARTZ_CompList_Unlock( This->m_pFilterList );
+ LeaveCriticalSection( &This->m_csGraphState );
+
+ TRACE( "returns %08lx, state %d\n",
+ hr, *pState );
+
+ return hr;
+}
+
+/*****************************************************************************/
static HRESULT WINAPI
IMediaFilter_fnQueryInterface(IMediaFilter* iface,REFIID riid,void** ppobj)
@@ -72,40 +113,185 @@
IMediaFilter_fnStop(IMediaFilter* iface)
{
CFilterGraph_THIS(iface,mediafilter);
+ HRESULT hr;
+ HRESULT hrFilter;
+ QUARTZ_CompListItem* pItem;
+ IBaseFilter* pFilter;
- FIXME("(%p)->() stub!\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ hr = S_OK;
+
+ EnterCriticalSection( &This->m_csGraphState );
+
+ if ( This->m_stateGraph != State_Stopped )
+ {
+ QUARTZ_CompList_Lock( This->m_pFilterList );
+
+ pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
+
+ while ( pItem != NULL )
+ {
+ pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
+ hrFilter = IBaseFilter_Stop( pFilter );
+ if ( hrFilter != S_OK )
+ {
+ if ( SUCCEEDED(hr) )
+ hr = hrFilter;
+ }
+
+ pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
+ }
+
+ QUARTZ_CompList_Unlock( This->m_pFilterList );
+
+ This->m_stateGraph = State_Stopped;
+ }
+
+ LeaveCriticalSection( &This->m_csGraphState );
+
+ return hr;
}
static HRESULT WINAPI
IMediaFilter_fnPause(IMediaFilter* iface)
{
CFilterGraph_THIS(iface,mediafilter);
+ HRESULT hr;
+ HRESULT hrFilter;
+ QUARTZ_CompListItem* pItem;
+ IBaseFilter* pFilter;
- FIXME("(%p)->() stub!\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ hr = S_OK;
+
+ EnterCriticalSection( &This->m_csGraphState );
+
+ if ( This->m_stateGraph != State_Paused )
+ {
+ QUARTZ_CompList_Lock( This->m_pFilterList );
+
+ pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
+
+ while ( pItem != NULL )
+ {
+ pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
+ hrFilter = IBaseFilter_Pause( pFilter );
+ if ( hrFilter != S_OK )
+ {
+ if ( SUCCEEDED(hr) )
+ hr = hrFilter;
+ }
+
+ pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
+ }
+
+ QUARTZ_CompList_Unlock( This->m_pFilterList );
+
+ This->m_stateGraph = State_Paused;
+ }
+
+ LeaveCriticalSection( &This->m_csGraphState );
+
+ return hr;
}
static HRESULT WINAPI
IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
{
CFilterGraph_THIS(iface,mediafilter);
+ HRESULT hr;
+ HRESULT hrFilter;
+ QUARTZ_CompListItem* pItem;
+ IBaseFilter* pFilter;
+ IReferenceClock* pClock;
- FIXME("(%p)->() stub!\n",This);
+ TRACE("(%p)->()\n",This);
- return E_NOTIMPL;
+ /* handle the special time. */
+ if ( rtStart == (REFERENCE_TIME)0 )
+ {
+ hr = IMediaFilter_GetSyncSource(iface,&pClock);
+ if ( hr == S_OK && pClock != NULL )
+ {
+ IReferenceClock_GetTime(pClock,&rtStart);
+ IReferenceClock_Release(pClock);
+ }
+ }
+
+ hr = S_OK;
+
+ EnterCriticalSection( &This->m_csGraphState );
+
+ if ( This->m_stateGraph != State_Running )
+ {
+ QUARTZ_CompList_Lock( This->m_pFilterList );
+
+ pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
+
+ while ( pItem != NULL )
+ {
+ pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
+ hrFilter = IBaseFilter_Run( pFilter, rtStart );
+ if ( hrFilter != S_OK )
+ {
+ if ( SUCCEEDED(hr) )
+ hr = hrFilter;
+ }
+
+ pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
+ }
+
+ QUARTZ_CompList_Unlock( This->m_pFilterList );
+
+ This->m_stateGraph = State_Running;
+ }
+
+ LeaveCriticalSection( &This->m_csGraphState );
+
+ return hr;
}
static HRESULT WINAPI
-IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dw,FILTER_STATE* pState)
+IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState)
{
CFilterGraph_THIS(iface,mediafilter);
+ HRESULT hr;
+ DWORD dwTickStart;
+ DWORD dwTickUsed;
- FIXME("(%p)->() stub!\n",This);
+ TRACE("(%p)->(%p)\n",This,pState);
+ if ( pState == NULL )
+ return E_POINTER;
- return E_NOTIMPL;
+ EnterCriticalSection( &This->m_csGraphState );
+ *pState = This->m_stateGraph;
+ LeaveCriticalSection( &This->m_csGraphState );
+
+ dwTickStart = GetTickCount();
+
+ while ( 1 )
+ {
+ hr = CFilterGraph_PollGraphState( This, pState );
+ if ( hr != VFW_S_STATE_INTERMEDIATE )
+ break;
+ if ( dwTimeOut == 0 )
+ break;
+
+ Sleep( (dwTimeOut >= WINE_QUARTZ_POLL_INTERVAL) ?
+ WINE_QUARTZ_POLL_INTERVAL : dwTimeOut );
+
+ dwTickUsed = GetTickCount() - dwTickStart;
+
+ dwTickStart += dwTickUsed;
+ if ( dwTimeOut <= dwTickUsed )
+ dwTimeOut = 0;
+ else
+ dwTimeOut -= dwTickUsed;
+ }
+
+ return hr;
}
static HRESULT WINAPI
@@ -151,12 +337,18 @@
HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
+
ICOM_VTBL(&pfg->mediafilter) = &imediafilter;
+ InitializeCriticalSection( &pfg->m_csGraphState );
+ pfg->m_stateGraph = State_Stopped;
+
return NOERROR;
}
void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
+
+ DeleteCriticalSection( &pfg->m_csGraphState );
}
diff --git a/dlls/quartz/irclock.c b/dlls/quartz/irclock.c
index 910f310..9b8bbbf 100644
--- a/dlls/quartz/irclock.c
+++ b/dlls/quartz/irclock.c
@@ -1,7 +1,7 @@
/*
* Implementation of CLSID_SystemClock.
*
- * FIXME - stub.
+ * FIXME - not tested yet.
*
* hidenori@a2.ctktv.ne.jp
*/
@@ -11,6 +11,7 @@
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
+#include "winuser.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "strmif.h"
@@ -23,6 +24,151 @@
#include "sysclock.h"
+#define QUARTZ_MSG_ADDTIMER (WM_APP+0)
+#define QUARTZ_MSG_REMOVETIMER (WM_APP+1)
+#define QUARTZ_MSG_EXITTHREAD (WM_APP+2)
+
+
+/****************************************************************************/
+
+static QUARTZ_TimerEntry* IReferenceClock_AllocTimerEntry(CSystemClock* This)
+{
+ QUARTZ_TimerEntry* pEntry;
+ DWORD dw;
+
+ pEntry = &This->m_timerEntries[0];
+ for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
+ {
+ if ( pEntry->hEvent == (HANDLE)NULL )
+ return pEntry;
+ pEntry ++;
+ }
+
+ return NULL;
+}
+
+static QUARTZ_TimerEntry* IReferenceClock_SearchTimer(CSystemClock* This, DWORD dwAdvCookie)
+{
+ QUARTZ_TimerEntry* pEntry;
+ DWORD dw;
+
+ pEntry = &This->m_timerEntries[0];
+ for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
+ {
+ if ( pEntry->hEvent != (HANDLE)NULL &&
+ pEntry->dwAdvCookie == dwAdvCookie )
+ return pEntry;
+ pEntry ++;
+ }
+
+ return NULL;
+}
+
+static void IReferenceClock_OnTimerUpdated(CSystemClock* This)
+{
+ QUARTZ_TimerEntry* pEntry;
+ REFERENCE_TIME rtCur;
+ REFERENCE_TIME rtSignal;
+ REFERENCE_TIME rtCount;
+ HRESULT hr;
+ LONG lCount;
+ DWORD dw;
+
+ hr = IReferenceClock_GetTime((IReferenceClock*)(&This->refclk),&rtCur);
+ if ( hr != NOERROR )
+ return;
+
+ pEntry = &This->m_timerEntries[0];
+ for ( dw = 0; dw < WINE_QUARTZ_SYSCLOCK_TIMER_MAX; dw++ )
+ {
+ if ( pEntry->hEvent != (HANDLE)NULL )
+ {
+ rtSignal = pEntry->rtStart + pEntry->rtInterval;
+ if ( rtCur >= rtSignal )
+ {
+ if ( pEntry->fPeriodic )
+ {
+ rtCount = ((rtCur - pEntry->rtStart) / pEntry->rtInterval);
+ lCount = ( rtCount > (REFERENCE_TIME)0x7fffffff ) ?
+ (LONG)0x7fffffff : (LONG)rtCount;
+ if ( !ReleaseSemaphore( pEntry->hEvent, lCount, NULL ) )
+ {
+ while ( lCount > 0 )
+ {
+ if ( !ReleaseSemaphore( pEntry->hEvent, 1, NULL ) )
+ break;
+ }
+ }
+ }
+ else
+ {
+ SetEvent( pEntry->hEvent );
+ pEntry->hEvent = (HANDLE)NULL;
+ }
+ }
+ }
+ pEntry ++;
+ }
+}
+
+static
+DWORD WINAPI IReferenceClock_TimerEntry( LPVOID lpvParam )
+{
+ CSystemClock* This = (CSystemClock*)lpvParam;
+ MSG msg;
+ DWORD dwRes;
+
+ /* initialize the message queue. */
+ PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );
+ /* resume the owner thread. */
+ SetEvent( This->m_hEventInit );
+
+ /* message loop. */
+ while ( 1 )
+ {
+ dwRes = MsgWaitForMultipleObjects(
+ 0, NULL, FALSE,
+ INFINITE, /* FIXME */
+ QS_ALLEVENTS );
+
+ EnterCriticalSection( &This->m_csClock );
+ IReferenceClock_OnTimerUpdated(This);
+ LeaveCriticalSection( &This->m_csClock );
+
+ while ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
+ {
+ if ( msg.message == WM_QUIT )
+ goto quitthread;
+
+ if ( msg.hwnd != (HWND)NULL )
+ {
+ TranslateMessage( &msg );
+ DispatchMessageA( &msg );
+ }
+ else
+ {
+ switch ( msg.message )
+ {
+ case QUARTZ_MSG_ADDTIMER:
+ case QUARTZ_MSG_REMOVETIMER:
+ break;
+ case QUARTZ_MSG_EXITTHREAD:
+ PostQuitMessage(0);
+ break;
+ default:
+ FIXME( "invalid message %04u\n", (unsigned)msg.message );
+ break;
+ }
+ }
+ }
+ }
+
+quitthread:
+ return 0;
+}
+
+/****************************************************************************/
+
static HRESULT WINAPI
IReferenceClock_fnQueryInterface(IReferenceClock* iface,REFIID riid,void** ppobj)
{
@@ -57,36 +203,151 @@
IReferenceClock_fnGetTime(IReferenceClock* iface,REFERENCE_TIME* prtTime)
{
CSystemClock_THIS(iface,refclk);
+ DWORD dwTimeCur;
- FIXME( "(%p)->() stub!\n", This );
- return E_NOTIMPL;
+ TRACE( "(%p)->(%p)\n", This, prtTime );
+
+ if ( prtTime == NULL )
+ return E_POINTER;
+
+ EnterCriticalSection( &This->m_csClock );
+
+ dwTimeCur = GetTickCount();
+ This->m_rtLast += (REFERENCE_TIME)(DWORD)(dwTimeCur - This->m_dwTimeLast);
+
+ This->m_dwTimeLast = dwTimeCur;
+
+ *prtTime = This->m_dwTimeLast;
+
+ LeaveCriticalSection( &This->m_csClock );
+
+ return NOERROR;
}
static HRESULT WINAPI
IReferenceClock_fnAdviseTime(IReferenceClock* iface,REFERENCE_TIME rtBase,REFERENCE_TIME rtStream,HEVENT hEvent,DWORD_PTR* pdwAdvCookie)
{
CSystemClock_THIS(iface,refclk);
+ QUARTZ_TimerEntry* pEntry;
+ HRESULT hr;
+ REFERENCE_TIME rtCur;
- FIXME( "(%p)->() stub!\n", This );
- return E_NOTIMPL;
+ TRACE( "(%p)->()\n", This );
+
+ if ( pdwAdvCookie == NULL )
+ return E_POINTER;
+ if ( hEvent == (HANDLE)NULL )
+ return E_INVALIDARG;
+
+ EnterCriticalSection( &This->m_csClock );
+
+ *pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);
+
+ hr = IReferenceClock_GetTime(iface,&rtCur);
+ if ( hr != NOERROR )
+ goto err;
+ if ( rtCur >= (rtBase+rtStream) )
+ {
+ SetEvent(hEvent);
+ hr = NOERROR;
+ goto err;
+ }
+
+ pEntry = IReferenceClock_AllocTimerEntry(This);
+ if ( pEntry == NULL )
+ {
+ hr = E_FAIL;
+ goto err;
+ }
+
+ if ( !PostThreadMessageA(
+ This->m_idThreadTimer,
+ QUARTZ_MSG_ADDTIMER,
+ 0, 0 ) )
+ {
+ hr = E_FAIL;
+ goto err;
+ }
+
+ pEntry->dwAdvCookie = *pdwAdvCookie;
+ pEntry->fPeriodic = FALSE;
+ pEntry->hEvent = hEvent;
+ pEntry->rtStart = rtBase;
+ pEntry->rtInterval = rtStream;
+
+ hr = NOERROR;
+err:
+ LeaveCriticalSection( &This->m_csClock );
+
+ return hr;
}
static HRESULT WINAPI
IReferenceClock_fnAdvisePeriodic(IReferenceClock* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtPeriod,HSEMAPHORE hSemaphore,DWORD_PTR* pdwAdvCookie)
{
CSystemClock_THIS(iface,refclk);
+ QUARTZ_TimerEntry* pEntry;
+ HRESULT hr;
- FIXME( "(%p)->() stub!\n", This );
- return E_NOTIMPL;
+ TRACE( "(%p)->()\n", This );
+
+ if ( pdwAdvCookie == NULL )
+ return E_POINTER;
+ if ( hSemaphore == (HSEMAPHORE)NULL )
+ return E_INVALIDARG;
+
+ EnterCriticalSection( &This->m_csClock );
+
+ *pdwAdvCookie = (DWORD_PTR)(This->m_dwAdvCookieNext ++);
+
+ pEntry = IReferenceClock_AllocTimerEntry(This);
+ if ( pEntry == NULL )
+ {
+ hr = E_FAIL;
+ goto err;
+ }
+
+ if ( !PostThreadMessageA(
+ This->m_idThreadTimer,
+ QUARTZ_MSG_ADDTIMER,
+ 0, 0 ) )
+ {
+ hr = E_FAIL;
+ goto err;
+ }
+
+ pEntry->dwAdvCookie = *pdwAdvCookie;
+ pEntry->fPeriodic = TRUE;
+ pEntry->hEvent = (HANDLE)hSemaphore;
+ pEntry->rtStart = rtStart;
+ pEntry->rtInterval = rtPeriod;
+
+ hr = NOERROR;
+err:
+ LeaveCriticalSection( &This->m_csClock );
+
+ return hr;
}
static HRESULT WINAPI
IReferenceClock_fnUnadvise(IReferenceClock* iface,DWORD_PTR dwAdvCookie)
{
CSystemClock_THIS(iface,refclk);
+ QUARTZ_TimerEntry* pEntry;
- FIXME( "(%p)->() stub!\n", This );
- return E_NOTIMPL;
+ TRACE( "(%p)->(%lu)\n", This, (DWORD)dwAdvCookie );
+
+ EnterCriticalSection( &This->m_csClock );
+
+ pEntry = IReferenceClock_SearchTimer(This,(DWORD)dwAdvCookie);
+ if ( pEntry != NULL )
+ {
+ pEntry->hEvent = (HANDLE)NULL;
+ }
+
+ LeaveCriticalSection( &This->m_csClock );
+
+ return NOERROR;
}
static ICOM_VTABLE(IReferenceClock) irefclk =
@@ -106,13 +367,71 @@
HRESULT CSystemClock_InitIReferenceClock( CSystemClock* psc )
{
+ HANDLE hEvents[2];
+
TRACE("(%p)\n",psc);
ICOM_VTBL(&psc->refclk) = &irefclk;
+ InitializeCriticalSection( &psc->m_csClock );
+ psc->m_dwTimeLast = GetTickCount();
+ psc->m_rtLast = (REFERENCE_TIME)0;
+ psc->m_hThreadTimer = (HANDLE)NULL;
+ psc->m_hEventInit = (HANDLE)NULL;
+ psc->m_idThreadTimer = 0;
+ psc->m_dwAdvCookieNext = 1;
+ ZeroMemory( psc->m_timerEntries, sizeof(psc->m_timerEntries) );
+
+ psc->m_hEventInit = CreateEventA( NULL, TRUE, FALSE, NULL );
+ if ( psc->m_hEventInit == (HANDLE)NULL )
+ goto err;
+
+ psc->m_hThreadTimer = CreateThread(
+ NULL, 0,
+ IReferenceClock_TimerEntry,
+ psc, 0, &psc->m_idThreadTimer );
+
+ if ( psc->m_hThreadTimer == (HANDLE)NULL )
+ {
+ CloseHandle( psc->m_hEventInit );
+ psc->m_hEventInit = (HANDLE)NULL;
+ goto err;
+ }
+
+ hEvents[0] = psc->m_hEventInit;
+ hEvents[1] = psc->m_hThreadTimer;
+ if ( WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE )
+ != WAIT_OBJECT_0 )
+ {
+ CloseHandle( psc->m_hEventInit );
+ psc->m_hEventInit = (HANDLE)NULL;
+ CloseHandle( psc->m_hThreadTimer );
+ psc->m_hThreadTimer = (HANDLE)NULL;
+ goto err;
+ }
+
return NOERROR;
+
+err:
+ DeleteCriticalSection( &psc->m_csClock );
+ return E_FAIL;
}
void CSystemClock_UninitIReferenceClock( CSystemClock* psc )
{
TRACE("(%p)\n",psc);
+
+ if ( psc->m_hThreadTimer != (HANDLE)NULL )
+ {
+ if ( PostThreadMessageA(
+ psc->m_idThreadTimer,
+ QUARTZ_MSG_EXITTHREAD,
+ 0, 0 ) )
+ {
+ WaitForSingleObject( psc->m_hThreadTimer, INFINITE );
+ }
+ CloseHandle( psc->m_hThreadTimer );
+ psc->m_hThreadTimer = (HANDLE)NULL;
+ }
+
+ DeleteCriticalSection( &psc->m_csClock );
}
diff --git a/dlls/quartz/iunk.c b/dlls/quartz/iunk.c
index 27cccfd..4cfe4bc 100644
--- a/dlls/quartz/iunk.c
+++ b/dlls/quartz/iunk.c
@@ -24,6 +24,8 @@
ICOM_THIS(QUARTZ_IUnkImpl,iface);
size_t ofs;
DWORD dwIndex;
+ QUARTZ_IFDelegation* pDelegation;
+ HRESULT hr;
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
@@ -49,8 +51,24 @@
}
if ( dwIndex == This->dwEntries )
{
- FIXME("unknown interface: %s\n",debugstr_guid(riid));
- return E_NOINTERFACE;
+ hr = E_NOINTERFACE;
+
+ /* delegation */
+ pDelegation = This->pDelegationFirst;
+ while ( pDelegation != NULL )
+ {
+ hr = (*pDelegation->pOnQueryInterface)( iface, riid, ppobj );
+ if ( hr != E_NOINTERFACE )
+ break;
+ pDelegation = pDelegation->pNext;
+ }
+
+ if ( hr == E_NOINTERFACE )
+ {
+ FIXME("unknown interface: %s\n",debugstr_guid(riid));
+ }
+
+ return hr;
}
}
@@ -106,12 +124,20 @@
ICOM_VTBL(pImpl) = &iunknown;
pImpl->pEntries = NULL;
pImpl->dwEntries = 0;
+ pImpl->pDelegationFirst = NULL;
pImpl->pOnFinalRelease = NULL;
pImpl->ref = 1;
pImpl->punkControl = (IUnknown*)pImpl;
- /* for delegation. */
+ /* for implementing aggregation. */
if ( punkOuter != NULL )
pImpl->punkControl = punkOuter;
}
+void QUARTZ_IUnkAddDelegation(
+ QUARTZ_IUnkImpl* pImpl, QUARTZ_IFDelegation* pDelegation )
+{
+ pDelegation->pNext = pImpl->pDelegationFirst;
+ pImpl->pDelegationFirst = pDelegation;
+}
+
diff --git a/dlls/quartz/iunk.h b/dlls/quartz/iunk.h
index 338d113..7ef0fe8 100644
--- a/dlls/quartz/iunk.h
+++ b/dlls/quartz/iunk.h
@@ -33,6 +33,13 @@
size_t ofsVTPtr; /* offset from IUnknown. */
} QUARTZ_IFEntry;
+typedef struct QUARTZ_IFDelegation
+{
+ struct QUARTZ_IFDelegation* pNext;
+ HRESULT (*pOnQueryInterface)(
+ IUnknown* punk, const IID* piid, void** ppobj );
+} QUARTZ_IFDelegation;
+
typedef struct QUARTZ_IUnkImpl
{
/* pointer of IUnknown interface. */
@@ -41,6 +48,8 @@
/* array of supported IIDs and offsets. */
const QUARTZ_IFEntry* pEntries;
DWORD dwEntries;
+ /* list of delegation handlers. */
+ QUARTZ_IFDelegation* pDelegationFirst;
/* called on final release. */
void (*pOnFinalRelease)(IUnknown* punk);
@@ -53,6 +62,8 @@
void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter );
+void QUARTZ_IUnkAddDelegation(
+ QUARTZ_IUnkImpl* pImpl, QUARTZ_IFDelegation* pDelegation );
#endif /* WINE_DSHOW_IUNK_H */
diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c
index 90cc02d..e82a750 100644
--- a/dlls/quartz/main.c
+++ b/dlls/quartz/main.c
@@ -20,6 +20,7 @@
#include "devenum.h"
#include "fmap.h"
#include "fmap2.h"
+#include "seekpass.h"
typedef struct QUARTZ_CLASSENTRY
@@ -63,6 +64,7 @@
{ &CLSID_SystemDeviceEnum, &QUARTZ_CreateSystemDeviceEnum },
{ &CLSID_FilterMapper, &QUARTZ_CreateFilterMapper },
{ &CLSID_FilterMapper2, &QUARTZ_CreateFilterMapper2 },
+ { &CLSID_SeekingPassThru, &QUARTZ_CreateSeekingPassThru },
{ NULL, NULL },
};
@@ -175,7 +177,7 @@
ICOM_THIS(IClassFactoryImpl,iface);
HRESULT hr;
- FIXME("(%p)->(%d),stub!\n",This,dolock);
+ TRACE("(%p)->(%d)\n",This,dolock);
if (dolock)
hr = IClassFactory_AddRef(iface);
else
@@ -335,29 +337,4 @@
}
-/***********************************************************************
- * AmpFactorToDB (QUARTZ.@)
- *
- * undocumented.
- * (converting from Amp to dB?)
- *
- */
-DWORD WINAPI QUARTZ_AmpFactorToDB( DWORD dw )
-{
- FIXME( "(%08lx): undocumented API - stub!\n", dw );
- return 0;
-}
-
-/***********************************************************************
- * DBToAmpFactor (QUARTZ.@)
- *
- * undocumented.
- * (converting from dB to Amp?)
- */
-DWORD WINAPI QUARTZ_DBToAmpFactor( DWORD dw )
-{
- FIXME( "(%08lx): undocumented API - stub!\n", dw );
- return 0;
-}
-
diff --git a/dlls/quartz/memalloc.h b/dlls/quartz/memalloc.h
index 4b6ae4a..2477ec5 100644
--- a/dlls/quartz/memalloc.h
+++ b/dlls/quartz/memalloc.h
@@ -24,6 +24,8 @@
MA_IMemAllocatorImpl memalloc;
/* IMemAllocator fields. */
+ CRITICAL_SECTION csMem;
+ ALLOCATOR_PROPERTIES prop;
} CMemoryAllocator;
#define CMemoryAllocator_THIS(iface,member) CMemoryAllocator* This = ((CMemoryAllocator*)(((char*)iface)-offsetof(CMemoryAllocator,member)))
diff --git a/dlls/quartz/seekpass.c b/dlls/quartz/seekpass.c
new file mode 100644
index 0000000..0620f31
--- /dev/null
+++ b/dlls/quartz/seekpass.c
@@ -0,0 +1,134 @@
+/*
+ * Implementation of CLSID_SeekingPassThru.
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winerror.h"
+#include "wine/obj_base.h"
+#include "strmif.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "seekpass.h"
+
+
+
+static HRESULT WINAPI
+ISeekingPassThru_fnQueryInterface(ISeekingPassThru* iface,REFIID riid,void** ppobj)
+{
+ CSeekingPassThru_THIS(iface,seekpass);
+
+ TRACE("(%p)->()\n",This);
+
+ return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+ISeekingPassThru_fnAddRef(ISeekingPassThru* iface)
+{
+ CSeekingPassThru_THIS(iface,seekpass);
+
+ TRACE("(%p)->()\n",This);
+
+ return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+ISeekingPassThru_fnRelease(ISeekingPassThru* iface)
+{
+ CSeekingPassThru_THIS(iface,seekpass);
+
+ TRACE("(%p)->()\n",This);
+
+ return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+ISeekingPassThru_fnInit(ISeekingPassThru* iface,BOOL bRendering,IPin* pPin)
+{
+ CSeekingPassThru_THIS(iface,seekpass);
+
+ FIXME("(%p)->(%d,%p) stub!\n",This,bRendering,pPin);
+
+ return E_NOTIMPL;
+}
+
+
+static ICOM_VTABLE(ISeekingPassThru) iseekingpassthru =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ /* IUnknown fields */
+ ISeekingPassThru_fnQueryInterface,
+ ISeekingPassThru_fnAddRef,
+ ISeekingPassThru_fnRelease,
+ /* ISeekingPassThru fields */
+ ISeekingPassThru_fnInit,
+};
+
+static
+HRESULT CSeekingPassThru_InitISeekingPassThru(CSeekingPassThru* This)
+{
+ TRACE("(%p)\n",This);
+ ICOM_VTBL(&This->seekpass) = &iseekingpassthru;
+
+ return NOERROR;
+}
+
+static
+void CSeekingPassThru_UninitISeekingPassThru(CSeekingPassThru* This)
+{
+ TRACE("(%p)\n",This);
+}
+
+
+/* can I use offsetof safely? - FIXME? */
+static QUARTZ_IFEntry IFEntries[] =
+{
+ { &IID_ISeekingPassThru, offsetof(CSeekingPassThru,seekpass)-offsetof(CSeekingPassThru,unk) },
+};
+
+
+static void QUARTZ_DestroySeekingPassThru(IUnknown* punk)
+{
+ CSeekingPassThru_THIS(punk,unk);
+
+ CSeekingPassThru_UninitISeekingPassThru(This);
+}
+
+HRESULT QUARTZ_CreateSeekingPassThru(IUnknown* punkOuter,void** ppobj)
+{
+ CSeekingPassThru* This;
+ HRESULT hr;
+
+ TRACE("(%p,%p)\n",punkOuter,ppobj);
+
+ This = (CSeekingPassThru*)QUARTZ_AllocObj( sizeof(CSeekingPassThru) );
+ if ( This == NULL )
+ return E_OUTOFMEMORY;
+
+ QUARTZ_IUnkInit( &This->unk, punkOuter );
+ hr = CSeekingPassThru_InitISeekingPassThru(This);
+ if ( FAILED(hr) )
+ {
+ QUARTZ_FreeObj( This );
+ return hr;
+ }
+
+ This->unk.pEntries = IFEntries;
+ This->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+ This->unk.pOnFinalRelease = QUARTZ_DestroySeekingPassThru;
+
+ *ppobj = (void*)(&This->unk);
+
+ return S_OK;
+}
+
diff --git a/dlls/quartz/seekpass.h b/dlls/quartz/seekpass.h
new file mode 100644
index 0000000..1176a3d
--- /dev/null
+++ b/dlls/quartz/seekpass.h
@@ -0,0 +1,35 @@
+#ifndef WINE_DSHOW_SEEKPASS_H
+#define WINE_DSHOW_SEEKPASS_H
+
+/*
+ implements CLSID_SeekingPassThru.
+
+ - At least, the following interfaces should be implemented:
+
+ IUnknown
+ + ISeekingPassThru
+
+*/
+
+#include "iunk.h"
+
+typedef struct QUARTZ_ISeekingPassThruImpl
+{
+ ICOM_VFIELD(ISeekingPassThru);
+} QUARTZ_ISeekingPassThruImpl;
+
+
+typedef struct CSeekingPassThru
+{
+ QUARTZ_IUnkImpl unk;
+ QUARTZ_ISeekingPassThruImpl seekpass;
+
+ /* ISeekingPassThru fields. */
+} CSeekingPassThru;
+
+#define CSeekingPassThru_THIS(iface,member) CSeekingPassThru* This = ((CSeekingPassThru*)(((char*)iface)-offsetof(CSeekingPassThru,member)))
+
+HRESULT QUARTZ_CreateSeekingPassThru(IUnknown* punkOuter,void** ppobj);
+
+
+#endif /* WINE_DSHOW_SEEKPASS_H */
diff --git a/dlls/quartz/sysclock.h b/dlls/quartz/sysclock.h
index 2fe9613..ce7c897 100644
--- a/dlls/quartz/sysclock.h
+++ b/dlls/quartz/sysclock.h
@@ -19,12 +19,33 @@
} SC_IReferenceClockImpl;
+/* implementation limit */
+#define WINE_QUARTZ_SYSCLOCK_TIMER_MAX 64
+
+typedef struct QUARTZ_TimerEntry
+{
+ DWORD dwAdvCookie;
+ BOOL fPeriodic;
+ HANDLE hEvent;
+ REFERENCE_TIME rtStart;
+ REFERENCE_TIME rtInterval;
+} QUARTZ_TimerEntry;
+
typedef struct CSystemClock
{
QUARTZ_IUnkImpl unk;
SC_IReferenceClockImpl refclk;
/* IReferenceClock fields. */
+ CRITICAL_SECTION m_csClock;
+ DWORD m_dwTimeLast;
+ REFERENCE_TIME m_rtLast;
+ HANDLE m_hThreadTimer;
+ HANDLE m_hEventInit;
+ DWORD m_idThreadTimer;
+
+ DWORD m_dwAdvCookieNext;
+ QUARTZ_TimerEntry m_timerEntries[WINE_QUARTZ_SYSCLOCK_TIMER_MAX];
} CSystemClock;
#define CSystemClock_THIS(iface,member) CSystemClock* This = ((CSystemClock*)(((char*)iface)-offsetof(CSystemClock,member)))
diff --git a/include/dshow.h b/include/dshow.h
index 222e5ec..a2e5064 100644
--- a/include/dshow.h
+++ b/include/dshow.h
@@ -13,9 +13,9 @@
#include "control.h"
#include "evcode.h"
#include "uuids.h"
-/*#include "errors.h"*/ /* not yet */
+#include "errors.h"
/*#include "edevdefs.h"*/ /* not yet */
-/*#include "audevcod.h"*/ /* not yet */
+#include "audevcod.h"
/*#include "dvdevcod.h"*/ /* not yet */
#ifndef AM_NOVTABLE
diff --git a/include/strmif.h b/include/strmif.h
index 34b3dee..9ea3212 100644
--- a/include/strmif.h
+++ b/include/strmif.h
@@ -471,8 +471,8 @@
/*** IPersist methods ***/
#define IBaseFilter_GetClassID(p,a1) ICOM_CALL1(GetClassID,p,a1)
/*** IMediaFilter methods ***/
-#define IBaseFilter_Stop(p,a1) ICOM_CALL1(Stop,p,a1)
-#define IBaseFilter_Pause(p,a1) ICOM_CALL1(Pause,p,a1)
+#define IBaseFilter_Stop(p) ICOM_CALL (Stop,p)
+#define IBaseFilter_Pause(p) ICOM_CALL (Pause,p)
#define IBaseFilter_Run(p,a1) ICOM_CALL1(Run,p,a1)
#define IBaseFilter_GetState(p,a1,a2) ICOM_CALL2(GetState,p,a1,a2)
#define IBaseFilter_SetSyncSource(p,a1) ICOM_CALL1(SetSyncSource,p,a1)
diff --git a/winedefault.reg b/winedefault.reg
index 4780e00..1597425 100644
--- a/winedefault.reg
+++ b/winedefault.reg
@@ -271,6 +271,11 @@
@="quartz.dll"
"ThreadingModel"="Both"
+# CLSID_SeekingPassThru
+[HKEY_CLASSES_ROOT\CLSID\{060AF76C-68DD-11D0-8FC1-00C04FD9189D}\InprocServer32]
+@="quartz.dll"
+"ThreadingModel"="Both"
+
# DirectShow filter categories
[HKEY_CLASSES_ROOT\CLSID\{DA4E3DA0-D07D-11D0-BD50-00A0C911CE86}]