/*
 * Implements MPEG-1 / MPEG-2 Parser(Splitter).
 *
 *	FIXME - no splitter implementation.
 *	FIXME - no packet support (implemented payload only)
 *	FIXME - no seeking
 *
 * Copyright (C) 2002 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 "mmreg.h"
#include "uuids.h"
#include "dvdmedia.h"

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

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

static const WCHAR QUARTZ_MPEG1Parser_Name[] =
{ 'M','P','E','G','-','I',' ','S','p','l','i','t','t','e','r',0 };
static const WCHAR QUARTZ_MPEG2Parser_Name[] =
{ 'M','P','E','G','-','2',' ','S','p','l','i','t','t','e','r',0 };
static const WCHAR QUARTZ_MPGParserInPin_Name[] =
{ 'I','n',0 };
static const WCHAR QUARTZ_MPGParserOutPin_VideoPinName[] =
{ 'V','i','d','e','o',0 };
static const WCHAR QUARTZ_MPGParserOutPin_AudioPinName[] =
{ 'A','u','d','i','o',0 };
	/* FIXME */
static const WCHAR QUARTZ_MPGParserOutPin_UnknownTypePinName[] =
{ 'O','u','t',0 };



static DWORD bitratesl1[16] =
	{  0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448,  0};
static DWORD bitratesl2[16] =
	{  0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384,  0};
static DWORD bitratesl3[16] =
	{  0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,  0};


/****************************************************************************
 *
 *	CMPGParseImpl
 */


typedef struct CMPGParseImpl CMPGParseImpl;
typedef struct CMPGParsePayload CMPGParsePayload;

enum MPGPayloadType
{
	MPGPayload_Video = 0xe0,
	MPGPayload_Audio = 0xc0,
};

struct CMPGParseImpl
{
	LONGLONG	llPosNext;
	BOOL	bRawPayload;
	DWORD	dwPayloadBlockSizeMax;
	DWORD	cPayloads;
	CMPGParsePayload*	pPayloads;
};

struct CMPGParsePayload
{
	enum MPGPayloadType	payloadtype;
	BOOL	bDataDiscontinuity;
};


static HRESULT CMPGParseImpl_SyncReadPayload(
	CParserImpl* pImpl, CMPGParseImpl* This,
	enum MPGPayloadType payloadtype,
	LONGLONG llPosStart, LONG lLength, BYTE* pbBuf )
{
	if ( This == NULL || This->pPayloads == NULL )
		return E_UNEXPECTED;

	if ( This->bRawPayload )
	{
		if ( payloadtype != This->pPayloads[0].payloadtype )
			return E_UNEXPECTED;
		return IAsyncReader_SyncRead( pImpl->m_pReader, llPosStart, lLength, pbBuf );
	}
	else
	{
		FIXME( "not implemented\n" );
	}

	return E_NOTIMPL;
}



static HRESULT CMPGParseImpl_InitParser( CParserImpl* pImpl, ULONG* pcStreams )
{
	CMPGParseImpl*	This = NULL;
	HRESULT hr;
	BYTE	hdrbuf[8];

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

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

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

	if ( hdrbuf[0] == 0x00 && hdrbuf[1] == 0x00 &&
		 hdrbuf[2] == 0x01 && hdrbuf[3] == 0xba )
	{
		This->bRawPayload = FALSE;
		This->dwPayloadBlockSizeMax = 0;

		FIXME( "no mpeg/system support\n" );
		return E_FAIL;
	}
	else
	if ( hdrbuf[0] == 0x00 && hdrbuf[1] == 0x00 &&
		 hdrbuf[2] == 0x01 && hdrbuf[3] == 0xb3 )
	{
		TRACE( "mpeg/video payload\n" );
		This->llPosNext = 0;
		This->bRawPayload = TRUE;
		This->dwPayloadBlockSizeMax = 0x4000;
		This->cPayloads = 1;
		This->pPayloads = (CMPGParsePayload*)QUARTZ_AllocMem( sizeof(CMPGParsePayload) );
		if ( This->pPayloads == NULL )
			return E_OUTOFMEMORY;
		*pcStreams = 1;
		This->pPayloads[0].payloadtype = MPGPayload_Video;
		This->pPayloads[0].bDataDiscontinuity = TRUE;
	}
	else
	if ( hdrbuf[0] == 0xff && (hdrbuf[1]&0xf0) == 0xf0 )
	{
		TRACE( "mpeg/audio payload\n" );
		This->llPosNext = 0;
		This->bRawPayload = TRUE;
		This->dwPayloadBlockSizeMax = 0;
		This->cPayloads = 1;
		This->pPayloads = (CMPGParsePayload*)QUARTZ_AllocMem( sizeof(CMPGParsePayload) );
		if ( This->pPayloads == NULL )
			return E_OUTOFMEMORY;
		*pcStreams = 1;
		This->pPayloads[0].payloadtype = MPGPayload_Audio;
		This->pPayloads[0].bDataDiscontinuity = TRUE;
	}
	else
	{
		return E_FAIL;
	}

	return S_OK;
}

static HRESULT CMPGParseImpl_UninitParser( CParserImpl* pImpl )
{
	CMPGParseImpl*	This = (CMPGParseImpl*)pImpl->m_pUserData;
	ULONG	nIndex;

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

	if ( This == NULL )
		return NOERROR;

	/* destruct */

	if ( This->pPayloads != NULL )
	{
		for ( nIndex = 0; nIndex < This->cPayloads; nIndex++ )
		{
			/* release this stream */

			
		}
		QUARTZ_FreeMem( This->pPayloads );
		This->pPayloads = NULL;
	}

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

	return NOERROR;
}

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

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

	if ( This == NULL || nStreamIndex >= This->cPayloads )
		return NULL;

	switch ( This->pPayloads[nStreamIndex].payloadtype )
	{
	case MPGPayload_Video:
		return QUARTZ_MPGParserOutPin_VideoPinName;
	case MPGPayload_Audio:
		return QUARTZ_MPGParserOutPin_AudioPinName;
	default:
		FIXME("mpeg - unknown stream type %02x\n",This->pPayloads[nStreamIndex].payloadtype);
	}

	/* FIXME */
	return QUARTZ_MPGParserOutPin_UnknownTypePinName;
}

static HRESULT CMPGParseImpl_GetStreamType( CParserImpl* pImpl, ULONG nStreamIndex, AM_MEDIA_TYPE* pmt )
{
	CMPGParseImpl*	This = (CMPGParseImpl*)pImpl->m_pUserData;
	HRESULT	hr;
	BYTE	hdrbuf[140+10];
	UINT	seqhdrlen;
	MPEG1VIDEOINFO*	pmpg1vi;
	MPEG2VIDEOINFO*	pmpg2vi;
	MPEG1WAVEFORMAT*	pmpg1wav;
	enum MPGPayloadType	payloadtype;
	DWORD	dwPayloadBlockSize;

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

	if ( This == NULL )
		return E_UNEXPECTED;
	if ( nStreamIndex >= This->cPayloads )
		return E_INVALIDARG;

	ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );

	payloadtype = This->pPayloads[nStreamIndex].payloadtype;
	switch ( payloadtype )
	{
	case MPGPayload_Video:
		hr = CMPGParseImpl_SyncReadPayload(
			pImpl, This, payloadtype, 0, 140+10, hdrbuf );
		if ( FAILED(hr) )
			return hr;
		if ( hr != S_OK )
			return E_FAIL;

		memcpy( &pmt->majortype, &MEDIATYPE_Video, sizeof(GUID) );
		seqhdrlen = 12;
		if ( hdrbuf[seqhdrlen-1] & 0x2 )
			seqhdrlen += 64;
		if ( hdrbuf[seqhdrlen-1] & 0x1 )
			seqhdrlen += 64;
		if ( hdrbuf[seqhdrlen  ] == 0x00 && hdrbuf[seqhdrlen+1] == 0x00 &&
			 hdrbuf[seqhdrlen+2] == 0x01 && hdrbuf[seqhdrlen+3] == 0xb5 )
		{
			/* video MPEG-2 */
			FIXME("video MPEG-2\n");
			if ( (hdrbuf[seqhdrlen+4]&0xf0) != 0x1 )
				return E_FAIL;
			memcpy( &pmt->subtype, &MEDIASUBTYPE_MPEG2_VIDEO, sizeof(GUID) );
			memcpy( &pmt->formattype, &FORMAT_MPEG2_VIDEO, sizeof(GUID) );
			pmt->bFixedSizeSamples = 0;
			pmt->bTemporalCompression = 1;
			pmt->lSampleSize = 0;
			pmt->cbFormat = sizeof(MPEG2VIDEOINFO);
			pmt->pbFormat = (BYTE*)CoTaskMemAlloc( sizeof(MPEG2VIDEOINFO) );
			if ( pmt->pbFormat == NULL )
				return E_OUTOFMEMORY;
			ZeroMemory( pmt->pbFormat, sizeof(MPEG2VIDEOINFO) );
			pmpg2vi = (MPEG2VIDEOINFO*)pmt->pbFormat;
			pmpg2vi->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
			pmpg2vi->hdr.bmiHeader.biWidth = ((UINT)hdrbuf[4] << 4) | ((UINT)hdrbuf[5] >> 4); /* FIXME! */
			pmpg2vi->hdr.bmiHeader.biHeight = (((UINT)hdrbuf[5] & 0xf) << 8) | ((UINT)hdrbuf[6]); /* FIXME! */
			pmpg2vi->hdr.dwInterlaceFlags = AMINTERLACE_FieldPatBothRegular; /* FIXME? */
			pmpg2vi->hdr.dwCopyProtectFlags = AMCOPYPROTECT_RestrictDuplication; /* FIXME? */
			pmpg2vi->hdr.dwPictAspectRatioX = 1; /* FIXME? */
			pmpg2vi->hdr.dwPictAspectRatioY = 1; /* FIXME? */
			pmpg2vi->dwStartTimeCode = 0;
			pmpg2vi->cbSequenceHeader = seqhdrlen + 10;
			switch ( hdrbuf[seqhdrlen+4] & 0xf )
			{
			case 5: pmpg2vi->dwProfile = AM_MPEG2Profile_Simple; break;
			case 4: pmpg2vi->dwProfile = AM_MPEG2Profile_Main; break;
			case 3: pmpg2vi->dwProfile = AM_MPEG2Profile_SNRScalable; break;
			case 2: pmpg2vi->dwProfile = AM_MPEG2Profile_SpatiallyScalable; break;
			case 1: pmpg2vi->dwProfile = AM_MPEG2Profile_High; break;
			default: return E_FAIL;
			}
			switch ( hdrbuf[seqhdrlen+5] >> 4 )
			{
			case 10: pmpg2vi->dwLevel = AM_MPEG2Level_Low; break;
			case  8: pmpg2vi->dwLevel = AM_MPEG2Level_Main; break;
			case  6: pmpg2vi->dwLevel = AM_MPEG2Level_High1440; break;
			case  4: pmpg2vi->dwLevel = AM_MPEG2Level_High; break;
			default: return E_FAIL;
			}
			pmpg2vi->dwFlags = 0; /* FIXME? */
			memcpy( pmpg2vi->dwSequenceHeader, hdrbuf, seqhdrlen + 10 );

			return S_OK;
		}
		else
		{
			/* MPEG-1 */
			memcpy( &pmt->subtype, &MEDIASUBTYPE_MPEG1Payload, sizeof(GUID) );
			memcpy( &pmt->formattype, &FORMAT_MPEGVideo, sizeof(GUID) );
			pmt->bFixedSizeSamples = 0;
			pmt->bTemporalCompression = 1;
			pmt->lSampleSize = 0;
			pmt->cbFormat = sizeof(MPEG1VIDEOINFO);
			pmt->pbFormat = (BYTE*)CoTaskMemAlloc( sizeof(MPEG1VIDEOINFO) );
			if ( pmt->pbFormat == NULL )
				return E_OUTOFMEMORY;
			ZeroMemory( pmt->pbFormat, sizeof(MPEG1VIDEOINFO) );
			pmpg1vi = (MPEG1VIDEOINFO*)pmt->pbFormat;
			pmpg1vi->hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
			pmpg1vi->hdr.bmiHeader.biWidth = ((UINT)hdrbuf[4] << 4) | ((UINT)hdrbuf[5] >> 4);
			pmpg1vi->hdr.bmiHeader.biHeight = (((UINT)hdrbuf[5] & 0xf) << 8) | ((UINT)hdrbuf[6]);
			pmpg1vi->hdr.bmiHeader.biPlanes = 1;
			pmpg1vi->dwStartTimeCode = 0;
			pmpg1vi->cbSequenceHeader = seqhdrlen;
			memcpy( pmpg1vi->bSequenceHeader, hdrbuf, seqhdrlen );
		}

		return S_OK;
	case MPGPayload_Audio:
		hr = CMPGParseImpl_SyncReadPayload(
			pImpl, This, payloadtype, 0, 4, hdrbuf );
		if ( FAILED(hr) )
			return hr;
		if ( hr != S_OK )
			return E_FAIL;

		memcpy( &pmt->majortype, &MEDIATYPE_Audio, sizeof(GUID) );
		memcpy( &pmt->formattype, &FORMAT_WaveFormatEx, sizeof(GUID) );

		if ( !( hdrbuf[1] & 0x8 ) )
		{
			/* FIXME!!! */
			FIXME("audio not MPEG-1\n");
			return E_FAIL;
		}
		else
		{
			/* MPEG-1 */
			memcpy( &pmt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload, sizeof(GUID) );
			pmt->bFixedSizeSamples = 0;
			pmt->bTemporalCompression = 1;
			pmt->lSampleSize = 0;
			pmt->cbFormat = sizeof(MPEG1WAVEFORMAT);
			pmt->pbFormat = (BYTE*)CoTaskMemAlloc( sizeof(MPEG1WAVEFORMAT) );
			if ( pmt->pbFormat == NULL )
				return E_OUTOFMEMORY;
			ZeroMemory( pmt->pbFormat, sizeof(MPEG1WAVEFORMAT) );
			pmpg1wav = (MPEG1WAVEFORMAT*)pmt->pbFormat;
			switch ( hdrbuf[1] & 0x6 )
			{
			case 0x6:
				TRACE("layer 1\n");
				pmpg1wav->fwHeadLayer = ACM_MPEG_LAYER1;
				break;
			case 0x4:
				TRACE("layer 2\n");
				pmpg1wav->fwHeadLayer = ACM_MPEG_LAYER2;
				break;
			case 0x2:
				TRACE("layer 3\n");
				pmpg1wav->fwHeadLayer = ACM_MPEG_LAYER3;
				break;
			default: return E_FAIL;
			}

			switch ( pmpg1wav->fwHeadLayer )
			{
			case ACM_MPEG_LAYER1:
				pmpg1wav->dwHeadBitrate = bitratesl1[hdrbuf[2]>>4]*1000;
				break;
			case ACM_MPEG_LAYER2:
				pmpg1wav->dwHeadBitrate = bitratesl2[hdrbuf[2]>>4]*1000;
				break;
			case ACM_MPEG_LAYER3:
				pmpg1wav->dwHeadBitrate = bitratesl3[hdrbuf[2]>>4]*1000;
				break;
			}
			if ( pmpg1wav->dwHeadBitrate == 0 )
				return E_FAIL;

			switch ( hdrbuf[3] & 0xc0 )
			{
			case 0x00:
				TRACE("STEREO\n");
				pmpg1wav->fwHeadMode = ACM_MPEG_STEREO;
				break;
			case 0x40:
				TRACE("JOINTSTEREO\n");
				pmpg1wav->fwHeadMode = ACM_MPEG_JOINTSTEREO;
				break;
			case 0x80:
				TRACE("DUALCHANNEL\n");
				pmpg1wav->fwHeadMode = ACM_MPEG_DUALCHANNEL;
				break;
			case 0xc0:
				TRACE("SINGLECHANNEL\n");
				pmpg1wav->fwHeadMode = ACM_MPEG_SINGLECHANNEL;
				break;
			}

			pmpg1wav->fwHeadModeExt = (hdrbuf[3] & 0x30) >> 4; /* FIXME?? */
			pmpg1wav->wHeadEmphasis = (hdrbuf[3] & 0x03); /* FIXME?? */
			pmpg1wav->fwHeadFlags = ACM_MPEG_ID_MPEG1;
			if ( hdrbuf[1] & 0x1 )
				pmpg1wav->fwHeadFlags |= ACM_MPEG_PROTECTIONBIT;
			if ( hdrbuf[2] & 0x1 )
				pmpg1wav->fwHeadFlags |= ACM_MPEG_PRIVATEBIT;
			if ( hdrbuf[3] & 0x8 )
				pmpg1wav->fwHeadFlags |= ACM_MPEG_COPYRIGHT;
			if ( hdrbuf[3] & 0x4 )
				pmpg1wav->fwHeadFlags |= ACM_MPEG_ORIGINALHOME;
			pmpg1wav->dwPTSLow = 0;
			pmpg1wav->dwPTSHigh = 0;

			pmpg1wav->wfx.wFormatTag = WAVE_FORMAT_MPEG;
			pmpg1wav->wfx.nChannels = (pmpg1wav->fwHeadMode != ACM_MPEG_SINGLECHANNEL) ? 2 : 1;
			switch ( hdrbuf[2] & 0x0c )
			{
			case 0x00:
				TRACE("44100Hz\n");
				pmpg1wav->wfx.nSamplesPerSec = 44100;
				break;
			case 0x01:
				TRACE("48000Hz\n");
				pmpg1wav->wfx.nSamplesPerSec = 48000;
				break;
			case 0x02:
				TRACE("32000Hz\n");
				pmpg1wav->wfx.nSamplesPerSec = 32000;
				break;
			default: return E_FAIL;
			}
			pmpg1wav->wfx.nAvgBytesPerSec = pmpg1wav->dwHeadBitrate >> 3;
			switch ( pmpg1wav->fwHeadLayer )
			{
			case ACM_MPEG_LAYER1:
				pmpg1wav->wfx.nBlockAlign = (384>>3) * pmpg1wav->dwHeadBitrate / pmpg1wav->wfx.nSamplesPerSec;
				break;
			case ACM_MPEG_LAYER2:
				pmpg1wav->wfx.nBlockAlign = (1152>>3) * pmpg1wav->dwHeadBitrate / pmpg1wav->wfx.nSamplesPerSec;
				break;
			case ACM_MPEG_LAYER3:
				pmpg1wav->wfx.nBlockAlign = 1;
				break;
			}
			pmpg1wav->wfx.wBitsPerSample = 0;
			pmpg1wav->wfx.cbSize = sizeof(MPEG1WAVEFORMAT) - sizeof(WAVEFORMATEX);
			if ( pmpg1wav->fwHeadLayer != ACM_MPEG_LAYER3 )
			{
				pmt->bFixedSizeSamples = 1;
				pmt->lSampleSize = pmpg1wav->wfx.nBlockAlign;
			}
			dwPayloadBlockSize = (pmpg1wav->wfx.nAvgBytesPerSec + pmpg1wav->wfx.nBlockAlign - 1) / pmpg1wav->wfx.nBlockAlign;
			if ( dwPayloadBlockSize > This->dwPayloadBlockSizeMax )
				This->dwPayloadBlockSizeMax = dwPayloadBlockSize;
		}

		return S_OK;
	default:
		FIXME("mpeg - unknown stream type %02x\n",This->pPayloads[nStreamIndex].payloadtype);
		break;
	}

	FIXME("stub\n");
	return E_NOTIMPL;
}

static HRESULT CMPGParseImpl_CheckStreamType( CParserImpl* pImpl, ULONG nStreamIndex, const AM_MEDIA_TYPE* pmt )
{
	CMPGParseImpl*	This = (CMPGParseImpl*)pImpl->m_pUserData;
	HRESULT hr;
	AM_MEDIA_TYPE	mt;
	MPEG1VIDEOINFO*	pmpg1vi;
	MPEG1VIDEOINFO*	pmpg1viCheck;
	MPEG2VIDEOINFO*	pmpg2vi;
	MPEG2VIDEOINFO*	pmpg2viCheck;
	WAVEFORMATEX*	pwfx;
	WAVEFORMATEX*	pwfxCheck;
	enum MPGPayloadType	payloadtype;

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

	if ( This == NULL )
		return E_UNEXPECTED;
	if ( nStreamIndex >= This->cPayloads )
		return E_INVALIDARG;

	hr = CMPGParseImpl_GetStreamType( pImpl, nStreamIndex, &mt );
	if ( FAILED(hr) )
		return hr;
	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;

	payloadtype = This->pPayloads[nStreamIndex].payloadtype;
	switch ( payloadtype )
	{
	case MPGPayload_Video:
		if ( IsEqualGUID( &mt.formattype, &FORMAT_MPEGVideo ) )
		{
			/* MPEG-1 Video */
			if ( pmt->cbFormat != mt.cbFormat ||
				 pmt->pbFormat == NULL )
			{
				hr = E_FAIL;
				goto end;
			}
			pmpg1vi = (MPEG1VIDEOINFO*)mt.pbFormat;
			pmpg1viCheck = (MPEG1VIDEOINFO*)pmt->pbFormat;
			if ( memcmp( pmpg1vi, pmpg1viCheck, sizeof(MPEG1VIDEOINFO) ) != 0 )
			{
				hr = E_FAIL;
				goto end;
			}
		}
		else
		if ( IsEqualGUID( &mt.formattype, &FORMAT_MPEG2_VIDEO ) )
		{
			/* MPEG-2 Video */
			if ( pmt->cbFormat != mt.cbFormat ||
				 pmt->pbFormat == NULL )
			{
				hr = E_FAIL;
				goto end;
			}
			pmpg2vi = (MPEG2VIDEOINFO*)mt.pbFormat;
			pmpg2viCheck = (MPEG2VIDEOINFO*)pmt->pbFormat;
			if ( memcmp( pmpg2vi, pmpg2viCheck, sizeof(MPEG2VIDEOINFO) ) != 0 )
			{
				hr = E_FAIL;
				goto end;
			}
		}
		else
		{
			hr = E_FAIL;
			goto end;
		}
		break;
	case MPGPayload_Audio:
		if ( IsEqualGUID( &mt.formattype, &FORMAT_WaveFormatEx ) )
		{
			if ( mt.cbFormat != pmt->cbFormat ||
				 pmt->pbFormat == NULL )
			{
				hr = E_FAIL;
				goto end;
			}
			pwfx = (WAVEFORMATEX*)mt.pbFormat;
			pwfxCheck = (WAVEFORMATEX*)pmt->pbFormat;

			if ( memcmp( pwfx, pwfxCheck, sizeof(WAVEFORMATEX) ) != 0 )
			{
				hr = E_FAIL;
				goto end;
			}
		}
		else
		{
			hr = E_FAIL;
			goto end;
		}

		break;
	default:
		FIXME( "unsupported payload type\n" );
		hr = E_FAIL;
		goto end;
	}

	hr = S_OK;
end:
	QUARTZ_MediaType_Free( &mt );

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

	return hr;
}

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

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

	if ( This == NULL )
		return E_UNEXPECTED;

	ZeroMemory( pReqProp, sizeof(ALLOCATOR_PROPERTIES) );
	pReqProp->cBuffers = This->cPayloads;
	pReqProp->cbBuffer = This->dwPayloadBlockSizeMax;

	return S_OK;
}

static HRESULT CMPGParseImpl_GetNextRequest( CParserImpl* pImpl, ULONG* pnStreamIndex, LONGLONG* pllStart, LONG* plLength, REFERENCE_TIME* prtStart, REFERENCE_TIME* prtStop, DWORD* pdwSampleFlags )
{
	CMPGParseImpl*	This = (CMPGParseImpl*)pImpl->m_pUserData;

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

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

	if ( This->bRawPayload )
	{
		if ( This->dwPayloadBlockSizeMax == 0 ||
			 This->cPayloads != 1 || This->pPayloads == NULL )
			return E_UNEXPECTED;
		*pnStreamIndex = 0;
		*pllStart = This->llPosNext;
		*plLength = This->dwPayloadBlockSizeMax;
		*prtStart = 0;
		*prtStop = 0;
		if ( This->pPayloads[0].bDataDiscontinuity )
		{
			*pdwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
			This->pPayloads[0].bDataDiscontinuity = FALSE;
		}
	}
	else
	{
		FIXME("stub\n");
		return E_NOTIMPL;
	}

	return S_OK;
}

static HRESULT CMPGParseImpl_ProcessSample( CParserImpl* pImpl, ULONG nStreamIndex, LONGLONG llStart, LONG lLength, IMediaSample* pSample )
{
	CMPGParseImpl*	This = (CMPGParseImpl*)pImpl->m_pUserData;
	HRESULT hr;

	TRACE("(%p,%lu,%ld,%ld,%p)\n",This,nStreamIndex,(long)llStart,lLength,pSample);

	if ( This == NULL )
		return E_UNEXPECTED;

	if ( This->bRawPayload )
	{
		hr = IMediaSample_SetTime(pSample,NULL,NULL);
		if ( FAILED(hr) )
			return hr;
	}

	return NOERROR;
}


static const struct ParserHandlers CMPGParseImpl_Handlers =
{
	CMPGParseImpl_InitParser,
	CMPGParseImpl_UninitParser,
	CMPGParseImpl_GetOutPinName,
	CMPGParseImpl_GetStreamType,
	CMPGParseImpl_CheckStreamType,
	CMPGParseImpl_GetAllocProp,
	CMPGParseImpl_GetNextRequest,
	CMPGParseImpl_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_CreateMPEG1Splitter(IUnknown* punkOuter,void** ppobj)
{
	return QUARTZ_CreateParser(
		punkOuter,ppobj,
		&CLSID_MPEG1Splitter,
		QUARTZ_MPEG1Parser_Name,
		QUARTZ_MPGParserInPin_Name,
		&CMPGParseImpl_Handlers );
}


