/*
 * Implements WAVE/AU/AIFF Parser.
 *
 * hidenori@a2.ctktv.ne.jp
 */

#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 "vfwmsgs.h"
#include "uuids.h"

#include "debugtools.h"
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	llBytesTotal;
	LONGLONG	llBytesProcessed;
	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;

	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->llBytesTotal = 0;
	This->llBytesProcessed = 0;
	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;
	}

	/* 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 )
{
	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;

	llAvail = This->llBytesTotal - This->llBytesProcessed;
	if ( llAvail > (LONGLONG)This->dwBlockSize )
		llAvail = (LONGLONG)This->dwBlockSize;
	llStart = 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 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 */
	NULL, /* pGetSeekingCaps */
	NULL, /* pIsTimeFormatSupported */
	NULL, /* pGetCurPos */
	NULL, /* pSetCurPos */
	NULL, /* pGetDuration */
	NULL, /* pSetDuration */
	NULL, /* pGetStopPos */
	NULL, /* pSetStopPos */
	NULL, /* pGetPreroll */
	NULL, /* pSetPreroll */
};

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


