/*
 * 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 "control.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 = QUARTZ_BitmapHasFixedSample( pbi ) ? 1 : 0;
		pmt->bTemporalCompression = 0; /* FIXME - 1 if inter-frame compression is used */
		pmt->lSampleSize = ( pbi->biCompression == 0 ) ? DIBSIZE(*pbi) : pbi->biSizeImage;
		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;

	TRACE("(%p,%p)\n",This,pReqProp);
	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 );
}


