/*
 * Implements IBaseFilter for parsers. (internal)
 *
 * Copyright (C) Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * FIXME - handle errors/flushing correctly.
 * FIXME - handle seeking.
 */

#include "config.h"

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmsystem.h"
#include "winerror.h"
#include "strmif.h"
#include "control.h"
#include "vfwmsgs.h"
#include "evcode.h"
#include "uuids.h"

#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(quartz);

#include "quartz_private.h"
#include "parser.h"
#include "mtype.h"
#include "memalloc.h"

#define	QUARTZ_MSG_EXITTHREAD	(WM_APP+2)
#define	QUARTZ_MSG_SEEK			(WM_APP+3)

#ifndef OATRUE
#define OATRUE (-1)
#define OAFALSE (0)
#endif

HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This );
void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This );
HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This );
void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This );

/***************************************************************************
 *
 *	CParserImpl internal thread
 *
 */

static
void CParserImplThread_ClearAllRequests( CParserImpl* This )
{
	ULONG	nIndex;

	TRACE("(%p)\n",This);

	for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
	{
		This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE;
		This->m_ppOutPins[nIndex]->m_pReqSample = NULL;
	}
}

static
void CParserImplThread_ReleaseAllRequests( CParserImpl* This )
{
	ULONG	nIndex;

	TRACE("(%p)\n",This);

	for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
	{
		if ( This->m_ppOutPins[nIndex]->m_bReqUsed )
		{
			if ( This->m_ppOutPins[nIndex]->m_pReqSample != NULL )
			{
				IMediaSample_Release(This->m_ppOutPins[nIndex]->m_pReqSample);
				This->m_ppOutPins[nIndex]->m_pReqSample = NULL;
			}
			This->m_ppOutPins[nIndex]->m_bReqUsed = FALSE;
		}
	}
}

static
BOOL CParserImplThread_HasPendingSamples( CParserImpl* This )
{
	ULONG	nIndex;

	for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
	{
		if ( This->m_ppOutPins[nIndex]->m_bReqUsed &&
			 This->m_ppOutPins[nIndex]->m_pReqSample != NULL )
			return TRUE;
	}

	return FALSE;
}

static
HRESULT CParserImplThread_FlushAllPendingSamples( CParserImpl* This )
{
	HRESULT hr;
	IMediaSample*	pSample;
	DWORD_PTR	dwContext;

	TRACE("(%p)\n",This);

	/* remove all samples from queue. */
	hr = IAsyncReader_BeginFlush(This->m_pReader);
	if ( FAILED(hr) )
		return hr;
	IAsyncReader_EndFlush(This->m_pReader);

	/* remove all processed samples from queue. */
	while ( 1 )
	{
		hr = IAsyncReader_WaitForNext(This->m_pReader,0,&pSample,&dwContext);
		if ( hr != S_OK )
			break;
	}

	CParserImplThread_ReleaseAllRequests(This);

	return NOERROR;
}

static HRESULT CParserImplThread_SendEndOfStream( CParserImpl* This )
{
	ULONG	nIndex;
	HRESULT hr;
	HRESULT hrRet;
	CParserOutPinImpl*	pOutPin;

	TRACE("(%p)\n",This);
	if ( This->m_bSendEOS )
		return NOERROR;
	This->m_bSendEOS = TRUE;

	hrRet = S_OK;
	for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
	{
		pOutPin = This->m_ppOutPins[nIndex];
		hr = CPinBaseImpl_SendEndOfStream(&pOutPin->pin);
		if ( FAILED(hr) )
		{
			if ( SUCCEEDED(hrRet) )
				hrRet = hr;
		}
		else
		{
			if ( hr != S_OK && hrRet == S_OK )
				hrRet = hr;
		}
	}

	return hrRet;
}

static
void CParserImplThread_MemDecommit( CParserImpl* This )
{
	ULONG	nIndex;
	IMemAllocator*	pAlloc;

	TRACE("(%p)\n",This);

	if ( This->m_pAllocator != NULL )
		IMemAllocator_Decommit( This->m_pAllocator );

	if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
	{
		for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
		{
			pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
			if ( pAlloc != NULL )
				IMemAllocator_Decommit( pAlloc );
		}
	}
}

static HRESULT CParserImplThread_SendFlush( CParserImpl* This )
{
	ULONG	nIndex;
	HRESULT hr;
	HRESULT hrRet;
	CParserOutPinImpl*	pOutPin;

	TRACE("(%p)\n",This);
	hrRet = S_OK;
	for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
	{
		pOutPin = This->m_ppOutPins[nIndex];
		hr = CPinBaseImpl_SendBeginFlush(&pOutPin->pin);
		if ( FAILED(hr) )
		{
			if ( SUCCEEDED(hrRet) )
				hrRet = hr;
		}
		else
		{
			if ( hr != S_OK && hrRet == S_OK )
				hrRet = hr;
			hr = CPinBaseImpl_SendEndFlush(&pOutPin->pin);
			if ( FAILED(hr) )
				hrRet = hr;
		}
	}

	return hrRet;
}

static void CParserImplThread_ErrorAbort( CParserImpl* This, HRESULT hr )
{
	CBaseFilterImpl_MediaEventNotify(
		&This->basefilter,EC_ERRORABORT,(LONG_PTR)hr,(LONG_PTR)0);
	CParserImplThread_SendEndOfStream(This);
}

static
void CParserImplThread_ResetAllStreams( CParserImpl* This )
{
	ULONG	nIndex;

	if ( This->m_pHandler->pSetCurPos != NULL )
	{
		for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
			This->m_pHandler->pSetCurPos(This,
				&This->m_guidTimeFormat,nIndex,(LONGLONG)0);
	}
}

static
HRESULT CParserImplThread_ProcessNextSample( CParserImpl* This )
{
	IMediaSample*	pSample;
	DWORD_PTR	dwContext;
	ULONG	nIndex;
	HRESULT hr;
	CParserOutPinImpl*	pOutPin;
	MSG	msg;

	while ( 1 )
	{
		if ( PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_REMOVE ) )
		{
			hr = NOERROR;
			switch ( msg.message )
			{
			case QUARTZ_MSG_EXITTHREAD:
				TRACE("(%p) EndThread\n",This);
				CParserImplThread_FlushAllPendingSamples(This);
				CParserImplThread_ClearAllRequests(This);
				CParserImplThread_SendFlush(This);
				CParserImplThread_SendEndOfStream(This);
				This->m_bSendEOS = FALSE;

				CParserImplThread_ResetAllStreams(This);
				CParserImplThread_MemDecommit(This);

				TRACE("(%p) exit thread\n",This);
				return S_FALSE;
			case QUARTZ_MSG_SEEK:
				FIXME("(%p) Seek\n",This);
				CParserImplThread_FlushAllPendingSamples(This);
				hr = CParserImplThread_SendFlush(This);
				CParserImplThread_SendEndOfStream(This);
				/* FIXME - process seeking. */
				/* FIXME - Send NewSegment. */
				break;
			default:
				FIXME( "invalid message %04u\n", (unsigned)msg.message );
				hr = E_FAIL;
				CParserImplThread_ErrorAbort(This,hr);
			}

			return hr;
		}

		hr = IAsyncReader_WaitForNext(This->m_pReader,PARSER_POLL_INTERVAL,&pSample,&dwContext);
		nIndex = (ULONG)dwContext;
		if ( hr != VFW_E_TIMEOUT )
			break;
	}
	if ( FAILED(hr) )
	{
		CParserImplThread_ErrorAbort(This,hr);
		return hr;
	}

	pOutPin = This->m_ppOutPins[nIndex];
	if ( pOutPin != NULL && pOutPin->m_bReqUsed )
	{
		if ( This->m_pHandler->pProcessSample != NULL )
			hr = This->m_pHandler->pProcessSample(This,nIndex,pOutPin->m_llReqStart,pOutPin->m_lReqLength,pOutPin->m_pReqSample);

		IMediaSample_SetSyncPoint( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_SPLICEPOINT) ? TRUE : FALSE );
		IMediaSample_SetPreroll( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_PREROLL) ? TRUE : FALSE );
		IMediaSample_SetDiscontinuity( pOutPin->m_pReqSample, (pOutPin->m_dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE );

		if ( SUCCEEDED(hr) )
		{
			if ( pOutPin->m_pOutPinAllocator != NULL &&
				 pOutPin->m_pOutPinAllocator != This->m_pAllocator )
			{
				/* if pin has its own allocator, sample must be copied */
				hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
				if ( SUCCEEDED(hr) )
				{
					hr = QUARTZ_IMediaSample_Copy(
						pSample, pOutPin->m_pReqSample, TRUE );
					if ( SUCCEEDED(hr) )
						hr = CPinBaseImpl_SendSample(&pOutPin->pin,pSample);
					IMediaSample_Release(pSample);
				}
			}
			else
			{
				hr = CPinBaseImpl_SendSample(&pOutPin->pin,pOutPin->m_pReqSample);
			}
		}

		if ( FAILED(hr) )
			CParserImplThread_ErrorAbort(This,hr);

		IMediaSample_Release(pOutPin->m_pReqSample);
		pOutPin->m_pReqSample = NULL;
		pOutPin->m_bReqUsed = FALSE;
	}

	if ( SUCCEEDED(hr) )
		hr = NOERROR;

	TRACE("return %08lx\n",hr);

	return hr;
}

static
DWORD WINAPI CParserImplThread_Entry( LPVOID pv )
{
	CParserImpl*	This = (CParserImpl*)pv;
	BOOL	bReqNext;
	ULONG	nIndex = 0;
	HRESULT hr;
	REFERENCE_TIME	rtSampleTimeStart, rtSampleTimeEnd;
	LONGLONG	llReqStart;
	LONG	lReqLength;
	DWORD	dwSampleFlags;
	REFERENCE_TIME	rtReqStart, rtReqStop;
	IMediaSample*	pSample;
	MSG	msg;

	/* initialize the message queue. */
	PeekMessageA( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE );

	CParserImplThread_ClearAllRequests(This);

	/* resume the owner thread. */
	SetEvent( This->m_hEventInit );

	TRACE( "Enter message loop.\n" );

	bReqNext = TRUE;
	while ( 1 )
	{
		if ( bReqNext )
		{
			/* Get the next request.  */
			hr = This->m_pHandler->pGetNextRequest( This, &nIndex, &llReqStart, &lReqLength, &rtReqStart, &rtReqStop, &dwSampleFlags );
			if ( FAILED(hr) )
			{
				CParserImplThread_ErrorAbort(This,hr);
				break;
			}
			if ( hr != S_OK )
			{
				/* Flush pending samples. */
				hr = S_OK;
				while ( CParserImplThread_HasPendingSamples(This) )
				{
					hr = CParserImplThread_ProcessNextSample(This);
					if ( hr != S_OK )
						break;
				}
				if ( hr != S_OK )
				{
					/* notification is already sent */
					break;
				}

				/* Send End Of Stream. */
				hr = CParserImplThread_SendEndOfStream(This);
				if ( hr != S_OK )
				{
					/* notification is already sent */
					break;
				}

				/* Blocking... */
				hr = CParserImplThread_ProcessNextSample(This);
				if ( hr != S_OK )
				{
					/* notification is already sent */
					break;
				}
				continue;
			}
			if ( This->m_ppOutPins[nIndex]->pin.pPinConnectedTo == NULL )
				continue;

			rtSampleTimeStart = This->basefilter.rtStart + llReqStart * QUARTZ_TIMEUNITS;
			rtSampleTimeEnd = (llReqStart + lReqLength) * QUARTZ_TIMEUNITS;
			bReqNext = FALSE;
		}

		if ( !This->m_ppOutPins[nIndex]->m_bReqUsed )
		{
			hr = IMemAllocator_GetBuffer( This->m_pAllocator, &pSample, NULL, NULL, 0 );
			if ( FAILED(hr) )
			{
				CParserImplThread_ErrorAbort(This,hr);
				break;
			}
			hr = IMediaSample_SetTime(pSample,&rtSampleTimeStart,&rtSampleTimeEnd);
			if ( SUCCEEDED(hr) )
				hr = IAsyncReader_Request(This->m_pReader,pSample,nIndex);
			if ( FAILED(hr) )
			{
				CParserImplThread_ErrorAbort(This,hr);
				break;
			}

			This->m_ppOutPins[nIndex]->m_bReqUsed = TRUE;
			This->m_ppOutPins[nIndex]->m_pReqSample = pSample;
			This->m_ppOutPins[nIndex]->m_llReqStart = llReqStart;
			This->m_ppOutPins[nIndex]->m_lReqLength = lReqLength;
			This->m_ppOutPins[nIndex]->m_rtReqStart = rtSampleTimeStart;
			This->m_ppOutPins[nIndex]->m_rtReqStop = rtSampleTimeEnd;
			This->m_ppOutPins[nIndex]->m_dwSampleFlags = dwSampleFlags;
			bReqNext = TRUE;
			continue;
		}

		hr = CParserImplThread_ProcessNextSample(This);
		if ( hr != S_OK )
		{
			/* notification is already sent */
			break;
		}
	}

	This->m_dwThreadId = 0;
	This->basefilter.bIntermediateState = FALSE;
	SetEvent( This->m_hEventInit );

	return 0;
}

/***************************************************************************
 *
 *	CParserImpl internal methods
 *
 */

static
void CParserImpl_SetAsyncReader( CParserImpl* This, IAsyncReader* pReader )
{
	if ( This->m_pReader != NULL )
	{
		IAsyncReader_Release( This->m_pReader );
		This->m_pReader = NULL;
	}
	if ( pReader != NULL )
	{
		This->m_pReader = pReader;
		IAsyncReader_AddRef(This->m_pReader);
	}
}

static
void CParserImpl_ReleaseOutPins( CParserImpl* This )
{
	ULONG nIndex;

	if ( This->m_ppOutPins != NULL )
	{
		for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
		{
			if ( This->m_ppOutPins[nIndex] != NULL )
			{
				IUnknown_Release(This->m_ppOutPins[nIndex]->unk.punkControl);
				This->m_ppOutPins[nIndex] = NULL;
			}
		}
		QUARTZ_FreeMem(This->m_ppOutPins);
		This->m_ppOutPins = NULL;
	}
	This->m_cOutStreams = 0;
}

static
BOOL CParserImpl_OutPinsAreConnected( CParserImpl* This )
{
	QUARTZ_CompListItem*	pItem;
	IPin*	pPin;
	IPin*	pPinPeer;
	HRESULT hr;

	QUARTZ_CompList_Lock( This->basefilter.pOutPins );
	pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
	while ( pItem != NULL )
	{
		if ( pItem == NULL )
			break;
		pPin = (IPin*)QUARTZ_CompList_GetItemPtr(pItem);
		pPinPeer = NULL;
		hr = IPin_ConnectedTo(pPin,&pPinPeer);
		if ( hr == S_OK && pPinPeer != NULL )
		{
			IPin_Release(pPinPeer);
			return TRUE;
		}
		pItem = QUARTZ_CompList_GetNext( This->basefilter.pOutPins, pItem );
	}
	QUARTZ_CompList_Unlock( This->basefilter.pOutPins );

	return FALSE;
}

static
void CParserImpl_ReleaseListOfOutPins( CParserImpl* This )
{
	QUARTZ_CompListItem*	pItem;

	QUARTZ_CompList_Lock( This->basefilter.pOutPins );
	while ( 1 )
	{
		pItem = QUARTZ_CompList_GetFirst( This->basefilter.pOutPins );
		if ( pItem == NULL )
			break;
		QUARTZ_CompList_RemoveComp(
			This->basefilter.pOutPins,
			QUARTZ_CompList_GetItemPtr(pItem) );
	}
	QUARTZ_CompList_Unlock( This->basefilter.pOutPins );
}


static
HRESULT CParserImpl_BeginThread( CParserImpl* This )
{
	DWORD dwRes;
	HANDLE hEvents[2];

	if ( This->m_bIsRunning )
	{
		TRACE("(%p) - already running\n",This);
		return NOERROR;
	}

	This->m_hEventInit = CreateEventA(NULL,TRUE,FALSE,NULL);
	if ( This->m_hEventInit == (HANDLE)NULL )
		return E_OUTOFMEMORY;

	/* create the processing thread. */
	This->m_hThread = CreateThread(
		NULL, 0,
		CParserImplThread_Entry,
		(LPVOID)This,
		0, &This->m_dwThreadId );
	if ( This->m_hThread == (HANDLE)NULL )
	{
		CloseHandle( This->m_hEventInit );
		This->m_hEventInit = (HANDLE)NULL;
		return E_FAIL;
	}

	hEvents[0] = This->m_hEventInit;
	hEvents[1] = This->m_hThread;

	dwRes = WaitForMultipleObjects(2,hEvents,FALSE,INFINITE);

	ResetEvent( This->m_hEventInit );
	CloseHandle( This->m_hThread );
	This->m_hThread = (HANDLE)NULL;

	if ( dwRes != WAIT_OBJECT_0 )
		return E_FAIL;

	This->m_bIsRunning = TRUE;

	return NOERROR;
}

static
BOOL CParserImpl_EndThread( CParserImpl* This, BOOL bAsync )
{
	DWORD	dwThreadId;

	TRACE("(%p)\n",This);
	dwThreadId = This->m_dwThreadId;
	if ( This->m_hEventInit != (HANDLE)NULL )
	{
		if ( dwThreadId != 0 )
			PostThreadMessageA(
				dwThreadId, QUARTZ_MSG_EXITTHREAD, 0, 0 );
		if ( bAsync &&
			 WaitForSingleObject( This->m_hEventInit, 0 ) == WAIT_TIMEOUT )
			return FALSE;

		WaitForSingleObject( This->m_hEventInit, INFINITE );
		CloseHandle( This->m_hEventInit );
		This->m_bIsRunning = FALSE;
		This->m_hEventInit = (HANDLE)NULL;
	}

	return TRUE;
}

static
HRESULT CParserImpl_MemCommit( CParserImpl* This )
{
	HRESULT hr;
	ULONG	nIndex;
	IMemAllocator*	pAlloc;

	TRACE("(%p)\n",This);

	if ( This->m_pAllocator == NULL )
		return E_UNEXPECTED;

	hr = IMemAllocator_Commit( This->m_pAllocator );
	if ( FAILED(hr) )
		return hr;

	if ( This->m_ppOutPins != NULL && This->m_cOutStreams > 0 )
	{
		for ( nIndex = 0; nIndex < This->m_cOutStreams; nIndex++ )
		{
			pAlloc = This->m_ppOutPins[nIndex]->m_pOutPinAllocator;
			if ( pAlloc != NULL && pAlloc != This->m_pAllocator )
			{
				hr = IMemAllocator_Commit( pAlloc );
				if ( FAILED(hr) )
					return hr;
			}
		}
	}

	return NOERROR;
}

static
HRESULT CParserImpl_GetPreferredTimeFormat( CParserImpl* This, GUID* pguidFormat )
{
	static const GUID* tryformats[] =
	{
		&TIME_FORMAT_MEDIA_TIME,
		&TIME_FORMAT_FRAME,
		&TIME_FORMAT_SAMPLE,
		&TIME_FORMAT_FIELD,
		&TIME_FORMAT_BYTE,
		NULL,
	};
	DWORD	n;

	if ( This->m_pHandler->pIsTimeFormatSupported == NULL )
		return E_NOTIMPL;

	n = 0;
	while ( tryformats[n] != NULL )
	{
		if ( This->m_pHandler->pIsTimeFormatSupported( This, tryformats[n] ) == S_OK )
		{
			memcpy( pguidFormat, tryformats[n], sizeof(GUID) );
			return S_OK;
		}
		n ++;
	}

	return E_FAIL;

}


/***************************************************************************
 *
 *	CParserImpl methods
 *
 */

static HRESULT CParserImpl_OnActive( CBaseFilterImpl* pImpl )
{
	CParserImpl_THIS(pImpl,basefilter);

	TRACE( "(%p)\n", This );

	if ( !CParserImpl_OutPinsAreConnected(This) )
		return NOERROR;

	return NOERROR;
}

static HRESULT CParserImpl_OnInactive( CBaseFilterImpl* pImpl )
{
	CParserImpl_THIS(pImpl,basefilter);
	HRESULT hr;

	TRACE( "(%p)\n", This );

	if ( !CParserImpl_OutPinsAreConnected(This) )
		return NOERROR;

	hr = CParserImpl_MemCommit(This);
	if ( FAILED(hr) )
		return hr;

	if ( This->basefilter.fstate == State_Stopped )
		CParserImpl_EndThread(This,FALSE);

	hr = CParserImpl_BeginThread(This);
	if ( FAILED(hr) )
	{
		FIXME("CParserImpl_BeginThread returns %08lx\n",hr);
		CParserImpl_EndThread(This,FALSE);
		return hr;
	}

	return NOERROR;
}

static HRESULT CParserImpl_OnStop( CBaseFilterImpl* pImpl )
{
	CParserImpl_THIS(pImpl,basefilter);

	FIXME( "(%p)\n", This );

	This->basefilter.bIntermediateState = TRUE;
	if ( !CParserImpl_EndThread(This,TRUE) )
		return VFW_S_STATE_INTERMEDIATE;

	This->basefilter.bIntermediateState = FALSE;
	return NOERROR;
}


static const CBaseFilterHandlers filterhandlers =
{
	CParserImpl_OnActive, /* pOnActive */
	CParserImpl_OnInactive, /* pOnInactive */
	CParserImpl_OnStop, /* pOnStop */
};


/***************************************************************************
 *
 *	CParserInPinImpl methods
 *
 */

static HRESULT CParserInPinImpl_OnPreConnect( CPinBaseImpl* pImpl, IPin* pPin )
{
	CParserInPinImpl_THIS(pImpl,pin);
	HRESULT hr;
	ULONG	nIndex;
	IUnknown*	punk;
	IAsyncReader* pReader = NULL;
	LPCWSTR pwszOutPinName;
	IMemAllocator*	pAllocActual;
	AM_MEDIA_TYPE*	pmt;

	TRACE("(%p,%p)\n",This,pPin);

	if ( This->pParser->m_pHandler->pInitParser == NULL ||
		 This->pParser->m_pHandler->pUninitParser == NULL ||
		 This->pParser->m_pHandler->pGetOutPinName == NULL ||
		 This->pParser->m_pHandler->pGetStreamType == NULL ||
		 This->pParser->m_pHandler->pCheckStreamType == NULL ||
		 This->pParser->m_pHandler->pGetAllocProp == NULL ||
		 This->pParser->m_pHandler->pGetNextRequest == NULL )
	{
		FIXME("this parser is not implemented.\n");
		return E_NOTIMPL;
	}

	/* at first, release all output pins. */
	if ( CParserImpl_OutPinsAreConnected(This->pParser) )
		return E_FAIL;
	CParserImpl_ReleaseListOfOutPins(This->pParser);
	CParserImpl_ReleaseOutPins(This->pParser);

	CParserImpl_SetAsyncReader( This->pParser, NULL );
	hr = IPin_QueryInterface( pPin, &IID_IAsyncReader, (void**)&pReader );
	if ( FAILED(hr) )
		return hr;
	CParserImpl_SetAsyncReader( This->pParser, pReader );
	IAsyncReader_Release(pReader);

	/* initialize parser. */
	hr = This->pParser->m_pHandler->pInitParser(This->pParser,&This->pParser->m_cOutStreams);
	if ( FAILED(hr) )
		return hr;
	This->pParser->m_ppOutPins = (CParserOutPinImpl**)QUARTZ_AllocMem(
		sizeof(CParserOutPinImpl*) * This->pParser->m_cOutStreams );
	if ( This->pParser->m_ppOutPins == NULL )
		return E_OUTOFMEMORY;
	for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
		This->pParser->m_ppOutPins[nIndex] = NULL;

	/* create and initialize an allocator. */
	hr = This->pParser->m_pHandler->pGetAllocProp(This->pParser,&This->pParser->m_propAlloc);
	if ( FAILED(hr) )
		return hr;
	if ( This->pParser->m_propAlloc.cbAlign == 0 )
		This->pParser->m_propAlloc.cbAlign = 1;

	if ( This->pParser->m_pAllocator == NULL )
	{
		hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
		if ( FAILED(hr) )
			return hr;
		hr = IUnknown_QueryInterface( punk, &IID_IMemAllocator, (void**)&This->pParser->m_pAllocator );
		IUnknown_Release(punk);
		if ( FAILED(hr) )
			return hr;
	}
	pAllocActual = NULL;
	hr = IAsyncReader_RequestAllocator(pReader,This->pParser->m_pAllocator,&This->pParser->m_propAlloc,&pAllocActual);
	if ( FAILED(hr) )
		return hr;
	IMemAllocator_Release(This->pParser->m_pAllocator);
	This->pParser->m_pAllocator = pAllocActual;

	/* create output pins. */
	for ( nIndex = 0; nIndex < This->pParser->m_cOutStreams; nIndex++ )
	{
		pwszOutPinName = This->pParser->m_pHandler->pGetOutPinName(This->pParser,nIndex);
		if ( pwszOutPinName == NULL )
			return E_FAIL;
		hr = QUARTZ_CreateParserOutPin(
			This->pParser,
			&This->pParser->m_csParser,
			&This->pParser->m_ppOutPins[nIndex],
			nIndex, pwszOutPinName );
		if ( SUCCEEDED(hr) )
			hr = QUARTZ_CompList_AddTailComp(
				This->pParser->basefilter.pOutPins,
				(IUnknown*)&(This->pParser->m_ppOutPins[nIndex]->pin),
				NULL, 0 );
		if ( FAILED(hr) )
			return hr;
		pmt = &This->pParser->m_ppOutPins[nIndex]->m_mtOut;
		QUARTZ_MediaType_Free( pmt );
		ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
		hr = This->pParser->m_pHandler->pGetStreamType(This->pParser,nIndex,pmt);
		if ( FAILED(hr) )
		{
			ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
			return hr;
		}
		This->pParser->m_ppOutPins[nIndex]->pin.cAcceptTypes = 1;
		This->pParser->m_ppOutPins[nIndex]->pin.pmtAcceptTypes = pmt;
	}

	return NOERROR;
}

static HRESULT CParserInPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
{
	CParserInPinImpl_THIS(pImpl,pin);

	/* assume the graph is already stopped */
	/*CParserImpl_OnInactive(&This->pParser->basefilter);*/
	/*CParserImpl_OnStop(&This->pParser->basefilter);*/
	if ( This->pParser->m_pHandler->pUninitParser != NULL )
		This->pParser->m_pHandler->pUninitParser(This->pParser);
	CParserImpl_SetAsyncReader( This->pParser, NULL );
	if ( This->pParser->m_pAllocator != NULL )
	{
		IMemAllocator_Decommit(This->pParser->m_pAllocator);
		IMemAllocator_Release(This->pParser->m_pAllocator);
		This->pParser->m_pAllocator = NULL;
	}

	return NOERROR;
}

static HRESULT CParserInPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
{
	CParserInPinImpl_THIS(pImpl,pin);

	TRACE("(%p,%p)\n",This,pmt);

	if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Stream ) )
		return E_FAIL;

	return NOERROR;
}

static const CBasePinHandlers inputpinhandlers =
{
	CParserInPinImpl_OnPreConnect, /* pOnPreConnect */
	NULL, /* pOnPostConnect */
	CParserInPinImpl_OnDisconnect, /* pOnDisconnect */
	CParserInPinImpl_CheckMediaType, /* pCheckMediaType */
	NULL, /* pQualityNotify */
	NULL, /* pReceive */
	NULL, /* pReceiveCanBlock */
	NULL, /* pEndOfStream */
	NULL, /* pBeginFlush */
	NULL, /* pEndFlush */
	NULL, /* pNewSegment */
};

/***************************************************************************
 *
 *	CParserOutPinImpl methods
 *
 */

static HRESULT CParserOutPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
{
	CParserOutPinImpl_THIS(pImpl,pin);
	ALLOCATOR_PROPERTIES	propReq;
	ALLOCATOR_PROPERTIES	propActual;
	IMemAllocator*	pAllocator;
	HRESULT hr;
	BOOL	bNewAllocator = FALSE;

	TRACE("(%p,%p)\n",This,pPin);

	if ( This->pin.pMemInputPinConnectedTo == NULL )
		return E_UNEXPECTED;

	if ( This->m_pOutPinAllocator != NULL )
	{
		IMemAllocator_Release(This->m_pOutPinAllocator);
		This->m_pOutPinAllocator = NULL;
	}

	/* try to use This->pParser->m_pAllocator. */
	ZeroMemory( &propReq, sizeof(ALLOCATOR_PROPERTIES) );
	hr = IMemInputPin_GetAllocatorRequirements(
		This->pin.pMemInputPinConnectedTo, &propReq );
	if ( propReq.cbAlign != 0 )
	{
		if ( This->pParser->m_propAlloc.cbAlign != ( This->pParser->m_propAlloc.cbAlign / propReq.cbAlign * propReq.cbAlign ) )
			bNewAllocator = TRUE;
	}
	if ( propReq.cbPrefix != 0 )
		bNewAllocator = TRUE;
	if ( !bNewAllocator )
	{
		hr = IMemInputPin_NotifyAllocator(
			This->pin.pMemInputPinConnectedTo,
			This->pParser->m_pAllocator, FALSE );
		if ( hr == NOERROR )
		{
			This->m_pOutPinAllocator = This->pParser->m_pAllocator;
			IMemAllocator_AddRef(This->m_pOutPinAllocator);
			return NOERROR;
		}
	}

	hr = IMemInputPin_GetAllocator(
			This->pin.pMemInputPinConnectedTo, &pAllocator );
	if ( FAILED(hr) )
		return hr;
	hr = IMemAllocator_SetProperties( pAllocator, &This->pParser->m_propAlloc, &propActual );
	if ( SUCCEEDED(hr) )
		hr = IMemInputPin_NotifyAllocator(
			This->pin.pMemInputPinConnectedTo, pAllocator, FALSE );
	if ( FAILED(hr) )
	{
		IMemAllocator_Release(pAllocator);
		return hr;
	}

	This->m_pOutPinAllocator = pAllocator;
	return NOERROR;
}

static HRESULT CParserOutPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
{
	CParserOutPinImpl_THIS(pImpl,pin);

	if ( This->m_pOutPinAllocator != NULL )
	{
		IMemAllocator_Release(This->m_pOutPinAllocator);
		This->m_pOutPinAllocator = NULL;
	}

	return NOERROR;
}

static HRESULT CParserOutPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
{
	CParserOutPinImpl_THIS(pImpl,pin);
	HRESULT hr;

	TRACE("(%p,%p)\n",This,pmt);
	if ( pmt == NULL )
		return E_POINTER;

	if ( This->pParser->m_pHandler->pCheckStreamType == NULL )
		return E_NOTIMPL;

	hr = This->pParser->m_pHandler->pCheckStreamType( This->pParser, This->nStreamIndex, pmt );
	if ( FAILED(hr) )
		return hr;

	return NOERROR;
}


static const CBasePinHandlers outputpinhandlers =
{
	NULL, /* pOnPreConnect */
	CParserOutPinImpl_OnPostConnect, /* pOnPostConnect */
	CParserOutPinImpl_OnDisconnect, /* pOnDisconnect */
	CParserOutPinImpl_CheckMediaType, /* pCheckMediaType */
	NULL, /* pQualityNotify */
	OutputPinSync_Receive, /* pReceive */
	OutputPinSync_ReceiveCanBlock, /* pReceiveCanBlock */
	OutputPinSync_EndOfStream, /* pEndOfStream */
	OutputPinSync_BeginFlush, /* pBeginFlush */
	OutputPinSync_EndFlush, /* pEndFlush */
	OutputPinSync_NewSegment, /* pNewSegment */
};

/***************************************************************************
 *
 *	new/delete CParserImpl
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry FilterIFEntries[] =
{
  { &IID_IPersist, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
  { &IID_IMediaFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
  { &IID_IBaseFilter, offsetof(CParserImpl,basefilter)-offsetof(CParserImpl,unk) },
};

static void QUARTZ_DestroyParser(IUnknown* punk)
{
	CParserImpl_THIS(punk,unk);

	TRACE( "(%p)\n", This );

	if ( This->m_pInPin != NULL )
		CParserInPinImpl_OnDisconnect(&This->m_pInPin->pin);

	CParserImpl_SetAsyncReader( This, NULL );
	if ( This->m_pAllocator != NULL )
	{
		IMemAllocator_Release(This->m_pAllocator);
		This->m_pAllocator = NULL;
	}
	if ( This->m_pInPin != NULL )
	{
		IUnknown_Release(This->m_pInPin->unk.punkControl);
		This->m_pInPin = NULL;
	}
	CParserImpl_ReleaseOutPins( This );

	DeleteCriticalSection( &This->m_csParser );

	CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
}

HRESULT QUARTZ_CreateParser(
	IUnknown* punkOuter,void** ppobj,
	const CLSID* pclsidParser,
	LPCWSTR pwszParserName,
	LPCWSTR pwszInPinName,
	const ParserHandlers* pHandler )
{
	CParserImpl*	This = NULL;
	HRESULT hr;

	TRACE("(%p,%p)\n",punkOuter,ppobj);

	This = (CParserImpl*)
		QUARTZ_AllocObj( sizeof(CParserImpl) );
	if ( This == NULL )
		return E_OUTOFMEMORY;
	ZeroMemory( This, sizeof(CParserImpl) );

	This->m_pInPin = NULL;
	This->m_cOutStreams = 0;
	This->m_ppOutPins = NULL;
	memcpy( &This->m_guidTimeFormat, &TIME_FORMAT_NONE, sizeof(GUID) );
	This->m_pReader = NULL;
	This->m_pAllocator = NULL;
	ZeroMemory( &This->m_propAlloc, sizeof(ALLOCATOR_PROPERTIES) );
	This->m_hEventInit = (HANDLE)NULL;
	This->m_bIsRunning = FALSE;
	This->m_hThread = (HANDLE)NULL;
	This->m_dwThreadId = 0;
	This->m_bSendEOS = FALSE;
	This->m_pHandler = pHandler;
	This->m_pUserData = NULL;

	QUARTZ_IUnkInit( &This->unk, punkOuter );

	hr = CBaseFilterImpl_InitIBaseFilter(
		&This->basefilter,
		This->unk.punkControl,
		pclsidParser,
		pwszParserName,
		&filterhandlers );
	if ( SUCCEEDED(hr) )
	{
		/* construct this class. */
		hr = S_OK;

		if ( FAILED(hr) )
		{
			CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
		}
	}

	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj(This);
		return hr;
	}

	This->unk.pEntries = FilterIFEntries;
	This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
	This->unk.pOnFinalRelease = QUARTZ_DestroyParser;
	InitializeCriticalSection( &This->m_csParser );

	/* create the input pin. */
	hr = QUARTZ_CreateParserInPin(
		This,
		&This->m_csParser,
		&This->m_pInPin,
		pwszInPinName );
	if ( SUCCEEDED(hr) )
		hr = QUARTZ_CompList_AddComp(
			This->basefilter.pInPins,
			(IUnknown*)&(This->m_pInPin->pin),
			NULL, 0 );

	if ( FAILED(hr) )
	{
		IUnknown_Release( This->unk.punkControl );
		return hr;
	}

	*ppobj = (void*)&(This->unk);

	(void)CParserImpl_GetPreferredTimeFormat( This, &This->m_guidTimeFormat );

	return S_OK;
}

/***************************************************************************
 *
 *	new/delete CParserInPinImpl
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry InPinIFEntries[] =
{
  { &IID_IPin, offsetof(CParserInPinImpl,pin)-offsetof(CParserInPinImpl,unk) },
  { &IID_IMemInputPin, offsetof(CParserInPinImpl,meminput)-offsetof(CParserInPinImpl,unk) },
};

static void QUARTZ_DestroyParserInPin(IUnknown* punk)
{
	CParserInPinImpl_THIS(punk,unk);

	TRACE( "(%p)\n", This );

	CPinBaseImpl_UninitIPin( &This->pin );
	CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
}

HRESULT QUARTZ_CreateParserInPin(
	CParserImpl* pFilter,
	CRITICAL_SECTION* pcsPin,
	CParserInPinImpl** ppPin,
	LPCWSTR pwszPinName )
{
	CParserInPinImpl*	This = NULL;
	HRESULT hr;

	TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);

	This = (CParserInPinImpl*)
		QUARTZ_AllocObj( sizeof(CParserInPinImpl) );
	if ( This == NULL )
		return E_OUTOFMEMORY;

	QUARTZ_IUnkInit( &This->unk, NULL );
	This->pParser = pFilter;

	hr = CPinBaseImpl_InitIPin(
		&This->pin,
		This->unk.punkControl,
		pcsPin, NULL,
		&pFilter->basefilter,
		pwszPinName,
		FALSE,
		&inputpinhandlers );

	if ( SUCCEEDED(hr) )
	{
		hr = CMemInputPinBaseImpl_InitIMemInputPin(
			&This->meminput,
			This->unk.punkControl,
			&This->pin );
		if ( FAILED(hr) )
		{
			CPinBaseImpl_UninitIPin( &This->pin );
		}
	}

	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj(This);
		return hr;
	}

	This->unk.pEntries = InPinIFEntries;
	This->unk.dwEntries = sizeof(InPinIFEntries)/sizeof(InPinIFEntries[0]);
	This->unk.pOnFinalRelease = QUARTZ_DestroyParserInPin;

	*ppPin = This;

	TRACE("returned successfully.\n");

	return S_OK;
}


/***************************************************************************
 *
 *	new/delete CParserOutPinImpl
 *
 */

/* can I use offsetof safely? - FIXME? */
static QUARTZ_IFEntry OutPinIFEntries[] =
{
  { &IID_IPin, offsetof(CParserOutPinImpl,pin)-offsetof(CParserOutPinImpl,unk) },
  { &IID_IQualityControl, offsetof(CParserOutPinImpl,qcontrol)-offsetof(CParserOutPinImpl,unk) },
  { &IID_IMediaSeeking, offsetof(CParserOutPinImpl,mediaseeking)-offsetof(CParserOutPinImpl,unk) },
  { &IID_IMediaPosition, offsetof(CParserOutPinImpl,mediaposition)-offsetof(CParserOutPinImpl,unk) },
};

static void QUARTZ_DestroyParserOutPin(IUnknown* punk)
{
	CParserOutPinImpl_THIS(punk,unk);

	TRACE( "(%p)\n", This );

	QUARTZ_MediaType_Free( &This->m_mtOut );
	if ( This->m_pOutPinAllocator != NULL )
		IMemAllocator_Release(This->m_pOutPinAllocator);

	CParserOutPinImpl_UninitIMediaPosition(This);
	CParserOutPinImpl_UninitIMediaSeeking(This);
	CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
	CPinBaseImpl_UninitIPin( &This->pin );

}

HRESULT QUARTZ_CreateParserOutPin(
	CParserImpl* pFilter,
	CRITICAL_SECTION* pcsPin,
	CParserOutPinImpl** ppPin,
	ULONG nStreamIndex,
	LPCWSTR pwszPinName )
{
	CParserOutPinImpl*	This = NULL;
	HRESULT hr;

	TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);

	This = (CParserOutPinImpl*)
		QUARTZ_AllocObj( sizeof(CParserOutPinImpl) );
	if ( This == NULL )
		return E_OUTOFMEMORY;

	QUARTZ_IUnkInit( &This->unk, NULL );
	This->pParser = pFilter;
	This->nStreamIndex = nStreamIndex;
	ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
	This->m_pOutPinAllocator = NULL;
	This->m_pUserData = NULL;
	This->m_bReqUsed = FALSE;
	This->m_pReqSample = NULL;
	This->m_llReqStart = 0;
	This->m_lReqLength = 0;
	This->m_rtReqStart = 0;
	This->m_rtReqStop = 0;
	This->m_dwSampleFlags = 0;


	hr = CPinBaseImpl_InitIPin(
		&This->pin,
		This->unk.punkControl,
		pcsPin, NULL,
		&pFilter->basefilter,
		pwszPinName,
		TRUE,
		&outputpinhandlers );

	if ( SUCCEEDED(hr) )
	{
		hr = CQualityControlPassThruImpl_InitIQualityControl(
			&This->qcontrol,
			This->unk.punkControl,
			&This->pin );
		if ( SUCCEEDED(hr) )
		{
			hr = CParserOutPinImpl_InitIMediaSeeking(This);
			if ( SUCCEEDED(hr) )
			{
				hr = CParserOutPinImpl_InitIMediaPosition(This);
				if ( FAILED(hr) )
				{
					CParserOutPinImpl_UninitIMediaSeeking(This);
				}
			}
			if ( FAILED(hr) )
			{
				CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
			}
		}
		if ( FAILED(hr) )
		{
			CPinBaseImpl_UninitIPin( &This->pin );
		}
	}

	if ( FAILED(hr) )
	{
		QUARTZ_FreeObj(This);
		return hr;
	}

	This->unk.pEntries = OutPinIFEntries;
	This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
	This->unk.pOnFinalRelease = QUARTZ_DestroyParserOutPin;

	*ppPin = This;

	TRACE("returned successfully.\n");

	return S_OK;
}


/***************************************************************************
 *
 *	IMediaSeeking for CParserOutPinImpl
 *
 */

static HRESULT WINAPI
IMediaSeeking_fnQueryInterface(IMediaSeeking* iface,REFIID riid,void** ppobj)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	TRACE("(%p)->()\n",This);

	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IMediaSeeking_fnAddRef(IMediaSeeking* iface)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	TRACE("(%p)->()\n",This);

	return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IMediaSeeking_fnRelease(IMediaSeeking* iface)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	TRACE("(%p)->()\n",This);

	return IUnknown_Release(This->unk.punkControl);
}


static HRESULT WINAPI
IMediaSeeking_fnGetCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pdwCaps);

	if ( pdwCaps == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, pdwCaps );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnCheckCapabilities(IMediaSeeking* iface,DWORD* pdwCaps)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;
	DWORD	dwCaps;

	TRACE("(%p)->(%p)\n",This,pdwCaps);

	if ( pdwCaps == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pdwCaps);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
		if ( SUCCEEDED(hr) )
		{
			dwCaps &= *pdwCaps;
			if ( dwCaps == *pdwCaps )
				hr = S_OK;
			else
			if ( dwCaps != 0 )
				hr = S_FALSE;
			else
				hr = E_FAIL;
			*pdwCaps = dwCaps;
		}
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaSeeking_fnIsFormatSupported(IMediaSeeking* iface,const GUID* pidFormat)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%s)\n",This,debugstr_guid(pidFormat));

	if ( pidFormat == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
	{
		FIXME("(%p)->(%s) not implemented\n",This,debugstr_guid(pidFormat));
	}
	else
	{
		hr = This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnQueryPreferredFormat(IMediaSeeking* iface,GUID* pidFormat)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT hr;

	TRACE("(%p)->(%p)\n",This,pidFormat);

	EnterCriticalSection( &This->pParser->m_csParser );
	hr = CParserImpl_GetPreferredTimeFormat( This->pParser, pidFormat );
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnGetTimeFormat(IMediaSeeking* iface,GUID* pidFormat)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pidFormat);

	if ( pidFormat == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
	}
	else
	{
		memcpy( pidFormat, &This->pParser->m_guidTimeFormat, sizeof(GUID) );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnIsUsingTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pidFormat);

	if ( pidFormat == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
	}
	else
	{
		hr = IsEqualGUID( pidFormat, &This->pParser->m_guidTimeFormat ) ? S_OK : S_FALSE;
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnSetTimeFormat(IMediaSeeking* iface,const GUID* pidFormat)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pidFormat);

	if ( pidFormat == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pIsTimeFormatSupported == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pidFormat);
	}
	else
	{
		if ( This->pParser->m_pHandler->pIsTimeFormatSupported( This->pParser, pidFormat ) == S_OK )
		{
			memcpy( &This->pParser->m_guidTimeFormat, pidFormat, sizeof(GUID) );
		}
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnGetDuration(IMediaSeeking* iface,LONGLONG* pllDuration)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pllDuration);

	if ( pllDuration == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetDuration == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pllDuration);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllDuration );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnGetStopPosition(IMediaSeeking* iface,LONGLONG* pllPos)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pllPos);

	if ( pllPos == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetStopPos == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pllPos);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnGetCurrentPosition(IMediaSeeking* iface,LONGLONG* pllPos)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pllPos);

	if ( pllPos == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetCurPos == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pllPos);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllPos );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnConvertTimeFormat(IMediaSeeking* iface,LONGLONG* pllOut,const GUID* pidFmtOut,LONGLONG llIn,const GUID* pidFmtIn)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaSeeking_fnSetPositions(IMediaSeeking* iface,LONGLONG* pllCur,DWORD dwCurFlags,LONGLONG* pllStop,DWORD dwStopFlags)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaSeeking_fnGetPositions(IMediaSeeking* iface,LONGLONG* pllCur,LONGLONG* pllStop)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);
	HRESULT	hr = E_NOTIMPL;

	TRACE("(%p)->(%p,%p)\n",This,pllCur,pllStop);

	if ( pllCur == NULL || pllStop == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetCurPos == NULL ||
		 This->pParser->m_pHandler->pGetStopPos == NULL )
	{
		FIXME("(%p)->(%p,%p) not implemented\n",This,pllCur,pllStop);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllCur );
		if ( SUCCEEDED(hr) )
			hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &This->pParser->m_guidTimeFormat, This->nStreamIndex, pllStop );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaSeeking_fnGetAvailable(IMediaSeeking* iface,LONGLONG* pllFirst,LONGLONG* pllLast)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaSeeking_fnSetRate(IMediaSeeking* iface,double dblRate)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaSeeking_fnGetRate(IMediaSeeking* iface,double* pdblRate)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaSeeking_fnGetPreroll(IMediaSeeking* iface,LONGLONG* pllPreroll)
{
	CParserOutPinImpl_THIS(iface,mediaseeking);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}




static ICOM_VTABLE(IMediaSeeking) imediaseeking =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IMediaSeeking_fnQueryInterface,
	IMediaSeeking_fnAddRef,
	IMediaSeeking_fnRelease,
	/* IMediaSeeking fields */
	IMediaSeeking_fnGetCapabilities,
	IMediaSeeking_fnCheckCapabilities,
	IMediaSeeking_fnIsFormatSupported,
	IMediaSeeking_fnQueryPreferredFormat,
	IMediaSeeking_fnGetTimeFormat,
	IMediaSeeking_fnIsUsingTimeFormat,
	IMediaSeeking_fnSetTimeFormat,
	IMediaSeeking_fnGetDuration,
	IMediaSeeking_fnGetStopPosition,
	IMediaSeeking_fnGetCurrentPosition,
	IMediaSeeking_fnConvertTimeFormat,
	IMediaSeeking_fnSetPositions,
	IMediaSeeking_fnGetPositions,
	IMediaSeeking_fnGetAvailable,
	IMediaSeeking_fnSetRate,
	IMediaSeeking_fnGetRate,
	IMediaSeeking_fnGetPreroll,
};

HRESULT CParserOutPinImpl_InitIMediaSeeking( CParserOutPinImpl* This )
{
	TRACE("(%p)\n",This);
	ICOM_VTBL(&This->mediaseeking) = &imediaseeking;

	return NOERROR;
}

void CParserOutPinImpl_UninitIMediaSeeking( CParserOutPinImpl* This )
{
	TRACE("(%p)\n",This);
}

/***************************************************************************
 *
 *	IMediaPosition for CParserOutPinImpl
 *
 */

static HRESULT WINAPI
IMediaPosition_fnQueryInterface(IMediaPosition* iface,REFIID riid,void** ppobj)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	TRACE("(%p)->()\n",This);

	return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
}

static ULONG WINAPI
IMediaPosition_fnAddRef(IMediaPosition* iface)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	TRACE("(%p)->()\n",This);

	return IUnknown_AddRef(This->unk.punkControl);
}

static ULONG WINAPI
IMediaPosition_fnRelease(IMediaPosition* iface)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	TRACE("(%p)->()\n",This);

	return IUnknown_Release(This->unk.punkControl);
}

static HRESULT WINAPI
IMediaPosition_fnGetTypeInfoCount(IMediaPosition* iface,UINT* pcTypeInfo)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaPosition_fnGetTypeInfo(IMediaPosition* iface,UINT iTypeInfo, LCID lcid, ITypeInfo** ppobj)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaPosition_fnGetIDsOfNames(IMediaPosition* iface,REFIID riid, LPOLESTR* ppwszName, UINT cNames, LCID lcid, DISPID* pDispId)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaPosition_fnInvoke(IMediaPosition* iface,DISPID DispId, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarRes, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}


static HRESULT WINAPI
IMediaPosition_fnget_Duration(IMediaPosition* iface,REFTIME* prefTime)
{
	CParserOutPinImpl_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	LONGLONG	llPos;

	TRACE("(%p)->(%p)\n",This,prefTime);

	if ( prefTime == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetDuration == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,prefTime);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetDuration( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
		if ( SUCCEEDED(hr) )
			*prefTime = (REFTIME)llPos;
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnput_CurrentPosition(IMediaPosition* iface,REFTIME refTime)
{
	CParserOutPinImpl_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	/*LONGLONG	llPos;*/

	FIXME("(%p)->() stub!\n",This);

#if 0	/* not yet */
	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pSetCurPos == NULL )
	{
		FIXME("(%p)->() not implemented\n",This);
	}
	else
	{
		llPos = (LONGLONG)refTime;
		hr = This->pParser->m_pHandler->pSetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
		/* FIXME - flush all streams. */
	}
	LeaveCriticalSection( &This->pParser->m_csParser );
#endif

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnget_CurrentPosition(IMediaPosition* iface,REFTIME* prefTime)
{
	CParserOutPinImpl_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	LONGLONG	llPos;

	TRACE("(%p)->(%p)\n",This,prefTime);

	if ( prefTime == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetCurPos == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,prefTime);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetCurPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
		if ( SUCCEEDED(hr) )
			*prefTime = (REFTIME)llPos;
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnget_StopTime(IMediaPosition* iface,REFTIME* prefTime)
{
	CParserOutPinImpl_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	LONGLONG	llPos;

	TRACE("(%p)->(%p)\n",This,prefTime);

	if ( prefTime == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetStopPos == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,prefTime);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, &llPos );
		if ( SUCCEEDED(hr) )
			*prefTime = (REFTIME)llPos;
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnput_StopTime(IMediaPosition* iface,REFTIME refTime)
{
	CParserOutPinImpl_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	LONGLONG	llPos;

	TRACE("(%p)->()\n",This);

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pSetStopPos == NULL )
	{
		FIXME("(%p)->() not implemented\n",This);
	}
	else
	{
		llPos = (LONGLONG)refTime;
		hr = This->pParser->m_pHandler->pSetStopPos( This->pParser, &TIME_FORMAT_MEDIA_TIME, This->nStreamIndex, llPos );
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnget_PrerollTime(IMediaPosition* iface,REFTIME* prefTime)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaPosition_fnput_PrerollTime(IMediaPosition* iface,REFTIME refTime)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	FIXME("(%p)->() stub!\n",This);

	return E_NOTIMPL;
}

static HRESULT WINAPI
IMediaPosition_fnput_Rate(IMediaPosition* iface,double dblRate)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	return IMediaSeeking_SetRate(CParserOutPinImpl_IMediaSeeking(This),dblRate);
}

static HRESULT WINAPI
IMediaPosition_fnget_Rate(IMediaPosition* iface,double* pdblRate)
{
	CParserOutPinImpl_THIS(iface,mediaposition);

	return IMediaSeeking_GetRate(CParserOutPinImpl_IMediaSeeking(This),pdblRate);
}

static HRESULT WINAPI
IMediaPosition_fnCanSeekForward(IMediaPosition* iface,LONG* pCanSeek)
{
	CParserOutPinImpl_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	DWORD	dwCaps;

	TRACE("(%p)->(%p)\n",This,pCanSeek);

	if ( pCanSeek == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
		if ( SUCCEEDED(hr) )
		{
			*pCanSeek = (dwCaps & AM_SEEKING_CanSeekForwards) ? OATRUE : OAFALSE;
			hr = S_OK;
		}
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}

static HRESULT WINAPI
IMediaPosition_fnCanSeekBackward(IMediaPosition* iface,LONG* pCanSeek)
{
	CParserOutPinImpl_THIS(iface,mediaposition);
	HRESULT	hr = E_NOTIMPL;
	DWORD	dwCaps;

	TRACE("(%p)->(%p)\n",This,pCanSeek);

	if ( pCanSeek == NULL )
		return E_POINTER;

	EnterCriticalSection( &This->pParser->m_csParser );
	if ( This->pParser->m_pHandler->pGetSeekingCaps == NULL )
	{
		FIXME("(%p)->(%p) not implemented\n",This,pCanSeek);
	}
	else
	{
		hr = This->pParser->m_pHandler->pGetSeekingCaps( This->pParser, &dwCaps );
		if ( SUCCEEDED(hr) )
		{
			*pCanSeek = (dwCaps & AM_SEEKING_CanSeekBackwards) ? OATRUE : OAFALSE;
			hr = S_OK;
		}
	}
	LeaveCriticalSection( &This->pParser->m_csParser );

	return hr;
}


static ICOM_VTABLE(IMediaPosition) imediaposition =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	IMediaPosition_fnQueryInterface,
	IMediaPosition_fnAddRef,
	IMediaPosition_fnRelease,
	/* IDispatch fields */
	IMediaPosition_fnGetTypeInfoCount,
	IMediaPosition_fnGetTypeInfo,
	IMediaPosition_fnGetIDsOfNames,
	IMediaPosition_fnInvoke,
	/* IMediaPosition fields */
	IMediaPosition_fnget_Duration,
	IMediaPosition_fnput_CurrentPosition,
	IMediaPosition_fnget_CurrentPosition,
	IMediaPosition_fnget_StopTime,
	IMediaPosition_fnput_StopTime,
	IMediaPosition_fnget_PrerollTime,
	IMediaPosition_fnput_PrerollTime,
	IMediaPosition_fnput_Rate,
	IMediaPosition_fnget_Rate,
	IMediaPosition_fnCanSeekForward,
	IMediaPosition_fnCanSeekBackward,
};


HRESULT CParserOutPinImpl_InitIMediaPosition( CParserOutPinImpl* This )
{
	TRACE("(%p)\n",This);
	ICOM_VTBL(&This->mediaposition) = &imediaposition;

	return NOERROR;
}

void CParserOutPinImpl_UninitIMediaPosition( CParserOutPinImpl* This )
{
	TRACE("(%p)\n",This);
}

