/*
 * 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_GetStreamType( CParserImpl* pImpl, ULONG nStreamIndex, AM_MEDIA_TYPE* pmt );

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;
	DWORD	n;
	AM_MEDIA_TYPE	mt;
	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;
	}

	/* To determine block size, scan all payloads. */
	ZeroMemory( &mt, sizeof(mt) );
	for ( n = 0; n < This->cPayloads; n++ )
	{
		CMPGParseImpl_GetStreamType(pImpl,n,&mt);
		QUARTZ_MediaType_Free(&mt);
	}

	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;
			TRACE("payload block size = %lu\n",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;

	TRACE("buf %d size %d\n",
		(int)This->cPayloads,
		(int)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 );
}


