/*
 * Implements WAVE/AU/AIFF Parser.
 *
 * 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
 */

#include "config.h"

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

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

#include "quartz_private.h"
#include "audioutl.h"
#include "parser.h"


static const WCHAR QUARTZ_WaveParser_Name[] =
{ 'W','a','v','e',' ','P','a','r','s','e','r',0 };
static const WCHAR QUARTZ_WaveParserInPin_Name[] =
{ 'I','n',0 };
static const WCHAR QUARTZ_WaveParserOutPin_Name[] =
{ 'O','u','t',0 };


/****************************************************************************/

/* S_OK = found, S_FALSE = not found */
HRESULT RIFF_GetNext(
	CParserImpl* pImpl, LONGLONG llOfs,
	DWORD* pdwCode, DWORD* pdwLength )
{
	BYTE bTemp[8];
	HRESULT hr;

	hr = IAsyncReader_SyncRead( pImpl->m_pReader, llOfs, 8, bTemp );
	if ( hr == S_OK )
	{
		*pdwCode = mmioFOURCC(bTemp[0],bTemp[1],bTemp[2],bTemp[3]);
		*pdwLength = PARSER_LE_UINT32(&bTemp[4]);
	}
	else
	{
		*pdwCode = 0;
		*pdwLength = 0;
	}

	return hr;
}

/* 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;
		llCurLen = 8 + (LONGLONG)((dwCurLen+1)&(~1));
		llOfs += llCurLen;
		if ( (LONGLONG)dwSearchLengthMax <= llCurLen )
			return S_FALSE;
		if ( dwSearchLengthMax != (DWORD)0xffffffff )
			dwSearchLengthMax -= (DWORD)llCurLen;
	}

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




/****************************************************************************
 *
 *	CWavParseImpl
 */

typedef enum WavParseFmtType
{
	WaveParse_Native,
	WaveParse_Signed8,
	WaveParse_Signed16BE,
	WaveParse_Unsigned16LE,
	WaveParse_Unsigned16BE,
} WavParseFmtType;

typedef struct CWavParseImpl
{
	DWORD	cbFmt;
	WAVEFORMATEX*	pFmt;
	DWORD	dwBlockSize;
	LONGLONG	llDataStart;
	LONGLONG	llBytesStop;
	LONGLONG	llBytesTotal;
	LONGLONG	llBytesProcessed;
	BOOL	bDataDiscontinuity;
	WavParseFmtType	iFmtType;
} CWavParseImpl;


static HRESULT CWavParseImpl_InitWAV( CParserImpl* pImpl, CWavParseImpl* This )
{
	HRESULT hr;
	LONGLONG	llOfs;
	DWORD	dwChunkLength;

	hr = RIFF_SearchChunk(
		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;

	This->cbFmt = dwChunkLength;
	if ( dwChunkLength < sizeof(WAVEFORMATEX) )
		This->cbFmt = sizeof(WAVEFORMATEX);
	This->pFmt = (WAVEFORMATEX*)QUARTZ_AllocMem( dwChunkLength );
	if ( This->pFmt == NULL )
		return E_OUTOFMEMORY;
	ZeroMemory( This->pFmt, This->cbFmt );

	hr = IAsyncReader_SyncRead(
		pImpl->m_pReader, llOfs, dwChunkLength, (BYTE*)This->pFmt );
	if ( hr != S_OK )
	{
		if ( SUCCEEDED(hr) )
			hr = E_FAIL;
		return hr;
	}


	hr = RIFF_SearchChunk(
		pImpl, (DWORD)0xffffffff,
		PARSER_RIFF_OfsFirst, PARSER_data,
		&llOfs, &dwChunkLength );
	if ( FAILED(hr) )
		return hr;
	if ( hr != S_OK || dwChunkLength == 0 )
		return E_FAIL;

	This->llDataStart = llOfs;
	This->llBytesTotal = (LONGLONG)dwChunkLength;

	return NOERROR;
}

static HRESULT CWavParseImpl_InitAU( CParserImpl* pImpl, CWavParseImpl* This )
{
	BYTE	au_hdr[24];
	DWORD	dataofs;
	DWORD	datalen;
	DWORD	datafmt;
	DWORD	datarate;
	DWORD	datachannels;
	HRESULT hr;
	WAVEFORMATEX	wfx;

	hr = IAsyncReader_SyncRead( pImpl->m_pReader, 0, 24, au_hdr );
	if ( FAILED(hr) )
		return hr;

	dataofs = PARSER_BE_UINT32(&au_hdr[4]);
	datalen = PARSER_BE_UINT32(&au_hdr[8]);
	datafmt = PARSER_BE_UINT32(&au_hdr[12]);
	datarate = PARSER_BE_UINT32(&au_hdr[16]);
	datachannels = PARSER_BE_UINT32(&au_hdr[20]);

	if ( dataofs < 24U || datalen == 0U )
		return E_FAIL;
	if ( datachannels != 1 && datachannels != 2 )
		return E_FAIL;

	ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
	wfx.nChannels = datachannels;
	wfx.nSamplesPerSec = datarate;

	switch ( datafmt )
	{
	case 1:
		wfx.wFormatTag = WAVE_FORMAT_MULAW;
		wfx.nBlockAlign = datachannels;
		wfx.wBitsPerSample = 8;
		break;
	case 2:
		wfx.wFormatTag = WAVE_FORMAT_PCM;
		wfx.nBlockAlign = datachannels;
		wfx.wBitsPerSample = 8;
		This->iFmtType = WaveParse_Signed8;
		break;
	case 3:
		wfx.wFormatTag = WAVE_FORMAT_PCM;
		wfx.nBlockAlign = datachannels;
		wfx.wBitsPerSample = 16;
		This->iFmtType = WaveParse_Signed16BE;
		break;
	default:
		FIXME("audio/basic - unknown format %lu\n", datafmt );
		return E_FAIL;
	}
	wfx.nAvgBytesPerSec = (datarate * datachannels * (DWORD)wfx.wBitsPerSample) >> 3;

	This->cbFmt = sizeof(WAVEFORMATEX);
	This->pFmt = (WAVEFORMATEX*)QUARTZ_AllocMem( sizeof(WAVEFORMATEX) );
	if ( This->pFmt == NULL )
		return E_OUTOFMEMORY;
	memcpy( This->pFmt, &wfx, sizeof(WAVEFORMATEX) );

	This->llDataStart = dataofs;
	This->llBytesTotal = datalen;

	TRACE("offset %lu, length %lu\n",dataofs,datalen);

	return NOERROR;
}

static HRESULT CWavParseImpl_InitAIFF( CParserImpl* pImpl, CWavParseImpl* This )
{
	FIXME( "AIFF is not supported now.\n" );
	return E_FAIL;
}

static HRESULT CWavParseImpl_InitParser( CParserImpl* pImpl, ULONG* pcStreams )
{
	CWavParseImpl*	This = NULL;
	HRESULT hr;
	BYTE	header[12];

	TRACE("(%p,%p)\n",pImpl,pcStreams);

	if ( pImpl->m_pReader == NULL )
		return E_UNEXPECTED;

	This = (CWavParseImpl*)QUARTZ_AllocMem( sizeof(CWavParseImpl) );
	if ( This == NULL )
		return E_OUTOFMEMORY;
	pImpl->m_pUserData = This;

	/* construct */
	This->cbFmt = 0;
	This->pFmt = NULL;
	This->dwBlockSize = 0;
	This->llDataStart = 0;
	This->llBytesStop = 0;
	This->llBytesTotal = 0;
	This->llBytesProcessed = 0;
	This->bDataDiscontinuity = TRUE;
	This->iFmtType = WaveParse_Native;

	hr = IAsyncReader_SyncRead( pImpl->m_pReader, 0, 12, header );
	if ( FAILED(hr) )
		return hr;
	if ( hr != S_OK )
		return E_FAIL;

	if ( !memcmp( &header[0], "RIFF", 4 ) &&
		 !memcmp( &header[8], "WAVE", 4 ) )
	{
		TRACE( "(%p) - it's audio/wav.\n", pImpl );
		hr = CWavParseImpl_InitWAV( pImpl, This );
	}
	else
	if ( !memcmp( &header[0], ".snd", 4 ) )
	{
		TRACE( "(%p) - it's audio/basic.\n", pImpl );
		hr = CWavParseImpl_InitAU( pImpl, This );
	}
	else
	if ( !memcmp( &header[0], "FORM", 4 ) &&
		 !memcmp( &header[8], "AIFF", 4 ) )
	{
		TRACE( "(%p) - it's audio/aiff.\n", pImpl );
		hr = CWavParseImpl_InitAIFF( pImpl, This );
	}
	else
	{
		FIXME( "(%p) - unknown format.\n", pImpl );
		hr = E_FAIL;
	}

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

	This->llBytesStop = This->llBytesTotal;

	/* initialized successfully. */
	*pcStreams = 1;

	This->dwBlockSize = (This->pFmt->nAvgBytesPerSec + (DWORD)This->pFmt->nBlockAlign - 1U) / (DWORD)This->pFmt->nBlockAlign;

	TRACE( "(%p) returned successfully.\n", pImpl );

	return NOERROR;
}

static HRESULT CWavParseImpl_UninitParser( CParserImpl* pImpl )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

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

	if ( This == NULL )
		return NOERROR;

	/* destruct */
	if ( This->pFmt != NULL ) QUARTZ_FreeMem(This->pFmt);

	QUARTZ_FreeMem( This );
	pImpl->m_pUserData = NULL;

	return NOERROR;
}

static LPCWSTR CWavParseImpl_GetOutPinName( CParserImpl* pImpl, ULONG nStreamIndex )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

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

	return QUARTZ_WaveParserOutPin_Name;
}

static HRESULT CWavParseImpl_GetStreamType( CParserImpl* pImpl, ULONG nStreamIndex, AM_MEDIA_TYPE* pmt )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

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

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
	memcpy( &pmt->majortype, &MEDIATYPE_Audio, sizeof(GUID) );
	QUARTZ_MediaSubType_FromFourCC( &pmt->subtype, (DWORD)This->pFmt->wFormatTag );
	pmt->bFixedSizeSamples = 1;
	pmt->bTemporalCompression = 0;
	pmt->lSampleSize = This->pFmt->nBlockAlign;
	memcpy( &pmt->formattype, &FORMAT_WaveFormatEx, sizeof(GUID) );
	pmt->pUnk = NULL;

	pmt->pbFormat = (BYTE*)CoTaskMemAlloc( This->cbFmt );
	if ( pmt->pbFormat == NULL )
		return E_OUTOFMEMORY;
	pmt->cbFormat = This->cbFmt;
	memcpy( pmt->pbFormat, This->pFmt, This->cbFmt );

	return NOERROR;
}

static HRESULT CWavParseImpl_CheckStreamType( CParserImpl* pImpl, ULONG nStreamIndex, const AM_MEDIA_TYPE* pmt )
{
	if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) ||
		 !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
		return E_FAIL;
	if ( pmt->pbFormat == NULL || pmt->cbFormat < sizeof(WAVEFORMATEX) )
		return E_FAIL;

	return NOERROR;
}

static HRESULT CWavParseImpl_GetAllocProp( CParserImpl* pImpl, ALLOCATOR_PROPERTIES* pReqProp )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

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

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	ZeroMemory( pReqProp, sizeof(ALLOCATOR_PROPERTIES) );
	pReqProp->cBuffers = 1;
	pReqProp->cbBuffer = This->dwBlockSize;

	return NOERROR;
}

static HRESULT CWavParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop, DWORD* pdwSampleFlags )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;
	LONGLONG	llAvail;
	LONGLONG	llStart;
	LONGLONG	llEnd;

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

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;
	*pdwSampleFlags = AM_SAMPLE_SPLICEPOINT;
	if ( This->bDataDiscontinuity )
	{
		*pdwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
		This->bDataDiscontinuity = FALSE;
	}

	llAvail = This->llBytesStop - This->llBytesProcessed;
	if ( llAvail > (LONGLONG)This->dwBlockSize )
		llAvail = (LONGLONG)This->dwBlockSize;
	llStart = This->llDataStart + This->llBytesProcessed;
	llEnd = llStart + llAvail;
	This->llBytesProcessed = llEnd;

	*pllStart = This->llBytesProcessed;
	*plLength = (LONG)llAvail;
	*prtStart = llStart * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;
	*prtStop = llEnd * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;

	return NOERROR;
}

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

	return NOERROR;
}

/***************************************************************************/

static HRESULT CWavParseImpl_GetSeekingCaps( CParserImpl* pImpl, DWORD* pdwCaps )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

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

	*pdwCaps =
		AM_SEEKING_CanSeekAbsolute |
		AM_SEEKING_CanSeekForwards |
		AM_SEEKING_CanSeekBackwards |
		AM_SEEKING_CanGetCurrentPos |
		AM_SEEKING_CanGetStopPos |
		AM_SEEKING_CanGetDuration;

	return S_OK;
}

static HRESULT CWavParseImpl_IsTimeFormatSupported( CParserImpl* pImpl, const GUID* pTimeFormat )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

	TRACE("(%p,%s)\n",This,debugstr_guid(pTimeFormat));

	if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
		return S_OK;

	return S_FALSE;
}

static HRESULT CWavParseImpl_GetCurPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPos )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

	TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
	{
		if ( This->pFmt->nAvgBytesPerSec == 0 )
			return E_FAIL;
		*pllPos = This->llBytesProcessed * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;
		TRACE("curpos %f\n",(double)(*pllPos/QUARTZ_TIMEUNITS));
		return S_OK;
	}

	return E_NOTIMPL;
}

static HRESULT CWavParseImpl_SetCurPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llPos )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;
	LONGLONG	llBytesCur;

	TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
	{
		if ( This->pFmt->nAvgBytesPerSec == 0 )
			return E_FAIL;
		llBytesCur = llPos * This->pFmt->nAvgBytesPerSec / QUARTZ_TIMEUNITS;
		if ( llBytesCur > This->llBytesTotal )
			llBytesCur = This->llBytesTotal;
		This->llBytesProcessed = llBytesCur;
		This->bDataDiscontinuity = TRUE;

		return S_OK;
	}

	return E_NOTIMPL;
}

static HRESULT CWavParseImpl_GetDuration( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllDuration )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

	TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
	{
		if ( This->pFmt->nAvgBytesPerSec == 0 )
			return E_FAIL;
		*pllDuration = This->llBytesTotal * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;
		TRACE("duration %f\n",(double)(*pllDuration/QUARTZ_TIMEUNITS));
		return S_OK;
	}

	return E_NOTIMPL;
}

static HRESULT CWavParseImpl_GetStopPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPos )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

	TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
	{
		if ( This->pFmt->nAvgBytesPerSec == 0 )
			return E_FAIL;
		*pllPos = This->llBytesStop * QUARTZ_TIMEUNITS / (LONGLONG)This->pFmt->nAvgBytesPerSec;
		return S_OK;
	}

	return E_NOTIMPL;
}

static HRESULT CWavParseImpl_SetStopPos( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG llPos )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;
	LONGLONG	llBytesStop;

	TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
	{
		if ( This->pFmt->nAvgBytesPerSec == 0 )
			return E_FAIL;
		llBytesStop = llPos * This->pFmt->nAvgBytesPerSec / QUARTZ_TIMEUNITS;
		if ( llBytesStop > This->llBytesTotal )
			llBytesStop = This->llBytesTotal;
		This->llBytesStop = llBytesStop;

		return S_OK;
	}

	return E_NOTIMPL;
}

static HRESULT CWavParseImpl_GetPreroll( CParserImpl* pImpl, const GUID* pTimeFormat, DWORD nStreamIndex, LONGLONG* pllPreroll )
{
	CWavParseImpl*	This = (CWavParseImpl*)pImpl->m_pUserData;

	TRACE("(%p,%s,%lu,...)\n",This,debugstr_guid(pTimeFormat),nStreamIndex);

	if ( This == NULL || This->pFmt == NULL )
		return E_UNEXPECTED;

	if ( IsEqualGUID(pTimeFormat,&TIME_FORMAT_MEDIA_TIME) )
	{
		*pllPreroll = 0;
		return S_OK;
	}

	return E_NOTIMPL;
}




/***************************************************************************/

static const struct ParserHandlers CWavParseImpl_Handlers =
{
	CWavParseImpl_InitParser,
	CWavParseImpl_UninitParser,
	CWavParseImpl_GetOutPinName,
	CWavParseImpl_GetStreamType,
	CWavParseImpl_CheckStreamType,
	CWavParseImpl_GetAllocProp,
	CWavParseImpl_GetNextRequest,
	CWavParseImpl_ProcessSample,

	/* for IQualityControl */
	NULL, /* pQualityNotify */

	/* for seeking */
	CWavParseImpl_GetSeekingCaps,
	CWavParseImpl_IsTimeFormatSupported,
	CWavParseImpl_GetCurPos,
	CWavParseImpl_SetCurPos,
	CWavParseImpl_GetDuration,
	CWavParseImpl_GetStopPos,
	CWavParseImpl_SetStopPos,
	CWavParseImpl_GetPreroll,
};

HRESULT QUARTZ_CreateWaveParser(IUnknown* punkOuter,void** ppobj)
{
	return QUARTZ_CreateParser(
		punkOuter,ppobj,
		&CLSID_quartzWaveParser,
		QUARTZ_WaveParser_Name,
		QUARTZ_WaveParserInPin_Name,
		&CWavParseImpl_Handlers );
}


