/*
 * Implements AVI Parser(Splitter).
 *
 *	FIXME - no seeking
 *
 * 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 "vfw.h"
#include "winerror.h"
#include "strmif.h"
#include "control.h"
#include "vfwmsgs.h"
#include "amvideo.h"
#include "uuids.h"

#include "wine/debug.h"
WINE_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;
	BOOL	bDataDiscontinuity;
};


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);
			This->pStreamsBuf[nIndex].bDataDiscontinuity = TRUE;
		}
		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, DWORD* pdwSampleFlags )
{
	CAVIParseImpl*	This = (CAVIParseImpl*)pImpl->m_pUserData;
	REFERENCE_TIME	rtNext;
	DWORD	nIndexNext;
	DWORD	nIndex;
	CAVIParseStream*	pStream;
	const WAVEFORMATEX*	pwfx;

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

	if ( This == NULL )
		return E_UNEXPECTED;
	*pdwSampleFlags = AM_SAMPLE_SPLICEPOINT;

	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;
		/* FIXME - is this frame keyframe?? */
		*pdwSampleFlags = AM_SAMPLE_SPLICEPOINT;
		if ( pStream->bDataDiscontinuity )
		{
			*pdwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
			pStream->bDataDiscontinuity = FALSE;
		}

		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, /* pGetStopPos */
	NULL, /* pSetStopPos */
	NULL, /* pGetPreroll */
};

HRESULT QUARTZ_CreateAVISplitter(IUnknown* punkOuter,void** ppobj)
{
	return QUARTZ_CreateParser(
		punkOuter,ppobj,
		&CLSID_AviSplitter,
		QUARTZ_AVIParser_Name,
		QUARTZ_AVIParserInPin_Name,
		&CAVIParseImpl_Handlers );
}


