Started implementing AVI splitter.
Implemented AsyncSource.
Merged some C sources.
Fixed some bugs.

diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in
index 2075644..2ebbea5 100644
--- a/dlls/quartz/Makefile.in
+++ b/dlls/quartz/Makefile.in
@@ -11,7 +11,9 @@
 C_SRCS = \
 	amundoc.c \
 	asyncsrc.c \
+	audioutl.c \
 	audren.c \
+	aviparse.c \
 	basefilt.c \
 	basepin.c \
 	complist.c \
@@ -19,14 +21,10 @@
 	devmon.c \
 	enumunk.c \
 	fgevent.c \
-	fgidisp.c \
 	fgpass.c \
 	fgraph.c \
 	fmap.c \
-	fmap2.c \
 	ifgraph.c \
-	igconfig.c \
-	igrver.c \
 	imcntl.c \
 	imfilter.c \
 	impos.c \
diff --git a/dlls/quartz/asyncsrc.c b/dlls/quartz/asyncsrc.c
index a5cd0d0..fcc54b3 100644
--- a/dlls/quartz/asyncsrc.c
+++ b/dlls/quartz/asyncsrc.c
@@ -1,7 +1,7 @@
 /*
  * Implements Asynchronous File/URL Source.
  *
- * FIXME - not work yet.
+ * FIXME - URL source is not implemented yet.
  *
  * hidenori@a2.ctktv.ne.jp
  */
@@ -13,7 +13,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "strmif.h"
 #include "vfwmsgs.h"
 #include "uuids.h"
@@ -26,41 +25,192 @@
 #include "memalloc.h"
 
 
+
+const WCHAR QUARTZ_wszAsyncFileSourceName[] =
+{'F','i','l','e',' ','S','o','u','r','c','e',' ','(','A','s','y','n','c','.',')',0};
+const WCHAR QUARTZ_wszAsyncFileSourcePinName[] =
+{'O','u','t',0};
+const WCHAR QUARTZ_wszAsyncURLSourceName[] =
+{'F','i','l','e',' ','S','o','u','r','c','e',' ','(','U','R','L',')',0};
+const WCHAR QUARTZ_wszAsyncURLSourcePinName[] =
+{'O','u','t',0};
+
+
+
 /***************************************************************************
  *
  *	CAsyncReaderImpl internal methods
  *
  */
 
+static
+AsyncSourceRequest* CAsyncReaderImpl_AllocRequest( CAsyncReaderImpl* This )
+{
+	AsyncSourceRequest* pReq;
+
+	EnterCriticalSection( &This->m_csFree );
+	pReq = This->m_pFreeFirst;
+	if ( pReq != NULL )
+		This->m_pFreeFirst = pReq->pNext;
+	LeaveCriticalSection( &This->m_csFree );
+
+	if ( pReq == NULL )
+	{
+		pReq = (AsyncSourceRequest*)QUARTZ_AllocMem(
+			sizeof(AsyncSourceRequest) );
+		if ( pReq == NULL )
+			return NULL;
+	}
+
+	pReq->pNext = NULL;
+	pReq->llStart = 0;
+	pReq->lLength = 0;
+	pReq->lActual = 0;
+	pReq->pBuf = NULL;
+	pReq->pSample = NULL;
+	pReq->dwContext = 0;
+
+	return pReq;
+}
+
+static
+void CAsyncReaderImpl_FreeRequest( CAsyncReaderImpl* This, AsyncSourceRequest* pReq, BOOL bReleaseMem )
+{
+	if ( !bReleaseMem )
+	{
+		EnterCriticalSection( &This->m_csFree );
+		pReq->pNext = This->m_pFreeFirst;
+		This->m_pFreeFirst = pReq;
+		LeaveCriticalSection( &This->m_csFree );
+	}
+	else
+	{
+		QUARTZ_FreeMem( pReq );
+	}
+}
+
+static
+AsyncSourceRequest* CAsyncReaderImpl_GetRequest( CAsyncReaderImpl* This )
+{
+	AsyncSourceRequest*	pReq;
+
+	EnterCriticalSection( &This->m_csRequest );
+	pReq = This->m_pRequestFirst;
+	if ( pReq != NULL )
+		This->m_pRequestFirst = pReq->pNext;
+	LeaveCriticalSection( &This->m_csRequest );
+
+	return pReq;
+}
+
+static
+AsyncSourceRequest* CAsyncReaderImpl_GetReply( CAsyncReaderImpl* This )
+{
+	AsyncSourceRequest*	pReq;
+
+	EnterCriticalSection( &This->m_csReply );
+	pReq = This->m_pReplyFirst;
+	if ( pReq != NULL )
+		This->m_pReplyFirst = pReq->pNext;
+	LeaveCriticalSection( &This->m_csReply );
+
+	return pReq;
+}
+
+static
+void CAsyncReaderImpl_PostRequest( CAsyncReaderImpl* This, AsyncSourceRequest* pReq )
+{
+	/* FIXME - add to tail */
+	EnterCriticalSection( &This->m_csRequest );
+	pReq->pNext = This->m_pRequestFirst;
+	This->m_pRequestFirst = pReq;
+	if ( This->m_hEventReqQueued != (HANDLE)NULL )
+		SetEvent( This->m_hEventReqQueued );
+	LeaveCriticalSection( &This->m_csRequest );
+}
+
+static
+void CAsyncReaderImpl_PostReply( CAsyncReaderImpl* This, AsyncSourceRequest* pReq )
+{
+	/* FIXME - add to tail */
+	EnterCriticalSection( &This->m_csReply );
+	pReq->pNext = This->m_pReplyFirst;
+	This->m_pReplyFirst = pReq;
+	if ( This->m_hEventSampQueued != (HANDLE)NULL )
+		SetEvent( This->m_hEventSampQueued );
+	LeaveCriticalSection( &This->m_csReply );
+}
+
+static
+void CAsyncReaderImpl_ReleaseReqList( CAsyncReaderImpl* This, AsyncSourceRequest* pReq, BOOL bReleaseMem )
+{
+	AsyncSourceRequest* pReqNext;
+
+	while ( pReq != NULL )
+	{
+		pReqNext = pReq->pNext;
+		CAsyncReaderImpl_FreeRequest(This,pReq,bReleaseMem);
+		pReq = pReqNext;
+	}
+}
+
 static DWORD WINAPI
 CAsyncReaderImpl_ThreadEntry( LPVOID pv )
 {
 	CAsyncReaderImpl*	This = (CAsyncReaderImpl*)pv;
 	HANDLE hWaitEvents[2];
-	HANDLE hReadEvents[2];
+	HRESULT hr;
 	DWORD	dwRes;
+	AsyncSourceRequest*	pReq = NULL;
 
 	SetEvent( This->m_hEventInit );
 
 	hWaitEvents[0] = This->m_hEventReqQueued;
-	hWaitEvents[1] = This->m_hEventAbort;
+	hWaitEvents[1] = This->m_hEventCancel;
 
-	hReadEvents[0] = This->m_hEventSampQueued;
-	hReadEvents[1] = This->m_hEventAbort;
+	TRACE("enter message loop.\n");
 
 	while ( 1 )
 	{
-		dwRes = WaitForMultipleObjects(2,hWaitEvents,FALSE,INFINITE);
-		if ( dwRes != WAIT_OBJECT_0 )
-			break;
+		ResetEvent( This->m_hEventReqQueued );
+		pReq = CAsyncReaderImpl_GetRequest(This);
+		if ( pReq == NULL )
+		{
+			dwRes = WaitForMultipleObjects(2,hWaitEvents,FALSE,INFINITE);
+			if ( dwRes != WAIT_OBJECT_0 )
+			{
+				if ( This->m_bAbortThread )
+					break;
+			}
+			continue;
+		}
 
-		/* FIXME - process a queued request */
+		/* process a queued request */
+		EnterCriticalSection( &This->m_csReader );
+		hr = This->pSource->m_pHandler->pRead( This->pSource, pReq->llStart, pReq->lLength, pReq->pBuf, &pReq->lActual, This->m_hEventCancel );
+		LeaveCriticalSection( &This->m_csReader );
 
-		dwRes = WaitForMultipleObjects(2,hReadEvents,FALSE,INFINITE);
-		if ( dwRes != WAIT_OBJECT_0 )
+		if ( FAILED(hr) )
+		{
+			/* Notify(ABORT) */
 			break;
+		}
+		if ( hr != S_OK )
+		{
+			if ( This->m_bAbortThread )
+				break;
+			ResetEvent( This->m_hEventCancel );
+		}
+
+		CAsyncReaderImpl_PostReply( This, pReq );
+		SetEvent( This->m_hEventSampQueued );
+		pReq = NULL;
 	}
 
+	if ( pReq != NULL )
+		CAsyncReaderImpl_PostRequest( This, pReq );
+
+	SetEvent( This->m_hEventSampQueued );
 	return 0;
 }
 
@@ -72,18 +222,18 @@
 	HANDLE hEvents[2];
 
 	if ( This->m_hEventInit != (HANDLE)NULL ||
-		 This->m_hEventAbort != (HANDLE)NULL ||
+		 This->m_hEventCancel != (HANDLE)NULL ||
 		 This->m_hEventReqQueued != (HANDLE)NULL ||
 		 This->m_hEventSampQueued != (HANDLE)NULL ||
-		 This->m_hEventCompletion != (HANDLE)NULL ||
 		 This->m_hThread != (HANDLE)NULL )
 		return E_UNEXPECTED;
+	This->m_bAbortThread = FALSE;
 
 	This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
 	if ( This->m_hEventInit == (HANDLE)NULL )
 		return E_OUTOFMEMORY;
-	This->m_hEventAbort = CreateEventA(NULL,TRUE,FALSE,NULL);
-	if ( This->m_hEventAbort == (HANDLE)NULL )
+	This->m_hEventCancel = CreateEventA(NULL,TRUE,FALSE,NULL);
+	if ( This->m_hEventCancel == (HANDLE)NULL )
 		return E_OUTOFMEMORY;
 	This->m_hEventReqQueued = CreateEventA(NULL,TRUE,FALSE,NULL);
 	if ( This->m_hEventReqQueued == (HANDLE)NULL )
@@ -91,9 +241,6 @@
 	This->m_hEventSampQueued = CreateEventA(NULL,TRUE,FALSE,NULL);
 	if ( This->m_hEventSampQueued == (HANDLE)NULL )
 		return E_OUTOFMEMORY;
-	This->m_hEventCompletion = CreateEventA(NULL,TRUE,FALSE,NULL);
-	if ( This->m_hEventCompletion == (HANDLE)NULL )
-		return E_OUTOFMEMORY;
 
 	/* create the processing thread. */
 	This->m_hThread = CreateThread(
@@ -119,9 +266,13 @@
 {
 	if ( This->m_hThread != (HANDLE)NULL )
 	{
-		SetEvent( This->m_hEventAbort );
-
-		WaitForSingleObject( This->m_hThread, INFINITE );
+		while ( 1 )
+		{
+			This->m_bAbortThread = TRUE;
+			SetEvent( This->m_hEventCancel );
+			if ( WaitForSingleObject( This->m_hThread, 100 ) == WAIT_OBJECT_0 )
+				break;
+		}
 		CloseHandle( This->m_hThread );
 		This->m_hThread = (HANDLE)NULL;
 	}
@@ -130,10 +281,10 @@
 		CloseHandle( This->m_hEventInit );
 		This->m_hEventInit = (HANDLE)NULL;
 	}
-	if ( This->m_hEventAbort != (HANDLE)NULL )
+	if ( This->m_hEventCancel != (HANDLE)NULL )
 	{
-		CloseHandle( This->m_hEventAbort );
-		This->m_hEventAbort = (HANDLE)NULL;
+		CloseHandle( This->m_hEventCancel );
+		This->m_hEventCancel = (HANDLE)NULL;
 	}
 	if ( This->m_hEventReqQueued != (HANDLE)NULL )
 	{
@@ -145,11 +296,6 @@
 		CloseHandle( This->m_hEventSampQueued );
 		This->m_hEventSampQueued = (HANDLE)NULL;
 	}
-	if ( This->m_hEventCompletion != (HANDLE)NULL )
-	{
-		CloseHandle( This->m_hEventCompletion );
-		This->m_hEventCompletion = (HANDLE)NULL;
-	}
 }
 
 /***************************************************************************
@@ -233,52 +379,146 @@
 CAsyncReaderImpl_fnRequest(IAsyncReader* iface,IMediaSample* pSample,DWORD_PTR dwContext)
 {
 	ICOM_THIS(CAsyncReaderImpl,iface);
+	HRESULT hr = NOERROR;
+	REFERENCE_TIME	rtStart;
+	REFERENCE_TIME	rtEnd;
+	AsyncSourceRequest*	pReq;
+	BYTE*	pData = NULL;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%p,%u)\n",This,pSample,dwContext);
 
-	EnterCriticalSection( This->pcsReader );
-	LeaveCriticalSection( This->pcsReader );
+	hr = IMediaSample_GetPointer(pSample,&pData);
+	if ( SUCCEEDED(hr) )
+		hr = IMediaSample_GetTime(pSample,&rtStart,&rtEnd);
+	if ( FAILED(hr) )
+		return hr;
 
-	return E_NOTIMPL;
+	pReq = CAsyncReaderImpl_AllocRequest(This);
+	if ( pReq == NULL )
+		return E_OUTOFMEMORY;
+
+	pReq->llStart = rtStart / QUARTZ_TIMEUNITS;
+	pReq->lLength = (LONG)(rtEnd / QUARTZ_TIMEUNITS - rtStart / QUARTZ_TIMEUNITS);
+	pReq->lActual = 0;
+	pReq->pBuf = pData;
+	pReq->pSample = pSample;
+	pReq->dwContext = dwContext;
+	CAsyncReaderImpl_PostRequest( This, pReq );
+
+	return NOERROR;
 }
 
 static HRESULT WINAPI
-CAsyncReaderImpl_fnWaitForNext(IAsyncReader* iface,DWORD dwTimeout,IMediaSample** pSample,DWORD_PTR* pdwContext)
+CAsyncReaderImpl_fnWaitForNext(IAsyncReader* iface,DWORD dwTimeout,IMediaSample** ppSample,DWORD_PTR* pdwContext)
 {
 	ICOM_THIS(CAsyncReaderImpl,iface);
+	HRESULT hr = NOERROR;
+	DWORD dwRes;
+	AsyncSourceRequest*	pReq;
+	REFERENCE_TIME	rtStart;
+	REFERENCE_TIME	rtEnd;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%lu,%p,%p)\n",This,dwTimeout,ppSample,pdwContext);
 
-	EnterCriticalSection( This->pcsReader );
-	LeaveCriticalSection( This->pcsReader );
+	EnterCriticalSection( &This->m_csRequest );
+	if ( This->m_bInFlushing )
+		hr = VFW_E_TIMEOUT;
+	LeaveCriticalSection( &This->m_csRequest );
 
-	return E_NOTIMPL;
+	if ( hr == NOERROR )
+	{
+		ResetEvent( This->m_hEventSampQueued );
+		pReq = CAsyncReaderImpl_GetReply(This);
+		if ( pReq == NULL )
+		{
+			dwRes = WaitForSingleObject( This->m_hEventSampQueued, dwTimeout );
+			if ( dwRes == WAIT_OBJECT_0 )
+				pReq = CAsyncReaderImpl_GetReply(This);
+		}
+		if ( pReq != NULL )
+		{
+			hr = IMediaSample_SetActualDataLength(pReq->pSample,pReq->lActual);
+			if ( hr == S_OK )
+			{
+				rtStart = pReq->llStart * QUARTZ_TIMEUNITS;
+				rtEnd = (pReq->llStart + pReq->lActual) * QUARTZ_TIMEUNITS;
+				hr = IMediaSample_SetTime(pReq->pSample,&rtStart,&rtEnd);
+			}
+			*ppSample = pReq->pSample;
+			*pdwContext = pReq->dwContext;
+			if ( hr == S_OK && pReq->lActual != pReq->lLength )
+				hr = S_FALSE;
+		}
+		else
+		{
+			hr = VFW_E_TIMEOUT;
+		}
+	}
+
+	return hr;
 }
 
 static HRESULT WINAPI
 CAsyncReaderImpl_fnSyncReadAligned(IAsyncReader* iface,IMediaSample* pSample)
 {
 	ICOM_THIS(CAsyncReaderImpl,iface);
+	HRESULT hr;
+	REFERENCE_TIME	rtStart;
+	REFERENCE_TIME	rtEnd;
+	BYTE*	pData = NULL;
+	LONGLONG	llStart;
+	LONG	lLength;
+	LONG	lActual;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->(%p)\n",This,pSample);
 
-	EnterCriticalSection( This->pcsReader );
-	LeaveCriticalSection( This->pcsReader );
+	hr = IMediaSample_GetPointer(pSample,&pData);
+	if ( SUCCEEDED(hr) )
+		hr = IMediaSample_GetTime(pSample,&rtStart,&rtEnd);
+	if ( FAILED(hr) )
+		return hr;
 
-	return E_NOTIMPL;
+	llStart = rtStart / QUARTZ_TIMEUNITS;
+	lLength = (LONG)(rtEnd / QUARTZ_TIMEUNITS - rtStart / QUARTZ_TIMEUNITS);
+	lActual = 0;
+
+	EnterCriticalSection( &This->m_csReader );
+	hr = This->pSource->m_pHandler->pRead( This->pSource, llStart, lLength, pData, &lActual, (HANDLE)NULL );
+	LeaveCriticalSection( &This->m_csReader );
+
+	if ( hr == NOERROR )
+	{
+		hr = IMediaSample_SetActualDataLength(pSample,lActual);
+		if ( hr == S_OK )
+		{
+			rtStart = llStart * QUARTZ_TIMEUNITS;
+			rtEnd = (llStart + lActual) * QUARTZ_TIMEUNITS;
+			hr = IMediaSample_SetTime(pSample,&rtStart,&rtEnd);
+		}
+		if ( hr == S_OK && lActual != lLength )
+			hr = S_FALSE;
+	}
+
+	return hr;
 }
 
 static HRESULT WINAPI
 CAsyncReaderImpl_fnSyncRead(IAsyncReader* iface,LONGLONG llPosStart,LONG lLength,BYTE* pbBuf)
 {
 	ICOM_THIS(CAsyncReaderImpl,iface);
+	HRESULT hr;
+	LONG lActual;
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->()\n",This);
 
-	EnterCriticalSection( This->pcsReader );
-	LeaveCriticalSection( This->pcsReader );
+	EnterCriticalSection( &This->m_csReader );
+	hr = This->pSource->m_pHandler->pRead( This->pSource, llPosStart, lLength, pbBuf, &lActual, (HANDLE)NULL );
+	LeaveCriticalSection( &This->m_csReader );
 
-	return E_NOTIMPL;
+	if ( hr == S_OK && lLength != lActual )
+		hr = S_FALSE;
+
+	return hr;
 }
 
 static HRESULT WINAPI
@@ -289,9 +529,7 @@
 
 	TRACE("(%p)->()\n",This);
 
-	EnterCriticalSection( This->pcsReader );
 	hr = This->pSource->m_pHandler->pGetLength( This->pSource, pllTotal, pllAvailable );
-	LeaveCriticalSection( This->pcsReader );
 
 	return hr;
 }
@@ -301,12 +539,15 @@
 {
 	ICOM_THIS(CAsyncReaderImpl,iface);
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->()\n",This);
 
-	EnterCriticalSection( This->pcsReader );
-	LeaveCriticalSection( This->pcsReader );
+	EnterCriticalSection( &This->m_csRequest );
+	This->m_bInFlushing = TRUE;
+	SetEvent( This->m_hEventCancel );
+	CAsyncReaderImpl_ReleaseReqList(This,This->m_pRequestFirst,FALSE);
+	LeaveCriticalSection( &This->m_csRequest );
 
-	return E_NOTIMPL;
+	return NOERROR;
 }
 
 static HRESULT WINAPI
@@ -314,12 +555,14 @@
 {
 	ICOM_THIS(CAsyncReaderImpl,iface);
 
-	FIXME("(%p)->() stub!\n",This);
+	TRACE("(%p)->()\n",This);
 
-	EnterCriticalSection( This->pcsReader );
-	LeaveCriticalSection( This->pcsReader );
+	EnterCriticalSection( &This->m_csRequest );
+	This->m_bInFlushing = FALSE;
+	ResetEvent( This->m_hEventCancel );
+	LeaveCriticalSection( &This->m_csRequest );
 
-	return E_NOTIMPL;
+	return NOERROR;
 }
 
 
@@ -344,8 +587,7 @@
 
 HRESULT CAsyncReaderImpl_InitIAsyncReader(
 	CAsyncReaderImpl* This, IUnknown* punkControl,
-	CAsyncSourceImpl* pSource,
-	CRITICAL_SECTION* pcsReader )
+	CAsyncSourceImpl* pSource )
 {
 	TRACE("(%p,%p)\n",This,punkControl);
 
@@ -358,13 +600,21 @@
 	ICOM_VTBL(This) = &iasyncreader;
 	This->punkControl = punkControl;
 	This->pSource = pSource;
-	This->pcsReader = pcsReader;
+	This->m_bInFlushing = FALSE;
+	This->m_bAbortThread = FALSE;
 	This->m_hEventInit = (HANDLE)NULL;
-	This->m_hEventAbort = (HANDLE)NULL;
+	This->m_hEventCancel = (HANDLE)NULL;
 	This->m_hEventReqQueued = (HANDLE)NULL;
 	This->m_hEventSampQueued = (HANDLE)NULL;
-	This->m_hEventCompletion = (HANDLE)NULL;
 	This->m_hThread = (HANDLE)NULL;
+	This->m_pRequestFirst = NULL;
+	This->m_pReplyFirst = NULL;
+	This->m_pFreeFirst = NULL;
+
+	InitializeCriticalSection( &This->m_csReader );
+	InitializeCriticalSection( &This->m_csRequest );
+	InitializeCriticalSection( &This->m_csReply );
+	InitializeCriticalSection( &This->m_csFree );
 
 	return NOERROR;
 }
@@ -373,6 +623,15 @@
 	CAsyncReaderImpl* This )
 {
 	TRACE("(%p)\n",This);
+
+	CAsyncReaderImpl_ReleaseReqList(This,This->m_pRequestFirst,TRUE);
+	CAsyncReaderImpl_ReleaseReqList(This,This->m_pReplyFirst,TRUE);
+	CAsyncReaderImpl_ReleaseReqList(This,This->m_pFreeFirst,TRUE);
+
+	DeleteCriticalSection( &This->m_csReader );
+	DeleteCriticalSection( &This->m_csRequest );
+	DeleteCriticalSection( &This->m_csReply );
+	DeleteCriticalSection( &This->m_csFree );
 }
 
 /***************************************************************************
@@ -450,6 +709,9 @@
 	if ( FAILED(hr) )
 		goto err;
 
+	This->pSource->pPin->pin.pmtAcceptTypes = &This->m_mt;
+	This->pSource->pPin->pin.cAcceptTypes = 1;
+
 	return NOERROR;
 err:;
 	return hr;
@@ -544,6 +806,8 @@
 {
 	CAsyncSourcePinImpl_THIS(pImpl,pin);
 
+	TRACE("(%p,%p)\n",This,pPin);
+
 	This->bAsyncReaderQueried = FALSE;
 
 	return NOERROR;
@@ -553,6 +817,8 @@
 {
 	CAsyncSourcePinImpl_THIS(pImpl,pin);
 
+	TRACE("(%p,%p)\n",This,pPin);
+
 	if ( !This->bAsyncReaderQueried )
 		return E_FAIL;
 
@@ -563,6 +829,8 @@
 {
 	CAsyncSourcePinImpl_THIS(pImpl,pin);
 
+	TRACE("(%p)\n",This);
+
 	This->bAsyncReaderQueried = FALSE;
 
 	return NOERROR;
@@ -723,7 +991,14 @@
 	InitializeCriticalSection( &This->csFilter );
 
 	/* create the output pin. */
-	hr = S_OK;
+	hr = QUARTZ_CreateAsyncSourcePin(
+		This, &This->csFilter,
+		&This->pPin, pwszOutPinName );
+	if ( SUCCEEDED(hr) )
+		hr = QUARTZ_CompList_AddComp(
+			This->basefilter.pOutPins,
+			(IUnknown*)&(This->pPin->pin),
+			NULL, 0 );
 
 	if ( FAILED(hr) )
 	{
@@ -756,6 +1031,7 @@
 
 	if ( IsEqualGUID( &IID_IAsyncReader, piid ) )
 	{
+		TRACE("IAsyncReader has been queried.\n");
 		*ppobj = (void*)&This->async;
 		IUnknown_AddRef(punk);
 		This->bAsyncReaderQueried = TRUE;
@@ -813,8 +1089,7 @@
 		hr = CAsyncReaderImpl_InitIAsyncReader(
 			&This->async,
 			This->unk.punkControl,
-			pFilter,
-			pcsPin );
+			pFilter );
 		if ( FAILED(hr) )
 		{
 			CPinBaseImpl_UninitIPin( &This->pin );
@@ -838,3 +1113,231 @@
 	return S_OK;
 }
 
+
+
+/***************************************************************************
+ *
+ *	Implements File Source.
+ *
+ */
+
+typedef struct AsyncSourceFileImpl
+{
+	HANDLE	hFile;
+	LONGLONG	llTotal;
+} AsyncSourceFileImpl;
+
+
+static HRESULT AsyncSourceFileImpl_Load( CAsyncSourceImpl* pImpl, LPCWSTR lpwszSourceName )
+{
+	AsyncSourceFileImpl*	This = (AsyncSourceFileImpl*)pImpl->m_pUserData;
+	DWORD	dwLow;
+	DWORD	dwHigh;
+
+	if ( This != NULL )
+		return E_UNEXPECTED;
+	This = (AsyncSourceFileImpl*)QUARTZ_AllocMem( sizeof(AsyncSourceFileImpl) );
+	pImpl->m_pUserData = (void*)This;
+	if ( This == NULL )
+		return E_OUTOFMEMORY;
+	This->hFile = INVALID_HANDLE_VALUE;
+	This->llTotal = 0;
+
+	This->hFile = CreateFileW( lpwszSourceName,
+		GENERIC_READ, FILE_SHARE_READ,
+		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL );
+	if ( This->hFile == INVALID_HANDLE_VALUE )
+		return E_FAIL;
+
+	SetLastError(NO_ERROR);
+	dwLow = GetFileSize( This->hFile, &dwHigh );
+	if ( dwLow == 0xffffffff && GetLastError() != NO_ERROR )
+		return E_FAIL;
+
+	This->llTotal = (LONGLONG)dwLow | ((LONGLONG)dwHigh << 32);
+
+	return NOERROR;
+}
+
+static HRESULT AsyncSourceFileImpl_Cleanup( CAsyncSourceImpl* pImpl )
+{
+	AsyncSourceFileImpl*	This = (AsyncSourceFileImpl*)pImpl->m_pUserData;
+
+	if ( This == NULL )
+		return NOERROR;
+
+	if ( This->hFile != INVALID_HANDLE_VALUE )
+		CloseHandle(This->hFile);
+
+	QUARTZ_FreeMem(This);
+	pImpl->m_pUserData = NULL;
+
+	return NOERROR;
+}
+
+static HRESULT AsyncSourceFileImpl_GetLength( CAsyncSourceImpl* pImpl, LONGLONG* pllTotal, LONGLONG* pllAvailable )
+{
+	AsyncSourceFileImpl*	This = (AsyncSourceFileImpl*)pImpl->m_pUserData;
+
+	if ( This == NULL )
+		return E_UNEXPECTED;
+
+	*pllTotal = This->llTotal;
+	*pllAvailable = This->llTotal;
+
+	return NOERROR;
+}
+
+static HRESULT AsyncSourceFileImpl_Read( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, LONG* plReturned, HANDLE hEventCancel )
+{
+	AsyncSourceFileImpl*	This = (AsyncSourceFileImpl*)pImpl->m_pUserData;
+	LONG	lReturned;
+	LONG	lBlock;
+	LONG	lOfsLow;
+	LONG	lOfsHigh;
+	DWORD	dw;
+	HRESULT hr = S_OK;
+
+	if ( This == NULL || This->hFile == INVALID_HANDLE_VALUE )
+		return E_UNEXPECTED;
+
+	lReturned = 0;
+
+	lOfsLow = (LONG)(llOfsStart & 0xffffffff);
+	lOfsHigh = (LONG)(llOfsStart >> 32);
+	SetLastError(NO_ERROR);
+	lOfsLow = SetFilePointer( This->hFile, lOfsLow, &lOfsHigh, FILE_BEGIN );
+	if ( lOfsLow == (LONG)0xffffffff && GetLastError() != NO_ERROR )
+		return E_FAIL;
+
+	while ( lLength > 0 )
+	{
+		if ( WaitForSingleObject( hEventCancel, 0 ) == WAIT_OBJECT_0 )
+		{
+			hr = S_FALSE;
+			break;
+		}
+
+		lBlock = ( lLength > ASYNCSRC_FILE_BLOCKSIZE ) ?
+			ASYNCSRC_FILE_BLOCKSIZE : lLength;
+
+		if ( !ReadFile(This->hFile,pBuf,(DWORD)lBlock,&dw,NULL) )
+		{
+			hr = E_FAIL;
+			break;
+		}
+		pBuf += dw;
+		lReturned += (LONG)dw;
+		lLength -= (LONG)dw;
+		if ( lBlock > (LONG)dw )
+			break;
+	}
+
+	*plReturned = lReturned;
+
+	return hr;
+}
+
+static const struct AsyncSourceHandlers asyncsrc_file =
+{
+	AsyncSourceFileImpl_Load,
+	AsyncSourceFileImpl_Cleanup,
+	AsyncSourceFileImpl_GetLength,
+	AsyncSourceFileImpl_Read,
+};
+
+HRESULT QUARTZ_CreateAsyncReader(IUnknown* punkOuter,void** ppobj)
+{
+	return QUARTZ_CreateAsyncSource(
+		punkOuter, ppobj,
+		&CLSID_AsyncReader,
+		QUARTZ_wszAsyncFileSourceName,
+		QUARTZ_wszAsyncFileSourcePinName,
+		&asyncsrc_file );
+}
+
+/***************************************************************************
+ *
+ *	Implements URL Source.
+ *
+ */
+
+typedef struct AsyncSourceURLImpl
+{
+	DWORD dwDummy;
+} AsyncSourceURLImpl;
+
+
+static HRESULT AsyncSourceURLImpl_Load( CAsyncSourceImpl* pImpl, LPCWSTR lpwszSourceName )
+{
+	AsyncSourceURLImpl*	This = (AsyncSourceURLImpl*)pImpl->m_pUserData;
+
+	FIXME("(%p,%p) stub!\n", pImpl, lpwszSourceName);
+
+	if ( This != NULL )
+		return E_UNEXPECTED;
+	This = (AsyncSourceURLImpl*)QUARTZ_AllocMem( sizeof(AsyncSourceURLImpl) );
+	pImpl->m_pUserData = (void*)This;
+	if ( This == NULL )
+		return E_OUTOFMEMORY;
+
+	return E_NOTIMPL;
+}
+
+static HRESULT AsyncSourceURLImpl_Cleanup( CAsyncSourceImpl* pImpl )
+{
+	AsyncSourceURLImpl*	This = (AsyncSourceURLImpl*)pImpl->m_pUserData;
+
+	FIXME("(%p) stub!\n", This);
+
+	if ( This == NULL )
+		return NOERROR;
+
+	QUARTZ_FreeMem(This);
+	pImpl->m_pUserData = NULL;
+
+	return NOERROR;
+}
+
+static HRESULT AsyncSourceURLImpl_GetLength( CAsyncSourceImpl* pImpl, LONGLONG* pllTotal, LONGLONG* pllAvailable )
+{
+	AsyncSourceURLImpl*	This = (AsyncSourceURLImpl*)pImpl->m_pUserData;
+
+	FIXME("(%p,%p,%p) stub!\n", This, pllTotal, pllAvailable);
+
+	if ( This == NULL )
+		return E_UNEXPECTED;
+
+	return E_NOTIMPL;
+}
+
+static HRESULT AsyncSourceURLImpl_Read( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, LONG* plReturned, HANDLE hEventCancel )
+{
+	AsyncSourceURLImpl*	This = (AsyncSourceURLImpl*)pImpl->m_pUserData;
+
+	FIXME("(%p) stub!\n", This);
+
+	if ( This == NULL )
+		return E_UNEXPECTED;
+
+	return E_NOTIMPL;
+}
+
+static const struct AsyncSourceHandlers asyncsrc_url =
+{
+	AsyncSourceURLImpl_Load,
+	AsyncSourceURLImpl_Cleanup,
+	AsyncSourceURLImpl_GetLength,
+	AsyncSourceURLImpl_Read,
+};
+
+
+HRESULT QUARTZ_CreateURLReader(IUnknown* punkOuter,void** ppobj)
+{
+	return QUARTZ_CreateAsyncSource(
+		punkOuter, ppobj,
+		&CLSID_URLReader,
+		QUARTZ_wszAsyncURLSourceName,
+		QUARTZ_wszAsyncURLSourcePinName,
+		&asyncsrc_url );
+}
diff --git a/dlls/quartz/asyncsrc.h b/dlls/quartz/asyncsrc.h
index 57e769d..ec1b6e2 100644
--- a/dlls/quartz/asyncsrc.h
+++ b/dlls/quartz/asyncsrc.h
@@ -12,6 +12,7 @@
 
 typedef struct CAsyncSourceImpl	CAsyncSourceImpl;
 typedef struct CAsyncSourcePinImpl	CAsyncSourcePinImpl;
+typedef struct AsyncSourceRequest	AsyncSourceRequest;
 typedef struct AsyncSourceHandlers	AsyncSourceHandlers;
 
 typedef struct CAsyncReaderImpl
@@ -23,13 +24,20 @@
 	/* IAsyncReader fields */
 	CAsyncSourceImpl*	pSource;
 
-	CRITICAL_SECTION*	pcsReader;
+	CRITICAL_SECTION	m_csReader;
+	BOOL	m_bInFlushing;
+	BOOL	m_bAbortThread;
 	HANDLE	m_hEventInit;
-	HANDLE	m_hEventAbort;
+	HANDLE	m_hEventCancel;
 	HANDLE	m_hEventReqQueued;
 	HANDLE	m_hEventSampQueued;
-	HANDLE	m_hEventCompletion;
 	HANDLE	m_hThread;
+	CRITICAL_SECTION	m_csRequest;
+	AsyncSourceRequest*	m_pRequestFirst;
+	CRITICAL_SECTION	m_csReply;
+	AsyncSourceRequest*	m_pReplyFirst;
+	CRITICAL_SECTION	m_csFree;
+	AsyncSourceRequest*	m_pFreeFirst;
 } CAsyncReaderImpl;
 
 typedef struct CFileSourceFilterImpl
@@ -70,15 +78,27 @@
 	CAsyncSourceImpl*	pSource;
 };
 
+struct AsyncSourceRequest
+{
+	AsyncSourceRequest*	pNext;
+
+	LONGLONG	llStart;
+	LONG	lLength;
+	LONG	lActual;
+	BYTE*	pBuf;
+	IMediaSample*	pSample; /* for async req. */
+	DWORD_PTR	dwContext; /* for async req. */
+};
+
 struct AsyncSourceHandlers
 {
 	/* all handlers MUST be implemented. */
 	HRESULT (*pLoad)( CAsyncSourceImpl* pImpl, LPCWSTR lpwszSourceName );
 	HRESULT (*pCleanup)( CAsyncSourceImpl* pImpl );
 	HRESULT (*pGetLength)( CAsyncSourceImpl* pImpl, LONGLONG* pllTotal, LONGLONG* pllAvailable );
-	HRESULT (*pReadAsync)( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, HANDLE hEventCompletion );
-	HRESULT (*pGetResult)( CAsyncSourceImpl* pImpl, LONG* plReturned );
-	HRESULT (*pCancelAsync)( CAsyncSourceImpl* pImpl );
+	/* S_OK = OK / S_FALSE = Canceled / other = error */
+	/* hEventCancel may be NULL */
+	HRESULT (*pRead)( CAsyncSourceImpl* pImpl, LONGLONG llOfsStart, LONG lLength, BYTE* pBuf, LONG* plReturned, HANDLE hEventCancel );
 };
 
 #define	CAsyncSourceImpl_THIS(iface,member)		CAsyncSourceImpl*	This = ((CAsyncSourceImpl*)(((char*)iface)-offsetof(CAsyncSourceImpl,member)))
@@ -87,8 +107,7 @@
 
 HRESULT CAsyncReaderImpl_InitIAsyncReader(
 	CAsyncReaderImpl* This, IUnknown* punkControl,
-	CAsyncSourceImpl* pSource,
-	CRITICAL_SECTION* pcsReader );
+	CAsyncSourceImpl* pSource );
 void CAsyncReaderImpl_UninitIAsyncReader(
 	CAsyncReaderImpl* This );
 HRESULT CFileSourceFilterImpl_InitIFileSourceFilter(
@@ -112,4 +131,10 @@
 	LPCWSTR pwszPinName );
 
 
+HRESULT QUARTZ_CreateAsyncReader(IUnknown* punkOuter,void** ppobj);
+HRESULT QUARTZ_CreateURLReader(IUnknown* punkOuter,void** ppobj);
+
+#define ASYNCSRC_FILE_BLOCKSIZE	4096
+
+
 #endif	/* WINE_DSHOW_ASYNCSRC_H */
diff --git a/dlls/quartz/audioutl.c b/dlls/quartz/audioutl.c
new file mode 100644
index 0000000..a9ef997
--- /dev/null
+++ b/dlls/quartz/audioutl.c
@@ -0,0 +1,63 @@
+/*
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "audioutl.h"
+
+
+void AUDIOUTL_ChangeSign8( BYTE* pbData, DWORD cbData )
+{
+	BYTE*	pbEnd = pbData + cbData;
+
+	while ( pbData < pbEnd )
+	{
+		*pbData ^= 0x80;
+		pbData ++;
+	}
+}
+
+void AUDIOUTL_ChangeSign16LE( BYTE* pbData, DWORD cbData )
+{
+	BYTE*	pbEnd = pbData + cbData;
+
+	pbData ++;
+	while ( pbData < pbEnd )
+	{
+		*pbData ^= 0x80;
+		pbData += 2;
+	}
+}
+
+void AUDIOUTL_ChangeSign16BE( BYTE* pbData, DWORD cbData )
+{
+	BYTE*	pbEnd = pbData + cbData;
+
+	while ( pbData < pbEnd )
+	{
+		*pbData ^= 0x80;
+		pbData += 2;
+	}
+}
+
+void AUDIOUTL_ByteSwap( BYTE* pbData, DWORD cbData )
+{
+	BYTE*	pbEnd = pbData + cbData - 1;
+	BYTE	bTemp;
+
+	while ( pbData < pbEnd )
+	{
+		bTemp = pbData[0];
+		pbData[0] = pbData[1];
+		pbData[1] = bTemp;
+		pbData += 2;
+	}
+}
+
+
diff --git a/dlls/quartz/audioutl.h b/dlls/quartz/audioutl.h
new file mode 100644
index 0000000..fcb8beb
--- /dev/null
+++ b/dlls/quartz/audioutl.h
@@ -0,0 +1,11 @@
+#ifndef QUARTZ_AUDIOUTL_H
+#define QUARTZ_AUDIOUTL_H
+
+
+void AUDIOUTL_ChangeSign8( BYTE* pbData, DWORD cbData );
+void AUDIOUTL_ChangeSign16LE( BYTE* pbData, DWORD cbData );
+void AUDIOUTL_ChangeSign16BE( BYTE* pbData, DWORD cbData );
+void AUDIOUTL_ByteSwap( BYTE* pbData, DWORD cbData );
+
+
+#endif  /* QUARTZ_AUDIOUTL_H */
diff --git a/dlls/quartz/audren.c b/dlls/quartz/audren.c
index 50e613e..92dc961 100644
--- a/dlls/quartz/audren.c
+++ b/dlls/quartz/audren.c
@@ -16,8 +16,6 @@
 #include "winuser.h"
 #include "mmsystem.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
-#include "wine/obj_oleaut.h"
 #include "strmif.h"
 #include "control.h"
 #include "vfwmsgs.h"
diff --git a/dlls/quartz/aviparse.c b/dlls/quartz/aviparse.c
new file mode 100644
index 0000000..6e94c4d
--- /dev/null
+++ b/dlls/quartz/aviparse.c
@@ -0,0 +1,695 @@
+/*
+ * Implements AVI Parser(Splitter).
+ *
+ * hidenori@a2.ctktv.ne.jp
+ */
+
+#include "config.h"
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "mmsystem.h"
+#include "vfw.h"
+#include "winerror.h"
+#include "strmif.h"
+#include "vfwmsgs.h"
+#include "amvideo.h"
+#include "uuids.h"
+
+#include "debugtools.h"
+DEFAULT_DEBUG_CHANNEL(quartz);
+
+#include "quartz_private.h"
+#include "parser.h"
+#include "mtype.h"
+
+
+
+static const WCHAR QUARTZ_AVIParser_Name[] =
+{ 'A','V','I',' ','S','p','l','i','t','t','e','r',0 };
+static const WCHAR QUARTZ_AVIParserInPin_Name[] =
+{ 'I','n',0 };
+static const WCHAR QUARTZ_AVIParserOutPin_Basename[] =
+{ 'S','t','r','e','a','m',0 };
+
+#define WINE_QUARTZ_AVIPINNAME_MAX	64
+
+/****************************************************************************
+ *
+ *	CAVIParseImpl
+ */
+
+
+typedef struct CAVIParseImpl CAVIParseImpl;
+typedef struct CAVIParseStream CAVIParseStream;
+
+struct CAVIParseImpl
+{
+	MainAVIHeader	avih;
+	CAVIParseStream*	pStreamsBuf;
+	DWORD	cIndexEntries;
+	AVIINDEXENTRY*	pIndexEntriesBuf;
+	WCHAR	wchWork[ WINE_QUARTZ_AVIPINNAME_MAX ];
+};
+
+struct CAVIParseStream
+{
+	AVIStreamHeader	strh;
+	DWORD	cbFmt;
+	BYTE*	pFmtBuf;
+	DWORD	cIndexEntries;
+	AVIINDEXENTRY*	pIndexEntries;
+	DWORD	cIndexCur;
+	REFERENCE_TIME	rtCur;
+	REFERENCE_TIME	rtInternal;
+};
+
+
+static HRESULT CAVIParseImpl_ParseStreamList(
+	CParserImpl* pImpl, CAVIParseImpl* This, ULONG nStreamIndex,
+	LONGLONG llOfsTop, DWORD dwListLen, CAVIParseStream* pStream )
+{
+	HRESULT hr;
+	LONGLONG	llOfs;
+	DWORD	dwChunkLength;
+
+	TRACE("search strh\n");
+	hr = RIFF_SearchChunk(
+		pImpl, dwListLen,
+		llOfsTop, PARSER_strh,
+		&llOfs, &dwChunkLength );
+	if ( hr == S_OK )
+	{
+		TRACE("strh has been detected\n");
+		if ( dwChunkLength < sizeof(AVIStreamHeader) )
+			hr = E_FAIL;
+		else
+			hr = IAsyncReader_SyncRead( pImpl->m_pReader,
+				llOfs, sizeof(AVIStreamHeader), (BYTE*)&pStream->strh );
+	}
+	if ( FAILED(hr) )
+		return hr;
+	if ( hr != S_OK )
+		return E_FAIL;
+
+	TRACE("search strf\n");
+	hr = RIFF_SearchChunk(
+		pImpl, dwListLen,
+		llOfsTop, PARSER_strf,
+		&llOfs, &dwChunkLength );
+	if ( hr == S_OK && dwChunkLength > 0 )
+	{
+		TRACE("strf has been detected\n");
+		pStream->cbFmt = dwChunkLength;
+		pStream->pFmtBuf = (BYTE*)QUARTZ_AllocMem( dwChunkLength );
+		if ( pStream->pFmtBuf == NULL )
+			hr = E_OUTOFMEMORY;
+		else
+			hr = IAsyncReader_SyncRead( pImpl->m_pReader,
+				llOfs, dwChunkLength, pStream->pFmtBuf );
+	}
+	if ( FAILED(hr) )
+		return hr;
+
+	TRACE("search indx\n");
+	hr = RIFF_SearchChunk(
+		pImpl, dwListLen,
+		llOfsTop, PARSER_indx,
+		&llOfs, &dwChunkLength );
+	if ( FAILED(hr) )
+		return hr;
+	if ( hr == S_OK )
+	{
+		FIXME( "'indx' has been detected - not implemented now!\n" );
+		return E_FAIL;
+	}
+
+	return NOERROR;
+}
+
+
+static HRESULT CAVIParseImpl_InitParser( CParserImpl* pImpl, ULONG* pcStreams )
+{
+	CAVIParseImpl*	This = NULL;
+	BYTE	riffhdr[12];
+	ULONG	i;
+	ULONG	nIndex;
+	HRESULT hr;
+	LONGLONG	llOfs_hdrl;
+	DWORD	dwLen_hdrl;
+	LONGLONG	llOfs;
+	DWORD	dwChunkId;
+	DWORD	dwChunkLength;
+	AVIINDEXENTRY*	pEntriesBuf = NULL;
+	ULONG	cEntries;
+	ULONG	cEntriesCur;
+
+	TRACE("(%p,%p)\n",pImpl,pcStreams);
+
+	hr = IAsyncReader_SyncRead( pImpl->m_pReader, 0, 12, riffhdr );
+	if ( FAILED(hr) )
+		return hr;
+	if ( hr != S_OK )
+		return E_FAIL;
+	if ( memcmp( &riffhdr[0], "RIFF", 4 ) != 0 ||
+		 memcmp( &riffhdr[8], "AVI ", 4 ) != 0 )
+		return E_FAIL;
+
+	TRACE("it's AVI\n");
+
+	This = (CAVIParseImpl*)QUARTZ_AllocMem( sizeof(CAVIParseImpl) );
+	if ( This == NULL )
+		return E_OUTOFMEMORY;
+	pImpl->m_pUserData = This;
+	ZeroMemory( This, sizeof(CAVIParseImpl) );
+	This->pStreamsBuf = NULL;
+	This->cIndexEntries = 0;
+	This->pIndexEntriesBuf = 0;
+
+	hr = RIFF_SearchList(
+		pImpl, (DWORD)0xffffffff,
+		PARSER_RIFF_OfsFirst, PARSER_hdrl,
+		&llOfs_hdrl, &dwLen_hdrl );
+	if ( FAILED(hr) )
+		return hr;
+	if ( hr != S_OK )
+		return E_FAIL;
+
+	/* read 'avih' */
+	TRACE("read avih\n");
+	hr = RIFF_SearchChunk(
+		pImpl, dwLen_hdrl,
+		llOfs_hdrl, PARSER_avih,
+		&llOfs, &dwChunkLength );
+	if ( FAILED(hr) )
+		return hr;
+	if ( hr != S_OK )
+		return E_FAIL;
+
+	if ( dwChunkLength > sizeof(MainAVIHeader) )
+		dwChunkLength = sizeof(MainAVIHeader);
+	hr = IAsyncReader_SyncRead( pImpl->m_pReader, llOfs, dwChunkLength, (BYTE*)&(This->avih) );
+	if ( FAILED(hr) )
+		return hr;
+	if ( hr != S_OK )
+		return E_FAIL;
+	if ( This->avih.dwStreams == 0 )
+		return E_FAIL;
+
+	/* initialize streams. */
+	This->pStreamsBuf = (CAVIParseStream*)QUARTZ_AllocMem(
+		sizeof(CAVIParseStream) * This->avih.dwStreams );
+	if ( This->pStreamsBuf == NULL )
+		return E_OUTOFMEMORY;
+	ZeroMemory( This->pStreamsBuf,
+		sizeof(CAVIParseStream) * This->avih.dwStreams );
+
+	llOfs = llOfs_hdrl;
+	for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ )
+	{
+		TRACE("search strl for stream %lu\n",nIndex);
+		hr = RIFF_SearchList(
+			pImpl,
+			dwLen_hdrl, llOfs, PARSER_strl,
+			&llOfs, &dwChunkLength );
+		if ( FAILED(hr) )
+			return hr;
+		if ( hr != S_OK )
+			return E_FAIL;
+
+		/* read 'strl'. */
+		hr = CAVIParseImpl_ParseStreamList(
+			pImpl, This, nIndex,
+			llOfs, dwChunkLength, &This->pStreamsBuf[nIndex] );
+
+		if ( FAILED(hr) )
+			return hr;
+		if ( hr != S_OK )
+			return E_FAIL;
+		llOfs += dwChunkLength;
+	}
+
+	/* initialize idx1. */
+	TRACE("search idx1\n");
+	hr = RIFF_SearchChunk(
+		pImpl, (DWORD)0xffffffff,
+		PARSER_RIFF_OfsFirst, PARSER_idx1,
+		&llOfs, &dwChunkLength );
+	if ( FAILED(hr) )
+		return hr;
+	if ( hr == S_OK )
+	{
+		/* read idx1. */
+		This->cIndexEntries = dwChunkLength / sizeof(AVIINDEXENTRY);
+		This->pIndexEntriesBuf = (AVIINDEXENTRY*)QUARTZ_AllocMem(
+			sizeof(AVIINDEXENTRY) * This->cIndexEntries );
+		if ( This->pIndexEntriesBuf == NULL )
+			return E_OUTOFMEMORY;
+		hr = IAsyncReader_SyncRead( pImpl->m_pReader, llOfs, sizeof(AVIINDEXENTRY) * This->cIndexEntries, (BYTE*)This->pIndexEntriesBuf );
+		if ( FAILED(hr) )
+			return hr;
+		if ( hr != S_OK )
+			return E_FAIL;
+
+		pEntriesBuf = (AVIINDEXENTRY*)QUARTZ_AllocMem(
+			sizeof(AVIINDEXENTRY) * This->cIndexEntries );
+		if ( pEntriesBuf == NULL )
+			return E_OUTOFMEMORY;
+		cEntries = 0;
+		for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ )
+		{
+			cEntriesCur = cEntries;
+			dwChunkId = (((nIndex%10)+'0')<<8) | ((nIndex/10)+'0');
+			for ( i = 0; i < This->cIndexEntries; i++ )
+			{
+				if ( (This->pIndexEntriesBuf[i].ckid & 0xffff) == dwChunkId )
+					memcpy( &pEntriesBuf[cEntries++], &This->pIndexEntriesBuf[i], sizeof(AVIINDEXENTRY) );
+			}
+			This->pStreamsBuf[nIndex].pIndexEntries = &pEntriesBuf[cEntriesCur];
+			This->pStreamsBuf[nIndex].cIndexEntries = cEntries - cEntriesCur;
+			This->pStreamsBuf[nIndex].cIndexCur = 0;
+			This->pStreamsBuf[nIndex].rtCur = 0;
+			This->pStreamsBuf[nIndex].rtInternal = 0;
+			TRACE("stream %lu - %lu entries\n",nIndex,This->pStreamsBuf[nIndex].cIndexEntries);
+		}
+		QUARTZ_FreeMem(This->pIndexEntriesBuf);
+		This->pIndexEntriesBuf = pEntriesBuf;
+
+		This->avih.dwSuggestedBufferSize = 0;
+		for ( i = 0; i < This->cIndexEntries; i++ )
+		{
+			if ( This->avih.dwSuggestedBufferSize < This->pIndexEntriesBuf[i].dwChunkLength )
+				This->avih.dwSuggestedBufferSize = This->pIndexEntriesBuf[i].dwChunkLength;
+		}
+	}
+	else
+	{
+		return E_FAIL;
+	}
+
+	if ( This->avih.dwStreams > 100 )
+		return E_FAIL;
+
+	*pcStreams = This->avih.dwStreams;
+
+	return NOERROR;
+}
+
+static HRESULT CAVIParseImpl_UninitParser( CParserImpl* pImpl )
+{
+	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
+	ULONG	nIndex;
+
+	TRACE("(%p)\n",This);
+
+	if ( This == NULL )
+		return NOERROR;
+
+	/* destruct */
+	if ( This->pStreamsBuf != NULL )
+	{
+		for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ )
+		{
+			/* release this stream */
+			if ( This->pStreamsBuf[nIndex].pFmtBuf != NULL )
+				QUARTZ_FreeMem(This->pStreamsBuf[nIndex].pFmtBuf);
+		}
+		QUARTZ_FreeMem( This->pStreamsBuf );
+		This->pStreamsBuf = NULL;
+	}
+
+	if ( This->pIndexEntriesBuf != NULL )
+	{
+		QUARTZ_FreeMem( This->pIndexEntriesBuf );
+		This->pIndexEntriesBuf = NULL;
+	}
+
+	QUARTZ_FreeMem( This );
+	pImpl->m_pUserData = NULL;
+
+	return NOERROR;
+}
+
+static LPCWSTR CAVIParseImpl_GetOutPinName( CParserImpl* pImpl, ULONG nStreamIndex )
+{
+	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
+	int wlen;
+
+	TRACE("(%p,%lu)\n",This,nStreamIndex);
+
+	if ( This == NULL || nStreamIndex >= This->avih.dwStreams )
+		return NULL;
+
+	wlen = lstrlenW(QUARTZ_AVIParserOutPin_Basename);
+	memcpy( This->wchWork, QUARTZ_AVIParserOutPin_Basename, sizeof(WCHAR)*wlen );
+	This->wchWork[ wlen ] = (nStreamIndex/10) + '0';
+	This->wchWork[ wlen+1 ] = (nStreamIndex%10) + '0';
+	This->wchWork[ wlen+2 ] = 0;
+
+	return This->wchWork;
+}
+
+static HRESULT CAVIParseImpl_GetStreamType( CParserImpl* pImpl, ULONG nStreamIndex, AM_MEDIA_TYPE* pmt )
+{
+	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
+	VIDEOINFOHEADER*	pvi;
+	BITMAPINFOHEADER*	pbi;
+	WAVEFORMATEX*	pwfx;
+	DWORD	cbFmt;
+	DWORD	cb;
+	HRESULT hr;
+
+	TRACE("(%p,%lu,%p)\n",This,nStreamIndex,pmt);
+
+	if ( This == NULL )
+		return E_UNEXPECTED;
+	if ( nStreamIndex >= This->avih.dwStreams )
+		return E_INVALIDARG;
+
+	cbFmt = This->pStreamsBuf[nStreamIndex].cbFmt;
+
+	ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
+	switch ( This->pStreamsBuf[nStreamIndex].strh.fccType )
+	{
+	case PARSER_vids:
+		pbi = (BITMAPINFOHEADER*)This->pStreamsBuf[nStreamIndex].pFmtBuf;
+		if ( pbi == NULL || cbFmt < sizeof(BITMAPINFOHEADER) )
+			goto unknown_format;
+
+		memcpy( &pmt->majortype, &MEDIATYPE_Video, sizeof(GUID) );
+		hr = QUARTZ_MediaSubType_FromBitmap( &pmt->subtype, pbi );
+		if ( FAILED(hr) )
+			goto unknown_format;
+		if ( hr != S_OK )
+			QUARTZ_MediaSubType_FromFourCC( &pmt->subtype, (DWORD)pbi->biCompression );
+
+		pmt->bFixedSizeSamples = ( pbi->biCompression == 0 || pbi->biCompression == 3 ) ? 1 : 0;
+		pmt->bTemporalCompression = 0;
+		pmt->lSampleSize = ( pbi->biCompression == 0 || pbi->biCompression == 3 ) ?
+			DIBSIZE(*pbi) : pbi->biSize;
+		memcpy( &pmt->formattype, &FORMAT_VideoInfo, sizeof(GUID) );
+
+		cb = sizeof(VIDEOINFOHEADER) + cbFmt;
+		pmt->pbFormat = (BYTE*)CoTaskMemAlloc( cb );
+		if ( pmt->pbFormat == NULL )
+			return E_OUTOFMEMORY;
+		ZeroMemory( pmt->pbFormat, cb );
+		pvi = (VIDEOINFOHEADER*)pmt->pbFormat;
+		pmt->cbFormat = cb;
+		memcpy( &pvi->bmiHeader, pbi, cbFmt );
+		break;
+	case PARSER_auds:
+		pwfx = (WAVEFORMATEX*)This->pStreamsBuf[nStreamIndex].pFmtBuf;
+		if ( pwfx == NULL || cbFmt < (sizeof(WAVEFORMATEX)-2) )
+			goto unknown_format;
+
+		memcpy( &pmt->majortype, &MEDIATYPE_Audio, sizeof(GUID) );
+		QUARTZ_MediaSubType_FromFourCC( &pmt->subtype, (DWORD)pwfx->wFormatTag );
+		pmt->bFixedSizeSamples = 1;
+		pmt->bTemporalCompression = 0;
+		pmt->lSampleSize = pwfx->nBlockAlign;
+		memcpy( &pmt->formattype, &FORMAT_WaveFormatEx, sizeof(GUID) );
+		pmt->pUnk = NULL;
+
+		cb = ( cbFmt < sizeof(WAVEFORMATEX) ) ? sizeof(WAVEFORMATEX) : cbFmt;
+		pmt->pbFormat = (BYTE*)CoTaskMemAlloc( cb );
+		if ( pmt->pbFormat == NULL )
+			return E_OUTOFMEMORY;
+		ZeroMemory( pmt->pbFormat, cb );
+		pmt->cbFormat = cbFmt;
+		memcpy( pmt->pbFormat, pwfx, cbFmt );
+		break;
+	case PARSER_mids:
+		/* FIXME? */
+		memcpy( &pmt->majortype, &MEDIATYPE_Midi, sizeof(GUID) );
+		memcpy( &pmt->subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) );
+		pmt->bFixedSizeSamples = 0;
+		pmt->bTemporalCompression = 0;
+		pmt->lSampleSize = 1;
+		memcpy( &pmt->formattype, &FORMAT_None, sizeof(GUID) );
+		pmt->pUnk = NULL;
+		pmt->cbFormat = 0;
+		pmt->pbFormat = NULL;
+		break;
+	case PARSER_txts:
+		/* FIXME? */
+		memcpy( &pmt->majortype, &MEDIATYPE_Text, sizeof(GUID) );
+		memcpy( &pmt->subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) );
+		pmt->bFixedSizeSamples = 0;
+		pmt->bTemporalCompression = 0;
+		pmt->lSampleSize = 1;
+		memcpy( &pmt->formattype, &FORMAT_None, sizeof(GUID) );
+		pmt->pUnk = NULL;
+		pmt->cbFormat = 0;
+		pmt->pbFormat = NULL;
+		break;
+	default:
+		goto unknown_format;
+	}
+
+	return NOERROR;
+
+unknown_format:;
+	FIXME( "(%p) unsupported stream type %c%c%c%c\n",This,
+			(int)((This->pStreamsBuf[nStreamIndex].strh.fccType>> 0)&0xff),
+			(int)((This->pStreamsBuf[nStreamIndex].strh.fccType>> 8)&0xff),
+			(int)((This->pStreamsBuf[nStreamIndex].strh.fccType>>16)&0xff),
+			(int)((This->pStreamsBuf[nStreamIndex].strh.fccType>>24)&0xff) );
+
+	memcpy( &pmt->majortype, &MEDIATYPE_NULL, sizeof(GUID) );
+	memcpy( &pmt->subtype, &MEDIASUBTYPE_NULL, sizeof(GUID) );
+	pmt->bFixedSizeSamples = 0;
+	pmt->bTemporalCompression = 0;
+	pmt->lSampleSize = 1;
+	memcpy( &pmt->formattype, &FORMAT_None, sizeof(GUID) );
+	pmt->pUnk = NULL;
+	pmt->cbFormat = 0;
+	pmt->pbFormat = NULL;
+
+	return NOERROR;
+}
+
+static HRESULT CAVIParseImpl_CheckStreamType( CParserImpl* pImpl, ULONG nStreamIndex, const AM_MEDIA_TYPE* pmt )
+{
+	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
+	HRESULT hr;
+	AM_MEDIA_TYPE	mt;
+	VIDEOINFOHEADER*	pvi;
+	VIDEOINFOHEADER*	pviCheck;
+	WAVEFORMATEX*	pwfx;
+	WAVEFORMATEX*	pwfxCheck;
+
+	TRACE("(%p,%lu,%p)\n",This,nStreamIndex,pmt);
+
+	hr = CAVIParseImpl_GetStreamType( pImpl, nStreamIndex, &mt );
+	if ( FAILED(hr) )
+		return hr;
+
+	TRACE("check GUIDs - %s,%s\n",debugstr_guid(&pmt->majortype),debugstr_guid(&pmt->subtype));
+	if ( !IsEqualGUID( &pmt->majortype, &mt.majortype ) ||
+		 !IsEqualGUID( &pmt->subtype, &mt.subtype ) ||
+		 !IsEqualGUID( &pmt->formattype, &mt.formattype ) )
+	{
+		hr = E_FAIL;
+		goto end;
+	}
+
+	TRACE("check format\n");
+	hr = S_OK;
+	switch ( This->pStreamsBuf[nStreamIndex].strh.fccType )
+	{
+	case PARSER_vids:
+		TRACE("check vids\n");
+		pvi = (VIDEOINFOHEADER*)mt.pbFormat;
+		pviCheck = (VIDEOINFOHEADER*)pmt->pbFormat;
+		if ( pvi == NULL || pviCheck == NULL || pmt->cbFormat < sizeof(VIDEOINFOHEADER) )
+			hr = E_FAIL;
+		if ( pvi->bmiHeader.biWidth != pviCheck->bmiHeader.biWidth ||
+			 pvi->bmiHeader.biHeight != pviCheck->bmiHeader.biHeight ||
+			 pvi->bmiHeader.biPlanes != pviCheck->bmiHeader.biPlanes ||
+			 pvi->bmiHeader.biBitCount != pviCheck->bmiHeader.biBitCount ||
+			 pvi->bmiHeader.biCompression != pviCheck->bmiHeader.biCompression ||
+			 pvi->bmiHeader.biClrUsed != pviCheck->bmiHeader.biClrUsed )
+			hr = E_FAIL;
+		break;
+	case PARSER_auds:
+		TRACE("check auds\n");
+		pwfx = (WAVEFORMATEX*)mt.pbFormat;
+		pwfxCheck = (WAVEFORMATEX*)pmt->pbFormat;
+		if ( pwfx == NULL || pwfxCheck == NULL || pmt->cbFormat < (sizeof(WAVEFORMATEX)-2) )
+			hr = E_FAIL;
+		if ( pwfx->wFormatTag != pwfxCheck->wFormatTag ||
+			 pwfx->nBlockAlign != pwfxCheck->nBlockAlign ||
+			 pwfx->wBitsPerSample != pwfxCheck->wBitsPerSample ||
+			 pwfx->nChannels != pwfxCheck->nChannels ||
+			 pwfx->nSamplesPerSec != pwfxCheck->nSamplesPerSec )
+			hr = E_FAIL;
+		break;
+	case PARSER_mids:
+	case PARSER_txts:
+		break;
+	default:
+		break;
+	}
+end:
+	QUARTZ_MediaType_Free( &mt );
+
+	TRACE("%08lx\n",hr);
+
+	return hr;
+}
+
+static HRESULT CAVIParseImpl_GetAllocProp( CParserImpl* pImpl, ALLOCATOR_PROPERTIES* pReqProp )
+{
+	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
+
+	if ( This == NULL )
+		return E_UNEXPECTED;
+
+	ZeroMemory( pReqProp, sizeof(ALLOCATOR_PROPERTIES) );
+	pReqProp->cBuffers = This->avih.dwStreams;
+	pReqProp->cbBuffer = This->avih.dwSuggestedBufferSize;
+
+	return NOERROR;
+}
+
+static HRESULT CAVIParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop )
+{
+	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
+	REFERENCE_TIME	rtNext;
+	DWORD	nIndexNext;
+	DWORD	nIndex;
+	CAVIParseStream*	pStream;
+	const WAVEFORMATEX*	pwfx;
+
+	if ( This == NULL )
+		return E_UNEXPECTED;
+
+	TRACE("(%p)\n",This);
+
+	nIndexNext = This->avih.dwStreams;
+	rtNext = ((REFERENCE_TIME)0x7fffffff<<32)|((REFERENCE_TIME)0xffffffff);
+	for ( nIndex = 0; nIndex < This->avih.dwStreams; nIndex++ )
+	{
+		TRACE("stream %lu - %lu,%lu\n",nIndex,(unsigned long)(This->pStreamsBuf[nIndex].rtCur*1000/QUARTZ_TIMEUNITS),This->pStreamsBuf[nIndex].cIndexCur);
+		if ( rtNext > This->pStreamsBuf[nIndex].rtCur &&
+			 This->pStreamsBuf[nIndex].cIndexCur < This->pStreamsBuf[nIndex].cIndexEntries )
+		{
+			nIndexNext = nIndex;
+			rtNext = This->pStreamsBuf[nIndex].rtCur;
+		}
+	}
+	if ( nIndexNext >= This->avih.dwStreams )
+		return S_FALSE;
+
+	if ( This->pIndexEntriesBuf != NULL )
+	{
+		pStream = &This->pStreamsBuf[nIndexNext];
+		*pnStreamIndex = nIndexNext;
+		*pllStart = (LONGLONG)pStream->pIndexEntries[pStream->cIndexCur].dwChunkOffset + 8;
+		*plLength = (LONG)pStream->pIndexEntries[pStream->cIndexCur].dwChunkLength;
+		*prtStart = rtNext;
+		*prtStop = rtNext;
+
+		switch ( pStream->strh.fccType )
+		{
+		case PARSER_vids:
+			TRACE("vids\n");
+			pStream->rtInternal ++;
+			rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS * (REFERENCE_TIME)pStream->strh.dwScale / (REFERENCE_TIME)pStream->strh.dwRate;
+			/* FIXME - handle AVIPALCHANGE */
+			break;
+		case PARSER_auds:
+			TRACE("auds\n");
+			pwfx = (const WAVEFORMATEX*)pStream->pFmtBuf;
+			if ( pwfx != NULL && pStream->cbFmt >= (sizeof(WAVEFORMATEX)-2) )
+			{
+				pStream->rtInternal += (REFERENCE_TIME)*plLength;
+				rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS / (REFERENCE_TIME)pwfx->nAvgBytesPerSec;
+			}
+			else
+			{
+				pStream->rtInternal += (REFERENCE_TIME)(*plLength);
+				rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS * (REFERENCE_TIME)pStream->strh.dwScale / ((REFERENCE_TIME)pStream->strh.dwSampleSize * (REFERENCE_TIME)pStream->strh.dwRate);
+			}
+			break;
+		case PARSER_mids:
+		case PARSER_txts:
+		default:
+			pStream->rtInternal += (REFERENCE_TIME)(*plLength);
+			rtNext = pStream->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS * (REFERENCE_TIME)pStream->strh.dwScale / ((REFERENCE_TIME)pStream->strh.dwSampleSize * (REFERENCE_TIME)pStream->strh.dwRate);
+			break;
+		}
+		pStream->cIndexCur ++;
+		pStream->rtCur = rtNext;
+		*prtStop = rtNext;
+	}
+	else
+	{
+		ERR( "no idx1\n" );
+		return E_NOTIMPL;
+	}
+
+	TRACE("return %lu / %ld-%ld / %lu-%lu\n",
+		*pnStreamIndex,(long)*pllStart,*plLength,
+		(unsigned long)((*prtStart)*1000/QUARTZ_TIMEUNITS),
+		(unsigned long)((*prtStop)*1000/QUARTZ_TIMEUNITS));
+
+	return NOERROR;
+}
+
+static HRESULT CAVIParseImpl_ProcessSample( CParserImpl* pImpl, ULONG nStreamIndex, LONGLONG llStart, LONG lLength, IMediaSample* pSample )
+{
+	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
+
+	TRACE("(%p,%lu,%ld,%ld,%p)\n",This,nStreamIndex,(long)llStart,lLength,pSample);
+
+	if ( This == NULL )
+		return E_UNEXPECTED;
+
+	return NOERROR;
+}
+
+
+
+
+static const struct ParserHandlers CAVIParseImpl_Handlers =
+{
+	CAVIParseImpl_InitParser,
+	CAVIParseImpl_UninitParser,
+	CAVIParseImpl_GetOutPinName,
+	CAVIParseImpl_GetStreamType,
+	CAVIParseImpl_CheckStreamType,
+	CAVIParseImpl_GetAllocProp,
+	CAVIParseImpl_GetNextRequest,
+	CAVIParseImpl_ProcessSample,
+
+	/* for IQualityControl */
+	NULL, /* pQualityNotify */
+
+	/* for seeking */
+	NULL, /* pGetSeekingCaps */
+	NULL, /* pIsTimeFormatSupported */
+	NULL, /* pGetCurPos */
+	NULL, /* pSetCurPos */
+	NULL, /* pGetDuration */
+	NULL, /* pSetDuration */
+	NULL, /* pGetStopPos */
+	NULL, /* pSetStopPos */
+	NULL, /* pGetPreroll */
+	NULL, /* pSetPreroll */
+};
+
+HRESULT QUARTZ_CreateAVISplitter(IUnknown* punkOuter,void** ppobj)
+{
+	return QUARTZ_CreateParser(
+		punkOuter,ppobj,
+		&CLSID_AviSplitter,
+		QUARTZ_AVIParser_Name,
+		QUARTZ_AVIParserInPin_Name,
+		&CAVIParseImpl_Handlers );
+}
+
+
diff --git a/dlls/quartz/basefilt.c b/dlls/quartz/basefilt.c
index c2db042..4bec553 100644
--- a/dlls/quartz/basefilt.c
+++ b/dlls/quartz/basefilt.c
@@ -11,10 +11,8 @@
 #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);
@@ -355,7 +353,7 @@
 	}
 
 	This->pfg = pfg;
-	This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszName)+1);
+	This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszName)+1);
 	This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
 	if ( This->pwszNameGraph == NULL )
 	{
@@ -440,7 +438,7 @@
 	This->rtStart = 0;
 	This->fstate = State_Stopped;
 
-	This->cbNameGraph = sizeof(WCHAR) * (strlenW(lpwszNameGraph)+1);
+	This->cbNameGraph = sizeof(WCHAR) * (lstrlenW(lpwszNameGraph)+1);
 	This->pwszNameGraph = (WCHAR*)QUARTZ_AllocMem( This->cbNameGraph );
 	if ( This->pwszNameGraph == NULL )
 		return E_OUTOFMEMORY;
diff --git a/dlls/quartz/basepin.c b/dlls/quartz/basepin.c
index 1f809b7..ea414a6 100644
--- a/dlls/quartz/basepin.c
+++ b/dlls/quartz/basepin.c
@@ -11,10 +11,8 @@
 #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);
@@ -67,7 +65,7 @@
 	HRESULT	hr = E_NOTIMPL;
 	ULONG	i;
 
-	FIXME("(%p)->(%p,%p) stub!\n",This,pPin,pmt);
+	FIXME("(%p)->(%p,%p)\n",This,pPin,pmt);
 
 	if ( !This->bOutput )
 		return E_UNEXPECTED;
@@ -167,7 +165,7 @@
 	ICOM_THIS(CPinBaseImpl,iface);
 	HRESULT	hr = E_NOTIMPL;
 
-	FIXME("(%p)->(%p,%p) stub!\n",This,pPin,pmt);
+	FIXME("(%p)->(%p,%p)\n",This,pPin,pmt);
 
 	if ( This->bOutput )
 		return E_UNEXPECTED;
@@ -559,7 +557,7 @@
 	ICOM_VTBL(This) = &ipin;
 	This->punkControl = punkControl;
 	This->pHandlers = pHandlers;
-	This->cbIdLen = sizeof(WCHAR)*(strlenW(pwszId)+1);
+	This->cbIdLen = sizeof(WCHAR)*(lstrlenW(pwszId)+1);
 	This->pwszId = NULL;
 	This->bOutput = bOutput;
 	This->pmtAcceptTypes = NULL;
@@ -986,7 +984,7 @@
 HRESULT OutputPinSync_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
 {
 	if ( pImpl->pMemInputPinConnectedTo == NULL )
-		return E_UNEXPECTED;
+		return NOERROR;
 
 	return IMemInputPin_Receive(pImpl->pMemInputPinConnectedTo,pSample);
 }
diff --git a/dlls/quartz/complist.c b/dlls/quartz/complist.c
index 48fca2b..efe97b4 100644
--- a/dlls/quartz/complist.c
+++ b/dlls/quartz/complist.c
@@ -8,11 +8,8 @@
 
 #include "windef.h"
 #include "winbase.h"
-#include "wingdi.h"
-#include "winuser.h"
 #include "winerror.h"
 #include "wine/obj_base.h"
-#include "strmif.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
@@ -126,7 +123,7 @@
 	return pNewList;
 }
 
-HRESULT QUARTZ_CompList_AddComp(
+static QUARTZ_CompListItem* QUARTZ_CompList_AllocComp(
 	QUARTZ_CompList* pList, IUnknown* punk,
 	const void* pvData, DWORD dwDataLen )
 {
@@ -134,7 +131,7 @@
 
 	pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) );
 	if ( pItem == NULL )
-		return E_OUTOFMEMORY; /* out of memory. */
+		return NULL;
 
 	pItem->pvData = NULL;
 	pItem->dwDataLen = 0;
@@ -144,7 +141,7 @@
 		if ( pItem->pvData == NULL )
 		{
 			QUARTZ_FreeMem( pItem );
-			return E_OUTOFMEMORY;
+			return NULL;
 		}
 		memcpy( pItem->pvData, pvData, dwDataLen );
 		pItem->dwDataLen = dwDataLen;
@@ -152,6 +149,19 @@
 
 	pItem->punk = punk; IUnknown_AddRef(punk);
 
+	return pItem;
+}
+
+HRESULT QUARTZ_CompList_AddComp(
+	QUARTZ_CompList* pList, IUnknown* punk,
+	const void* pvData, DWORD dwDataLen )
+{
+	QUARTZ_CompListItem*	pItem;
+
+	pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
+	if ( pItem == NULL )
+		return E_OUTOFMEMORY;
+
 	if ( pList->pFirst != NULL )
 		pList->pFirst->pPrev = pItem;
 	else
@@ -163,6 +173,27 @@
 	return S_OK;
 }
 
+HRESULT QUARTZ_CompList_AddTailComp(
+	QUARTZ_CompList* pList, IUnknown* punk,
+	const void* pvData, DWORD dwDataLen )
+{
+	QUARTZ_CompListItem*	pItem;
+
+	pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen );
+	if ( pItem == NULL )
+		return E_OUTOFMEMORY;
+
+	if ( pList->pLast != NULL )
+		pList->pLast->pNext = pItem;
+	else
+		pList->pFirst = pItem;
+	pItem->pPrev = pList->pLast;
+	pList->pLast = pItem;
+	pItem->pNext = NULL;
+
+	return S_OK;
+}
+
 HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk )
 {
 	QUARTZ_CompListItem*	pCur;
@@ -230,12 +261,24 @@
 	return pList->pFirst;
 }
 
+QUARTZ_CompListItem* QUARTZ_CompList_GetLast(
+	QUARTZ_CompList* pList )
+{
+	return pList->pLast;
+}
+
 QUARTZ_CompListItem* QUARTZ_CompList_GetNext(
 	QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev )
 {
 	return pPrev->pNext;
 }
 
+QUARTZ_CompListItem* QUARTZ_CompList_GetPrev(
+	QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext )
+{
+	return pNext->pPrev;
+}
+
 IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem )
 {
 	return pItem->punk;
diff --git a/dlls/quartz/complist.h b/dlls/quartz/complist.h
index 9f02dc2..c0d7f0a 100644
--- a/dlls/quartz/complist.h
+++ b/dlls/quartz/complist.h
@@ -20,6 +20,9 @@
 HRESULT QUARTZ_CompList_AddComp(
 	QUARTZ_CompList* pList, IUnknown* punk,
 	const void* pvData, DWORD dwDataLen );
+HRESULT QUARTZ_CompList_AddTailComp(
+	QUARTZ_CompList* pList, IUnknown* punk,
+	const void* pvData, DWORD dwDataLen );
 HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk );
 QUARTZ_CompListItem* QUARTZ_CompList_SearchComp(
 	QUARTZ_CompList* pList, IUnknown* punk );
@@ -27,8 +30,12 @@
 	QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen );
 QUARTZ_CompListItem* QUARTZ_CompList_GetFirst(
 	QUARTZ_CompList* pList );
+QUARTZ_CompListItem* QUARTZ_CompList_GetLast(
+	QUARTZ_CompList* pList );
 QUARTZ_CompListItem* QUARTZ_CompList_GetNext(
 	QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev );
+QUARTZ_CompListItem* QUARTZ_CompList_GetPrev(
+	QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext );
 IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem );
 const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem );
 DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem );
diff --git a/dlls/quartz/devenum.c b/dlls/quartz/devenum.c
index 9832e35..70d46e3 100644
--- a/dlls/quartz/devenum.c
+++ b/dlls/quartz/devenum.c
@@ -14,14 +14,7 @@
 #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);
@@ -159,7 +152,7 @@
 		0, KEY_READ, &hKey ) != ERROR_SUCCESS )
 		return E_FAIL;
 
-	dwLen = strlenW(wszPath);
+	dwLen = lstrlenW(wszPath);
 	wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
 	dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;
 
diff --git a/dlls/quartz/devmon.c b/dlls/quartz/devmon.c
index 7ed055d..cef8eb7 100644
--- a/dlls/quartz/devmon.c
+++ b/dlls/quartz/devmon.c
@@ -13,14 +13,12 @@
 #include "winuser.h"
 #include "winreg.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "objidl.h"
 #include "oleidl.h"
 #include "ocidl.h"
 #include "oleauto.h"
 #include "strmif.h"
 #include "uuids.h"
-#include "wine/unicode.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
@@ -366,7 +364,7 @@
 	pdm->m_hkRoot = hkRoot;
 	pdm->m_pwszPath = NULL;
 
-	dwLen = sizeof(WCHAR)*(strlenW(lpKeyPath)+1);
+	dwLen = sizeof(WCHAR)*(lstrlenW(lpKeyPath)+1);
 	pdm->m_pwszPath = (WCHAR*)QUARTZ_AllocMem( dwLen );
 	if ( pdm->m_pwszPath == NULL )
 		return E_OUTOFMEMORY;
diff --git a/dlls/quartz/enumunk.c b/dlls/quartz/enumunk.c
index 8552bf3..e344b8e 100644
--- a/dlls/quartz/enumunk.c
+++ b/dlls/quartz/enumunk.c
@@ -8,14 +8,9 @@
 
 #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 "wine/obj_misc.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
diff --git a/dlls/quartz/fgevent.c b/dlls/quartz/fgevent.c
index 2d25a35..a07938e 100644
--- a/dlls/quartz/fgevent.c
+++ b/dlls/quartz/fgevent.c
@@ -11,8 +11,6 @@
 #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 "evcode.h"
diff --git a/dlls/quartz/fgidisp.c b/dlls/quartz/fgidisp.c
deleted file mode 100644
index d350aef..0000000
--- a/dlls/quartz/fgidisp.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Implementation of IDispatch 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
-IDispatch_fnQueryInterface(IDispatch* iface,REFIID riid,void** ppobj)
-{
-	CFilterGraph_THIS(iface,disp);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IDispatch_fnAddRef(IDispatch* iface)
-{
-	CFilterGraph_THIS(iface,disp);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IDispatch_fnRelease(IDispatch* iface)
-{
-	CFilterGraph_THIS(iface,disp);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-static HRESULT WINAPI
-IDispatch_fnGetTypeInfoCount(IDispatch* iface,UINT* pcTypeInfo)
-{
-	CFilterGraph_THIS(iface,disp);
-
-	FIXME("(%p)->()\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IDispatch_fnGetTypeInfo(IDispatch* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
-{
-	CFilterGraph_THIS(iface,disp);
-
-	FIXME("(%p)->()\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IDispatch_fnGetIDsOfNames(IDispatch* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
-{
-	CFilterGraph_THIS(iface,disp);
-
-	FIXME("(%p)->()\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IDispatch_fnInvoke(IDispatch* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
-{
-	CFilterGraph_THIS(iface,disp);
-
-	FIXME("(%p)->()\n",This);
-
-	return E_NOTIMPL;
-}
-
-
-
-static ICOM_VTABLE(IDispatch) idispatch =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IDispatch_fnQueryInterface,
-	IDispatch_fnAddRef,
-	IDispatch_fnRelease,
-	/* IDispatch fields */
-	IDispatch_fnGetTypeInfoCount,
-	IDispatch_fnGetTypeInfo,
-	IDispatch_fnGetIDsOfNames,
-	IDispatch_fnInvoke,
-};
-
-
-HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->disp) = &idispatch;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIDispatch( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-}
-
diff --git a/dlls/quartz/fgpass.c b/dlls/quartz/fgpass.c
index 340a352..ddd61d1 100644
--- a/dlls/quartz/fgpass.c
+++ b/dlls/quartz/fgpass.c
@@ -13,8 +13,6 @@
 #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"
diff --git a/dlls/quartz/fgraph.c b/dlls/quartz/fgraph.c
index 6efda00..e545fb5 100644
--- a/dlls/quartz/fgraph.c
+++ b/dlls/quartz/fgraph.c
@@ -11,8 +11,6 @@
 #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"
@@ -221,3 +219,109 @@
 {
 	TRACE("(%p)\n",pfg);
 }
+
+/***************************************************************************
+ *
+ *	CFilterGraph::IDispatch
+ *
+ */
+
+static HRESULT WINAPI
+IDispatch_fnQueryInterface(IDispatch* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,disp);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IDispatch_fnAddRef(IDispatch* iface)
+{
+	CFilterGraph_THIS(iface,disp);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IDispatch_fnRelease(IDispatch* iface)
+{
+	CFilterGraph_THIS(iface,disp);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+static HRESULT WINAPI
+IDispatch_fnGetTypeInfoCount(IDispatch* iface,UINT* pcTypeInfo)
+{
+	CFilterGraph_THIS(iface,disp);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IDispatch_fnGetTypeInfo(IDispatch* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
+{
+	CFilterGraph_THIS(iface,disp);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IDispatch_fnGetIDsOfNames(IDispatch* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
+{
+	CFilterGraph_THIS(iface,disp);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IDispatch_fnInvoke(IDispatch* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
+{
+	CFilterGraph_THIS(iface,disp);
+
+	FIXME("(%p)->()\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+static ICOM_VTABLE(IDispatch) idispatch =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IDispatch_fnQueryInterface,
+	IDispatch_fnAddRef,
+	IDispatch_fnRelease,
+	/* IDispatch fields */
+	IDispatch_fnGetTypeInfoCount,
+	IDispatch_fnGetTypeInfo,
+	IDispatch_fnGetIDsOfNames,
+	IDispatch_fnInvoke,
+};
+
+
+HRESULT CFilterGraph_InitIDispatch( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->disp) = &idispatch;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIDispatch( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
diff --git a/dlls/quartz/fgraph.h b/dlls/quartz/fgraph.h
index 9329820..34a30f0 100644
--- a/dlls/quartz/fgraph.h
+++ b/dlls/quartz/fgraph.h
@@ -125,7 +125,6 @@
 	/* IFilterGraph2 fields. */
 	QUARTZ_CompList*	m_pFilterList;
 	/* IGraphVersion fields. */
-	CRITICAL_SECTION	m_csGraphVersion;
 	LONG	m_lGraphVersion;
 	/* IMediaControl fields. */
 	/* IMediaFilter fields. */
diff --git a/dlls/quartz/fmap.c b/dlls/quartz/fmap.c
index 9234786..a114ec6 100644
--- a/dlls/quartz/fmap.c
+++ b/dlls/quartz/fmap.c
@@ -1,5 +1,5 @@
 /*
- * Implementation of CLSID_FilterMapper.
+ * Implementation of CLSID_FilterMapper and CLSID_FilterMapper2.
  *
  * FIXME - stub.
  *
@@ -14,10 +14,7 @@
 #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"
@@ -35,7 +32,7 @@
  */
 
 /* can I use offsetof safely? - FIXME? */
-static QUARTZ_IFEntry IFEntries[] =
+static QUARTZ_IFEntry FMapIFEntries[] =
 {
   { &IID_IFilterMapper, offsetof(CFilterMapper,fmap)-offsetof(CFilterMapper,unk) },
 };
@@ -67,8 +64,8 @@
 		return hr;
 	}
 
-	pfm->unk.pEntries = IFEntries;
-	pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
+	pfm->unk.pEntries = FMapIFEntries;
+	pfm->unk.dwEntries = sizeof(FMapIFEntries)/sizeof(FMapIFEntries[0]);
 	pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper;
 
 	*ppobj = (void*)(&pfm->unk);
@@ -254,3 +251,212 @@
 {
 	TRACE("(%p)\n",pfm);
 }
+
+
+/***************************************************************************
+ *
+ *	new/delete for CLSID_FilterMapper2
+ *
+ */
+
+/* can I use offsetof safely? - FIXME? */
+static QUARTZ_IFEntry FMap2IFEntries[] =
+{
+  { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
+  { &IID_IFilterMapper3, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
+};
+
+
+static void QUARTZ_DestroyFilterMapper2(IUnknown* punk)
+{
+	CFilterMapper2_THIS(punk,unk);
+
+	CFilterMapper2_UninitIFilterMapper3( This );
+}
+
+HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
+{
+	CFilterMapper2*	pfm;
+	HRESULT	hr;
+
+	TRACE("(%p,%p)\n",punkOuter,ppobj);
+
+	pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) );
+	if ( pfm == NULL )
+		return E_OUTOFMEMORY;
+
+	QUARTZ_IUnkInit( &pfm->unk, punkOuter );
+	hr = CFilterMapper2_InitIFilterMapper3( pfm );
+	if ( FAILED(hr) )
+	{
+		QUARTZ_FreeObj( pfm );
+		return hr;
+	}
+
+	pfm->unk.pEntries = FMap2IFEntries;
+	pfm->unk.dwEntries = sizeof(FMap2IFEntries)/sizeof(FMap2IFEntries[0]);
+	pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2;
+
+	*ppobj = (void*)(&pfm->unk);
+
+	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);
+}
+
diff --git a/dlls/quartz/fmap.h b/dlls/quartz/fmap.h
index c21cc2e..61d249f 100644
--- a/dlls/quartz/fmap.h
+++ b/dlls/quartz/fmap.h
@@ -33,5 +33,37 @@
 void CFilterMapper_UninitIFilterMapper( CFilterMapper* pfm );
 
 
-#endif	/* WINE_DSHOW_FMAP_H */
 
+/*
+		implements CLSID_FilterMapper2.
+
+	- At least, the following interfaces should be implemented:
+
+	IUnknown
+		+ IFilterMapper2 - IFilterMapper3
+ */
+
+#include "iunk.h"
+
+
+typedef struct FM2_IFilterMapper3Impl
+{
+	ICOM_VFIELD(IFilterMapper3);
+} FM2_IFilterMapper3Impl;
+
+typedef struct CFilterMapper2
+{
+	QUARTZ_IUnkImpl	unk;
+	FM2_IFilterMapper3Impl	fmap3;
+	/* IFilterMapper3 fields */
+} CFilterMapper2;
+
+#define	CFilterMapper2_THIS(iface,member)		CFilterMapper2*	This = ((CFilterMapper2*)(((char*)iface)-offsetof(CFilterMapper2,member)))
+
+HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj);
+
+
+HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* psde );
+void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* psde );
+
+#endif	/* WINE_DSHOW_FMAP_H */
diff --git a/dlls/quartz/fmap2.c b/dlls/quartz/fmap2.c
deleted file mode 100644
index 315d231..0000000
--- a/dlls/quartz/fmap2.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Implementation of 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"
-
-
-/***************************************************************************
- *
- *	new/delete for CLSID_FilterMapper2
- *
- */
-
-/* can I use offsetof safely? - FIXME? */
-static QUARTZ_IFEntry IFEntries[] =
-{
-  { &IID_IFilterMapper2, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
-  { &IID_IFilterMapper3, offsetof(CFilterMapper2,fmap3)-offsetof(CFilterMapper2,unk) },
-};
-
-
-static void QUARTZ_DestroyFilterMapper2(IUnknown* punk)
-{
-	CFilterMapper2_THIS(punk,unk);
-
-	CFilterMapper2_UninitIFilterMapper3( This );
-}
-
-HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj)
-{
-	CFilterMapper2*	pfm;
-	HRESULT	hr;
-
-	TRACE("(%p,%p)\n",punkOuter,ppobj);
-
-	pfm = (CFilterMapper2*)QUARTZ_AllocObj( sizeof(CFilterMapper2) );
-	if ( pfm == NULL )
-		return E_OUTOFMEMORY;
-
-	QUARTZ_IUnkInit( &pfm->unk, punkOuter );
-	hr = CFilterMapper2_InitIFilterMapper3( pfm );
-	if ( FAILED(hr) )
-	{
-		QUARTZ_FreeObj( pfm );
-		return hr;
-	}
-
-	pfm->unk.pEntries = IFEntries;
-	pfm->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
-	pfm->unk.pOnFinalRelease = QUARTZ_DestroyFilterMapper2;
-
-	*ppobj = (void*)(&pfm->unk);
-
-	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);
-}
-
diff --git a/dlls/quartz/fmap2.h b/dlls/quartz/fmap2.h
deleted file mode 100644
index 6cf7718..0000000
--- a/dlls/quartz/fmap2.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef	WINE_DSHOW_FMAP2_H
-#define	WINE_DSHOW_FMAP2_H
-
-/*
-		implements CLSID_FilterMapper2.
-
-	- At least, the following interfaces should be implemented:
-
-	IUnknown
-		+ IFilterMapper2 - IFilterMapper3
- */
-
-#include "iunk.h"
-
-
-typedef struct FM2_IFilterMapper3Impl
-{
-	ICOM_VFIELD(IFilterMapper3);
-} FM2_IFilterMapper3Impl;
-
-typedef struct CFilterMapper2
-{
-	QUARTZ_IUnkImpl	unk;
-	FM2_IFilterMapper3Impl	fmap3;
-	/* IFilterMapper3 fields */
-} CFilterMapper2;
-
-#define	CFilterMapper2_THIS(iface,member)		CFilterMapper2*	This = ((CFilterMapper2*)(((char*)iface)-offsetof(CFilterMapper2,member)))
-
-HRESULT QUARTZ_CreateFilterMapper2(IUnknown* punkOuter,void** ppobj);
-
-
-HRESULT CFilterMapper2_InitIFilterMapper3( CFilterMapper2* psde );
-void CFilterMapper2_UninitIFilterMapper3( CFilterMapper2* psde );
-
-
-#endif	/* WINE_DSHOW_FMAP2_H */
-
diff --git a/dlls/quartz/ifgraph.c b/dlls/quartz/ifgraph.c
index ae80747..e86979e 100644
--- a/dlls/quartz/ifgraph.c
+++ b/dlls/quartz/ifgraph.c
@@ -1,5 +1,6 @@
 /*
- * Implementation of IFilterGraph.
+ * Implementation of IFilterGraph and related interfaces
+ *	+ IGraphVersion, IGraphConfig
  *
  * FIXME - create a thread to process some methods correctly.
  *
@@ -17,13 +18,10 @@
 #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 "vfwmsgs.h"
-#include "wine/unicode.h"
 #include "evcode.h"
 
 #include "debugtools.h"
@@ -86,15 +84,17 @@
 
 	IMediaEventSink_Notify(CFilterGraph_IMediaEventSink(This),
 			EC_GRAPH_CHANGED, 0, 0);
-	EnterCriticalSection( &This->m_csGraphVersion );
 	This->m_lGraphVersion ++;
-	LeaveCriticalSection( &This->m_csGraphVersion );
 
 	return NOERROR;
 }
 
 
-/****************************************************************************/
+/***************************************************************************
+ *
+ *	CFilterGraph::IFilterGraph2 methods
+ *
+ */
 
 static HRESULT WINAPI
 IFilterGraph2_fnQueryInterface(IFilterGraph2* iface,REFIID riid,void** ppobj)
@@ -155,13 +155,13 @@
 	{
 		pItem = QUARTZ_CompList_SearchData(
 			This->m_pFilterList,
-			pName, sizeof(WCHAR)*(strlenW(pName)+1) );
+			pName, sizeof(WCHAR)*(lstrlenW(pName)+1) );
 		if ( pItem == NULL )
 			goto name_ok;
 
 		hrSucceeded = VFW_S_DUPLICATE_NAME;
 
-		iLen = strlenW(pName);
+		iLen = lstrlenW(pName);
 		if ( iLen > 32 )
 			iLen = 32;
 		memcpy( info.achName, pName, sizeof(WCHAR)*iLen );
@@ -174,7 +174,7 @@
 		if ( FAILED(hr) )
 			goto end;
 
-		iLen = strlenW(info.achName);
+		iLen = lstrlenW(info.achName);
 		pItem = QUARTZ_CompList_SearchData(
 			This->m_pFilterList,
 			info.achName, sizeof(WCHAR)*(iLen+1) );
@@ -186,7 +186,7 @@
 	}
 
 	/* generate modified names for this filter.. */
-	iLen = strlenW(info.achName);
+	iLen = lstrlenW(info.achName);
 	if ( iLen > 32 )
 		iLen = 32;
 	info.achName[iLen++] = ' ';
@@ -215,7 +215,7 @@
 	/* register this filter. */
 	hr = QUARTZ_CompList_AddComp(
 		This->m_pFilterList, (IUnknown*)pFilter,
-		pName, sizeof(WCHAR)*(strlenW(pName)+1) );
+		pName, sizeof(WCHAR)*(lstrlenW(pName)+1) );
 	if ( FAILED(hr) )
 		goto end;
 
@@ -325,7 +325,7 @@
 
 	pItem = QUARTZ_CompList_SearchData(
 		This->m_pFilterList,
-		pName, sizeof(WCHAR)*(strlenW(pName)+1) );
+		pName, sizeof(WCHAR)*(lstrlenW(pName)+1) );
 	if ( pItem != NULL )
 	{
 		*ppFilter = (IBaseFilter*)QUARTZ_CompList_GetItemPtr(pItem);
@@ -346,6 +346,7 @@
 	PIN_INFO	infoOut;
 	FILTER_INFO	finfoIn;
 	FILTER_INFO	finfoOut;
+	FILTER_STATE	fs;
 	HRESULT	hr;
 
 	TRACE( "(%p)->(%p,%p,%p)\n",This,pOut,pIn,pmt );
@@ -357,6 +358,14 @@
 
 	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 = IPin_QueryPinInfo(pIn,&infoIn);
 	if ( FAILED(hr) )
 		goto end;
@@ -482,7 +491,7 @@
 
 	FIXME( "(%p)->() stub!\n", This );
 
-	/* FIXME - search all filters. */
+	/* FIXME - search all filters from renderer. */
 
 	hr = QUARTZ_CreateSystemClock( NULL, (void**)&punk );
 	if ( FAILED(hr) )
@@ -668,7 +677,9 @@
 
 	/* reconnect asynchronously. */
 
+	QUARTZ_CompList_Lock( This->m_pFilterList );
 	hr = CFilterGraph_GraphChanged(This);
+	QUARTZ_CompList_Unlock( This->m_pFilterList );
 
 	return E_NOTIMPL;
 }
@@ -747,3 +758,274 @@
 
 	QUARTZ_CompList_Free( pfg->m_pFilterList );
 }
+
+/***************************************************************************
+ *
+ *	CFilterGraph::IGraphVersion methods
+ *
+ */
+
+static HRESULT WINAPI
+IGraphVersion_fnQueryInterface(IGraphVersion* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,graphversion);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IGraphVersion_fnAddRef(IGraphVersion* iface)
+{
+	CFilterGraph_THIS(iface,graphversion);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IGraphVersion_fnRelease(IGraphVersion* iface)
+{
+	CFilterGraph_THIS(iface,graphversion);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+
+static HRESULT WINAPI
+IGraphVersion_fnQueryVersion(IGraphVersion* iface,LONG* plVersion)
+{
+	CFilterGraph_THIS(iface,graphversion);
+
+	TRACE("(%p)->(%p)\n",This,plVersion);
+
+	if ( plVersion == NULL )
+		return E_POINTER;
+
+	QUARTZ_CompList_Lock( This->m_pFilterList );
+	*plVersion = This->m_lGraphVersion;
+	QUARTZ_CompList_Unlock( This->m_pFilterList );
+
+	return NOERROR;
+}
+
+
+static ICOM_VTABLE(IGraphVersion) igraphversion =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IGraphVersion_fnQueryInterface,
+	IGraphVersion_fnAddRef,
+	IGraphVersion_fnRelease,
+	/* IGraphVersion fields */
+	IGraphVersion_fnQueryVersion,
+};
+
+
+
+HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->graphversion) = &igraphversion;
+
+	pfg->m_lGraphVersion = 1;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
+/***************************************************************************
+ *
+ *	CFilterGraph::IGraphConfig methods
+ *
+ */
+
+static HRESULT WINAPI
+IGraphConfig_fnQueryInterface(IGraphConfig* iface,REFIID riid,void** ppobj)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
+}
+
+static ULONG WINAPI
+IGraphConfig_fnAddRef(IGraphConfig* iface)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_AddRef(This->unk.punkControl);
+}
+
+static ULONG WINAPI
+IGraphConfig_fnRelease(IGraphConfig* iface)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	TRACE("(%p)->()\n",This);
+
+	return IUnknown_Release(This->unk.punkControl);
+}
+
+
+
+static HRESULT WINAPI
+IGraphConfig_fnReconnect(IGraphConfig* iface,IPin* pOut,IPin* pIn,const AM_MEDIA_TYPE* pmt,IBaseFilter* pFilter,HANDLE hAbort,DWORD dwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnReconfigure(IGraphConfig* iface,IGraphConfigCallback* pCallback,PVOID pvParam,DWORD dwFlags,HANDLE hAbort)
+{
+	CFilterGraph_THIS(iface,grphconf);
+	HRESULT hr;
+
+	FIXME("(%p)->(%p,%p,%08lx,%08x) stub!\n",This,pCallback,pvParam,dwFlags,hAbort);
+
+	QUARTZ_CompList_Lock( This->m_pFilterList );
+	EnterCriticalSection( &This->m_csGraphState );
+
+	hr = IGraphConfigCallback_Reconfigure(pCallback,pvParam,dwFlags);
+
+	LeaveCriticalSection( &This->m_csGraphState );
+	QUARTZ_CompList_Unlock( This->m_pFilterList );
+
+	return hr;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnAddFilterToCache(IGraphConfig* iface,IBaseFilter* pFilter)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnEnumCacheFilter(IGraphConfig* iface,IEnumFilters** ppenum)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	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
+IGraphConfig_fnGetStartTime(IGraphConfig* iface,REFERENCE_TIME* prt)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnPushThroughData(IGraphConfig* iface,IPin* pOut,IPinConnection* pConn,HANDLE hAbort)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnSetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnGetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD* pdwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+static HRESULT WINAPI
+IGraphConfig_fnRemoveFilterEx(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
+{
+	CFilterGraph_THIS(iface,grphconf);
+
+	FIXME("(%p)->() stub!\n",This);
+
+	return E_NOTIMPL;
+}
+
+
+
+
+
+static ICOM_VTABLE(IGraphConfig) igraphconfig =
+{
+	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+	/* IUnknown fields */
+	IGraphConfig_fnQueryInterface,
+	IGraphConfig_fnAddRef,
+	IGraphConfig_fnRelease,
+	/* IGraphConfig fields */
+	IGraphConfig_fnReconnect,
+	IGraphConfig_fnReconfigure,
+	IGraphConfig_fnAddFilterToCache,
+	IGraphConfig_fnEnumCacheFilter,
+	IGraphConfig_fnRemoveFilterFromCache,
+	IGraphConfig_fnGetStartTime,
+	IGraphConfig_fnPushThroughData,
+	IGraphConfig_fnSetFilterFlags,
+	IGraphConfig_fnGetFilterFlags,
+	IGraphConfig_fnRemoveFilterEx,
+};
+
+
+
+HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+	ICOM_VTBL(&pfg->grphconf) = &igraphconfig;
+
+	return NOERROR;
+}
+
+void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg )
+{
+	TRACE("(%p)\n",pfg);
+}
+
+
diff --git a/dlls/quartz/igconfig.c b/dlls/quartz/igconfig.c
deleted file mode 100644
index 4ab9b08..0000000
--- a/dlls/quartz/igconfig.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Implementation of IGraphConfig 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
-IGraphConfig_fnQueryInterface(IGraphConfig* iface,REFIID riid,void** ppobj)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IGraphConfig_fnAddRef(IGraphConfig* iface)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IGraphConfig_fnRelease(IGraphConfig* iface)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-
-
-static HRESULT WINAPI
-IGraphConfig_fnReconnect(IGraphConfig* iface,IPin* pOut,IPin* pIn,const AM_MEDIA_TYPE* pmt,IBaseFilter* pFilter,HANDLE hAbort,DWORD dwFlags)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IGraphConfig_fnReconfigure(IGraphConfig* iface,IGraphConfigCallback* pCallback,PVOID pvParam,DWORD dwFlags,HANDLE hAbort)
-{
-	CFilterGraph_THIS(iface,grphconf);
-	HRESULT hr;
-
-	FIXME("(%p)->(%p,%p,%08lx,%08x) stub!\n",This,pCallback,pvParam,dwFlags,hAbort);
-
-	QUARTZ_CompList_Lock( This->m_pFilterList );
-	EnterCriticalSection( &This->m_csGraphState );
-
-	hr = IGraphConfigCallback_Reconfigure(pCallback,pvParam,dwFlags);
-
-	LeaveCriticalSection( &This->m_csGraphState );
-	QUARTZ_CompList_Unlock( This->m_pFilterList );
-
-	return hr;
-}
-
-static HRESULT WINAPI
-IGraphConfig_fnAddFilterToCache(IGraphConfig* iface,IBaseFilter* pFilter)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IGraphConfig_fnEnumCacheFilter(IGraphConfig* iface,IEnumFilters** ppenum)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	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
-IGraphConfig_fnGetStartTime(IGraphConfig* iface,REFERENCE_TIME* prt)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IGraphConfig_fnPushThroughData(IGraphConfig* iface,IPin* pOut,IPinConnection* pConn,HANDLE hAbort)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IGraphConfig_fnSetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IGraphConfig_fnGetFilterFlags(IGraphConfig* iface,IBaseFilter* pFilter,DWORD* pdwFlags)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-static HRESULT WINAPI
-IGraphConfig_fnRemoveFilterEx(IGraphConfig* iface,IBaseFilter* pFilter,DWORD dwFlags)
-{
-	CFilterGraph_THIS(iface,grphconf);
-
-	FIXME("(%p)->() stub!\n",This);
-
-	return E_NOTIMPL;
-}
-
-
-
-
-
-static ICOM_VTABLE(IGraphConfig) igraphconfig =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IGraphConfig_fnQueryInterface,
-	IGraphConfig_fnAddRef,
-	IGraphConfig_fnRelease,
-	/* IGraphConfig fields */
-	IGraphConfig_fnReconnect,
-	IGraphConfig_fnReconfigure,
-	IGraphConfig_fnAddFilterToCache,
-	IGraphConfig_fnEnumCacheFilter,
-	IGraphConfig_fnRemoveFilterFromCache,
-	IGraphConfig_fnGetStartTime,
-	IGraphConfig_fnPushThroughData,
-	IGraphConfig_fnSetFilterFlags,
-	IGraphConfig_fnGetFilterFlags,
-	IGraphConfig_fnRemoveFilterEx,
-};
-
-
-
-HRESULT CFilterGraph_InitIGraphConfig( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->grphconf) = &igraphconfig;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIGraphConfig( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-}
-
diff --git a/dlls/quartz/igrver.c b/dlls/quartz/igrver.c
deleted file mode 100644
index 3fee68c..0000000
--- a/dlls/quartz/igrver.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Implementation of IGraphVersion 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
-IGraphVersion_fnQueryInterface(IGraphVersion* iface,REFIID riid,void** ppobj)
-{
-	CFilterGraph_THIS(iface,graphversion);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
-}
-
-static ULONG WINAPI
-IGraphVersion_fnAddRef(IGraphVersion* iface)
-{
-	CFilterGraph_THIS(iface,graphversion);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_AddRef(This->unk.punkControl);
-}
-
-static ULONG WINAPI
-IGraphVersion_fnRelease(IGraphVersion* iface)
-{
-	CFilterGraph_THIS(iface,graphversion);
-
-	TRACE("(%p)->()\n",This);
-
-	return IUnknown_Release(This->unk.punkControl);
-}
-
-
-static HRESULT WINAPI
-IGraphVersion_fnQueryVersion(IGraphVersion* iface,LONG* plVersion)
-{
-	CFilterGraph_THIS(iface,graphversion);
-
-	TRACE("(%p)->(%p)\n",This,plVersion);
-
-	if ( plVersion == NULL )
-		return E_POINTER;
-
-	EnterCriticalSection( &This->m_csGraphVersion );
-	*plVersion = This->m_lGraphVersion;
-	LeaveCriticalSection( &This->m_csGraphVersion );
-
-	return NOERROR;
-}
-
-
-static ICOM_VTABLE(IGraphVersion) igraphversion =
-{
-	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-	/* IUnknown fields */
-	IGraphVersion_fnQueryInterface,
-	IGraphVersion_fnAddRef,
-	IGraphVersion_fnRelease,
-	/* IGraphVersion fields */
-	IGraphVersion_fnQueryVersion,
-};
-
-
-
-HRESULT CFilterGraph_InitIGraphVersion( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-	ICOM_VTBL(&pfg->graphversion) = &igraphversion;
-
-	InitializeCriticalSection( &pfg->m_csGraphVersion );
-	pfg->m_lGraphVersion = 1;
-
-	return NOERROR;
-}
-
-void CFilterGraph_UninitIGraphVersion( CFilterGraph* pfg )
-{
-	TRACE("(%p)\n",pfg);
-
-	DeleteCriticalSection( &pfg->m_csGraphVersion );
-}
-
diff --git a/dlls/quartz/imcntl.c b/dlls/quartz/imcntl.c
index 512600c..467210c 100644
--- a/dlls/quartz/imcntl.c
+++ b/dlls/quartz/imcntl.c
@@ -13,8 +13,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
-#include "wine/obj_oleaut.h"
 #include "oleauto.h"
 #include "strmif.h"
 #include "control.h"
diff --git a/dlls/quartz/imfilter.c b/dlls/quartz/imfilter.c
index a602852..08a5c2a 100644
--- a/dlls/quartz/imfilter.c
+++ b/dlls/quartz/imfilter.c
@@ -13,8 +13,6 @@
 #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"
diff --git a/dlls/quartz/impos.c b/dlls/quartz/impos.c
index 38d6903..24bf13e 100644
--- a/dlls/quartz/impos.c
+++ b/dlls/quartz/impos.c
@@ -13,8 +13,6 @@
 #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"
diff --git a/dlls/quartz/imseek.c b/dlls/quartz/imseek.c
index 2a515fb..3489329 100644
--- a/dlls/quartz/imseek.c
+++ b/dlls/quartz/imseek.c
@@ -14,8 +14,6 @@
 #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"
diff --git a/dlls/quartz/main.c b/dlls/quartz/main.c
index fb8421c..5d64626 100644
--- a/dlls/quartz/main.c
+++ b/dlls/quartz/main.c
@@ -14,7 +14,6 @@
 #include "winnls.h"
 #include "mmsystem.h"
 #include "ole2.h"
-#include "wine/obj_oleaut.h"
 #include "strmif.h"
 #include "control.h"
 #include "uuids.h"
@@ -23,17 +22,19 @@
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
 
+#include "initguid.h"
+
 #include "quartz_private.h"
 #include "fgraph.h"
 #include "sysclock.h"
 #include "memalloc.h"
 #include "devenum.h"
 #include "fmap.h"
-#include "fmap2.h"
 #include "seekpass.h"
 #include "audren.h"
 #include "vidren.h"
 #include "parser.h"
+#include "asyncsrc.h"
 
 typedef struct QUARTZ_CLASSENTRY
 {
@@ -80,6 +81,9 @@
 	{ &CLSID_AudioRender, &QUARTZ_CreateAudioRenderer },
 	{ &CLSID_VideoRenderer, &QUARTZ_CreateVideoRenderer },
 	{ &CLSID_quartzWaveParser, &QUARTZ_CreateWaveParser },
+	{ &CLSID_AviSplitter, &QUARTZ_CreateAVISplitter },
+	{ &CLSID_AsyncReader, &QUARTZ_CreateAsyncReader },
+	{ &CLSID_URLReader, &QUARTZ_CreateURLReader },
 	{ NULL, NULL },
 };
 
diff --git a/dlls/quartz/memalloc.c b/dlls/quartz/memalloc.c
index 31e0e6b..133ea46 100644
--- a/dlls/quartz/memalloc.c
+++ b/dlls/quartz/memalloc.c
@@ -11,7 +11,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "strmif.h"
 #include "uuids.h"
 
diff --git a/dlls/quartz/mtype.c b/dlls/quartz/mtype.c
index 0510fdf..2f61ba6 100644
--- a/dlls/quartz/mtype.c
+++ b/dlls/quartz/mtype.c
@@ -11,7 +11,7 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
+#include "mmsystem.h"
 #include "strmif.h"
 #include "vfwmsgs.h"
 #include "uuids.h"
@@ -119,6 +119,108 @@
 	return IsEqualGUID( psubtype, &guidTemp );
 }
 
+HRESULT QUARTZ_MediaSubType_FromBitmap(
+	GUID* psubtype, const BITMAPINFOHEADER* pbi )
+{
+	HRESULT hr;
+	DWORD*	pdwBitf;
+
+	if ( (pbi->biCompression & 0xffff) != 0 )
+		return S_FALSE;
+
+	if ( pbi->biWidth <= 0 || pbi->biHeight == 0 )
+		return E_FAIL;
+
+	hr = E_FAIL;
+	switch ( pbi->biCompression )
+	{
+	case 0:
+		if ( pbi->biPlanes != 1 )
+			break;
+		switch ( pbi->biBitCount )
+		{
+		case  1:
+			memcpy( psubtype, &MEDIASUBTYPE_RGB1, sizeof(GUID) );
+			hr = S_OK;
+			break;
+		case  4:
+			memcpy( psubtype, &MEDIASUBTYPE_RGB4, sizeof(GUID) );
+			hr = S_OK;
+			break;
+		case  8:
+			memcpy( psubtype, &MEDIASUBTYPE_RGB8, sizeof(GUID) );
+			hr = S_OK;
+			break;
+		case 16:
+			memcpy( psubtype, &MEDIASUBTYPE_RGB555, sizeof(GUID) );
+			hr = S_OK;
+			break;
+		case 24:
+			memcpy( psubtype, &MEDIASUBTYPE_RGB24, sizeof(GUID) );
+			hr = S_OK;
+			break;
+		case 32:
+			memcpy( psubtype, &MEDIASUBTYPE_RGB32, sizeof(GUID) );
+			hr = S_OK;
+			break;
+		}
+		break;
+	case 1:
+		if ( pbi->biPlanes == 1 && pbi->biHeight > 0 &&
+			 pbi->biBitCount == 8 )
+		{
+			QUARTZ_MediaSubType_FromFourCC( psubtype, mmioFOURCC('M','R','L','E') );
+			hr = S_OK;
+		}
+		break;
+	case 2:
+		if ( pbi->biPlanes == 1 && pbi->biHeight > 0 &&
+			 pbi->biBitCount == 4 )
+		{
+			QUARTZ_MediaSubType_FromFourCC( psubtype, mmioFOURCC('M','R','L','E') );
+			hr = S_OK;
+		}
+		break;
+	case 3:
+		if ( pbi->biPlanes != 1 )
+			break;
+		pdwBitf = (DWORD*)( (BYTE*)pbi + sizeof(BITMAPINFOHEADER) );
+		switch ( pbi->biBitCount )
+		{
+		case 16:
+			if ( pdwBitf[0] == 0x7c00 &&
+				 pdwBitf[1] == 0x03e0 &&
+				 pdwBitf[2] == 0x001f )
+			{
+				memcpy( psubtype, &MEDIASUBTYPE_RGB555, sizeof(GUID) );
+				hr = S_OK;
+			}
+			if ( pdwBitf[0] == 0xf800 &&
+				 pdwBitf[1] == 0x07e0 &&
+				 pdwBitf[2] == 0x001f )
+			{
+				memcpy( psubtype, &MEDIASUBTYPE_RGB565, sizeof(GUID) );
+				hr = S_OK;
+			}
+			break;
+		case 32:
+			if ( pdwBitf[0] == 0x00ff0000 &&
+				 pdwBitf[1] == 0x0000ff00 &&
+				 pdwBitf[2] == 0x000000ff )
+			{
+				memcpy( psubtype, &MEDIASUBTYPE_RGB32, sizeof(GUID) );
+				hr = S_OK;
+			}
+			break;
+		}
+		break;
+	}
+
+	return hr;
+}
+
+
+
 /****************************************************************************/
 
 typedef struct IEnumMediaTypesImpl
diff --git a/dlls/quartz/mtype.h b/dlls/quartz/mtype.h
index 9332f3e..d27958e 100644
--- a/dlls/quartz/mtype.h
+++ b/dlls/quartz/mtype.h
@@ -22,6 +22,9 @@
 BOOL QUARTZ_MediaSubType_IsFourCC(
 	const GUID* psubtype );
 
+HRESULT QUARTZ_MediaSubType_FromBitmap(
+	GUID* psubtype, const BITMAPINFOHEADER* pbi );
+
 HRESULT QUARTZ_CreateEnumMediaTypes(
 	IEnumMediaTypes** ppobj,
 	const AM_MEDIA_TYPE* pTypes, ULONG cTypes );
diff --git a/dlls/quartz/parser.c b/dlls/quartz/parser.c
index 897b31a..d0e124a 100644
--- a/dlls/quartz/parser.c
+++ b/dlls/quartz/parser.c
@@ -2,6 +2,8 @@
  * Implements IBaseFilter for parsers. (internal)
  *
  * hidenori@a2.ctktv.ne.jp
+ *
+ * FIXME - save the array of pSample and handle errors/flushing correctly.
  */
 
 #include "config.h"
@@ -12,7 +14,6 @@
 #include "winuser.h"
 #include "mmsystem.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "strmif.h"
 #include "vfwmsgs.h"
 #include "uuids.h"
@@ -179,6 +180,8 @@
 		hr = NOERROR;
 
 	IMediaSample_Release(pSample);
+	TRACE("return %08lx\n",hr);
+
 	return hr;
 }
 
@@ -232,6 +235,9 @@
 				}
 				continue;
 			}
+			if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL )
+				continue;
+
 			rtSampleTimeStart = llReqStart * QUARTZ_TIMEUNITS;
 			rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS;
 			bReqNext = FALSE;
diff --git a/dlls/quartz/parser.h b/dlls/quartz/parser.h
index 1fb997c..45d4214 100644
--- a/dlls/quartz/parser.h
+++ b/dlls/quartz/parser.h
@@ -124,7 +124,6 @@
 	LPCWSTR pwszPinName );
 
 
-#define QUARTZ_TIMEUNITS		((LONGLONG)10000000)
 #define PARSER_POLL_INTERVAL	100
 
 #define PARSER_RIFF_OfsFirst 12
@@ -136,6 +135,9 @@
 #define PARSER_fact mmioFOURCC('f','a','c','t')
 #define PARSER_data mmioFOURCC('d','a','t','a')
 
+#define PARSER_LIST mmioFOURCC('L','I','S','T')
+
+#define PARSER_hdrl mmioFOURCC('h','d','r','l')
 #define PARSER_avih mmioFOURCC('a','v','i','h')
 #define PARSER_strl mmioFOURCC('s','t','r','l')
 #define PARSER_strh mmioFOURCC('s','t','r','h')
@@ -156,7 +158,22 @@
 #define PARSER_BE_UINT32(ptr)	(((DWORD)(ptr)[0]<<24)|((DWORD)(ptr)[1]<<16)|((DWORD)(ptr)[2]<<8)|((DWORD)(ptr)[3]))
 
 HRESULT QUARTZ_CreateWaveParser(IUnknown* punkOuter,void** ppobj);
+HRESULT QUARTZ_CreateAVISplitter(IUnknown* punkOuter,void** ppobj);
 
 
+HRESULT RIFF_GetNext(
+	CParserImpl* pImpl, LONGLONG llOfs,
+	DWORD* pdwCode, DWORD* pdwLength );
+HRESULT RIFF_SearchChunk(
+	CParserImpl* pImpl,
+	DWORD dwSearchLengthMax,
+	LONGLONG llOfs, DWORD dwChunk,
+	LONGLONG* pllOfs, DWORD* pdwChunkLength );
+HRESULT RIFF_SearchList(
+	CParserImpl* pImpl,
+	DWORD dwSearchLengthMax,
+	LONGLONG llOfs, DWORD dwListChunk,
+	LONGLONG* pllOfs, DWORD* pdwChunkLength );
+
 
 #endif	/* WINE_DSHOW_PARSER_H */
diff --git a/dlls/quartz/quartz_private.h b/dlls/quartz/quartz_private.h
index 5efb684..14a58c7 100644
--- a/dlls/quartz/quartz_private.h
+++ b/dlls/quartz/quartz_private.h
@@ -9,5 +9,7 @@
 void QUARTZ_FreeMem( void* pMem );
 void* QUARTZ_ReallocMem( void* pMem, DWORD dwSize );
 
+#define QUARTZ_TIMEUNITS		((LONGLONG)10000000)
+
 #endif	/* QUARTZ_PRIVATE_H */
 
diff --git a/dlls/quartz/regsvr.c b/dlls/quartz/regsvr.c
index f979137..01fb327 100644
--- a/dlls/quartz/regsvr.c
+++ b/dlls/quartz/regsvr.c
@@ -13,7 +13,6 @@
 #include "winerror.h"
 #include "winreg.h"
 #include "uuids.h"
-#include "wine/unicode.h"
 
 #include "debugtools.h"
 DEFAULT_DEBUG_CHANNEL(quartz);
@@ -46,7 +45,7 @@
 static
 void QUARTZ_CatPathSepW( WCHAR* pBuf )
 {
-	int	len = strlenW(pBuf);
+	int	len = lstrlenW(pBuf);
 	pBuf[len] = '\\';
 	pBuf[len+1] = 0;
 }
@@ -96,7 +95,7 @@
 	return RegSetValueExW(
 		hKey, lpszName, 0, REG_SZ,
 		(const BYTE*)lpValue,
-		sizeof(lpValue[0]) * (strlenW(lpValue)+1) );
+		sizeof(lpValue[0]) * (lstrlenW(lpValue)+1) );
 }
 
 static
@@ -124,16 +123,16 @@
 {
 	int avail;
 
-	strcpyW( pwszBuf, QUARTZ_wszCLSID );
+	lstrcpyW( pwszBuf, QUARTZ_wszCLSID );
 	QUARTZ_CatPathSepW( pwszBuf+5 );
 	QUARTZ_GUIDtoString( pwszBuf+6, pclsid );
 	if ( lpszPathFromCLSID != NULL )
 	{
-		avail = (int)dwBufLen - strlenW(pwszBuf) - 8;
-		if ( avail <= strlenW(lpszPathFromCLSID) )
+		avail = (int)dwBufLen - lstrlenW(pwszBuf) - 8;
+		if ( avail <= lstrlenW(lpszPathFromCLSID) )
 			return E_FAIL;
 		QUARTZ_CatPathSepW( pwszBuf );
-		strcatW( pwszBuf, lpszPathFromCLSID );
+		lstrcatW( pwszBuf, lpszPathFromCLSID );
 	}
 
 	return NOERROR;
@@ -245,9 +244,9 @@
 	WCHAR	szCLSID[ 256 ];
 
 	QUARTZ_GUIDtoString( szCLSID, pguidFilterCategory );
-	strcpyW( szFilterPath, QUARTZ_wszInstance );
+	lstrcpyW( szFilterPath, QUARTZ_wszInstance );
 	QUARTZ_CatPathSepW( szFilterPath );
-	strcatW( szFilterPath, szCLSID );
+	lstrcatW( szFilterPath, szCLSID );
 
 	if ( fRegister )
 	{
@@ -313,9 +312,9 @@
 	WCHAR	szCLSID[ 256 ];
 
 	QUARTZ_GUIDtoString( szCLSID, pclsid );
-	strcpyW( szFilterPath, QUARTZ_wszInstance );
+	lstrcpyW( szFilterPath, QUARTZ_wszInstance );
 	QUARTZ_CatPathSepW( szFilterPath );
-	strcatW( szFilterPath, ( lpInstance != NULL ) ? lpInstance : szCLSID );
+	lstrcatW( szFilterPath, ( lpInstance != NULL ) ? lpInstance : szCLSID );
 
 	if ( fRegister )
 	{
diff --git a/dlls/quartz/sample.c b/dlls/quartz/sample.c
index 6b30408..c9c0e15 100644
--- a/dlls/quartz/sample.c
+++ b/dlls/quartz/sample.c
@@ -11,7 +11,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "strmif.h"
 #include "vfwmsgs.h"
 
diff --git a/dlls/quartz/seekpass.c b/dlls/quartz/seekpass.c
index c8c45f6..1c20f67 100644
--- a/dlls/quartz/seekpass.c
+++ b/dlls/quartz/seekpass.c
@@ -13,7 +13,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "strmif.h"
 #include "control.h"
 #include "uuids.h"
diff --git a/dlls/quartz/sysclock.c b/dlls/quartz/sysclock.c
index b2b64f7..bef024a 100644
--- a/dlls/quartz/sysclock.c
+++ b/dlls/quartz/sysclock.c
@@ -11,7 +11,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "strmif.h"
 #include "uuids.h"
 
diff --git a/dlls/quartz/vidren.c b/dlls/quartz/vidren.c
index e30a076..47cade8 100644
--- a/dlls/quartz/vidren.c
+++ b/dlls/quartz/vidren.c
@@ -14,8 +14,6 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
-#include "wine/obj_oleaut.h"
 #include "mmsystem.h"
 #include "strmif.h"
 #include "control.h"
diff --git a/dlls/quartz/wavparse.c b/dlls/quartz/wavparse.c
index 6514e99..49fbe2c 100644
--- a/dlls/quartz/wavparse.c
+++ b/dlls/quartz/wavparse.c
@@ -11,8 +11,8 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "mmsystem.h"
+#include "mmreg.h"
 #include "winerror.h"
-#include "wine/obj_base.h"
 #include "strmif.h"
 #include "vfwmsgs.h"
 #include "uuids.h"
@@ -21,9 +21,7 @@
 DEFAULT_DEBUG_CHANNEL(quartz);
 
 #include "quartz_private.h"
-
-/* for CLSID_quartzWaveParser. */
-#include "initguid.h"
+#include "audioutl.h"
 #include "parser.h"
 
 
@@ -63,29 +61,87 @@
 /* S_OK = found, S_FALSE = not found */
 HRESULT RIFF_SearchChunk(
 	CParserImpl* pImpl,
+	DWORD dwSearchLengthMax,
 	LONGLONG llOfs, DWORD dwChunk,
 	LONGLONG* pllOfs, DWORD* pdwChunkLength )
 {
 	HRESULT hr;
 	DWORD dwCurCode;
 	DWORD dwCurLen;
+	LONGLONG llCurLen;
 
 	while ( 1 )
 	{
 		hr = RIFF_GetNext( pImpl, llOfs, &dwCurCode, &dwCurLen );
 		if ( hr != S_OK )
 			break;
+		TRACE("%c%c%c%c len %lu\n",
+			(int)(dwCurCode>> 0)&0xff,
+			(int)(dwCurCode>> 8)&0xff,
+			(int)(dwCurCode>>16)&0xff,
+			(int)(dwCurCode>>24)&0xff,
+			(unsigned long)dwCurLen);
 		if ( dwChunk == dwCurCode )
 			break;
-		llOfs += 8 + (LONGLONG)((dwCurLen+1)&(~1));
+		llCurLen = 8 + (LONGLONG)((dwCurLen+1)&(~1));
+		llOfs += llCurLen;
+		if ( (LONGLONG)dwSearchLengthMax <= llCurLen )
+			return S_FALSE;
+		if ( dwSearchLengthMax != (DWORD)0xffffffff )
+			dwSearchLengthMax -= (DWORD)llCurLen;
 	}
 
-	*pllOfs = llOfs;
+	*pllOfs = llOfs + 8;
 	*pdwChunkLength = dwCurLen;
 
 	return hr;
 }
 
+/* S_OK = found, S_FALSE = not found */
+HRESULT RIFF_SearchList(
+	CParserImpl* pImpl,
+	DWORD dwSearchLengthMax,
+	LONGLONG llOfs, DWORD dwListChunk,
+	LONGLONG* pllOfs, DWORD* pdwChunkLength )
+{
+	HRESULT hr;
+	DWORD dwCurLen;
+	LONGLONG llCurLen;
+	BYTE bTemp[4];
+
+	while ( 1 )
+	{
+		hr = RIFF_SearchChunk(
+			pImpl, dwSearchLengthMax,
+			llOfs, PARSER_LIST,
+			&llOfs, &dwCurLen );
+		if ( hr != S_OK )
+			break;
+
+		hr = IAsyncReader_SyncRead( pImpl->m_pReader, llOfs, 4, bTemp );
+		if ( hr != S_OK )
+			break;
+
+		if ( mmioFOURCC(bTemp[0],bTemp[1],bTemp[2],bTemp[3]) == dwListChunk )
+			break;
+
+		llCurLen = (LONGLONG)((dwCurLen+1)&(~1));
+		llOfs += llCurLen;
+		if ( (LONGLONG)dwSearchLengthMax <= (llCurLen+8) )
+			return S_FALSE;
+		if ( dwSearchLengthMax != (DWORD)0xffffffff )
+			dwSearchLengthMax -= (DWORD)(llCurLen+8);
+	}
+
+	if ( dwCurLen < 12 )
+		return E_FAIL;
+
+	*pllOfs = llOfs+4;
+	*pdwChunkLength = dwCurLen-4;
+
+	return hr;
+}
+
 
 
 
@@ -122,13 +178,13 @@
 	DWORD	dwChunkLength;
 
 	hr = RIFF_SearchChunk(
-		pImpl, PARSER_RIFF_OfsFirst,
-		PARSER_fmt, &llOfs, &dwChunkLength );
+		pImpl, (DWORD)0xffffffff,
+		PARSER_RIFF_OfsFirst, PARSER_fmt,
+		&llOfs, &dwChunkLength );
 	if ( FAILED(hr) )
 		return hr;
 	if ( hr != S_OK || ( dwChunkLength < (sizeof(WAVEFORMATEX)-2) ) )
 		return E_FAIL;
-	llOfs += 8;
 
 	This->cbFmt = dwChunkLength;
 	if ( dwChunkLength < sizeof(WAVEFORMATEX) )
@@ -149,8 +205,9 @@
 
 
 	hr = RIFF_SearchChunk(
-		pImpl, PARSER_RIFF_OfsFirst,
-		PARSER_data, &llOfs, &dwChunkLength );
+		pImpl, (DWORD)0xffffffff,
+		PARSER_RIFF_OfsFirst, PARSER_data,
+		&llOfs, &dwChunkLength );
 	if ( FAILED(hr) )
 		return hr;
 	if ( hr != S_OK || dwChunkLength == 0 )
@@ -195,18 +252,18 @@
 	switch ( datafmt )
 	{
 	case 1:
-		wfx.wFormatTag = 7;
+		wfx.wFormatTag = WAVE_FORMAT_MULAW;
 		wfx.nBlockAlign = datachannels;
 		wfx.wBitsPerSample = 8;
 		break;
 	case 2:
-		wfx.wFormatTag = 1;
+		wfx.wFormatTag = WAVE_FORMAT_PCM;
 		wfx.nBlockAlign = datachannels;
 		wfx.wBitsPerSample = 8;
 		This->iFmtType = WaveParse_Signed8;
 		break;
 	case 3:
-		wfx.wFormatTag = 1;
+		wfx.wFormatTag = WAVE_FORMAT_PCM;
 		wfx.nBlockAlign = datachannels;
 		wfx.wBitsPerSample = 16;
 		This->iFmtType = WaveParse_Signed16BE;
@@ -417,13 +474,36 @@
 static HRESULT CWavParseImpl_ProcessSample( CParserImpl* pImpl, ULONG nStreamIndex, LONGLONG llStart, LONG lLength, IMediaSample* pSample )
 {
 	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;
+	BYTE*	pData;
+	LONG	lActLen;
+	HRESULT hr;
 
 	TRACE("(%p)\n",This);
 
+	hr = IMediaSample_GetPointer(pSample,&pData);
+	if ( FAILED(hr) )
+		return hr;
+	lActLen = (LONG)IMediaSample_GetActualDataLength(pSample);
+	if ( lActLen != lLength )
+		return E_FAIL;
+
 	switch ( This->iFmtType )
 	{
 	case WaveParse_Native:
 		break;
+	case WaveParse_Signed8:
+		AUDIOUTL_ChangeSign8(pData,lActLen);
+		break;
+	case WaveParse_Signed16BE:
+		AUDIOUTL_ByteSwap(pData,lActLen);
+		break;
+	case WaveParse_Unsigned16LE:
+		AUDIOUTL_ChangeSign16LE(pData,lActLen);
+		break;
+	case WaveParse_Unsigned16BE:
+		AUDIOUTL_ChangeSign16BE(pData,lActLen);
+		AUDIOUTL_ByteSwap(pData,lActLen);
+		break;
 	default:
 		FIXME("(%p) - %d not implemented\n", This, This->iFmtType );
 		return E_FAIL;
diff --git a/include/amvideo.h b/include/amvideo.h
index 19dabb6..50cd438 100644
--- a/include/amvideo.h
+++ b/include/amvideo.h
@@ -1,7 +1,6 @@
 #ifndef __WINE_AMVIDEO_H_
 #define __WINE_AMVIDEO_H_
 
-#include "ole2.h"
 #include "ddraw.h"
 
 
diff --git a/include/control.h b/include/control.h
index a5c9c43..c1675d1 100644
--- a/include/control.h
+++ b/include/control.h
@@ -1,8 +1,6 @@
 #ifndef __WINE_CONTROL_H_
 #define __WINE_CONTROL_H_
 
-#include "ole2.h"
-
 /* forward decls. */
 
 typedef struct IAMCollection IAMCollection;
diff --git a/include/strmif.h b/include/strmif.h
index 9176e66..0186206 100644
--- a/include/strmif.h
+++ b/include/strmif.h
@@ -10,7 +10,10 @@
 #ifndef __WINE_STRMIF_H_
 #define __WINE_STRMIF_H_
 
-#include "ole2.h"
+#include "wine/obj_base.h"
+#include "wine/obj_misc.h"
+#include "wine/obj_storage.h"
+#include "wine/obj_moniker.h"
 #include "wine/obj_oleaut.h"
 #include "wine/obj_property.h"
 #include "wine/obj_ksproperty.h"