Fixed some broken macros.

Added some stubs.
Implemeted undocumented APIs.
Implemented many methods in IMediaFilter, IMediaControl and
IReferenceClock.
Started Implementing IMemoryAllocator.
This commit is contained in:
Hidenori Takeshima 2001-09-11 00:29:03 +00:00 committed by Alexandre Julliard
parent f80cf43270
commit ecbf6c112b
20 changed files with 977 additions and 72 deletions

View File

@ -10,6 +10,7 @@ SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
amerror.c \
amundoc.c \
complist.c \
devenum.c \
devmon.c \
@ -40,6 +41,7 @@ C_SRCS = \
memalloc.c \
monprop.c \
regsvr.c \
seekpass.c \
sysclock.c
@MAKE_DLL_RULES@

55
dlls/quartz/amundoc.c Normal file
View File

@ -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;
}

View File

@ -79,6 +79,10 @@ static void QUARTZ_DestroyFilterGraph(IUnknown* punk)
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 )
{

View File

@ -120,6 +120,9 @@ typedef struct CFilterGraph
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 @@ typedef struct CFilterGraph
#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);

View File

@ -90,8 +90,11 @@ IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR
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 @@ IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
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

View File

@ -80,7 +80,15 @@ IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCateg
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 @@ IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCW
ppMoniker,debugstr_guid(pclsidCategory),
debugstr_w(lpwszInst),pRF2 );
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 );
}

View File

@ -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 @@ IMediaControl_fnRun(IMediaControl* iface)
{
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 @@ IMediaControl_fnPause(IMediaControl* iface)
{
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 @@ IMediaControl_fnGetState(IMediaControl* iface,LONG lTimeOut,OAFilterState* pFilt
{
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 @@ IMediaControl_fnStopWhenReady(IMediaControl* iface)
{
CFilterGraph_THIS(iface,mediacontrol);
FIXME("(%p)->()\n",This);
TRACE("(%p)->()\n",This);
return E_NOTIMPL;
return IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
}

View File

@ -57,9 +57,40 @@ static HRESULT WINAPI
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 @@ IMemAllocator_fnGetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pProp)
{
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 @@ static ICOM_VTABLE(IMemAllocator) imemalloc =
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 );
}

View File

@ -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 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#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 @@ static HRESULT WINAPI
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 @@ static ICOM_VTABLE(IMediaFilter) imediafilter =
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 );
}

View File

@ -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 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#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 @@ static HRESULT WINAPI
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 @@ static ICOM_VTABLE(IReferenceClock) irefclk =
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 );
}

View File

@ -24,6 +24,8 @@ IUnknown_fnQueryInterface(IUnknown* iface,REFIID riid,LPVOID *ppobj)
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);
@ -48,9 +50,25 @@ IUnknown_fnQueryInterface(IUnknown* iface,REFIID riid,LPVOID *ppobj)
}
}
if ( dwIndex == This->dwEntries )
{
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 E_NOINTERFACE;
}
return hr;
}
}
@ -106,12 +124,20 @@ void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter )
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;
}

View File

@ -33,6 +33,13 @@ typedef struct QUARTZ_IFEntry
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 @@ typedef struct QUARTZ_IUnkImpl
/* 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 @@ typedef struct QUARTZ_IUnkImpl
void QUARTZ_IUnkInit( QUARTZ_IUnkImpl* pImpl, IUnknown* punkOuter );
void QUARTZ_IUnkAddDelegation(
QUARTZ_IUnkImpl* pImpl, QUARTZ_IFDelegation* pDelegation );
#endif /* WINE_DSHOW_IUNK_H */

View File

@ -20,6 +20,7 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "devenum.h"
#include "fmap.h"
#include "fmap2.h"
#include "seekpass.h"
typedef struct QUARTZ_CLASSENTRY
@ -63,6 +64,7 @@ static const QUARTZ_CLASSENTRY QUARTZ_ClassList[] =
{ &CLSID_SystemDeviceEnum, &QUARTZ_CreateSystemDeviceEnum },
{ &CLSID_FilterMapper, &QUARTZ_CreateFilterMapper },
{ &CLSID_FilterMapper2, &QUARTZ_CreateFilterMapper2 },
{ &CLSID_SeekingPassThru, &QUARTZ_CreateSeekingPassThru },
{ NULL, NULL },
};
@ -175,7 +177,7 @@ static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface,BOOL doloc
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 @@ HRESULT WINAPI QUARTZ_DllUnregisterServer( void )
}
/***********************************************************************
* 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;
}

View File

@ -24,6 +24,8 @@ typedef struct CMemoryAllocator
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)))

134
dlls/quartz/seekpass.c Normal file
View File

@ -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;
}

35
dlls/quartz/seekpass.h Normal file
View File

@ -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 */

View File

@ -19,12 +19,33 @@ typedef struct SC_IReferenceClockImpl
} 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)))

View File

@ -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

View File

@ -471,8 +471,8 @@ ICOM_DEFINE(IBaseFilter,IMediaFilter)
/*** 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)

View File

@ -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}]