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

Merged some C sources.

Fixed some bugs. Started implementing some pass-through interfaces.
parent 7695d690
...@@ -9,40 +9,30 @@ LDDLLFLAGS = @LDDLLFLAGS@ ...@@ -9,40 +9,30 @@ LDDLLFLAGS = @LDDLLFLAGS@
SYMBOLFILE = $(MODULE).tmp.o SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \ C_SRCS = \
amerror.c \
amundoc.c \ amundoc.c \
basefilt.c \
basepin.c \
complist.c \ complist.c \
devenum.c \ devenum.c \
devmon.c \ devmon.c \
enumunk.c \ enumunk.c \
fgclsid.c \ fgevent.c \
fgidisp.c \ fgidisp.c \
fgpass.c \
fgraph.c \ fgraph.c \
fmap.c \ fmap.c \
fmap2.c \ fmap2.c \
ibasaud.c \
ibasvid.c \
idevenum.c \
ifgraph.c \ ifgraph.c \
ifmap.c \ igconfig.c \
ifmap3.c \
igrver.c \ igrver.c \
imcntl.c \ imcntl.c \
imem.c \
imesink.c \
imevent.c \
imfilter.c \ imfilter.c \
impos.c \ impos.c \
imseek.c \ imseek.c \
irclock.c \
iunk.c \ iunk.c \
ividwin.c \
main.c \ main.c \
memalloc.c \ memalloc.c \
monprop.c \ mtype.c \
ptimpl.c \
ptmpos.c \
ptmseek.c \
regsvr.c \ regsvr.c \
sample.c \ sample.c \
seekpass.c \ seekpass.c \
......
TODO
- merge some C sources.
- implements all filters.
- handles plug-in distributor.
- implements some interfaces as plug-ins(???)
- implements ICM
- implements mciqtz(mci driver for quartz)
known BUGS
- all FIXMEs.
- some filters crash at CoCreateInstance. (ole???)
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "winnls.h"
#include "wine/obj_base.h"
#include "strmif.h"
#include "errors.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
static
LPWSTR QUARTZ_strncpyAtoW( LPWSTR lpwstr, LPCSTR lpstr, INT wbuflen )
{
INT len;
len = MultiByteToWideChar( CP_ACP, 0, lpstr, -1, lpwstr, wbuflen );
if ( len == 0 )
*lpwstr = 0;
return lpwstr;
}
static LPCSTR hresult_to_string( HRESULT hr )
{
switch ( hr )
{
#define ENTRY(x) case x: return (const char*)#x
/* some known codes */
ENTRY(S_OK);
ENTRY(S_FALSE);
ENTRY(E_FAIL);
ENTRY(E_POINTER);
ENTRY(E_NOTIMPL);
ENTRY(E_NOINTERFACE);
ENTRY(E_OUTOFMEMORY);
ENTRY(CLASS_E_CLASSNOTAVAILABLE);
ENTRY(CLASS_E_NOAGGREGATION);
/* vfwmsgs.h */
ENTRY(VFW_S_NO_MORE_ITEMS);
ENTRY(VFW_E_BAD_KEY);
ENTRY(VFW_E_INVALIDMEDIATYPE);
ENTRY(VFW_E_INVALIDSUBTYPE);
ENTRY(VFW_E_NEED_OWNER);
ENTRY(VFW_E_ENUM_OUT_OF_SYNC);
ENTRY(VFW_E_ALREADY_CONNECTED);
ENTRY(VFW_E_FILTER_ACTIVE);
ENTRY(VFW_E_NO_TYPES);
ENTRY(VFW_E_NO_ACCEPTABLE_TYPES);
ENTRY(VFW_E_INVALID_DIRECTION);
ENTRY(VFW_E_NOT_CONNECTED);
ENTRY(VFW_E_NO_ALLOCATOR);
ENTRY(VFW_E_RUNTIME_ERROR);
ENTRY(VFW_E_BUFFER_NOTSET);
ENTRY(VFW_E_BUFFER_OVERFLOW);
ENTRY(VFW_E_BADALIGN);
ENTRY(VFW_E_ALREADY_COMMITTED);
ENTRY(VFW_E_BUFFERS_OUTSTANDING);
ENTRY(VFW_E_NOT_COMMITTED);
ENTRY(VFW_E_SIZENOTSET);
ENTRY(VFW_E_NO_CLOCK);
ENTRY(VFW_E_NO_SINK);
ENTRY(VFW_E_NO_INTERFACE);
ENTRY(VFW_E_NOT_FOUND);
ENTRY(VFW_E_CANNOT_CONNECT);
ENTRY(VFW_E_CANNOT_RENDER);
ENTRY(VFW_E_CHANGING_FORMAT);
ENTRY(VFW_E_NO_COLOR_KEY_SET);
ENTRY(VFW_E_NOT_OVERLAY_CONNECTION);
ENTRY(VFW_E_NOT_SAMPLE_CONNECTION);
ENTRY(VFW_E_PALETTE_SET);
ENTRY(VFW_E_COLOR_KEY_SET);
ENTRY(VFW_E_NO_COLOR_KEY_FOUND);
ENTRY(VFW_E_NO_PALETTE_AVAILABLE);
ENTRY(VFW_E_NO_DISPLAY_PALETTE);
ENTRY(VFW_E_TOO_MANY_COLORS);
ENTRY(VFW_E_STATE_CHANGED);
ENTRY(VFW_E_NOT_STOPPED);
ENTRY(VFW_E_NOT_PAUSED);
ENTRY(VFW_E_NOT_RUNNING);
ENTRY(VFW_E_WRONG_STATE);
ENTRY(VFW_E_START_TIME_AFTER_END);
ENTRY(VFW_E_INVALID_RECT);
ENTRY(VFW_E_TYPE_NOT_ACCEPTED);
ENTRY(VFW_E_SAMPLE_REJECTED);
ENTRY(VFW_E_SAMPLE_REJECTED_EOS);
ENTRY(VFW_S_DUPLICATE_NAME);
ENTRY(VFW_E_DUPLICATE_NAME);
ENTRY(VFW_E_TIMEOUT);
ENTRY(VFW_E_INVALID_FILE_FORMAT);
ENTRY(VFW_E_ENUM_OUT_OF_RANGE);
ENTRY(VFW_E_CIRCULAR_GRAPH);
ENTRY(VFW_E_NOT_ALLOWED_TO_SAVE);
ENTRY(VFW_E_TIME_ALREADY_PASSED);
ENTRY(VFW_E_ALREADY_CANCELLED);
ENTRY(VFW_E_CORRUPT_GRAPH_FILE);
ENTRY(VFW_E_ADVISE_ALREADY_SET);
ENTRY(VFW_S_STATE_INTERMEDIATE);
ENTRY(VFW_E_NO_MODEX_AVAILABLE);
ENTRY(VFW_E_NO_ADVISE_SET);
ENTRY(VFW_E_NO_FULLSCREEN);
ENTRY(VFW_E_IN_FULLSCREEN_MODE);
ENTRY(VFW_E_UNKNOWN_FILE_TYPE);
ENTRY(VFW_E_CANNOT_LOAD_SOURCE_FILTER);
ENTRY(VFW_S_PARTIAL_RENDER);
ENTRY(VFW_E_FILE_TOO_SHORT);
ENTRY(VFW_E_INVALID_FILE_VERSION);
ENTRY(VFW_S_SOME_DATA_IGNORED);
ENTRY(VFW_S_CONNECTIONS_DEFERRED);
ENTRY(VFW_E_INVALID_CLSID);
ENTRY(VFW_E_INVALID_MEDIA_TYPE);
ENTRY(VFW_E_SAMPLE_TIME_NOT_SET);
ENTRY(VFW_S_RESOURCE_NOT_NEEDED);
ENTRY(VFW_E_MEDIA_TIME_NOT_SET);
ENTRY(VFW_E_NO_TIME_FORMAT_SET);
ENTRY(VFW_E_MONO_AUDIO_HW);
ENTRY(VFW_S_MEDIA_TYPE_IGNORED);
ENTRY(VFW_E_NO_DECOMPRESSOR);
ENTRY(VFW_E_NO_AUDIO_HARDWARE);
ENTRY(VFW_S_VIDEO_NOT_RENDERED);
ENTRY(VFW_S_AUDIO_NOT_RENDERED);
ENTRY(VFW_E_RPZA);
ENTRY(VFW_S_RPZA);
ENTRY(VFW_E_PROCESSOR_NOT_SUITABLE);
ENTRY(VFW_E_UNSUPPORTED_AUDIO);
ENTRY(VFW_E_UNSUPPORTED_VIDEO);
ENTRY(VFW_E_MPEG_NOT_CONSTRAINED);
ENTRY(VFW_E_NOT_IN_GRAPH);
ENTRY(VFW_S_ESTIMATED);
ENTRY(VFW_E_NO_TIME_FORMAT);
ENTRY(VFW_E_READ_ONLY);
ENTRY(VFW_S_RESERVED);
ENTRY(VFW_E_BUFFER_UNDERFLOW);
ENTRY(VFW_E_UNSUPPORTED_STREAM);
ENTRY(VFW_E_NO_TRANSPORT);
ENTRY(VFW_S_STREAM_OFF);
ENTRY(VFW_S_CANT_CUE);
ENTRY(VFW_E_BAD_VIDEOCD);
ENTRY(VFW_S_NO_STOP_TIME);
ENTRY(VFW_E_OUT_OF_VIDEO_MEMORY);
ENTRY(VFW_E_VP_NEGOTIATION_FAILED);
ENTRY(VFW_E_DDRAW_CAPS_NOT_SUITABLE);
ENTRY(VFW_E_NO_VP_HARDWARE);
ENTRY(VFW_E_NO_CAPTURE_HARDWARE);
ENTRY(VFW_E_DVD_OPERATION_INHIBITED);
ENTRY(VFW_E_DVD_INVALIDDOMAIN);
ENTRY(VFW_E_DVD_NO_BUTTON);
ENTRY(VFW_E_DVD_GRAPHNOTREADY);
ENTRY(VFW_E_DVD_RENDERFAIL);
ENTRY(VFW_E_DVD_DECNOTENOUGH);
ENTRY(VFW_E_DDRAW_VERSION_NOT_SUITABLE);
ENTRY(VFW_E_COPYPROT_FAILED);
ENTRY(VFW_S_NOPREVIEWPIN);
ENTRY(VFW_E_TIME_EXPIRED);
ENTRY(VFW_S_DVD_NON_ONE_SEQUENTIAL);
ENTRY(VFW_E_DVD_WRONG_SPEED);
ENTRY(VFW_E_DVD_MENU_DOES_NOT_EXIST);
ENTRY(VFW_E_DVD_CMD_CANCELLED);
ENTRY(VFW_E_DVD_STATE_WRONG_VERSION);
ENTRY(VFW_E_DVD_STATE_CORRUPT);
ENTRY(VFW_E_DVD_STATE_WRONG_DISC);
ENTRY(VFW_E_DVD_INCOMPATIBLE_REGION);
ENTRY(VFW_E_DVD_NO_ATTRIBUTES);
ENTRY(VFW_E_DVD_NO_GOUP_PGC);
ENTRY(VFW_E_DVD_LOW_PARENTAL_LEVEL);
ENTRY(VFW_E_DVD_NOT_IN_KARAOKE_MODE);
ENTRY(VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE);
ENTRY(VFW_S_DVD_NOT_ACCURATE);
ENTRY(VFW_E_FRAME_STEP_UNSUPPORTED);
ENTRY(VFW_E_DVD_STREAM_DISABLED);
ENTRY(VFW_E_DVD_TITLE_UNKNOWN);
ENTRY(VFW_E_DVD_INVALID_DISC);
ENTRY(VFW_E_DVD_NO_RESUME_INFORMATION);
ENTRY(VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD);
ENTRY(VFW_E_PIN_ALREADY_BLOCKED);
ENTRY(VFW_E_CERTIFICATION_FAILURE);
#undef ENTRY
}
return NULL;
}
/***********************************************************************
* AMGetErrorTextA (quartz.@)
*/
DWORD WINAPI AMGetErrorTextA(HRESULT hr, LPSTR pszbuf, DWORD dwBufLen)
{
LPCSTR lpszRes;
DWORD len;
lpszRes = hresult_to_string( hr );
if ( lpszRes == NULL )
return 0;
len = (DWORD)(strlen(lpszRes)+1);
if ( len > dwBufLen )
return 0;
memcpy( pszbuf, lpszRes, len );
return len;
}
/***********************************************************************
* AMGetErrorTextW (quartz.@)
*/
DWORD WINAPI AMGetErrorTextW(HRESULT hr, LPWSTR pwszbuf, DWORD dwBufLen)
{
CHAR szBuf[MAX_ERROR_TEXT_LEN+1];
DWORD dwLen;
dwLen = AMGetErrorTextA(hr,szBuf,MAX_ERROR_TEXT_LEN);
if ( dwLen == 0 )
return 0;
szBuf[dwLen] = 0;
QUARTZ_strncpyAtoW( pwszbuf, szBuf, dwBufLen );
return lstrlenW( pwszbuf );
}
/*
* Implements IBaseFilter. (internal)
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "strmif.h"
#include "vfwmsgs.h"
#include "wine/unicode.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "basefilt.h"
#include "enumunk.h"
static HRESULT WINAPI
CBaseFilterImpl_fnQueryInterface(IBaseFilter* iface,REFIID riid,void** ppobj)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
}
static ULONG WINAPI
CBaseFilterImpl_fnAddRef(IBaseFilter* iface)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->punkControl);
}
static ULONG WINAPI
CBaseFilterImpl_fnRelease(IBaseFilter* iface)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->punkControl);
}
static HRESULT WINAPI
CBaseFilterImpl_fnGetClassID(IBaseFilter* iface,CLSID* pclsid)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->()\n",This);
if ( pclsid == NULL )
return E_POINTER;
memcpy( pclsid, This->pclsidFilter, sizeof(CLSID) );
return NOERROR;
}
static HRESULT WINAPI
CBaseFilterImpl_fnStop(IBaseFilter* iface)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->()\n",This);
EnterCriticalSection( &This->csFilter );
/* FIXME - call OnStop() */
This->fstate = State_Stopped;
LeaveCriticalSection( &This->csFilter );
return NOERROR;
}
static HRESULT WINAPI
CBaseFilterImpl_fnPause(IBaseFilter* iface)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->()\n",This);
EnterCriticalSection( &This->csFilter );
/* FIXME - call OnPause() */
This->fstate = State_Paused;
LeaveCriticalSection( &This->csFilter );
return NOERROR;
}
static HRESULT WINAPI
CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->()\n",This);
EnterCriticalSection( &This->csFilter );
/* FIXME - call OnRun() */
This->rtStart = rtStart;
This->fstate = State_Running;
LeaveCriticalSection( &This->csFilter );
return NOERROR;
}
static HRESULT WINAPI
CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->(%p)\n",This,pState);
if ( pState == NULL )
return E_POINTER;
/* FIXME - ignore 'intermediate state' now */
EnterCriticalSection( &This->csFilter );
*pState = This->fstate;
LeaveCriticalSection( &This->csFilter );
return NOERROR;
}
static HRESULT WINAPI
CBaseFilterImpl_fnSetSyncSource(IBaseFilter* iface,IReferenceClock* pobjClock)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->(%p)\n",This,pobjClock);
EnterCriticalSection( &This->csFilter );
if ( This->pClock != NULL )
{
IReferenceClock_Release( This->pClock );
This->pClock = NULL;
}
This->pClock = pobjClock;
if ( pobjClock != NULL )
IReferenceClock_AddRef( pobjClock );
LeaveCriticalSection( &This->csFilter );
return NOERROR;
}
static HRESULT WINAPI
CBaseFilterImpl_fnGetSyncSource(IBaseFilter* iface,IReferenceClock** ppobjClock)
{
ICOM_THIS(CBaseFilterImpl,iface);
HRESULT hr = VFW_E_NO_CLOCK;
TRACE("(%p)->(%p)\n",This,ppobjClock);
if ( ppobjClock == NULL )
return E_POINTER;
EnterCriticalSection( &This->csFilter );
*ppobjClock = This->pClock;
if ( This->pClock != NULL )
{
hr = NOERROR;
IReferenceClock_AddRef( This->pClock );
}
LeaveCriticalSection( &This->csFilter );
return hr;
}
static HRESULT WINAPI
CBaseFilterImpl_fnEnumPins(IBaseFilter* iface,IEnumPins** ppenum)
{
ICOM_THIS(CBaseFilterImpl,iface);
HRESULT hr = E_FAIL;
QUARTZ_CompList* pListPins;
QUARTZ_CompListItem* pItem;
IUnknown* punkPin;
TRACE("(%p)->(%p)\n",This,ppenum);
if ( ppenum == NULL )
return E_POINTER;
*ppenum = NULL;
pListPins = QUARTZ_CompList_Alloc();
if ( pListPins == NULL )
return E_OUTOFMEMORY;
QUARTZ_CompList_Lock( This->pInPins );
QUARTZ_CompList_Lock( This->pOutPins );
pItem = QUARTZ_CompList_GetFirst( This->pInPins );
while ( pItem != NULL )
{
punkPin = QUARTZ_CompList_GetItemPtr( pItem );
hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
if ( FAILED(hr) )
goto err;
pItem = QUARTZ_CompList_GetNext( This->pInPins, pItem );
}
pItem = QUARTZ_CompList_GetFirst( This->pOutPins );
while ( pItem != NULL )
{
punkPin = QUARTZ_CompList_GetItemPtr( pItem );
hr = QUARTZ_CompList_AddComp( pListPins, punkPin, NULL, 0 );
if ( FAILED(hr) )
goto err;
pItem = QUARTZ_CompList_GetNext( This->pOutPins, pItem );
}
hr = QUARTZ_CreateEnumUnknown(
&IID_IEnumPins, (void**)ppenum, pListPins );
err:
QUARTZ_CompList_Unlock( This->pInPins );
QUARTZ_CompList_Unlock( This->pOutPins );
QUARTZ_CompList_Free( pListPins );
return hr;
}
static HRESULT WINAPI
CBaseFilterImpl_fnFindPin(IBaseFilter* iface,LPCWSTR lpwszId,IPin** ppobj)
{
ICOM_THIS(CBaseFilterImpl,iface);
FIXME("(%p)->(%s,%p) stub!\n",This,debugstr_w(lpwszId),ppobj);
if ( ppobj == NULL )
return E_POINTER;
return E_NOTIMPL;
}
static HRESULT WINAPI
CBaseFilterImpl_fnQueryFilterInfo(IBaseFilter* iface,FILTER_INFO* pfi)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->(%p)\n",This,pfi);
if ( pfi == NULL )
return E_POINTER;
EnterCriticalSection( &This->csFilter );
if ( This->cbNameGraph <= sizeof(WCHAR)*MAX_FILTER_NAME )
{
memcpy( pfi->achName, This->pwszNameGraph, This->cbNameGraph );
}
else
{
memcpy( pfi->achName, This->pwszNameGraph,
sizeof(WCHAR)*MAX_FILTER_NAME );
pfi->achName[MAX_FILTER_NAME-1] = (WCHAR)0;
}
pfi->pGraph = This->pfg;
if ( pfi->pGraph != NULL )
IFilterGraph_AddRef(pfi->pGraph);
LeaveCriticalSection( &This->csFilter );
return NOERROR;
}
static HRESULT WINAPI
CBaseFilterImpl_fnJoinFilterGraph(IBaseFilter* iface,IFilterGraph* pfg,LPCWSTR lpwszName)
{
ICOM_THIS(CBaseFilterImpl,iface);
HRESULT hr;
TRACE("(%p)->(%p,%s)\n",This,pfg,debugstr_w(lpwszName));
EnterCriticalSection( &This->csFilter );
if ( This->pwszNameGraph != NULL )
{
QUARTZ_FreeMem( This->pwszNameGraph );
This->pwszNameGraph = NULL;
This->cbNameGraph = 0;
}
This->pfg = pfg;
This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszName)+1);
This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
if ( This->pwszNameGraph == NULL )
{
hr = E_OUTOFMEMORY;
goto err;
}
memcpy( This->pwszNameGraph, lpwszName, This->cbNameGraph );
hr = NOERROR;
err:
LeaveCriticalSection( &This->csFilter );
return hr;
}
static HRESULT WINAPI
CBaseFilterImpl_fnQueryVendorInfo(IBaseFilter* iface,LPWSTR* lpwszVendor)
{
ICOM_THIS(CBaseFilterImpl,iface);
TRACE("(%p)->(%p)\n",This,lpwszVendor);
/* E_NOTIMPL means 'no vender information'. */
return E_NOTIMPL;
}
static ICOM_VTABLE(IBaseFilter) ibasefilter =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
CBaseFilterImpl_fnQueryInterface,
CBaseFilterImpl_fnAddRef,
CBaseFilterImpl_fnRelease,
/* IPersist fields */
CBaseFilterImpl_fnGetClassID,
/* IMediaFilter fields */
CBaseFilterImpl_fnStop,
CBaseFilterImpl_fnPause,
CBaseFilterImpl_fnRun,
CBaseFilterImpl_fnGetState,
CBaseFilterImpl_fnSetSyncSource,
CBaseFilterImpl_fnGetSyncSource,
/* IBaseFilter fields */
CBaseFilterImpl_fnEnumPins,
CBaseFilterImpl_fnFindPin,
CBaseFilterImpl_fnQueryFilterInfo,
CBaseFilterImpl_fnJoinFilterGraph,
CBaseFilterImpl_fnQueryVendorInfo,
};
HRESULT CBaseFilterImpl_InitIBaseFilter(
CBaseFilterImpl* This, IUnknown* punkControl,
const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph )
{
TRACE("(%p,%p)\n",This,punkControl);
if ( punkControl == NULL )
{
ERR( "punkControl must not be NULL\n" );
return E_INVALIDARG;
}
ICOM_VTBL(This) = &ibasefilter;
This->punkControl = punkControl;
This->pclsidFilter = pclsidFilter;
This->pInPins = NULL;
This->pOutPins = NULL;
This->pfg = NULL;
This->cbNameGraph = 0;
This->pwszNameGraph = NULL;
This->pClock = NULL;
This->rtStart = 0;
This->fstate = State_Stopped;
This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszNameGraph)+1);
This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
if ( This->pwszNameGraph == NULL )
return E_OUTOFMEMORY;
memcpy( This->pwszNameGraph, lpwszNameGraph, This->cbNameGraph );
InitializeCriticalSection( &This->csFilter );
return NOERROR;
}
void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This )
{
QUARTZ_CompListItem* pListItem;
IPin* pPin;
TRACE("(%p)\n",This);
if ( This->pInPins != NULL )
{
while ( 1 )
{
pListItem = QUARTZ_CompList_GetFirst( This->pInPins );
if ( pListItem == NULL )
break;
pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
QUARTZ_CompList_RemoveComp( This->pInPins, (IUnknown*)pPin );
IPin_Release( pPin );
}
QUARTZ_CompList_Free( This->pInPins );
This->pInPins = NULL;
}
if ( This->pOutPins != NULL )
{
while ( 1 )
{
pListItem = QUARTZ_CompList_GetFirst( This->pOutPins );
if ( pListItem == NULL )
break;
pPin = (IPin*)QUARTZ_CompList_GetItemPtr( pListItem );
QUARTZ_CompList_RemoveComp( This->pOutPins, (IUnknown*)pPin );
IPin_Release( pPin );
}
QUARTZ_CompList_Free( This->pOutPins );
This->pOutPins = NULL;
}
if ( This->pwszNameGraph != NULL )
{
QUARTZ_FreeMem( This->pwszNameGraph );
This->pwszNameGraph = NULL;
}
if ( This->pClock != NULL )
{
IReferenceClock_Release( This->pClock );
This->pClock = NULL;
}
DeleteCriticalSection( &This->csFilter );
}
#ifndef WINE_DSHOW_BASEFILT_H
#define WINE_DSHOW_BASEFILT_H
/*
* The following interfaces must be used as a part of aggregation.
* The punkControl must not be NULL since all IUnknown methods are
* implemented only for aggregation.
*/
/*
* implements IBaseFilter (internal)
*
* a base class for implementing IBaseFilter.
*/
#include "complist.h"
typedef struct CBaseFilterImpl
{
ICOM_VFIELD(IBaseFilter);
/* IUnknown fields */
IUnknown* punkControl;
/* IBaseFilter fields */
CRITICAL_SECTION csFilter;
const CLSID* pclsidFilter;
QUARTZ_CompList* pInPins; /* a list of IPin-s. */
QUARTZ_CompList* pOutPins; /* a list of IPin-s. */
IFilterGraph* pfg;
DWORD cbNameGraph;
WCHAR* pwszNameGraph;
IReferenceClock* pClock;
REFERENCE_TIME rtStart;
FILTER_STATE fstate;
} CBaseFilterImpl;
HRESULT CBaseFilterImpl_InitIBaseFilter(
CBaseFilterImpl* This, IUnknown* punkControl,
const CLSID* pclsidFilter, LPCWSTR lpwszNameGraph );
void CBaseFilterImpl_UninitIBaseFilter( CBaseFilterImpl* This );
/*
* Implements IPin and IMemInputPin. (internal)
*
* a base class for implementing IPin.
*/
typedef struct CPinBaseImpl
{
ICOM_VFIELD(IPin);
/* IUnknown fields */
IUnknown* punkControl;
/* IPin fields */
DWORD cbIdLen;
WCHAR* pwszId;
BOOL bOutput;
CRITICAL_SECTION csPin;
CBaseFilterImpl* pFilter;
IPin* pPinConnectedTo;
AM_MEDIA_TYPE* pmtConn;
} CPinBaseImpl;
typedef struct CMemInputPinBaseImpl
{
ICOM_VFIELD(IMemInputPin);
/* IUnknown fields */
IUnknown* punkControl;
/* IMemInputPin fields */
CRITICAL_SECTION* pcsPin;
IMemAllocator* pAllocator;
BOOL bReadonly;
} CMemInputPinBaseImpl;
HRESULT CPinBaseImpl_InitIPin(
CPinBaseImpl* This, IUnknown* punkControl,
CBaseFilterImpl* pFilter, LPCWSTR pwszId,
BOOL bOutput );
void CPinBaseImpl_UninitIPin( CPinBaseImpl* This );
HRESULT CMemInputPinBaseImpl_InitIMemInputPin(
CMemInputPinBaseImpl* This, IUnknown* punkControl,
CRITICAL_SECTION* pcsPin
);
void CMemInputPinBaseImpl_UninitIMemInputPin(
CMemInputPinBaseImpl* This );
#endif /* WINE_DSHOW_BASEFILT_H */
/* /*
* Implementation of CLSID_SystemDeviceEnum. * Implementation of CLSID_SystemDeviceEnum.
* *
* FIXME - stub. * FIXME - not tested enough.
* *
* hidenori@a2.ctktv.ne.jp * hidenori@a2.ctktv.ne.jp
*/ */
...@@ -12,18 +12,33 @@ ...@@ -12,18 +12,33 @@
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winreg.h"
#include "winerror.h" #include "winerror.h"
#include "wine/obj_base.h" #include "wine/obj_base.h"
#include "wine/obj_oleaut.h" #include "objidl.h"
#include "oleidl.h"
#include "ocidl.h"
#include "strmif.h" #include "strmif.h"
#include "control.h" #include "control.h"
#include "uuids.h" #include "uuids.h"
#include "wine/unicode.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz); DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h" #include "quartz_private.h"
#include "devenum.h" #include "devenum.h"
#include "regsvr.h"
#include "enumunk.h"
#include "complist.h"
#include "devmon.h"
/***************************************************************************
*
* new/delete for CLSID_SystemDeviceEnum
*
*/
/* can I use offsetof safely? - FIXME? */ /* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry IFEntries[] = static QUARTZ_IFEntry IFEntries[] =
...@@ -68,3 +83,159 @@ HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj) ...@@ -68,3 +83,159 @@ HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj)
return S_OK; return S_OK;
} }
/***************************************************************************
*
* CSysDevEnum::ICreateDevEnum
*
*/
static HRESULT WINAPI
ICreateDevEnum_fnQueryInterface(ICreateDevEnum* iface,REFIID riid,void** ppobj)
{
CSysDevEnum_THIS(iface,createdevenum);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
ICreateDevEnum_fnAddRef(ICreateDevEnum* iface)
{
CSysDevEnum_THIS(iface,createdevenum);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
ICreateDevEnum_fnRelease(ICreateDevEnum* iface)
{
CSysDevEnum_THIS(iface,createdevenum);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDeviceClass,IEnumMoniker** ppobj, DWORD dwFlags)
{
CSysDevEnum_THIS(iface,createdevenum);
HRESULT hr;
HKEY hKey;
QUARTZ_CompList* pMonList;
IMoniker* pMon;
DWORD dwIndex;
LONG lr;
WCHAR wszPath[ 1024 ];
DWORD dwLen;
DWORD dwNameMax;
DWORD cbName;
FILETIME ftLastWrite;
TRACE("(%p)->(%s,%p,%08lx)\n",This,
debugstr_guid(rclsidDeviceClass),ppobj,dwFlags);
if ( dwFlags != 0 )
{
FIXME("unknown flags %08lx\n",dwFlags);
return E_NOTIMPL;
}
if ( ppobj == NULL )
return E_POINTER;
*ppobj = NULL;
hr = QUARTZ_CreateCLSIDPath(
wszPath, sizeof(wszPath)/sizeof(wszPath[0]),
rclsidDeviceClass, QUARTZ_wszInstance );
if ( FAILED(hr) )
return hr;
if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath,
0, KEY_READ, &hKey ) != ERROR_SUCCESS )
return E_FAIL;
dwLen = strlenW(wszPath);
wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;
pMonList = QUARTZ_CompList_Alloc();
if ( pMonList == NULL )
{
hr = E_OUTOFMEMORY;
goto err;
}
/* enumerate all subkeys. */
dwIndex = 0;
while ( 1 )
{
cbName = dwNameMax;
lr = RegEnumKeyExW(
hKey, dwIndex, &wszPath[dwLen], &cbName,
NULL, NULL, NULL, &ftLastWrite );
if ( lr == ERROR_NO_MORE_ITEMS )
break;
if ( lr != ERROR_SUCCESS )
{
hr = E_FAIL;
goto err;
}
hr = QUARTZ_CreateDeviceMoniker(
HKEY_CLASSES_ROOT, wszPath, &pMon );
if ( FAILED(hr) )
goto err;
hr = QUARTZ_CompList_AddComp(
pMonList, (IUnknown*)pMon, NULL, 0 );
IMoniker_Release( pMon );
if ( FAILED(hr) )
goto err;
dwIndex ++;
}
/* create an enumerator. */
hr = QUARTZ_CreateEnumUnknown(
&IID_IEnumMoniker, (void**)ppobj, pMonList );
if ( FAILED(hr) )
goto err;
hr = S_OK;
err:
if ( pMonList != NULL )
QUARTZ_CompList_Free( pMonList );
RegCloseKey( hKey );
return hr;
}
static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
ICreateDevEnum_fnQueryInterface,
ICreateDevEnum_fnAddRef,
ICreateDevEnum_fnRelease,
/* ICreateDevEnum fields */
ICreateDevEnum_fnCreateClassEnumerator,
};
HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
{
TRACE("(%p)\n",psde);
ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;
return NOERROR;
}
void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
{
TRACE("(%p)\n",psde);
}
/* /*
* Implements IMoniker for CLSID_CDeviceMoniker. * Implements IMoniker for CLSID_CDeviceMoniker.
* Implements IPropertyBag. (internal)
* *
* hidenori@a2.ctktv.ne.jp * hidenori@a2.ctktv.ne.jp
*/ */
...@@ -26,10 +27,15 @@ DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -26,10 +27,15 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h" #include "quartz_private.h"
#include "devmon.h" #include "devmon.h"
#include "monprop.h"
#include "regsvr.h" #include "regsvr.h"
/***************************************************************************
*
* CDeviceMoniker::IMoniker
*
*/
static HRESULT WINAPI static HRESULT WINAPI
IMoniker_fnQueryInterface(IMoniker* iface,REFIID riid,void** ppobj) IMoniker_fnQueryInterface(IMoniker* iface,REFIID riid,void** ppobj)
{ {
...@@ -149,8 +155,11 @@ static HRESULT WINAPI IMoniker_fnBindToObject(IMoniker* iface,IBindCtx* pbc, IMo ...@@ -149,8 +155,11 @@ static HRESULT WINAPI IMoniker_fnBindToObject(IMoniker* iface,IBindCtx* pbc, IMo
if ( FAILED(hr) ) if ( FAILED(hr) )
return hr; return hr;
return CoCreateInstance( hr = CoCreateInstance(
&clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult ); &clsid, NULL, CLSCTX_INPROC_SERVER, riid, ppvResult );
TRACE( "hr = %08lx\n", hr );
return hr;
} }
static HRESULT WINAPI IMoniker_fnBindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) static HRESULT WINAPI IMoniker_fnBindToStorage(IMoniker* iface,IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult)
...@@ -373,6 +382,11 @@ static void CDeviceMoniker_UninitIMoniker( ...@@ -373,6 +382,11 @@ static void CDeviceMoniker_UninitIMoniker(
QUARTZ_FreeMem( pdm->m_pwszPath ); QUARTZ_FreeMem( pdm->m_pwszPath );
} }
/***************************************************************************
*
* new/delete for CDeviceMoniker
*
*/
static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk) static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk)
{ {
...@@ -382,7 +396,7 @@ static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk) ...@@ -382,7 +396,7 @@ static void QUARTZ_DestroyDeviceMoniker(IUnknown* punk)
} }
/* can I use offsetof safely? - FIXME? */ /* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry IFEntries[] = static QUARTZ_IFEntry CDeviceMoniker_IFEntries[] =
{ {
{ &IID_IPersist, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) }, { &IID_IPersist, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
{ &IID_IPersistStream, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) }, { &IID_IPersistStream, offsetof(CDeviceMoniker,moniker)-offsetof(CDeviceMoniker,unk) },
...@@ -410,8 +424,8 @@ HRESULT QUARTZ_CreateDeviceMoniker( ...@@ -410,8 +424,8 @@ HRESULT QUARTZ_CreateDeviceMoniker(
return hr; return hr;
} }
pdm->unk.pEntries = IFEntries; pdm->unk.pEntries = CDeviceMoniker_IFEntries;
pdm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]); pdm->unk.dwEntries = sizeof(CDeviceMoniker_IFEntries)/sizeof(CDeviceMoniker_IFEntries[0]);
pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker; pdm->unk.pOnFinalRelease = &QUARTZ_DestroyDeviceMoniker;
*ppMoniker = (IMoniker*)(&pdm->moniker); *ppMoniker = (IMoniker*)(&pdm->moniker);
...@@ -420,3 +434,205 @@ HRESULT QUARTZ_CreateDeviceMoniker( ...@@ -420,3 +434,205 @@ HRESULT QUARTZ_CreateDeviceMoniker(
} }
/***************************************************************************
*
* CRegPropertyBag::IPropertyBag
*
*/
static HRESULT WINAPI
IPropertyBag_fnQueryInterface(IPropertyBag* iface,REFIID riid,void** ppobj)
{
CRegPropertyBag_THIS(iface,propbag);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IPropertyBag_fnAddRef(IPropertyBag* iface)
{
CRegPropertyBag_THIS(iface,propbag);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IPropertyBag_fnRelease(IPropertyBag* iface)
{
CRegPropertyBag_THIS(iface,propbag);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IPropertyBag_fnRead(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar,IErrorLog* pLog)
{
CRegPropertyBag_THIS(iface,propbag);
LONG lr;
DWORD dwSize;
DWORD dwValueType;
TRACE("(%p)->(%s,%p,%p)\n",This,
debugstr_w(lpszPropName),pVar,pLog);
if ( lpszPropName == NULL || pVar == NULL )
return E_POINTER;
dwSize = 0;
lr = RegQueryValueExW(
This->m_hKey, lpszPropName, NULL,
&dwValueType, NULL, &dwSize );
if ( lr != ERROR_SUCCESS )
{
TRACE( "RegQueryValueExW failed.\n" );
return E_INVALIDARG;
}
switch ( dwValueType )
{
case REG_SZ:
TRACE( "REG_SZ / length = %lu\n", dwSize );
if ( pVar->n1.n2.vt == VT_EMPTY )
pVar->n1.n2.vt = VT_BSTR;
if ( pVar->n1.n2.vt != VT_BSTR )
{
TRACE( "type of VARIANT is not BSTR\n" );
return E_FAIL;
}
pVar->n1.n2.n3.bstrVal = SysAllocStringByteLen(
NULL, dwSize );
if ( pVar->n1.n2.n3.bstrVal == NULL )
{
TRACE( "out of memory.\n" );
return E_OUTOFMEMORY;
}
lr = RegQueryValueExW(
This->m_hKey, lpszPropName, NULL,
&dwValueType,
(BYTE*)pVar->n1.n2.n3.bstrVal, &dwSize );
if ( lr != ERROR_SUCCESS )
{
TRACE( "failed to query value\n" );
SysFreeString(pVar->n1.n2.n3.bstrVal);
return E_FAIL;
}
TRACE( "value is BSTR; %s\n", debugstr_w(pVar->n1.n2.n3.bstrVal) );
break;
default:
FIXME("(%p)->(%s,%p,%p) - unsupported value type.\n",This,
debugstr_w(lpszPropName),pVar,pLog);
return E_FAIL;
}
TRACE( "returned successfully.\n" );
return NOERROR;
}
static HRESULT WINAPI
IPropertyBag_fnWrite(IPropertyBag* iface,LPCOLESTR lpszPropName,VARIANT* pVar)
{
CRegPropertyBag_THIS(iface,propbag);
FIXME("(%p)->(%s,%p) stub!\n",This,
debugstr_w(lpszPropName),pVar);
if ( lpszPropName == NULL || pVar == NULL )
return E_POINTER;
return E_NOTIMPL;
}
static ICOM_VTABLE(IPropertyBag) ipropbag =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IPropertyBag_fnQueryInterface,
IPropertyBag_fnAddRef,
IPropertyBag_fnRelease,
/* IPropertyBag fields */
IPropertyBag_fnRead,
IPropertyBag_fnWrite,
};
static HRESULT CRegPropertyBag_InitIPropertyBag(
CRegPropertyBag* prpb, HKEY hkRoot, LPCWSTR lpKeyPath )
{
ICOM_VTBL(&prpb->propbag) = &ipropbag;
if ( RegOpenKeyExW(
hkRoot, lpKeyPath, 0,
KEY_ALL_ACCESS, &prpb->m_hKey ) != ERROR_SUCCESS )
return E_FAIL;
return NOERROR;
}
static void CRegPropertyBag_UninitIPropertyBag(
CRegPropertyBag* prpb )
{
RegCloseKey( prpb->m_hKey );
}
/***************************************************************************
*
* new/delete for CRegPropertyBag
*
*/
static void QUARTZ_DestroyRegPropertyBag(IUnknown* punk)
{
CRegPropertyBag_THIS(punk,unk);
CRegPropertyBag_UninitIPropertyBag(This);
}
/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry CRegPropertyBag_IFEntries[] =
{
{ &IID_IPropertyBag, offsetof(CRegPropertyBag,propbag)-offsetof(CRegPropertyBag,unk) },
};
HRESULT QUARTZ_CreateRegPropertyBag(
HKEY hkRoot, LPCWSTR lpKeyPath,
IPropertyBag** ppPropBag )
{
CRegPropertyBag* prpb;
HRESULT hr;
TRACE("(%08x,%s,%p)\n",hkRoot,debugstr_w(lpKeyPath),ppPropBag );
prpb = (CRegPropertyBag*)QUARTZ_AllocObj( sizeof(CRegPropertyBag) );
if ( prpb == NULL )
return E_OUTOFMEMORY;
QUARTZ_IUnkInit( &prpb->unk, NULL );
hr = CRegPropertyBag_InitIPropertyBag( prpb, hkRoot, lpKeyPath );
if ( FAILED(hr) )
{
QUARTZ_FreeObj( prpb );
return hr;
}
prpb->unk.pEntries = CRegPropertyBag_IFEntries;
prpb->unk.dwEntries = sizeof(CRegPropertyBag_IFEntries)/sizeof(CRegPropertyBag_IFEntries[0]);
prpb->unk.pOnFinalRelease = &QUARTZ_DestroyRegPropertyBag;
*ppPropBag = (IPropertyBag*)(&prpb->propbag);
return S_OK;
}
...@@ -33,4 +33,34 @@ HRESULT QUARTZ_CreateDeviceMoniker( ...@@ -33,4 +33,34 @@ HRESULT QUARTZ_CreateDeviceMoniker(
IMoniker** ppMoniker ); IMoniker** ppMoniker );
/*
implements IPropertyBag for accessing registry.
- At least, the following interfaces should be implemented:
IUnknown
+ IPropertyBag
*/
#include "iunk.h"
typedef struct DMON_IPropertyBagImpl
{
ICOM_VFIELD(IPropertyBag);
} DMON_IPropertyBagImpl;
typedef struct CRegPropertyBag
{
QUARTZ_IUnkImpl unk;
DMON_IPropertyBagImpl propbag;
/* IPropertyBag fields */
HKEY m_hKey;
} CRegPropertyBag;
#define CRegPropertyBag_THIS(iface,member) CRegPropertyBag* This = (CRegPropertyBag*)(((char*)iface)-offsetof(CRegPropertyBag,member))
HRESULT QUARTZ_CreateRegPropertyBag(
HKEY hkRoot, LPCWSTR lpKeyPath,
IPropertyBag** ppPropBag );
#endif /* WINE_DSHOW_DEVMON_H */ #endif /* WINE_DSHOW_DEVMON_H */
...@@ -177,6 +177,7 @@ IEnumUnknown_fnClone(IEnumUnknown* iface,IEnumUnknown** ppunk) ...@@ -177,6 +177,7 @@ IEnumUnknown_fnClone(IEnumUnknown* iface,IEnumUnknown** ppunk)
This->IFEntries[0].piid, This->IFEntries[0].piid,
(void**)ppunk, (void**)ppunk,
This->pCompList ); This->pCompList );
FIXME( "current pointer must be seeked correctly\n" );
QUARTZ_CompList_Unlock( This->pCompList ); QUARTZ_CompList_Unlock( This->pCompList );
......
/*
* Implementation of IPersist for FilterGraph.
*
* FIXME - stub.
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "wine/obj_oleaut.h"
#include "strmif.h"
#include "control.h"
#include "uuids.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "fgraph.h"
static HRESULT WINAPI
IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IPersist_fnAddRef(IPersist* iface)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IPersist_fnRelease(IPersist* iface)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
if ( pclsid == NULL )
return E_POINTER;
memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) );
return E_NOTIMPL;
}
static ICOM_VTABLE(IPersist) ipersist =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IPersist_fnQueryInterface,
IPersist_fnAddRef,
IPersist_fnRelease,
/* IPersist fields */
IPersist_fnGetClassID,
};
HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
ICOM_VTBL(&pfg->persist) = &ipersist;
return NOERROR;
}
void CFilterGraph_UninitIPersist( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
}
/* /*
* Implementation of IMediaEvent[Ex] for FilterGraph. * CLSID_FilterGraph event handling.
*
* FIXME - stub.
* *
* hidenori@a2.ctktv.ne.jp * hidenori@a2.ctktv.ne.jp
*/ */
...@@ -17,7 +15,9 @@ ...@@ -17,7 +15,9 @@
#include "wine/obj_oleaut.h" #include "wine/obj_oleaut.h"
#include "strmif.h" #include "strmif.h"
#include "control.h" #include "control.h"
#include "evcode.h"
#include "uuids.h" #include "uuids.h"
#include "vfwmsgs.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz); DEFAULT_DEBUG_CHANNEL(quartz);
...@@ -25,7 +25,22 @@ DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -25,7 +25,22 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h" #include "quartz_private.h"
#include "fgraph.h" #include "fgraph.h"
#define EVENTQUEUE_BLOCKSIZE 16
#define EVENTQUEUE_MAX 1024
struct FilterGraph_MEDIAEVENT
{
long lEventCode;
LONG_PTR lParam1;
LONG_PTR lParam2;
};
/***************************************************************************
*
* CLSID_FilterGraph::IMediaEvent[Ex]
*
*/
static HRESULT WINAPI static HRESULT WINAPI
IMediaEventEx_fnQueryInterface(IMediaEventEx* iface,REFIID riid,void** ppobj) IMediaEventEx_fnQueryInterface(IMediaEventEx* iface,REFIID riid,void** ppobj)
...@@ -111,23 +126,112 @@ IMediaEventEx_fnGetEventHandle(IMediaEventEx* iface,OAEVENT* hEvent) ...@@ -111,23 +126,112 @@ IMediaEventEx_fnGetEventHandle(IMediaEventEx* iface,OAEVENT* hEvent)
} }
static HRESULT WINAPI static HRESULT WINAPI
IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* lEventCode,LONG_PTR* plParam1,LONG_PTR* plParam2,long lTimeOut) IMediaEventEx_fnGetEvent(IMediaEventEx* iface,long* plEventCode,LONG_PTR* plParam1,LONG_PTR* plParam2,long lTimeOut)
{ {
CFilterGraph_THIS(iface,mediaevent); CFilterGraph_THIS(iface,mediaevent);
ULONG cbQueued;
FIXME("(%p)->() stub!\n",This); DWORD dw;
DWORD dwStart;
return E_NOTIMPL; HRESULT hr;
FilterGraph_MEDIAEVENT* pEvent;
TRACE("(%p)->(%p,%p,%p,%ld)\n",This,plEventCode,
plParam1,plParam2,lTimeOut);
if ( plEventCode == NULL || plParam1 == NULL || plParam2 == NULL )
return E_POINTER;
while ( 1 )
{
dwStart = GetTickCount();
dw = WaitForSingleObject( This->m_hMediaEvent, lTimeOut );
if ( dw == WAIT_TIMEOUT )
return VFW_E_TIMEOUT;
if ( dw != WAIT_OBJECT_0 )
return E_FAIL;
EnterCriticalSection( &This->m_csMediaEvents );
hr = S_FALSE;
if ( This->m_cbMediaEventsMax > 0 )
{
cbQueued =
(This->m_cbMediaEventsMax +
This->m_cbMediaEventsPut - This->m_cbMediaEventsGet) %
This->m_cbMediaEventsMax;
if ( cbQueued > 0 )
{
pEvent = &This->m_pMediaEvents[This->m_cbMediaEventsGet];
*plEventCode = pEvent->lEventCode;
*plParam1 = pEvent->lParam1;
*plParam2 = pEvent->lParam2;
This->m_cbMediaEventsGet = (This->m_cbMediaEventsGet + 1) %
This->m_cbMediaEventsMax;
hr = NOERROR;
}
}
LeaveCriticalSection( &This->m_csMediaEvents );
if ( hr != S_FALSE )
return hr;
if ( lTimeOut != INFINITE )
{
lTimeOut -= GetTickCount() - dwStart;
if ( lTimeOut < 0 )
return VFW_E_TIMEOUT;
}
}
} }
static HRESULT WINAPI static HRESULT WINAPI
IMediaEventEx_fnWaitForCompletion(IMediaEventEx* iface,long lTimeOut,long* plEventCode) IMediaEventEx_fnWaitForCompletion(IMediaEventEx* iface,long lTimeOut,long* plEventCode)
{ {
CFilterGraph_THIS(iface,mediaevent); CFilterGraph_THIS(iface,mediaevent);
HRESULT hr;
FIXME("(%p)->() stub!\n",This); long lEventCode;
LONG_PTR lParam1;
return E_NOTIMPL; LONG_PTR lParam2;
DWORD dwTimePrev;
DWORD dwTimeCur;
TRACE("(%p)->(%ld,%p)\n",This,lTimeOut,plEventCode);
if ( plEventCode == NULL )
return E_POINTER;
*plEventCode = 0;
dwTimePrev = GetTickCount();
while ( 1 )
{
hr = IMediaEventEx_GetEvent(
CFilterGraph_IMediaEventEx(This),
&lEventCode,&lParam1,&lParam2,lTimeOut);
if ( hr == VFW_E_TIMEOUT )
hr = E_ABORT;
if ( hr != NOERROR )
return hr;
IMediaEventEx_FreeEventParams(
CFilterGraph_IMediaEventEx(This),
lEventCode,lParam1,lParam2);
if ( lEventCode == EC_COMPLETE ||
lEventCode == EC_ERRORABORT ||
lEventCode == EC_USERABORT )
{
*plEventCode = lEventCode;
return NOERROR;
}
if ( lTimeOut != INFINITE )
{
dwTimeCur = GetTickCount();
lTimeOut -= dwTimeCur - dwTimePrev;
dwTimePrev = dwTimeCur;
if ( lTimeOut < 0 )
return E_ABORT;
}
}
} }
static HRESULT WINAPI static HRESULT WINAPI
...@@ -227,12 +331,116 @@ HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg ) ...@@ -227,12 +331,116 @@ HRESULT CFilterGraph_InitIMediaEventEx( CFilterGraph* pfg )
if ( pfg->m_hMediaEvent == (HANDLE)NULL ) if ( pfg->m_hMediaEvent == (HANDLE)NULL )
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
InitializeCriticalSection( &pfg->m_csMediaEvents );
pfg->m_pMediaEvents = NULL;
pfg->m_cbMediaEventsPut = 0;
pfg->m_cbMediaEventsGet = 0;
pfg->m_cbMediaEventsMax = 0;
return NOERROR; return NOERROR;
} }
void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg ) void CFilterGraph_UninitIMediaEventEx( CFilterGraph* pfg )
{ {
HRESULT hr;
long lEventCode;
LONG_PTR lParam1;
LONG_PTR lParam2;
TRACE("(%p)\n",pfg); TRACE("(%p)\n",pfg);
while ( 1 )
{
hr = IMediaEventEx_GetEvent(
CFilterGraph_IMediaEventEx(pfg),
&lEventCode,&lParam1,&lParam2,0);
if ( hr != NOERROR )
break;
IMediaEventEx_FreeEventParams(
CFilterGraph_IMediaEventEx(pfg),
lEventCode,lParam1,lParam2);
}
if ( pfg->m_pMediaEvents != NULL )
{
QUARTZ_FreeMem( pfg->m_pMediaEvents );
pfg->m_pMediaEvents = NULL;
}
DeleteCriticalSection( &pfg->m_csMediaEvents );
CloseHandle( pfg->m_hMediaEvent ); CloseHandle( pfg->m_hMediaEvent );
} }
/***************************************************************************
*
* CLSID_FilterGraph::IMediaEventSink
*
*/
static HRESULT WINAPI
IMediaEventSink_fnQueryInterface(IMediaEventSink* iface,REFIID riid,void** ppobj)
{
CFilterGraph_THIS(iface,mediaeventsink);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IMediaEventSink_fnAddRef(IMediaEventSink* iface)
{
CFilterGraph_THIS(iface,mediaeventsink);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IMediaEventSink_fnRelease(IMediaEventSink* iface)
{
CFilterGraph_THIS(iface,mediaeventsink);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IMediaEventSink_fnNotify(IMediaEventSink* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
{
CFilterGraph_THIS(iface,mediaeventsink);
FIXME("(%p)->(%ld,%08x,%08x) stub!\n",This,lEventCode,lParam1,lParam2);
return E_NOTIMPL;
}
static ICOM_VTABLE(IMediaEventSink) imediaeventsink =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IMediaEventSink_fnQueryInterface,
IMediaEventSink_fnAddRef,
IMediaEventSink_fnRelease,
/* IMediaEventSink fields */
IMediaEventSink_fnNotify,
};
HRESULT CFilterGraph_InitIMediaEventSink( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
ICOM_VTBL(&pfg->mediaeventsink) = &imediaeventsink;
return NOERROR;
}
void CFilterGraph_UninitIMediaEventSink( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
}
...@@ -23,6 +23,12 @@ DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -23,6 +23,12 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h" #include "quartz_private.h"
#include "fgraph.h" #include "fgraph.h"
/***************************************************************************
*
* new/delete for CFilterGraph
*
*/
/* can I use offsetof safely? - FIXME? */ /* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry IFEntries[] = static QUARTZ_IFEntry IFEntries[] =
{ {
...@@ -32,6 +38,7 @@ static QUARTZ_IFEntry IFEntries[] = ...@@ -32,6 +38,7 @@ static QUARTZ_IFEntry IFEntries[] =
{ &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) }, { &IID_IGraphBuilder, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
{ &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) }, { &IID_IFilterGraph2, offsetof(CFilterGraph,fgraph)-offsetof(CFilterGraph,unk) },
{ &IID_IGraphVersion, offsetof(CFilterGraph,graphversion)-offsetof(CFilterGraph,unk) }, { &IID_IGraphVersion, offsetof(CFilterGraph,graphversion)-offsetof(CFilterGraph,unk) },
{ &IID_IGraphConfig, offsetof(CFilterGraph,grphconf)-offsetof(CFilterGraph,unk) },
{ &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) }, { &IID_IMediaControl, offsetof(CFilterGraph,mediacontrol)-offsetof(CFilterGraph,unk) },
{ &IID_IMediaFilter, offsetof(CFilterGraph,mediafilter)-offsetof(CFilterGraph,unk) }, { &IID_IMediaFilter, offsetof(CFilterGraph,mediafilter)-offsetof(CFilterGraph,unk) },
{ &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) }, { &IID_IMediaEvent, offsetof(CFilterGraph,mediaevent)-offsetof(CFilterGraph,unk) },
...@@ -60,6 +67,7 @@ static const struct FGInitEntry FGRAPH_Init[] = ...@@ -60,6 +67,7 @@ static const struct FGInitEntry FGRAPH_Init[] =
FGENT(IDispatch) FGENT(IDispatch)
FGENT(IFilterGraph2) FGENT(IFilterGraph2)
FGENT(IGraphVersion) FGENT(IGraphVersion)
FGENT(IGraphConfig)
FGENT(IMediaControl) FGENT(IMediaControl)
FGENT(IMediaFilter) FGENT(IMediaFilter)
FGENT(IMediaEventEx) FGENT(IMediaEventEx)
...@@ -80,6 +88,8 @@ static void QUARTZ_DestroyFilterGraph(IUnknown* punk) ...@@ -80,6 +88,8 @@ static void QUARTZ_DestroyFilterGraph(IUnknown* punk)
CFilterGraph_THIS(punk,unk); CFilterGraph_THIS(punk,unk);
int i; int i;
TRACE( "(%p)\n", punk );
/* At first, call Stop. */ /* At first, call Stop. */
IMediaControl_Stop( CFilterGraph_IMediaControl(This) ); IMediaControl_Stop( CFilterGraph_IMediaControl(This) );
IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) ); IMediaFilter_Stop( CFilterGraph_IMediaFilter(This) );
...@@ -136,3 +146,78 @@ HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj) ...@@ -136,3 +146,78 @@ HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj)
} }
/***************************************************************************
*
* CFilterGraph::IPersist
*
*/
static HRESULT WINAPI
IPersist_fnQueryInterface(IPersist* iface,REFIID riid,void** ppobj)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IPersist_fnAddRef(IPersist* iface)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IPersist_fnRelease(IPersist* iface)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IPersist_fnGetClassID(IPersist* iface,CLSID* pclsid)
{
CFilterGraph_THIS(iface,persist);
TRACE("(%p)->()\n",This);
if ( pclsid == NULL )
return E_POINTER;
memcpy( pclsid, &CLSID_FilterGraph, sizeof(CLSID) );
return E_NOTIMPL;
}
static ICOM_VTABLE(IPersist) ipersist =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IPersist_fnQueryInterface,
IPersist_fnAddRef,
IPersist_fnRelease,
/* IPersist fields */
IPersist_fnGetClassID,
};
HRESULT CFilterGraph_InitIPersist( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
ICOM_VTBL(&pfg->persist) = &ipersist;
return NOERROR;
}
void CFilterGraph_UninitIPersist( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
}
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
+ IDispatch + IDispatch
+ IFilterGraph - IGraphBuilder - IFilterGraph2 + IFilterGraph - IGraphBuilder - IFilterGraph2
+ IGraphVersion + IGraphVersion
+ IGraphConfig
+ IDispatch - IMediaControl + IDispatch - IMediaControl
+ IPersist - IMediaFilter + IPersist - IMediaFilter
+ IDispatch - IMediaEvent - IMediaEventEx + IDispatch - IMediaEvent - IMediaEventEx
...@@ -50,6 +51,11 @@ typedef struct FG_IGraphVersionImpl ...@@ -50,6 +51,11 @@ typedef struct FG_IGraphVersionImpl
ICOM_VFIELD(IGraphVersion); ICOM_VFIELD(IGraphVersion);
} FG_IGraphVersionImpl; } FG_IGraphVersionImpl;
typedef struct FG_IGraphConfigImpl
{
ICOM_VFIELD(IGraphConfig);
} FG_IGraphConfigImpl;
typedef struct FG_IMediaControlImpl typedef struct FG_IMediaControlImpl
{ {
ICOM_VFIELD(IMediaControl); ICOM_VFIELD(IMediaControl);
...@@ -95,6 +101,7 @@ typedef struct FG_IVideoWindowImpl ...@@ -95,6 +101,7 @@ typedef struct FG_IVideoWindowImpl
ICOM_VFIELD(IVideoWindow); ICOM_VFIELD(IVideoWindow);
} FG_IVideoWindowImpl; } FG_IVideoWindowImpl;
typedef struct FilterGraph_MEDIAEVENT FilterGraph_MEDIAEVENT;
typedef struct CFilterGraph typedef struct CFilterGraph
{ {
...@@ -103,6 +110,7 @@ typedef struct CFilterGraph ...@@ -103,6 +110,7 @@ typedef struct CFilterGraph
FG_IDispatchImpl disp; FG_IDispatchImpl disp;
FG_IFilterGraph2Impl fgraph; FG_IFilterGraph2Impl fgraph;
FG_IGraphVersionImpl graphversion; FG_IGraphVersionImpl graphversion;
FG_IGraphConfigImpl grphconf;
FG_IMediaControlImpl mediacontrol; FG_IMediaControlImpl mediacontrol;
FG_IMediaFilterImpl mediafilter; FG_IMediaFilterImpl mediafilter;
FG_IMediaEventImpl mediaevent; FG_IMediaEventImpl mediaevent;
...@@ -123,8 +131,15 @@ typedef struct CFilterGraph ...@@ -123,8 +131,15 @@ typedef struct CFilterGraph
/* IMediaFilter fields. */ /* IMediaFilter fields. */
CRITICAL_SECTION m_csGraphState; CRITICAL_SECTION m_csGraphState;
FILTER_STATE m_stateGraph; /* must NOT accessed directly! */ FILTER_STATE m_stateGraph; /* must NOT accessed directly! */
CRITICAL_SECTION m_csClock;
IReferenceClock* m_pClock;
/* IMediaEvent fields. */ /* IMediaEvent fields. */
HANDLE m_hMediaEvent; HANDLE m_hMediaEvent;
CRITICAL_SECTION m_csMediaEvents;
FilterGraph_MEDIAEVENT* m_pMediaEvents;
ULONG m_cbMediaEventsPut;
ULONG m_cbMediaEventsGet;
ULONG m_cbMediaEventsMax;
/* IMediaEventSink fields. */ /* IMediaEventSink fields. */
/* IMediaPosition fields. */ /* IMediaPosition fields. */
/* IMediaSeeking fields. */ /* IMediaSeeking fields. */
...@@ -137,8 +152,10 @@ typedef struct CFilterGraph ...@@ -137,8 +152,10 @@ typedef struct CFilterGraph
#define CFilterGraph_IPersist(th) ((IPersist*)&((th)->persist)) #define CFilterGraph_IPersist(th) ((IPersist*)&((th)->persist))
#define CFilterGraph_IDispatch(th) ((IDispatch*)&((th)->disp)) #define CFilterGraph_IDispatch(th) ((IDispatch*)&((th)->disp))
#define CFilterGraph_IFilterGraph2(th) ((IFilterGraph2*)&((th)->fgraph)) #define CFilterGraph_IFilterGraph2(th) ((IFilterGraph2*)&((th)->fgraph))
#define CFilterGraph_IMediaFilter(th) ((IMediaFilter*)&((th)->mediafilter))
#define CFilterGraph_IMediaControl(th) ((IMediaControl*)&((th)->mediacontrol)) #define CFilterGraph_IMediaControl(th) ((IMediaControl*)&((th)->mediacontrol))
#define CFilterGraph_IMediaFilter(th) ((IMediaFilter*)&((th)->mediafilter))
#define CFilterGraph_IMediaEventEx(th) ((IMediaEventEx*)&((th)->mediaevent))
#define CFilterGraph_IMediaEventSink(th) ((IMediaEventSink*)&((th)->mediaeventsink))
HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj); HRESULT QUARTZ_CreateFilterGraph(IUnknown* punkOuter,void** ppobj);
...@@ -150,6 +167,8 @@ HRESULT CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg ); ...@@ -150,6 +167,8 @@ HRESULT CFilterGraph_InitIFilterGraph2( CFilterGraph* pfg );
void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg ); void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg );
HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg ); HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg );
void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg ); void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg );
HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg );
void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg );
HRESULT CFilterGraph_InitIMediaControl( CFilterGraph* pfg ); HRESULT CFilterGraph_InitIMediaControl( CFilterGraph* pfg );
void CFilterGraph_UninitIMediaControl( CFilterGraph* pfg ); void CFilterGraph_UninitIMediaControl( CFilterGraph* pfg );
HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg ); HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg );
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winreg.h"
#include "winerror.h" #include "winerror.h"
#include "wine/obj_base.h" #include "wine/obj_base.h"
#include "wine/obj_oleaut.h" #include "wine/obj_oleaut.h"
...@@ -24,6 +25,14 @@ DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -24,6 +25,14 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h" #include "quartz_private.h"
#include "fmap.h" #include "fmap.h"
#include "regsvr.h"
/***************************************************************************
*
* new/delete for CLSID_FilterMapper
*
*/
/* can I use offsetof safely? - FIXME? */ /* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry IFEntries[] = static QUARTZ_IFEntry IFEntries[] =
...@@ -66,3 +75,182 @@ HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj) ...@@ -66,3 +75,182 @@ HRESULT QUARTZ_CreateFilterMapper(IUnknown* punkOuter,void** ppobj)
return S_OK; return S_OK;
} }
/***************************************************************************
*
* CLSID_FilterMapper::IFilterMapper
*
*/
static HRESULT WINAPI
IFilterMapper_fnQueryInterface(IFilterMapper* iface,REFIID riid,void** ppobj)
{
CFilterMapper_THIS(iface,fmap);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IFilterMapper_fnAddRef(IFilterMapper* iface)
{
CFilterMapper_THIS(iface,fmap);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IFilterMapper_fnRelease(IFilterMapper* iface)
{
CFilterMapper_THIS(iface,fmap);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,DWORD dwMerit)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s,%s,%08lx)\n",This,
debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);
/* FIXME */
/* FIXME - handle dwMerit! */
return QUARTZ_RegisterAMovieFilter(
&CLSID_LegacyAmFilterCategory,
&clsid,
NULL, 0,
lpwszName, NULL, TRUE );
}
static HRESULT WINAPI
IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
{
CFilterMapper_THIS(iface,fmap);
HRESULT hr;
FIXME("(%p)->()\n",This);
if ( pclsidMedia == NULL )
return E_POINTER;
hr = CoCreateGuid(pclsidMedia);
if ( FAILED(hr) )
return hr;
/* FIXME */
/* this doesn't work. */
/* return IFilterMapper_RegisterFilter(iface,
*pclsidMedia,lpwszName,0x60000000); */
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,BOOL bRendered,BOOL bOutput,BOOL bZero,BOOL bMany,CLSID clsidReserved,LPCWSTR lpwszReserved)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,CLSID clsidMajorType,CLSID clsidSubType)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));
/* FIXME */
return QUARTZ_RegisterAMovieFilter(
&CLSID_LegacyAmFilterCategory,
&clsidFilter,
NULL, 0, NULL, NULL, FALSE );
}
static HRESULT WINAPI
IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
/* FIXME */
/* this doesn't work. */
/* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s,%s) stub!\n",This,
debugstr_guid(&clsidPin),debugstr_w(lpwszName));
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj,DWORD dwMerit,BOOL bInputNeeded,CLSID clsInMajorType,CLSID clsidSubType,BOOL bRender,BOOL bOutputNeeded,CLSID clsOutMajorType,CLSID clsOutSubType)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static ICOM_VTABLE(IFilterMapper) ifmap =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IFilterMapper_fnQueryInterface,
IFilterMapper_fnAddRef,
IFilterMapper_fnRelease,
/* IFilterMapper fields */
IFilterMapper_fnRegisterFilter,
IFilterMapper_fnRegisterFilterInstance,
IFilterMapper_fnRegisterPin,
IFilterMapper_fnRegisterPinType,
IFilterMapper_fnUnregisterFilter,
IFilterMapper_fnUnregisterFilterInstance,
IFilterMapper_fnUnregisterPin,
IFilterMapper_fnEnumMatchingFilters,
};
HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
{
TRACE("(%p)\n",pfm);
ICOM_VTBL(&pfm->fmap) = &ifmap;
return NOERROR;
}
void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
{
TRACE("(%p)\n",pfm);
}
...@@ -11,8 +11,9 @@ ...@@ -11,8 +11,9 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winerror.h"
#include "winuser.h" #include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "wine/obj_base.h" #include "wine/obj_base.h"
#include "wine/obj_oleaut.h" #include "wine/obj_oleaut.h"
#include "strmif.h" #include "strmif.h"
...@@ -24,6 +25,14 @@ DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -24,6 +25,14 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h" #include "quartz_private.h"
#include "fmap2.h" #include "fmap2.h"
#include "regsvr.h"
/***************************************************************************
*
* new/delete for CLSID_FilterMapper2
*
*/
/* can I use offsetof safely? - FIXME? */ /* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry IFEntries[] = static QUARTZ_IFEntry IFEntries[] =
...@@ -67,3 +76,162 @@ HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj) ...@@ -67,3 +76,162 @@ HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
return S_OK; return S_OK;
} }
/***************************************************************************
*
* CLSID_FilterMapper2::IFilterMapper3
*
*/
static HRESULT WINAPI
IFilterMapper3_fnQueryInterface(IFilterMapper3* iface,REFIID riid,void** ppobj)
{
CFilterMapper2_THIS(iface,fmap3);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IFilterMapper3_fnAddRef(IFilterMapper3* iface)
{
CFilterMapper2_THIS(iface,fmap3);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IFilterMapper3_fnRelease(IFilterMapper3* iface)
{
CFilterMapper2_THIS(iface,fmap3);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME("(%p)->(%s,%lu,%s) stub!\n",This,
debugstr_guid(rclsidCategory),
(unsigned long)dwMerit,debugstr_w(lpwszDesc));
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME("(%p)->(%s,%s,%s) stub!\n",This,
debugstr_guid(pclsidCategory),
debugstr_w(lpwszInst),
debugstr_guid(rclsidFilter));
if ( pclsidCategory == NULL )
pclsidCategory = &CLSID_LegacyAmFilterCategory;
/* FIXME */
return QUARTZ_RegisterAMovieFilter(
pclsidCategory,
rclsidFilter,
NULL, 0,
NULL, lpwszInst, FALSE );
}
static HRESULT WINAPI
IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
debugstr_guid(rclsidFilter),debugstr_w(lpName),
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 );
}
static HRESULT WINAPI
IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,IEnumMoniker** ppMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper3_fnGetICreateDevEnum(IFilterMapper3* iface,ICreateDevEnum** ppDevEnum)
{
CFilterMapper2_THIS(iface,fmap3);
/* undocumented */
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static ICOM_VTABLE(IFilterMapper3) ifmap3 =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IFilterMapper3_fnQueryInterface,
IFilterMapper3_fnAddRef,
IFilterMapper3_fnRelease,
/* IFilterMapper2 fields */
IFilterMapper3_fnCreateCategory,
IFilterMapper3_fnUnregisterFilter,
IFilterMapper3_fnRegisterFilter,
IFilterMapper3_fnEnumMatchingFilters,
/* IFilterMapper3 fields */
IFilterMapper3_fnGetICreateDevEnum,
};
HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm )
{
TRACE("(%p)\n",pfm);
ICOM_VTBL(&pfm->fmap3) = &ifmap3;
return NOERROR;
}
void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm )
{
TRACE("(%p)\n",pfm);
}
/*
* Implementation of ICreateDevEnum for CLSID_SystemDeviceEnum.
*
* FIXME - stub.
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "objidl.h"
#include "oleidl.h"
#include "ocidl.h"
#include "strmif.h"
#include "control.h"
#include "uuids.h"
#include "wine/unicode.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "devenum.h"
#include "regsvr.h"
#include "enumunk.h"
#include "complist.h"
#include "devmon.h"
static HRESULT WINAPI
ICreateDevEnum_fnQueryInterface(ICreateDevEnum* iface,REFIID riid,void** ppobj)
{
CSysDevEnum_THIS(iface,createdevenum);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
ICreateDevEnum_fnAddRef(ICreateDevEnum* iface)
{
CSysDevEnum_THIS(iface,createdevenum);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
ICreateDevEnum_fnRelease(ICreateDevEnum* iface)
{
CSysDevEnum_THIS(iface,createdevenum);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDeviceClass,IEnumMoniker** ppobj, DWORD dwFlags)
{
CSysDevEnum_THIS(iface,createdevenum);
HRESULT hr;
HKEY hKey;
QUARTZ_CompList* pMonList;
IMoniker* pMon;
DWORD dwIndex;
LONG lr;
WCHAR wszPath[ 1024 ];
DWORD dwLen;
DWORD dwNameMax;
DWORD cbName;
FILETIME ftLastWrite;
TRACE("(%p)->(%s,%p,%08lx)\n",This,
debugstr_guid(rclsidDeviceClass),ppobj,dwFlags);
if ( dwFlags != 0 )
{
FIXME("unknown flags %08lx\n",dwFlags);
return E_NOTIMPL;
}
if ( ppobj == NULL )
return E_POINTER;
*ppobj = NULL;
hr = QUARTZ_CreateCLSIDPath(
wszPath, sizeof(wszPath)/sizeof(wszPath[0]),
rclsidDeviceClass, QUARTZ_wszInstance );
if ( FAILED(hr) )
return hr;
if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath,
0, KEY_READ, &hKey ) != ERROR_SUCCESS )
return E_FAIL;
dwLen = strlenW(wszPath);
wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;
pMonList = QUARTZ_CompList_Alloc();
if ( pMonList == NULL )
{
hr = E_OUTOFMEMORY;
goto err;
}
/* enumerate all subkeys. */
dwIndex = 0;
while ( 1 )
{
cbName = dwNameMax;
lr = RegEnumKeyExW(
hKey, dwIndex, &wszPath[dwLen], &cbName,
NULL, NULL, NULL, &ftLastWrite );
if ( lr == ERROR_NO_MORE_ITEMS )
break;
if ( lr != ERROR_SUCCESS )
{
hr = E_FAIL;
goto err;
}
hr = QUARTZ_CreateDeviceMoniker(
HKEY_CLASSES_ROOT, wszPath, &pMon );
if ( FAILED(hr) )
goto err;
hr = QUARTZ_CompList_AddComp(
pMonList, (IUnknown*)pMon, NULL, 0 );
IMoniker_Release( pMon );
if ( FAILED(hr) )
goto err;
dwIndex ++;
}
/* create an enumerator. */
hr = QUARTZ_CreateEnumUnknown(
&IID_IEnumMoniker, (void**)ppobj, pMonList );
if ( FAILED(hr) )
goto err;
hr = S_OK;
err:
if ( pMonList != NULL )
QUARTZ_CompList_Free( pMonList );
RegCloseKey( hKey );
return hr;
}
static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
ICreateDevEnum_fnQueryInterface,
ICreateDevEnum_fnAddRef,
ICreateDevEnum_fnRelease,
/* ICreateDevEnum fields */
ICreateDevEnum_fnCreateClassEnumerator,
};
HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
{
TRACE("(%p)\n",psde);
ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;
return NOERROR;
}
void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
{
TRACE("(%p)\n",psde);
}
/* /*
* Implementation of IFilterGraph. * Implementation of IFilterGraph.
* *
* FIXME - stub. * FIXME - create a thread to process some methods correctly.
* FIXME - implement IGraphBuilder / IFilterGraph2. *
* FIXME - ReconnectEx
* FIXME - process Pause/Stop asynchronously and notify when completed.
*
* *
* hidenori@a2.ctktv.ne.jp * hidenori@a2.ctktv.ne.jp
*/ */
...@@ -21,6 +24,7 @@ ...@@ -21,6 +24,7 @@
#include "uuids.h" #include "uuids.h"
#include "vfwmsgs.h" #include "vfwmsgs.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "evcode.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz); DEFAULT_DEBUG_CHANNEL(quartz);
...@@ -28,6 +32,7 @@ DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -28,6 +32,7 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h" #include "quartz_private.h"
#include "fgraph.h" #include "fgraph.h"
#include "enumunk.h" #include "enumunk.h"
#include "sysclock.h"
static HRESULT CFilterGraph_DisconnectAllPins( IBaseFilter* pFilter ) static HRESULT CFilterGraph_DisconnectAllPins( IBaseFilter* pFilter )
...@@ -111,6 +116,7 @@ static HRESULT WINAPI ...@@ -111,6 +116,7 @@ static HRESULT WINAPI
IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pName) IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pName)
{ {
CFilterGraph_THIS(iface,fgraph); CFilterGraph_THIS(iface,fgraph);
FILTER_STATE fs;
FILTER_INFO info; FILTER_INFO info;
HRESULT hr; HRESULT hr;
HRESULT hrSucceeded = S_OK; HRESULT hrSucceeded = S_OK;
...@@ -121,6 +127,16 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa ...@@ -121,6 +127,16 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa
QUARTZ_CompList_Lock( This->m_pFilterList ); QUARTZ_CompList_Lock( This->m_pFilterList );
hr = IMediaFilter_GetState(CFilterGraph_IMediaFilter(This),0,&fs);
if ( hr == VFW_S_STATE_INTERMEDIATE )
hr = VFW_E_STATE_CHANGED;
if ( fs != State_Stopped )
hr = VFW_E_NOT_STOPPED;
if ( FAILED(hr) )
goto end;
TRACE( "(%p) search the specified name.\n",This );
if ( pName != NULL ) if ( pName != NULL )
{ {
pItem = QUARTZ_CompList_SearchData( pItem = QUARTZ_CompList_SearchData(
...@@ -180,6 +196,8 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa ...@@ -180,6 +196,8 @@ IFilterGraph2_fnAddFilter(IFilterGraph2* iface,IBaseFilter* pFilter, LPCWSTR pNa
goto end; goto end;
name_ok: name_ok:
TRACE( "(%p) add this filter.\n",This );
/* register this filter. */ /* register this filter. */
hr = QUARTZ_CompList_AddComp( hr = QUARTZ_CompList_AddComp(
This->m_pFilterList, (IUnknown*)pFilter, This->m_pFilterList, (IUnknown*)pFilter,
...@@ -188,13 +206,23 @@ name_ok: ...@@ -188,13 +206,23 @@ name_ok:
goto end; goto end;
hr = IBaseFilter_JoinFilterGraph(pFilter,(IFilterGraph*)iface,pName); hr = IBaseFilter_JoinFilterGraph(pFilter,(IFilterGraph*)iface,pName);
if ( SUCCEEDED(hr) )
{
EnterCriticalSection( &This->m_csClock );
hr = IBaseFilter_SetSyncSource( pFilter, This->m_pClock );
LeaveCriticalSection( &This->m_csClock );
}
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
IBaseFilter_JoinFilterGraph(pFilter,NULL,pName);
QUARTZ_CompList_RemoveComp( QUARTZ_CompList_RemoveComp(
This->m_pFilterList,(IUnknown*)pFilter); This->m_pFilterList,(IUnknown*)pFilter);
goto end; goto end;
} }
/* IDistributorNotify_NotifyGraphChange() */
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_GRAPH_CHANGED, 0, 0);
EnterCriticalSection( &This->m_csGraphVersion ); EnterCriticalSection( &This->m_csGraphVersion );
This->m_lGraphVersion ++; This->m_lGraphVersion ++;
LeaveCriticalSection( &This->m_csGraphVersion ); LeaveCriticalSection( &This->m_csGraphVersion );
...@@ -203,6 +231,8 @@ name_ok: ...@@ -203,6 +231,8 @@ name_ok:
end: end:
QUARTZ_CompList_Unlock( This->m_pFilterList ); QUARTZ_CompList_Unlock( This->m_pFilterList );
TRACE( "(%p) return %08lx\n", This, hr );
return hr; return hr;
} }
...@@ -211,27 +241,42 @@ IFilterGraph2_fnRemoveFilter(IFilterGraph2* iface,IBaseFilter* pFilter) ...@@ -211,27 +241,42 @@ IFilterGraph2_fnRemoveFilter(IFilterGraph2* iface,IBaseFilter* pFilter)
{ {
CFilterGraph_THIS(iface,fgraph); CFilterGraph_THIS(iface,fgraph);
QUARTZ_CompListItem* pItem; QUARTZ_CompListItem* pItem;
FILTER_STATE fs;
HRESULT hr = NOERROR; HRESULT hr = NOERROR;
TRACE( "(%p)->(%p)\n",This,pFilter ); TRACE( "(%p)->(%p)\n",This,pFilter );
QUARTZ_CompList_Lock( This->m_pFilterList ); QUARTZ_CompList_Lock( This->m_pFilterList );
hr = IMediaFilter_GetState(CFilterGraph_IMediaFilter(This),0,&fs);
if ( hr == VFW_S_STATE_INTERMEDIATE )
hr = VFW_E_STATE_CHANGED;
if ( fs != State_Stopped )
hr = VFW_E_NOT_STOPPED;
if ( FAILED(hr) )
goto end;
hr = S_FALSE; /* FIXME? */
pItem = QUARTZ_CompList_SearchComp( pItem = QUARTZ_CompList_SearchComp(
This->m_pFilterList, (IUnknown*)pFilter ); This->m_pFilterList, (IUnknown*)pFilter );
if ( pItem != NULL ) if ( pItem != NULL )
{ {
CFilterGraph_DisconnectAllPins(pFilter); CFilterGraph_DisconnectAllPins(pFilter);
IBaseFilter_SetSyncSource( pFilter, NULL );
hr = IBaseFilter_JoinFilterGraph( hr = IBaseFilter_JoinFilterGraph(
pFilter, NULL, QUARTZ_CompList_GetDataPtr(pItem) ); pFilter, NULL, QUARTZ_CompList_GetDataPtr(pItem) );
QUARTZ_CompList_RemoveComp( QUARTZ_CompList_RemoveComp(
This->m_pFilterList, (IUnknown*)pFilter ); This->m_pFilterList, (IUnknown*)pFilter );
} }
/* IDistributorNotify_NotifyGraphChange() */
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_GRAPH_CHANGED, 0, 0);
EnterCriticalSection( &This->m_csGraphVersion ); EnterCriticalSection( &This->m_csGraphVersion );
This->m_lGraphVersion ++; This->m_lGraphVersion ++;
LeaveCriticalSection( &This->m_csGraphVersion ); LeaveCriticalSection( &This->m_csGraphVersion );
end:;
QUARTZ_CompList_Unlock( This->m_pFilterList ); QUARTZ_CompList_Unlock( This->m_pFilterList );
return hr; return hr;
...@@ -332,34 +377,35 @@ IFilterGraph2_fnConnectDirect(IFilterGraph2* iface,IPin* pOut,IPin* pIn,const AM ...@@ -332,34 +377,35 @@ IFilterGraph2_fnConnectDirect(IFilterGraph2* iface,IPin* pOut,IPin* pIn,const AM
pConnTo = NULL; pConnTo = NULL;
hr = IPin_ConnectedTo(pIn,&pConnTo); hr = IPin_ConnectedTo(pIn,&pConnTo);
if ( FAILED(hr) ) if ( hr == NOERROR && pConnTo != NULL )
goto end;
if ( pConnTo != NULL )
{ {
IPin_Release(pConnTo); IPin_Release(pConnTo);
hr = VFW_E_ALREADY_CONNECTED;
goto end; goto end;
} }
pConnTo = NULL; pConnTo = NULL;
hr = IPin_ConnectedTo(pOut,&pConnTo); hr = IPin_ConnectedTo(pOut,&pConnTo);
if ( FAILED(hr) ) if ( hr == NOERROR && pConnTo != NULL )
goto end;
if ( pConnTo != NULL )
{ {
IPin_Release(pConnTo); IPin_Release(pConnTo);
hr = VFW_E_ALREADY_CONNECTED;
goto end; goto end;
} }
hr = IPin_Connect(pIn,pOut,pmt); TRACE("(%p) try to connect %p<->%p\n",This,pIn,pOut);
if ( FAILED(hr) )
goto end;
hr = IPin_Connect(pOut,pIn,pmt); hr = IPin_Connect(pOut,pIn,pmt);
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
TRACE("(%p)->Connect(%p,%p) hr = %08lx\n",pOut,pIn,pmt,hr);
IPin_Disconnect(pOut);
IPin_Disconnect(pIn); IPin_Disconnect(pIn);
goto end; goto end;
} }
/* IDistributorNotify_NotifyGraphChange() */
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_GRAPH_CHANGED, 0, 0);
EnterCriticalSection( &This->m_csGraphVersion ); EnterCriticalSection( &This->m_csGraphVersion );
This->m_lGraphVersion ++; This->m_lGraphVersion ++;
LeaveCriticalSection( &This->m_csGraphVersion ); LeaveCriticalSection( &This->m_csGraphVersion );
...@@ -384,36 +430,67 @@ IFilterGraph2_fnReconnect(IFilterGraph2* iface,IPin* pPin) ...@@ -384,36 +430,67 @@ IFilterGraph2_fnReconnect(IFilterGraph2* iface,IPin* pPin)
{ {
CFilterGraph_THIS(iface,fgraph); CFilterGraph_THIS(iface,fgraph);
FIXME( "(%p)->(%p) stub!\n",This,pPin ); TRACE( "(%p)->(%p)\n",This,pPin );
EnterCriticalSection( &This->m_csGraphVersion );
This->m_lGraphVersion ++;
LeaveCriticalSection( &This->m_csGraphVersion );
return E_NOTIMPL; return IFilterGraph2_ReconnectEx(iface,pPin,NULL);
} }
static HRESULT WINAPI static HRESULT WINAPI
IFilterGraph2_fnDisconnect(IFilterGraph2* iface,IPin* pPin) IFilterGraph2_fnDisconnect(IFilterGraph2* iface,IPin* pPin)
{ {
CFilterGraph_THIS(iface,fgraph); CFilterGraph_THIS(iface,fgraph);
IPin* pConnTo;
HRESULT hr;
TRACE( "(%p)->(%p)\n",This,pPin );
QUARTZ_CompList_Lock( This->m_pFilterList );
FIXME( "(%p)->(%p) stub!\n",This,pPin ); pConnTo = NULL;
hr = IPin_ConnectedTo(pPin,&pConnTo);
if ( hr == NOERROR && pConnTo != NULL )
{
IPin_Disconnect(pConnTo);
IPin_Release(pConnTo);
}
hr = IPin_Disconnect(pPin);
/* IDistributorNotify_NotifyGraphChange() */
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_GRAPH_CHANGED, 0, 0);
EnterCriticalSection( &This->m_csGraphVersion ); EnterCriticalSection( &This->m_csGraphVersion );
This->m_lGraphVersion ++; This->m_lGraphVersion ++;
LeaveCriticalSection( &This->m_csGraphVersion ); LeaveCriticalSection( &This->m_csGraphVersion );
return E_NOTIMPL; QUARTZ_CompList_Unlock( This->m_pFilterList );
return hr;
} }
static HRESULT WINAPI static HRESULT WINAPI
IFilterGraph2_fnSetDefaultSyncSource(IFilterGraph2* iface) IFilterGraph2_fnSetDefaultSyncSource(IFilterGraph2* iface)
{ {
CFilterGraph_THIS(iface,fgraph); CFilterGraph_THIS(iface,fgraph);
IUnknown* punk;
IReferenceClock* pClock;
HRESULT hr;
FIXME( "(%p)->() stub!\n", This ); FIXME( "(%p)->() stub!\n", This );
return E_NOTIMPL;
/* FIXME - search all filters. */
hr = QUARTZ_CreateSystemClock( NULL, (void**)&punk );
if ( FAILED(hr) )
return hr;
hr = IUnknown_QueryInterface( punk, &IID_IReferenceClock, (void**)&pClock ); IUnknown_Release( punk );
if ( FAILED(hr) )
return hr;
hr = IMediaFilter_SetSyncSource(
CFilterGraph_IMediaFilter(This), pClock );
IReferenceClock_Release( pClock );
return hr;
} }
static HRESULT WINAPI static HRESULT WINAPI
...@@ -583,6 +660,11 @@ IFilterGraph2_fnReconnectEx(IFilterGraph2* iface,IPin* pPin,const AM_MEDIA_TYPE* ...@@ -583,6 +660,11 @@ IFilterGraph2_fnReconnectEx(IFilterGraph2* iface,IPin* pPin,const AM_MEDIA_TYPE*
FIXME( "(%p)->(%p,%p) stub!\n",This,pPin,pmt ); FIXME( "(%p)->(%p,%p) stub!\n",This,pPin,pmt );
/* reconnect asynchronously. */
/* IDistributorNotify_NotifyGraphChange() */
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_GRAPH_CHANGED, 0, 0);
EnterCriticalSection( &This->m_csGraphVersion ); EnterCriticalSection( &This->m_csGraphVersion );
This->m_lGraphVersion ++; This->m_lGraphVersion ++;
LeaveCriticalSection( &This->m_csGraphVersion ); LeaveCriticalSection( &This->m_csGraphVersion );
...@@ -657,7 +739,7 @@ void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg ) ...@@ -657,7 +739,7 @@ void CFilterGraph_UninitIFilterGraph2( CFilterGraph* pfg )
pItem = QUARTZ_CompList_GetFirst( pfg->m_pFilterList ); pItem = QUARTZ_CompList_GetFirst( pfg->m_pFilterList );
if ( pItem == NULL ) if ( pItem == NULL )
break; break;
IFilterGraph2_fnRemoveFilter( IFilterGraph2_RemoveFilter(
(IFilterGraph2*)(&pfg->fgraph), (IFilterGraph2*)(&pfg->fgraph),
(IBaseFilter*)QUARTZ_CompList_GetItemPtr(pItem) ); (IBaseFilter*)QUARTZ_CompList_GetItemPtr(pItem) );
} }
......
/*
* Implementation of IFilterMapper for CLSID_FilterMapper.
*
* FIXME - stub.
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "wine/obj_oleaut.h"
#include "strmif.h"
#include "control.h"
#include "uuids.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "fmap.h"
#include "regsvr.h"
static HRESULT WINAPI
IFilterMapper_fnQueryInterface(IFilterMapper* iface,REFIID riid,void** ppobj)
{
CFilterMapper_THIS(iface,fmap);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IFilterMapper_fnAddRef(IFilterMapper* iface)
{
CFilterMapper_THIS(iface,fmap);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IFilterMapper_fnRelease(IFilterMapper* iface)
{
CFilterMapper_THIS(iface,fmap);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IFilterMapper_fnRegisterFilter(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,DWORD dwMerit)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s,%s,%08lx)\n",This,
debugstr_guid(&clsid),debugstr_w(lpwszName),dwMerit);
/* FIXME */
/* FIXME - handle dwMerit! */
return QUARTZ_RegisterAMovieFilter(
&CLSID_LegacyAmFilterCategory,
&clsid,
NULL, 0,
lpwszName, NULL, TRUE );
}
static HRESULT WINAPI
IFilterMapper_fnRegisterFilterInstance(IFilterMapper* iface,CLSID clsid,LPCWSTR lpwszName,CLSID* pclsidMedia)
{
CFilterMapper_THIS(iface,fmap);
HRESULT hr;
FIXME("(%p)->()\n",This);
if ( pclsidMedia == NULL )
return E_POINTER;
hr = CoCreateGuid(pclsidMedia);
if ( FAILED(hr) )
return hr;
/* FIXME */
/* this doesn't work. */
/* return IFilterMapper_RegisterFilter(iface,
*pclsidMedia,lpwszName,0x60000000); */
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnRegisterPin(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,BOOL bRendered,BOOL bOutput,BOOL bZero,BOOL bMany,CLSID clsidReserved,LPCWSTR lpwszReserved)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnRegisterPinType(IFilterMapper* iface,CLSID clsidFilter,LPCWSTR lpwszName,CLSID clsidMajorType,CLSID clsidSubType)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnUnregisterFilter(IFilterMapper* iface,CLSID clsidFilter)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidFilter));
/* FIXME */
return QUARTZ_RegisterAMovieFilter(
&CLSID_LegacyAmFilterCategory,
&clsidFilter,
NULL, 0, NULL, NULL, FALSE );
}
static HRESULT WINAPI
IFilterMapper_fnUnregisterFilterInstance(IFilterMapper* iface,CLSID clsidMedia)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s)\n",This,debugstr_guid(&clsidMedia));
/* FIXME */
/* this doesn't work. */
/* return IFilterMapper_UnregisterFilter(iface,clsidMedia); */
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnUnregisterPin(IFilterMapper* iface,CLSID clsidPin,LPCWSTR lpwszName)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->(%s,%s) stub!\n",This,
debugstr_guid(&clsidPin),debugstr_w(lpwszName));
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper_fnEnumMatchingFilters(IFilterMapper* iface,IEnumRegFilters** ppobj,DWORD dwMerit,BOOL bInputNeeded,CLSID clsInMajorType,CLSID clsidSubType,BOOL bRender,BOOL bOutputNeeded,CLSID clsOutMajorType,CLSID clsOutSubType)
{
CFilterMapper_THIS(iface,fmap);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static ICOM_VTABLE(IFilterMapper) ifmap =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IFilterMapper_fnQueryInterface,
IFilterMapper_fnAddRef,
IFilterMapper_fnRelease,
/* IFilterMapper fields */
IFilterMapper_fnRegisterFilter,
IFilterMapper_fnRegisterFilterInstance,
IFilterMapper_fnRegisterPin,
IFilterMapper_fnRegisterPinType,
IFilterMapper_fnUnregisterFilter,
IFilterMapper_fnUnregisterFilterInstance,
IFilterMapper_fnUnregisterPin,
IFilterMapper_fnEnumMatchingFilters,
};
HRESULT CFilterMapper_InitIFilterMapper( CFilterMapper* pfm )
{
TRACE("(%p)\n",pfm);
ICOM_VTBL(&pfm->fmap) = &ifmap;
return NOERROR;
}
void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm )
{
TRACE("(%p)\n",pfm);
}
/*
* Implementation of IFilterMapper3 for CLSID_FilterMapper2.
*
* FIXME - stub.
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "wine/obj_oleaut.h"
#include "strmif.h"
#include "control.h"
#include "uuids.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "fmap2.h"
#include "regsvr.h"
static HRESULT WINAPI
IFilterMapper3_fnQueryInterface(IFilterMapper3* iface,REFIID riid,void** ppobj)
{
CFilterMapper2_THIS(iface,fmap3);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IFilterMapper3_fnAddRef(IFilterMapper3* iface)
{
CFilterMapper2_THIS(iface,fmap3);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IFilterMapper3_fnRelease(IFilterMapper3* iface)
{
CFilterMapper2_THIS(iface,fmap3);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IFilterMapper3_fnCreateCategory(IFilterMapper3* iface,REFCLSID rclsidCategory,DWORD dwMerit,LPCWSTR lpwszDesc)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME("(%p)->(%s,%lu,%s) stub!\n",This,
debugstr_guid(rclsidCategory),
(unsigned long)dwMerit,debugstr_w(lpwszDesc));
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper3_fnUnregisterFilter(IFilterMapper3* iface,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,REFCLSID rclsidFilter)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME("(%p)->(%s,%s,%s) stub!\n",This,
debugstr_guid(pclsidCategory),
debugstr_w(lpwszInst),
debugstr_guid(rclsidFilter));
if ( pclsidCategory == NULL )
pclsidCategory = &CLSID_LegacyAmFilterCategory;
/* FIXME */
return QUARTZ_RegisterAMovieFilter(
pclsidCategory,
rclsidFilter,
NULL, 0,
NULL, lpwszInst, FALSE );
}
static HRESULT WINAPI
IFilterMapper3_fnRegisterFilter(IFilterMapper3* iface,REFCLSID rclsidFilter,LPCWSTR lpName,IMoniker** ppMoniker,const CLSID* pclsidCategory,const OLECHAR* lpwszInst,const REGFILTER2* pRF2)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME( "(%p)->(%s,%s,%p,%s,%s,%p) stub!\n",This,
debugstr_guid(rclsidFilter),debugstr_w(lpName),
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 );
}
static HRESULT WINAPI
IFilterMapper3_fnEnumMatchingFilters(IFilterMapper3* iface,IEnumMoniker** ppMoniker,DWORD dwFlags,BOOL bExactMatch,DWORD dwMerit,BOOL bInputNeeded,DWORD cInputTypes,const GUID* pguidInputTypes,const REGPINMEDIUM* pPinMediumIn,const CLSID* pPinCategoryIn,BOOL bRender,BOOL bOutputNeeded,DWORD cOutputTypes,const GUID* pguidOutputTypes,const REGPINMEDIUM* pPinMediumOut,const CLSID* pPinCategoryOut)
{
CFilterMapper2_THIS(iface,fmap3);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI
IFilterMapper3_fnGetICreateDevEnum(IFilterMapper3* iface,ICreateDevEnum** ppDevEnum)
{
CFilterMapper2_THIS(iface,fmap3);
/* undocumented */
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static ICOM_VTABLE(IFilterMapper3) ifmap3 =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IFilterMapper3_fnQueryInterface,
IFilterMapper3_fnAddRef,
IFilterMapper3_fnRelease,
/* IFilterMapper2 fields */
IFilterMapper3_fnCreateCategory,
IFilterMapper3_fnUnregisterFilter,
IFilterMapper3_fnRegisterFilter,
IFilterMapper3_fnEnumMatchingFilters,
/* IFilterMapper3 fields */
IFilterMapper3_fnGetICreateDevEnum,
};
HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* pfm )
{
TRACE("(%p)\n",pfm);
ICOM_VTBL(&pfm->fmap3) = &ifmap3;
return NOERROR;
}
void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* pfm )
{
TRACE("(%p)\n",pfm);
}
/* /*
* Implementation of IBasicAudio for FilterGraph. * Implementation of IGraphConfig for FilterGraph.
* *
* FIXME - stub. * FIXME - stub.
* *
...@@ -28,9 +28,9 @@ DEFAULT_DEBUG_CHANNEL(quartz); ...@@ -28,9 +28,9 @@ DEFAULT_DEBUG_CHANNEL(quartz);
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj) IGraphConfig_fnQueryInterface(IGraphConfig* iface,REFIID riid,void** ppobj)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
TRACE("(%p)->()\n",This); TRACE("(%p)->()\n",This);
...@@ -38,9 +38,9 @@ IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj) ...@@ -38,9 +38,9 @@ IBasicAudio_fnQueryInterface(IBasicAudio* iface,REFIID riid,void** ppobj)
} }
static ULONG WINAPI static ULONG WINAPI
IBasicAudio_fnAddRef(IBasicAudio* iface) IGraphConfig_fnAddRef(IGraphConfig* iface)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
TRACE("(%p)->()\n",This); TRACE("(%p)->()\n",This);
...@@ -48,126 +48,152 @@ IBasicAudio_fnAddRef(IBasicAudio* iface) ...@@ -48,126 +48,152 @@ IBasicAudio_fnAddRef(IBasicAudio* iface)
} }
static ULONG WINAPI static ULONG WINAPI
IBasicAudio_fnRelease(IBasicAudio* iface) IGraphConfig_fnRelease(IGraphConfig* iface)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
TRACE("(%p)->()\n",This); TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl); return IUnknown_Release(This->unk.punkControl);
} }
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnGetTypeInfoCount(IBasicAudio* iface,UINT* pcTypeInfo) IGraphConfig_fnReconnect(IGraphConfig* iface,IPin* pOut,IPin* pIn,const AM_MEDIA_TYPE* pmt,IBaseFilter* pFilter,HANDLE hAbort,DWORD dwFlags)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnGetTypeInfo(IBasicAudio* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj) IGraphConfig_fnReconfigure(IGraphConfig* iface,IGraphConfigCallback* pCallback,PVOID pvParam,DWORD dwFlags,HANDLE hAbort)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnGetIDsOfNames(IBasicAudio* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId) IGraphConfig_fnAddFilterToCache(IGraphConfig* iface,IBaseFilter* pFilter)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnInvoke(IBasicAudio* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr) IGraphConfig_fnEnumCacheFilter(IGraphConfig* iface,IEnumFilters** ppenum)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI
IGraphConfig_fnRemoveFilterFromCache(IGraphConfig* iface,IBaseFilter* pFilter)
{
CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnput_Volume(IBasicAudio* iface,long lVol) IGraphConfig_fnGetStartTime(IGraphConfig* iface,REFERENCE_TIME* prt)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnget_Volume(IBasicAudio* iface,long* plVol) IGraphConfig_fnPushThroughData(IGraphConfig* iface,IPin* pOut,IPinConnection* pConn,HANDLE hAbort)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnput_Balance(IBasicAudio* iface,long lBalance) IGraphConfig_fnSetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI static HRESULT WINAPI
IBasicAudio_fnget_Balance(IBasicAudio* iface,long* plBalance) IGraphConfig_fnGetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD* pdwFlags)
{ {
CFilterGraph_THIS(iface,basaud); CFilterGraph_THIS(iface,grphconf);
FIXME("(%p)->()\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI
IGraphConfig_fnRemoveFilterEx(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
{
CFilterGraph_THIS(iface,grphconf);
static ICOM_VTABLE(IBasicAudio) ibasicaudio = FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static ICOM_VTABLE(IGraphConfig) igraphconfig =
{ {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */ /* IUnknown fields */
IBasicAudio_fnQueryInterface, IGraphConfig_fnQueryInterface,
IBasicAudio_fnAddRef, IGraphConfig_fnAddRef,
IBasicAudio_fnRelease, IGraphConfig_fnRelease,
/* IDispatch fields */ /* IGraphConfig fields */
IBasicAudio_fnGetTypeInfoCount, IGraphConfig_fnReconnect,
IBasicAudio_fnGetTypeInfo, IGraphConfig_fnReconfigure,
IBasicAudio_fnGetIDsOfNames, IGraphConfig_fnAddFilterToCache,
IBasicAudio_fnInvoke, IGraphConfig_fnEnumCacheFilter,
/* IBasicAudio fields */ IGraphConfig_fnRemoveFilterFromCache,
IBasicAudio_fnput_Volume, IGraphConfig_fnGetStartTime,
IBasicAudio_fnget_Volume, IGraphConfig_fnPushThroughData,
IBasicAudio_fnput_Balance, IGraphConfig_fnSetFilterFlags,
IBasicAudio_fnget_Balance, IGraphConfig_fnGetFilterFlags,
IGraphConfig_fnRemoveFilterEx,
}; };
HRESULT CFilterGraph_InitIBasicAudio( CFilterGraph* pfg )
HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg )
{ {
TRACE("(%p)\n",pfg); TRACE("(%p)\n",pfg);
ICOM_VTBL(&pfg->basaud) = &ibasicaudio; ICOM_VTBL(&pfg->grphconf) = &igraphconfig;
return NOERROR; return NOERROR;
} }
void CFilterGraph_UninitIBasicAudio( CFilterGraph* pfg ) void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg )
{ {
TRACE("(%p)\n",pfg); TRACE("(%p)\n",pfg);
} }
......
/*
* Implementation of CLSID_MemoryAllocator.
*
* FIXME - not tested.
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.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 "memalloc.h"
static HRESULT WINAPI
IMemAllocator_fnQueryInterface(IMemAllocator* iface,REFIID riid,void** ppobj)
{
CMemoryAllocator_THIS(iface,memalloc);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IMemAllocator_fnAddRef(IMemAllocator* iface)
{
CMemoryAllocator_THIS(iface,memalloc);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IMemAllocator_fnRelease(IMemAllocator* iface)
{
CMemoryAllocator_THIS(iface,memalloc);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IMemAllocator_fnSetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pPropReq,ALLOCATOR_PROPERTIES* pPropActual)
{
CMemoryAllocator_THIS(iface,memalloc);
long padding;
HRESULT hr;
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;
hr = NOERROR;
EnterCriticalSection( &This->csMem );
if ( This->pData != NULL || This->ppSamples != NULL )
{
/* if commited, properties must not be changed. */
hr = E_UNEXPECTED;
goto end;
}
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) );
end:
LeaveCriticalSection( &This->csMem );
return hr;
}
static HRESULT WINAPI
IMemAllocator_fnGetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pProp)
{
CMemoryAllocator_THIS(iface,memalloc);
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
IMemAllocator_fnCommit(IMemAllocator* iface)
{
CMemoryAllocator_THIS(iface,memalloc);
HRESULT hr;
LONG lBufSize;
LONG i;
BYTE* pCur;
TRACE( "(%p)->()\n", This );
EnterCriticalSection( &This->csMem );
hr = NOERROR;
if ( This->pData != NULL || This->ppSamples != NULL ||
This->prop.cBuffers <= 0 )
goto end;
lBufSize = This->prop.cBuffers *
(This->prop.cbBuffer + This->prop.cbPrefix) +
This->prop.cbAlign;
if ( lBufSize <= 0 )
lBufSize = 1;
This->pData = (BYTE*)QUARTZ_AllocMem( lBufSize );
if ( This->pData == NULL )
{
hr = E_OUTOFMEMORY;
goto end;
}
This->ppSamples = (CMemMediaSample**)QUARTZ_AllocMem(
sizeof(CMemMediaSample*) * This->prop.cBuffers );
if ( This->ppSamples == NULL )
{
hr = E_OUTOFMEMORY;
goto end;
}
for ( i = 0; i < This->prop.cBuffers; i++ )
This->ppSamples[i] = NULL;
pCur = This->pData + This->prop.cbAlign - ((This->pData-(BYTE*)NULL) & (This->prop.cbAlign-1));
for ( i = 0; i < This->prop.cBuffers; i++ )
{
hr = QUARTZ_CreateMemMediaSample(
pCur, (This->prop.cbBuffer + This->prop.cbPrefix),
iface, &This->ppSamples[i] );
if ( FAILED(hr) )
goto end;
pCur += (This->prop.cbBuffer + This->prop.cbPrefix);
}
hr = NOERROR;
end:
if ( FAILED(hr) )
IMemAllocator_Decommit(iface);
LeaveCriticalSection( &This->csMem );
return hr;
}
static HRESULT WINAPI
IMemAllocator_fnDecommit(IMemAllocator* iface)
{
CMemoryAllocator_THIS(iface,memalloc);
HRESULT hr;
LONG i;
BOOL bBlock;
TRACE( "(%p)->()\n", This );
EnterCriticalSection( &This->csMem );
hr = NOERROR;
if ( This->pData == NULL && This->ppSamples == NULL )
goto end;
while ( 1 )
{
bBlock = FALSE;
i = 0;
ResetEvent( This->hEventSample );
while ( 1 )
{
if ( i >= This->prop.cBuffers )
break;
if ( This->ppSamples[i] != NULL )
{
if ( This->ppSamples[i]->ref == 0 )
{
QUARTZ_DestroyMemMediaSample( This->ppSamples[i] );
This->ppSamples[i] = NULL;
}
else
{
bBlock = TRUE;
}
}
i++;
}
if ( !bBlock )
{
hr = NOERROR;
break;
}
WaitForSingleObject( This->hEventSample, INFINITE );
}
end:
LeaveCriticalSection( &This->csMem );
return hr;
}
static HRESULT WINAPI
IMemAllocator_fnGetBuffer(IMemAllocator* iface,IMediaSample** ppSample,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd,DWORD dwFlags)
{
CMemoryAllocator_THIS(iface,memalloc);
LONG i;
HRESULT hr;
TRACE( "(%p)->(%p,%p,%p,%lu)\n", This, ppSample, prtStart, prtEnd, dwFlags );
if ( ppSample == NULL )
return E_POINTER;
EnterCriticalSection( &This->csMem );
hr = NOERROR;
if ( This->pData == NULL || This->ppSamples == NULL ||
This->prop.cBuffers <= 0 )
{
hr = E_FAIL; /* FIXME? */
goto end;
}
while ( 1 )
{
ResetEvent( This->hEventSample );
for ( i = 0; i < This->prop.cBuffers; i++ )
{
if ( This->ppSamples[i]->ref == 0 )
{
*ppSample = (IMediaSample*)(This->ppSamples[i]);
IMediaSample_AddRef( *ppSample );
hr = NOERROR;
goto end;
}
}
if ( dwFlags & AM_GBF_NOWAIT )
{
hr = E_FAIL; /* FIXME? */
goto end;
}
WaitForSingleObject( This->hEventSample, INFINITE );
}
end:
LeaveCriticalSection( &This->csMem );
return hr;
}
static HRESULT WINAPI
IMemAllocator_fnReleaseBuffer(IMemAllocator* iface,IMediaSample* pSample)
{
CMemoryAllocator_THIS(iface,memalloc);
TRACE( "(%p)->(%p)\n", This, pSample );
SetEvent( This->hEventSample );
return NOERROR;
}
static ICOM_VTABLE(IMemAllocator) imemalloc =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IMemAllocator_fnQueryInterface,
IMemAllocator_fnAddRef,
IMemAllocator_fnRelease,
/* IMemAllocator fields */
IMemAllocator_fnSetProperties,
IMemAllocator_fnGetProperties,
IMemAllocator_fnCommit,
IMemAllocator_fnDecommit,
IMemAllocator_fnGetBuffer,
IMemAllocator_fnReleaseBuffer,
};
HRESULT CMemoryAllocator_InitIMemAllocator( CMemoryAllocator* pma )
{
TRACE("(%p)\n",pma);
ICOM_VTBL(&pma->memalloc) = &imemalloc;
ZeroMemory( &pma->prop, sizeof(pma->prop) );
pma->hEventSample = (HANDLE)NULL;
pma->pData = NULL;
pma->ppSamples = NULL;
pma->hEventSample = CreateEventA( NULL, TRUE, FALSE, NULL );
if ( pma->hEventSample == (HANDLE)NULL )
return E_OUTOFMEMORY;
InitializeCriticalSection( &pma->csMem );
return NOERROR;
}
void CMemoryAllocator_UninitIMemAllocator( CMemoryAllocator* pma )
{
TRACE("(%p)\n",pma);
IMemAllocator_Decommit( (IMemAllocator*)(&pma->memalloc) );
DeleteCriticalSection( &pma->csMem );
if ( pma->hEventSample != (HANDLE)NULL )
CloseHandle( pma->hEventSample );
}
/*
* Implementation of IMediaEventSink for FilterGraph.
*
* FIXME - stub.
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "wine/obj_base.h"
#include "wine/obj_oleaut.h"
#include "strmif.h"
#include "control.h"
#include "uuids.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "fgraph.h"
static HRESULT WINAPI
IMediaEventSink_fnQueryInterface(IMediaEventSink* iface,REFIID riid,void** ppobj)
{
CFilterGraph_THIS(iface,mediaeventsink);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IMediaEventSink_fnAddRef(IMediaEventSink* iface)
{
CFilterGraph_THIS(iface,mediaeventsink);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IMediaEventSink_fnRelease(IMediaEventSink* iface)
{
CFilterGraph_THIS(iface,mediaeventsink);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
static HRESULT WINAPI
IMediaEventSink_fnNotify(IMediaEventSink* iface,long lEventCode,LONG_PTR lParam1,LONG_PTR lParam2)
{
CFilterGraph_THIS(iface,mediaeventsink);
FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL;
}
static ICOM_VTABLE(IMediaEventSink) imediaeventsink =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IMediaEventSink_fnQueryInterface,
IMediaEventSink_fnAddRef,
IMediaEventSink_fnRelease,
/* IMediaEventSink fields */
IMediaEventSink_fnNotify,
};
HRESULT CFilterGraph_InitIMediaEventSink( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
ICOM_VTBL(&pfg->mediaeventsink) = &imediaeventsink;
return NOERROR;
}
void CFilterGraph_UninitIMediaEventSink( CFilterGraph* pfg )
{
TRACE("(%p)\n",pfg);
}
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "control.h" #include "control.h"
#include "uuids.h" #include "uuids.h"
#include "vfwmsgs.h" #include "vfwmsgs.h"
#include "evcode.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz); DEFAULT_DEBUG_CHANNEL(quartz);
...@@ -127,6 +128,8 @@ IMediaFilter_fnStop(IMediaFilter* iface) ...@@ -127,6 +128,8 @@ IMediaFilter_fnStop(IMediaFilter* iface)
if ( This->m_stateGraph != State_Stopped ) if ( This->m_stateGraph != State_Stopped )
{ {
/* IDistributorNotify_Stop() */
QUARTZ_CompList_Lock( This->m_pFilterList ); QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList ); pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
...@@ -171,6 +174,8 @@ IMediaFilter_fnPause(IMediaFilter* iface) ...@@ -171,6 +174,8 @@ IMediaFilter_fnPause(IMediaFilter* iface)
if ( This->m_stateGraph != State_Paused ) if ( This->m_stateGraph != State_Paused )
{ {
/* IDistributorNotify_Pause() */
QUARTZ_CompList_Lock( This->m_pFilterList ); QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList ); pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
...@@ -210,23 +215,32 @@ IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart) ...@@ -210,23 +215,32 @@ IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
TRACE("(%p)->()\n",This); TRACE("(%p)->()\n",This);
/* handle the special time. */ EnterCriticalSection( &This->m_csGraphState );
if ( rtStart == (REFERENCE_TIME)0 )
if ( This->m_stateGraph == State_Stopped )
{ {
hr = IMediaFilter_GetSyncSource(iface,&pClock); hr = IMediaFilter_Pause(iface);
if ( hr == S_OK && pClock != NULL ) if ( FAILED(hr) )
{ goto end;
IReferenceClock_GetTime(pClock,&rtStart);
IReferenceClock_Release(pClock);
}
} }
hr = S_OK; /* 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);
}
}
EnterCriticalSection( &This->m_csGraphState ); hr = NOERROR;
if ( This->m_stateGraph != State_Running ) if ( This->m_stateGraph != State_Running )
{ {
/* IDistributorNotify_Run() */
QUARTZ_CompList_Lock( This->m_pFilterList ); QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList ); pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
...@@ -249,6 +263,7 @@ IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart) ...@@ -249,6 +263,7 @@ IMediaFilter_fnRun(IMediaFilter* iface,REFERENCE_TIME rtStart)
This->m_stateGraph = State_Running; This->m_stateGraph = State_Running;
} }
end:
LeaveCriticalSection( &This->m_csGraphState ); LeaveCriticalSection( &This->m_csGraphState );
return hr; return hr;
...@@ -266,10 +281,6 @@ IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState ...@@ -266,10 +281,6 @@ IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState
if ( pState == NULL ) if ( pState == NULL )
return E_POINTER; return E_POINTER;
EnterCriticalSection( &This->m_csGraphState );
*pState = This->m_stateGraph;
LeaveCriticalSection( &This->m_csGraphState );
dwTickStart = GetTickCount(); dwTickStart = GetTickCount();
while ( 1 ) while ( 1 )
...@@ -292,6 +303,10 @@ IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState ...@@ -292,6 +303,10 @@ IMediaFilter_fnGetState(IMediaFilter* iface,DWORD dwTimeOut,FILTER_STATE* pState
dwTimeOut -= dwTickUsed; dwTimeOut -= dwTickUsed;
} }
EnterCriticalSection( &This->m_csGraphState );
*pState = This->m_stateGraph;
LeaveCriticalSection( &This->m_csGraphState );
return hr; return hr;
} }
...@@ -299,20 +314,77 @@ static HRESULT WINAPI ...@@ -299,20 +314,77 @@ static HRESULT WINAPI
IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock) IMediaFilter_fnSetSyncSource(IMediaFilter* iface,IReferenceClock* pobjClock)
{ {
CFilterGraph_THIS(iface,mediafilter); CFilterGraph_THIS(iface,mediafilter);
QUARTZ_CompListItem* pItem;
IBaseFilter* pFilter;
HRESULT hr = NOERROR;
HRESULT hrCur;
FIXME("(%p)->() stub!\n",This); TRACE("(%p)->(%p)\n",This,pobjClock);
/* IDistributorNotify_SetSyncSource() */
EnterCriticalSection( &This->m_csClock );
QUARTZ_CompList_Lock( This->m_pFilterList );
if ( This->m_pClock != NULL )
{
IReferenceClock_Release(This->m_pClock);
This->m_pClock = NULL;
}
return E_NOTIMPL; This->m_pClock = pobjClock;
if ( pobjClock != NULL )
IReferenceClock_AddRef( pobjClock );
pItem = QUARTZ_CompList_GetFirst( This->m_pFilterList );
while ( pItem != NULL )
{
pFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr( pItem );
hrCur = IBaseFilter_SetSyncSource(pFilter,pobjClock);
if ( FAILED(hrCur) )
hr = hrCur;
pItem = QUARTZ_CompList_GetNext( This->m_pFilterList, pItem );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
if ( This->m_pClock != NULL )
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_CLOCK_CHANGED, 0, 0);
else
IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
EC_CLOCK_UNSET, 0, 0);
LeaveCriticalSection( &This->m_csClock );
TRACE( "hr = %08lx\n", hr );
return hr;
} }
static HRESULT WINAPI static HRESULT WINAPI
IMediaFilter_fnGetSyncSource(IMediaFilter* iface,IReferenceClock** ppobjClock) IMediaFilter_fnGetSyncSource(IMediaFilter* iface,IReferenceClock** ppobjClock)
{ {
CFilterGraph_THIS(iface,mediafilter); CFilterGraph_THIS(iface,mediafilter);
HRESULT hr = VFW_E_NO_CLOCK;
TRACE("(%p)->(%p)\n",This,ppobjClock);
if ( ppobjClock == NULL )
return E_POINTER;
EnterCriticalSection( &This->m_csClock );
*ppobjClock = This->m_pClock;
if ( This->m_pClock != NULL )
{
hr = NOERROR;
IReferenceClock_AddRef( This->m_pClock );
}
LeaveCriticalSection( &This->m_csClock );
FIXME("(%p)->() stub!\n",This); TRACE( "hr = %08lx\n", hr );
return E_NOTIMPL; return hr;
} }
...@@ -342,7 +414,9 @@ HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg ) ...@@ -342,7 +414,9 @@ HRESULT CFilterGraph_InitIMediaFilter( CFilterGraph* pfg )
ICOM_VTBL(&pfg->mediafilter) = &imediafilter; ICOM_VTBL(&pfg->mediafilter) = &imediafilter;
InitializeCriticalSection( &pfg->m_csGraphState ); InitializeCriticalSection( &pfg->m_csGraphState );
InitializeCriticalSection( &pfg->m_csClock );
pfg->m_stateGraph = State_Stopped; pfg->m_stateGraph = State_Stopped;
pfg->m_pClock = NULL;
return NOERROR; return NOERROR;
} }
...@@ -351,5 +425,12 @@ void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg ) ...@@ -351,5 +425,12 @@ void CFilterGraph_UninitIMediaFilter( CFilterGraph* pfg )
{ {
TRACE("(%p)\n",pfg); TRACE("(%p)\n",pfg);
if ( pfg->m_pClock != NULL )
{
IReferenceClock_Release( pfg->m_pClock );
pfg->m_pClock = NULL;
}
DeleteCriticalSection( &pfg->m_csGraphState ); DeleteCriticalSection( &pfg->m_csGraphState );
DeleteCriticalSection( &pfg->m_csClock );
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
* Implementation of IMediaSeeking for FilterGraph. * Implementation of IMediaSeeking for FilterGraph.
* *
* FIXME - stub. * FIXME - stub.
* FIXME - this interface should be allocated as a plug-in(?)
* *
* hidenori@a2.ctktv.ne.jp * hidenori@a2.ctktv.ne.jp
*/ */
...@@ -133,6 +134,7 @@ IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration) ...@@ -133,6 +134,7 @@ IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
{ {
CFilterGraph_THIS(iface,mediaseeking); CFilterGraph_THIS(iface,mediaseeking);
/* the following line may produce too many FIXMEs... */
FIXME("(%p)->() stub!\n",This); FIXME("(%p)->() stub!\n",This);
return E_NOTIMPL; return E_NOTIMPL;
......
/*
* Implementation of CLSID_SystemClock.
*
* FIXME - not tested yet.
*
* hidenori@a2.ctktv.ne.jp
*/
#include "config.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.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 "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)
{
CSystemClock_THIS(iface,refclk);
TRACE("(%p)->()\n",This);
return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}
static ULONG WINAPI
IReferenceClock_fnAddRef(IReferenceClock* iface)
{
CSystemClock_THIS(iface,refclk);
TRACE("(%p)->()\n",This);
return IUnknown_AddRef(This->unk.punkControl);
}
static ULONG WINAPI
IReferenceClock_fnRelease(IReferenceClock* iface)
{
CSystemClock_THIS(iface,refclk);
TRACE("(%p)->()\n",This);
return IUnknown_Release(This->unk.punkControl);
}
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) * (REFERENCE_TIME)10000;
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;
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;
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;
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 =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown fields */
IReferenceClock_fnQueryInterface,
IReferenceClock_fnAddRef,
IReferenceClock_fnRelease,
/* IReferenceClock fields */
IReferenceClock_fnGetTime,
IReferenceClock_fnAdviseTime,
IReferenceClock_fnAdvisePeriodic,
IReferenceClock_fnUnadvise,
};
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 );
}
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