Commit ecbf6c11 authored by Hidenori Takeshima's avatar Hidenori Takeshima Committed by Alexandre Julliard

Fixed some broken macros.

Added some stubs. Implemeted undocumented APIs. Implemented many methods in IMediaFilter, IMediaControl and IReferenceClock. Started Implementing IMemoryAllocator.
parent f80cf432
......@@ -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@
......
#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;
}
......@@ -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 )
{
......
......@@ -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);
......
......@@ -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
......
......@@ -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 );
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 );
}
......
......@@ -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) );
}
......
......@@ -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 );
}
......@@ -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 );
}
/*
* 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;
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;
FIXME( "(%p)->() stub!\n", This );
return E_NOTIMPL;
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;
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;
}
FIXME( "(%p)->() stub!\n", This );
return E_NOTIMPL;
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;
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;
}
FIXME( "(%p)->() stub!\n", This );
return E_NOTIMPL;
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;
TRACE( "(%p)->(%lu)\n", This, (DWORD)dwAdvCookie );
EnterCriticalSection( &This->m_csClock );
FIXME( "(%p)->() stub!\n", This );
return E_NOTIMPL;
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 );
}
......@@ -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);
......@@ -49,8 +51,24 @@ IUnknown_fnQueryInterface(IUnknown* iface,REFIID riid,LPVOID *ppobj)
}
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 @@ 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;
}
......@@ -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 */
......@@ -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;
}
......@@ -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)))
......
/*
* 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;
}
#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 */
......@@ -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)))
......
......@@ -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
......
......@@ -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)
......
......@@ -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}]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment