/*
 * Implements IPin and IMemInputPin. (internal)
 *
 * 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 "winerror.h"
#include "strmif.h"
#include "vfwmsgs.h"

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

#include "quartz_private.h"
#include "basefilt.h"
#include "memalloc.h"


/***************************************************************************
 *
 *	CPinBaseImpl
 *
 */

static HRESULT WINAPI
CPinBaseImpl_fnQueryInterface(IPin* iface,REFIID riid,void** ppobj)
{
	ICOM_THIS(CPinBaseImpl,iface);

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

	return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
}

static ULONG WINAPI
CPinBaseImpl_fnAddRef(IPin* iface)
{
	ICOM_THIS(CPinBaseImpl,iface);

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

	return IUnknown_AddRef(This->punkControl);
}

static ULONG WINAPI
CPinBaseImpl_fnRelease(IPin* iface)
{
	ICOM_THIS(CPinBaseImpl,iface);

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

	return IUnknown_Release(This->punkControl);
}

static HRESULT WINAPI
CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT	hr = E_NOTIMPL;
	ULONG	i;
	FILTER_STATE	fs;

	TRACE("(%p)->(%p,%p)\n",This,pPin,pmt);

	if ( !This->bOutput )
	{
		TRACE("Connect() should not be sent to input pins\n");
		return E_UNEXPECTED;
	}
	if ( pPin == NULL )
		return E_POINTER;

	TRACE("try to connect to %p\n",pPin);

	EnterCriticalSection( This->pcsPin );

	if ( This->pPinConnectedTo != NULL )
	{
		hr = VFW_E_ALREADY_CONNECTED;
		goto err;
	}

	/* return fail if running */
	hr = IBaseFilter_GetState((IBaseFilter*)(This->pFilter),0,&fs);
	if ( hr != S_OK || fs != State_Stopped )
	{
		TRACE("not stopped\n");
		hr = VFW_E_NOT_STOPPED;
		goto err;
	}

	if ( This->pHandlers->pOnPreConnect != NULL )
	{
		hr = This->pHandlers->pOnPreConnect(This,pPin);
		if ( FAILED(hr) )
		{
			TRACE("OnPreconnect() failed hr = %08lx\n",hr);
			goto err;
		}
	}

	if ( pmt != NULL )
	{
		hr = IPin_QueryAccept(iface,pmt);
		if ( FAILED(hr) )
			goto err;
		This->pPinConnectedTo = pPin;
		hr = IPin_ReceiveConnection(pPin,iface,pmt);
		This->pPinConnectedTo = NULL;
		if ( FAILED(hr) )
			goto err;
	}
	else
	{
		for ( i = 0; i < This->cAcceptTypes; i++ )
		{
			pmt = &This->pmtAcceptTypes[i];
			hr = IPin_QueryAccept(iface,pmt);
			if ( SUCCEEDED(hr) )
			{
				This->pPinConnectedTo = pPin;
				hr = IPin_ReceiveConnection(pPin,iface,pmt);
				This->pPinConnectedTo = NULL;

				TRACE("ReceiveConnection - %08lx\n",hr);
				if ( SUCCEEDED(hr) )
				{
					goto connected;
				}
			}
		}

		hr = VFW_E_TYPE_NOT_ACCEPTED;
		goto err;
	}

connected:;
	This->pmtConn = QUARTZ_MediaType_Duplicate( pmt );
	if ( This->pmtConn == NULL )
	{
		hr = E_OUTOFMEMORY;
		IPin_Disconnect(pPin);
		goto err;
	}

	This->pPinConnectedTo = pPin; IPin_AddRef(pPin);
	hr = IPin_QueryInterface(pPin,&IID_IMemInputPin,(void**)&This->pMemInputPinConnectedTo);
	if ( FAILED(hr) )
	{
		TRACE("no IMemInputPin\n");
		IPin_Disconnect(pPin);
		goto err;
	}

	if ( This->pHandlers->pOnPostConnect != NULL )
	{
		hr = This->pHandlers->pOnPostConnect(This,pPin);
		if ( FAILED(hr) )
		{
			TRACE("OnPostConnect() failed hr = %08lx\n",hr);
			IPin_Disconnect(pPin);
			goto err;
		}
	}

	hr = S_OK;

err:
	if ( FAILED(hr) )
	{
		IPin_Disconnect(iface);
	}
	LeaveCriticalSection( This->pcsPin );

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

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT	hr = E_NOTIMPL;
	FILTER_STATE fs;

	TRACE("(%p)->(%p,%p)\n",This,pPin,pmt);

	if ( This->bOutput )
	{
		TRACE("ReceiveConnection() should not be sent to output pins\n");
		return E_UNEXPECTED;
	}
	if ( pPin == NULL || pmt == NULL )
		return E_POINTER;

	EnterCriticalSection( This->pcsPin );

	if ( This->pPinConnectedTo != NULL )
	{
		hr = VFW_E_ALREADY_CONNECTED;
		goto err;
	}

	/* return fail if running */
	hr = IBaseFilter_GetState((IBaseFilter*)(This->pFilter),0,&fs);
	if ( hr != S_OK || fs != State_Stopped )
	{
		TRACE("not stopped\n");
		hr = VFW_E_NOT_STOPPED;
		goto err;
	}

	if ( This->pHandlers->pOnPreConnect != NULL )
	{
		hr = This->pHandlers->pOnPreConnect(This,pPin);
		if ( FAILED(hr) )
		{
			TRACE("OnPreConnect() failed hr = %08lx\n",hr);
			goto err;
		}
	}

	hr = IPin_QueryAccept(iface,pmt);
	if ( FAILED(hr) )
		goto err;

	This->pmtConn = QUARTZ_MediaType_Duplicate( pmt );
	if ( This->pmtConn == NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}

	if ( This->pHandlers->pOnPostConnect != NULL )
	{
		hr = This->pHandlers->pOnPostConnect(This,pPin);
		if ( FAILED(hr) )
		{
			TRACE("OnPostConnect() failed hr = %08lx\n",hr);
			goto err;
		}
	}

	hr = S_OK;
	This->pPinConnectedTo = pPin; IPin_AddRef(pPin);

err:
	if ( FAILED(hr) )
		IPin_Disconnect(iface);
	LeaveCriticalSection( This->pcsPin );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnDisconnect(IPin* iface)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr = NOERROR;
	FILTER_STATE fs;

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

	EnterCriticalSection( This->pcsPin );

	/* return fail if running */
	hr = IBaseFilter_GetState((IBaseFilter*)(This->pFilter),0,&fs);
	if ( hr != S_OK || fs != State_Stopped )
	{
		TRACE("not stopped\n");
		hr = VFW_E_NOT_STOPPED;
		goto err;
	}

	if ( This->pHandlers->pOnDisconnect != NULL )
		hr = This->pHandlers->pOnDisconnect(This);

	if ( This->pmtConn != NULL )
	{
		QUARTZ_MediaType_Destroy( This->pmtConn );
		This->pmtConn = NULL;
	}
	if ( This->pMemInputPinConnectedTo != NULL )
	{
		IMemInputPin_Release(This->pMemInputPinConnectedTo);
		This->pMemInputPinConnectedTo = NULL;
	}
	if ( This->pPinConnectedTo != NULL )
	{
		/* FIXME - cleanup */

		IPin_Release(This->pPinConnectedTo);
		This->pPinConnectedTo = NULL;
		hr = NOERROR;
	}
	else
	{
		hr = S_FALSE; /* FIXME - is this correct??? */
	}

err:
	LeaveCriticalSection( This->pcsPin );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnConnectedTo(IPin* iface,IPin** ppPin)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT	hr = VFW_E_NOT_CONNECTED;

	TRACE("(%p)->(%p)\n",This,ppPin);

	if ( ppPin == NULL )
		return E_POINTER;

	EnterCriticalSection( This->pcsPin );

	*ppPin = This->pPinConnectedTo;
	if ( This->pPinConnectedTo != NULL )
	{
		IPin_AddRef(This->pPinConnectedTo);
		hr = NOERROR;
	}

	LeaveCriticalSection( This->pcsPin );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnConnectionMediaType(IPin* iface,AM_MEDIA_TYPE* pmt)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr = E_FAIL;

	TRACE("(%p)->(%p)\n",This,pmt);

	if ( pmt == NULL )
		return E_POINTER;

	EnterCriticalSection( This->pcsPin );

	if ( This->pmtConn != NULL )
	{
		hr = QUARTZ_MediaType_Copy( pmt, This->pmtConn );
	}
	else
	{
		ZeroMemory( pmt, sizeof(AM_MEDIA_TYPE) );
		pmt->bFixedSizeSamples = TRUE;
		pmt->lSampleSize = 1;
		hr = VFW_E_NOT_CONNECTED;
	}

	LeaveCriticalSection( This->pcsPin );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnQueryPinInfo(IPin* iface,PIN_INFO* pinfo)
{
	ICOM_THIS(CPinBaseImpl,iface);

	TRACE("(%p)->(%p)\n",This,pinfo);

	if ( pinfo == NULL )
		return E_POINTER;

	EnterCriticalSection( This->pcsPin );

	ZeroMemory( pinfo, sizeof(PIN_INFO) );
	pinfo->pFilter = (IBaseFilter*)(This->pFilter);
	if ( pinfo->pFilter != NULL )
		IBaseFilter_AddRef( pinfo->pFilter );
	pinfo->dir = This->bOutput ? PINDIR_OUTPUT : PINDIR_INPUT;
	if ( This->cbIdLen <= sizeof(pinfo->achName) )
		memcpy( pinfo->achName, This->pwszId, This->cbIdLen );
	else
	{
		memcpy( pinfo->achName, This->pwszId, sizeof(pinfo->achName) );
		pinfo->achName[sizeof(pinfo->achName)/sizeof(pinfo->achName[0])-1] = 0;
	}

	LeaveCriticalSection( This->pcsPin );

	return NOERROR;
}

static HRESULT WINAPI
CPinBaseImpl_fnQueryDirection(IPin* iface,PIN_DIRECTION* pdir)
{
	ICOM_THIS(CPinBaseImpl,iface);

	TRACE("(%p)->(%p)\n",This,pdir);

	if ( pdir == NULL )
		return E_POINTER;

	*pdir = This->bOutput ? PINDIR_OUTPUT : PINDIR_INPUT;

	return NOERROR;
}

static HRESULT WINAPI
CPinBaseImpl_fnQueryId(IPin* iface,LPWSTR* lpwszId)
{
	ICOM_THIS(CPinBaseImpl,iface);

	TRACE("(%p)->(%p)\n",This,lpwszId);

	if ( lpwszId == NULL )
		return E_POINTER;

	*lpwszId = (WCHAR*)CoTaskMemAlloc( This->cbIdLen );
	if ( *lpwszId == NULL )
		return E_OUTOFMEMORY;
	memcpy( *lpwszId, This->pwszId, This->cbIdLen );

	return NOERROR;
}

static HRESULT WINAPI
CPinBaseImpl_fnQueryAccept(IPin* iface,const AM_MEDIA_TYPE* pmt)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr;

	TRACE("(%p)->(%p)\n",This,pmt);

	if ( pmt == NULL )
		return E_POINTER;

	hr = NOERROR;
	EnterCriticalSection( This->pcsPin );
	if ( This->pHandlers->pCheckMediaType != NULL )
		hr = This->pHandlers->pCheckMediaType(This,pmt);
	LeaveCriticalSection( This->pcsPin );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnEnumMediaTypes(IPin* iface,IEnumMediaTypes** ppenum)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr;

	TRACE("(%p)->(%p)\n",This,ppenum);

	if ( ppenum == NULL )
		return E_POINTER;

	hr = E_NOTIMPL;

	EnterCriticalSection( This->pcsPin );
	if ( This->cAcceptTypes > 0 )
		hr = QUARTZ_CreateEnumMediaTypes(
			ppenum, This->pmtAcceptTypes, This->cAcceptTypes );
	LeaveCriticalSection( This->pcsPin );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnQueryInternalConnections(IPin* iface,IPin** ppPin,ULONG* pul)
{
	ICOM_THIS(CPinBaseImpl,iface);

	TRACE("(%p)->(%p,%p)\n",This,ppPin,pul);

	/* E_NOTIMPL means 'no internal connections'. */
	return E_NOTIMPL;
}

static HRESULT WINAPI
CPinBaseImpl_fnEndOfStream(IPin* iface)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr = E_NOTIMPL;

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

	if ( This->bOutput )
		return E_UNEXPECTED;

	EnterCriticalSection( This->pcsPinReceive );
	if ( This->pHandlers->pEndOfStream != NULL )
		hr = This->pHandlers->pEndOfStream(This);
	LeaveCriticalSection( This->pcsPinReceive );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnBeginFlush(IPin* iface)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr = E_NOTIMPL;

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

	if ( This->bOutput )
		return E_UNEXPECTED;

	EnterCriticalSection( This->pcsPin );
	if ( This->pHandlers->pBeginFlush != NULL )
		hr = This->pHandlers->pBeginFlush(This);
	LeaveCriticalSection( This->pcsPin );

	EnterCriticalSection( This->pcsPinReceive );
	LeaveCriticalSection( This->pcsPinReceive );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnEndFlush(IPin* iface)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr = E_NOTIMPL;

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

	if ( This->bOutput )
		return E_UNEXPECTED;

	EnterCriticalSection( This->pcsPin );
	if ( This->pHandlers->pEndFlush != NULL )
		hr = This->pHandlers->pEndFlush(This);
	LeaveCriticalSection( This->pcsPin );

	return hr;
}

static HRESULT WINAPI
CPinBaseImpl_fnNewSegment(IPin* iface,REFERENCE_TIME rtStart,REFERENCE_TIME rtStop,double rate)
{
	ICOM_THIS(CPinBaseImpl,iface);
	HRESULT hr = E_NOTIMPL;

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

	if ( This->bOutput )
		return E_UNEXPECTED;

	EnterCriticalSection( This->pcsPin );
	if ( This->pHandlers->pNewSegment != NULL )
		hr = This->pHandlers->pNewSegment(This,rtStart,rtStop,rate);
	LeaveCriticalSection( This->pcsPin );

	return hr;
}




static ICOM_VTABLE(IPin) ipin =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	CPinBaseImpl_fnQueryInterface,
	CPinBaseImpl_fnAddRef,
	CPinBaseImpl_fnRelease,
	/* IPin fields */
	CPinBaseImpl_fnConnect,
	CPinBaseImpl_fnReceiveConnection,
	CPinBaseImpl_fnDisconnect,
	CPinBaseImpl_fnConnectedTo,
	CPinBaseImpl_fnConnectionMediaType,
	CPinBaseImpl_fnQueryPinInfo,
	CPinBaseImpl_fnQueryDirection,
	CPinBaseImpl_fnQueryId,
	CPinBaseImpl_fnQueryAccept,
	CPinBaseImpl_fnEnumMediaTypes,
	CPinBaseImpl_fnQueryInternalConnections,
	CPinBaseImpl_fnEndOfStream,
	CPinBaseImpl_fnBeginFlush,
	CPinBaseImpl_fnEndFlush,
	CPinBaseImpl_fnNewSegment,
};


HRESULT CPinBaseImpl_InitIPin(
	CPinBaseImpl* This, IUnknown* punkControl,
	CRITICAL_SECTION* pcsPin,
	CRITICAL_SECTION* pcsPinReceive,
	CBaseFilterImpl* pFilter, LPCWSTR pwszId,
	BOOL bOutput,
	const CBasePinHandlers*	pHandlers )
{
	HRESULT	hr = NOERROR;

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

	if ( punkControl == NULL )
	{
		ERR( "punkControl must not be NULL\n" );
		return E_INVALIDARG;
	}

	ICOM_VTBL(This) = &ipin;
	This->punkControl = punkControl;
	This->pHandlers = pHandlers;
	This->cbIdLen = sizeof(WCHAR)*(lstrlenW(pwszId)+1);
	This->pwszId = NULL;
	This->bOutput = bOutput;
	This->pmtAcceptTypes = NULL;
	This->cAcceptTypes = 0;
	This->pcsPin = pcsPin;
	This->pcsPinReceive = pcsPinReceive;
	This->pFilter = pFilter;
	This->pPinConnectedTo = NULL;
	This->pMemInputPinConnectedTo = NULL;
	This->pmtConn = NULL;
	This->pAsyncOut = NULL;

	This->pwszId = (WCHAR*)QUARTZ_AllocMem( This->cbIdLen );
	if ( This->pwszId == NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}
	memcpy( This->pwszId, pwszId, This->cbIdLen );

	return NOERROR;

err:;
	CPinBaseImpl_UninitIPin( This );
	return hr;
}

void CPinBaseImpl_UninitIPin( CPinBaseImpl* This )
{
	TRACE("(%p)\n",This);

	IPin_Disconnect( (IPin*)(This) );

	if ( This->pwszId != NULL )
	{
		QUARTZ_FreeMem( This->pwszId );
		This->pwszId = NULL;
	}
}


/***************************************************************************
 *
 *	CMemInputPinBaseImpl
 *
 */


static HRESULT WINAPI
CMemInputPinBaseImpl_fnQueryInterface(IMemInputPin* iface,REFIID riid,void** ppobj)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);

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

	return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
}

static ULONG WINAPI
CMemInputPinBaseImpl_fnAddRef(IMemInputPin* iface)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);

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

	return IUnknown_AddRef(This->punkControl);
}

static ULONG WINAPI
CMemInputPinBaseImpl_fnRelease(IMemInputPin* iface)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);

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

	return IUnknown_Release(This->punkControl);
}


static HRESULT WINAPI
CMemInputPinBaseImpl_fnGetAllocator(IMemInputPin* iface,IMemAllocator** ppAllocator)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);
	HRESULT hr = NOERROR;
	IUnknown* punk;

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

	if ( ppAllocator == NULL )
		return E_POINTER;

	EnterCriticalSection( This->pPin->pcsPin );

	if ( This->pAllocator == NULL )
	{
		hr = QUARTZ_CreateMemoryAllocator(NULL,(void**)&punk);
		if ( hr == NOERROR )
		{
			hr = IUnknown_QueryInterface(punk,
				&IID_IMemAllocator,(void**)&This->pAllocator);
			IUnknown_Release(punk);
		}
	}

	if ( hr == NOERROR )
	{
		*ppAllocator = This->pAllocator;
		IMemAllocator_AddRef(This->pAllocator);
	}

	LeaveCriticalSection( This->pPin->pcsPin );

	return hr;
}

static HRESULT WINAPI
CMemInputPinBaseImpl_fnNotifyAllocator(IMemInputPin* iface,IMemAllocator* pAllocator,BOOL bReadonly)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);

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

	if ( pAllocator == NULL )
		return E_POINTER;

	EnterCriticalSection( This->pPin->pcsPin );

	if ( This->pAllocator != NULL )
	{
		IMemAllocator_Release(This->pAllocator);
		This->pAllocator = NULL;
	}
	This->pAllocator = pAllocator;
	IMemAllocator_AddRef(This->pAllocator);

	This->bReadonly = bReadonly;

	LeaveCriticalSection( This->pPin->pcsPin );

	return NOERROR;
}

static HRESULT WINAPI
CMemInputPinBaseImpl_fnGetAllocatorRequirements(IMemInputPin* iface,ALLOCATOR_PROPERTIES* pProp)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);

	TRACE("(%p)->(%p)\n",This,pProp);

	if ( pProp == NULL )
		return E_POINTER;

	/* E_MOTIMPL means 'no requirements' */
	return E_NOTIMPL;
}

static HRESULT WINAPI
CMemInputPinBaseImpl_fnReceive(IMemInputPin* iface,IMediaSample* pSample)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);
	HRESULT hr = E_NOTIMPL;

	TRACE("(%p)->(%p)\n",This,pSample);

	EnterCriticalSection( This->pPin->pcsPinReceive );
	if ( This->pPin->pHandlers->pReceive != NULL )
		hr = This->pPin->pHandlers->pReceive(This->pPin,pSample);
	LeaveCriticalSection( This->pPin->pcsPinReceive );

	return hr;
}

static HRESULT WINAPI
CMemInputPinBaseImpl_fnReceiveMultiple(IMemInputPin* iface,IMediaSample** ppSample,long nSample,long* pnSampleProcessed)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);
	long	n;
	HRESULT hr;

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

	if ( ppSample == NULL || pnSampleProcessed == NULL )
		return E_POINTER;

	hr = NOERROR;
	for ( n = 0; n < nSample; n++ )
	{
		hr = IMemInputPin_Receive(iface,ppSample[n]);
		if ( FAILED(hr) )
			break;
	}

	*pnSampleProcessed = n;
	return hr;
}

static HRESULT WINAPI
CMemInputPinBaseImpl_fnReceiveCanBlock(IMemInputPin* iface)
{
	ICOM_THIS(CMemInputPinBaseImpl,iface);
	HRESULT hr = E_NOTIMPL;

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

	EnterCriticalSection( This->pPin->pcsPin );
	if ( This->pPin->pHandlers->pReceiveCanBlock != NULL )
		hr = This->pPin->pHandlers->pReceiveCanBlock(This->pPin);
	LeaveCriticalSection( This->pPin->pcsPin );

	return hr;
}


static ICOM_VTABLE(IMemInputPin) imeminputpin =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	CMemInputPinBaseImpl_fnQueryInterface,
	CMemInputPinBaseImpl_fnAddRef,
	CMemInputPinBaseImpl_fnRelease,
	/* IMemInputPin fields */
	CMemInputPinBaseImpl_fnGetAllocator,
	CMemInputPinBaseImpl_fnNotifyAllocator,
	CMemInputPinBaseImpl_fnGetAllocatorRequirements,
	CMemInputPinBaseImpl_fnReceive,
	CMemInputPinBaseImpl_fnReceiveMultiple,
	CMemInputPinBaseImpl_fnReceiveCanBlock,
};

HRESULT CMemInputPinBaseImpl_InitIMemInputPin(
	CMemInputPinBaseImpl* This, IUnknown* punkControl,
	CPinBaseImpl* pPin )
{
	TRACE("(%p,%p)\n",This,punkControl);

	if ( punkControl == NULL )
	{
		ERR( "punkControl must not be NULL\n" );
		return E_INVALIDARG;
	}

	ICOM_VTBL(This) = &imeminputpin;
	This->punkControl = punkControl;
	This->pPin = pPin;
	This->pAllocator = NULL;
	This->bReadonly = FALSE;

	return NOERROR;
}

void CMemInputPinBaseImpl_UninitIMemInputPin(
	CMemInputPinBaseImpl* This )
{
	TRACE("(%p)\n",This);

	if ( This->pAllocator != NULL )
	{
		IMemAllocator_Release(This->pAllocator);
		This->pAllocator = NULL;
	}
}

/***************************************************************************
 *
 *	CQualityControlPassThruImpl
 *
 */

static HRESULT WINAPI
CQualityControlPassThruImpl_fnQueryInterface(IQualityControl* iface,REFIID riid,void** ppobj)
{
	ICOM_THIS(CQualityControlPassThruImpl,iface);

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

	return IUnknown_QueryInterface(This->punkControl,riid,ppobj);
}

static ULONG WINAPI
CQualityControlPassThruImpl_fnAddRef(IQualityControl* iface)
{
	ICOM_THIS(CQualityControlPassThruImpl,iface);

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

	return IUnknown_AddRef(This->punkControl);
}

static ULONG WINAPI
CQualityControlPassThruImpl_fnRelease(IQualityControl* iface)
{
	ICOM_THIS(CQualityControlPassThruImpl,iface);

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

	return IUnknown_Release(This->punkControl);
}


static HRESULT WINAPI
CQualityControlPassThruImpl_fnNotify(IQualityControl* iface,IBaseFilter* pFilter,Quality q)
{
	ICOM_THIS(CQualityControlPassThruImpl,iface);
	HRESULT hr = S_FALSE;

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

	if ( This->pControl != NULL )
		return IQualityControl_Notify( This->pControl, pFilter, q );

	EnterCriticalSection( This->pPin->pcsPin );
	if ( This->pPin->pHandlers->pQualityNotify != NULL )
		hr = This->pPin->pHandlers->pQualityNotify(This->pPin,pFilter,q);
	LeaveCriticalSection( This->pPin->pcsPin );

	return hr;
}

static HRESULT WINAPI
CQualityControlPassThruImpl_fnSetSink(IQualityControl* iface,IQualityControl* pControl)
{
	ICOM_THIS(CQualityControlPassThruImpl,iface);

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

	This->pControl = pControl; /* AddRef() must not be called */

	return NOERROR;
}

static ICOM_VTABLE(IQualityControl) iqualitycontrol =
{
	ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
	/* IUnknown fields */
	CQualityControlPassThruImpl_fnQueryInterface,
	CQualityControlPassThruImpl_fnAddRef,
	CQualityControlPassThruImpl_fnRelease,
	/* IQualityControl fields */
	CQualityControlPassThruImpl_fnNotify,
	CQualityControlPassThruImpl_fnSetSink,
};

HRESULT CQualityControlPassThruImpl_InitIQualityControl(
	CQualityControlPassThruImpl* This, IUnknown* punkControl,
	CPinBaseImpl* pPin )
{
	TRACE("(%p,%p)\n",This,punkControl);

	if ( punkControl == NULL )
	{
		ERR( "punkControl must not be NULL\n" );
		return E_INVALIDARG;
	}

	ICOM_VTBL(This) = &iqualitycontrol;
	This->punkControl = punkControl;
	This->pPin = pPin;

	return NOERROR;
}

void CQualityControlPassThruImpl_UninitIQualityControl(
	CQualityControlPassThruImpl* This )
{
}

/***************************************************************************
 *
 *	helper methods for output pins.
 *
 */

HRESULT CPinBaseImpl_SendSample( CPinBaseImpl* This, IMediaSample* pSample )
{
	if ( This->pHandlers->pReceive == NULL )
		return E_NOTIMPL;

	return This->pHandlers->pReceive( This, pSample );
}

HRESULT CPinBaseImpl_SendReceiveCanBlock( CPinBaseImpl* This )
{
	if ( This->pHandlers->pReceiveCanBlock == NULL )
		return E_NOTIMPL;

	return This->pHandlers->pReceiveCanBlock( This );
}

HRESULT CPinBaseImpl_SendEndOfStream( CPinBaseImpl* This )
{
	if ( This->pHandlers->pEndOfStream == NULL )
		return E_NOTIMPL;

	return This->pHandlers->pEndOfStream( This );
}

HRESULT CPinBaseImpl_SendBeginFlush( CPinBaseImpl* This )
{
	if ( This->pHandlers->pBeginFlush == NULL )
		return E_NOTIMPL;

	return This->pHandlers->pBeginFlush( This );
}

HRESULT CPinBaseImpl_SendEndFlush( CPinBaseImpl* This )
{
	if ( This->pHandlers->pEndFlush == NULL )
		return E_NOTIMPL;

	return This->pHandlers->pEndFlush( This );
}

HRESULT CPinBaseImpl_SendNewSegment( CPinBaseImpl* This, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
{
	if ( This->pHandlers->pNewSegment == NULL )
		return E_NOTIMPL;

	return This->pHandlers->pNewSegment( This, rtStart, rtStop, rate );
}



/***************************************************************************
 *
 *	handlers for output pins.
 *
 */

HRESULT OutputPinSync_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
{
	if ( pImpl->pMemInputPinConnectedTo == NULL )
		return NOERROR;

	return IMemInputPin_Receive(pImpl->pMemInputPinConnectedTo,pSample);
}

HRESULT OutputPinSync_ReceiveCanBlock( CPinBaseImpl* pImpl )
{
	if ( pImpl->pMemInputPinConnectedTo == NULL )
		return S_FALSE;

	return IMemInputPin_ReceiveCanBlock(pImpl->pMemInputPinConnectedTo);
}

HRESULT OutputPinSync_EndOfStream( CPinBaseImpl* pImpl )
{
	if ( pImpl->pPinConnectedTo == NULL )
		return NOERROR;

	return IPin_EndOfStream(pImpl->pPinConnectedTo);
}

HRESULT OutputPinSync_BeginFlush( CPinBaseImpl* pImpl )
{
	if ( pImpl->pPinConnectedTo == NULL )
		return NOERROR;

	return IPin_BeginFlush(pImpl->pPinConnectedTo);
}

HRESULT OutputPinSync_EndFlush( CPinBaseImpl* pImpl )
{
	if ( pImpl->pPinConnectedTo == NULL )
		return NOERROR;

	return IPin_EndFlush(pImpl->pPinConnectedTo);
}

HRESULT OutputPinSync_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
{
	if ( pImpl->pPinConnectedTo == NULL )
		return NOERROR;

	return IPin_NewSegment(pImpl->pPinConnectedTo,rtStart,rtStop,rate);
}

/***************************************************************************
 *
 *	handlers for output pins (async).
 *
 */

typedef struct OutputPinTask OutputPinTask;

enum OutputPinTaskType
{
	OutTask_ExitThread,
	OutTask_Receive,
	OutTask_EndOfStream,
	OutTask_BeginFlush,
	OutTask_EndFlush,
	OutTask_NewSegment,
};

struct OutputPinTask
{
	OutputPinTask* pNext;
	enum OutputPinTaskType tasktype;
	IMediaSample* pSample;
	REFERENCE_TIME rtStart;
	REFERENCE_TIME rtStop;
	double rate;
};

struct OutputPinAsyncImpl
{
	HANDLE m_hTaskThread;
	HANDLE m_hTaskEvent;
	IPin* m_pPin; /* connected pin */
	IMemInputPin* m_pMemInputPin; /* connected pin */
	CRITICAL_SECTION m_csTasks;
	OutputPinTask* m_pFirst;
	OutputPinTask* m_pLast;
	OutputPinTask* m_pTaskExitThread;
};

static OutputPinTask* OutputPinAsync_AllocTask( enum OutputPinTaskType tasktype )
{
	OutputPinTask* pTask;

	pTask = (OutputPinTask*)QUARTZ_AllocMem( sizeof(OutputPinTask) );
	pTask->pNext = NULL;
	pTask->tasktype = tasktype;
	pTask->pSample = NULL;

	return pTask;
}

static void OutputPinAsync_FreeTask( OutputPinTask* pTask )
{
	if ( pTask->pSample != NULL )
		IMediaSample_Release( pTask->pSample );
	QUARTZ_FreeMem( pTask );
}

static void OutputPinAsync_AddTask( OutputPinAsyncImpl* This, OutputPinTask* pTask, BOOL bFirst )
{
	EnterCriticalSection( &This->m_csTasks );

	if ( bFirst )
	{
		pTask->pNext = This->m_pFirst;
		This->m_pFirst = pTask;
		if ( This->m_pLast == NULL )
			This->m_pLast = pTask;
	}
	else
	{
		if ( This->m_pLast != NULL )
			This->m_pLast->pNext = pTask;
		else
			This->m_pFirst = pTask;
		This->m_pLast = pTask;
	}

	LeaveCriticalSection( &This->m_csTasks );

	SetEvent( This->m_hTaskEvent );
}

static OutputPinTask* OutputPinAsync_GetNextTask( OutputPinAsyncImpl* This )
{
	OutputPinTask* pTask;

	EnterCriticalSection( &This->m_csTasks );
	pTask = This->m_pFirst;
	if ( pTask != NULL )
	{
		This->m_pFirst = pTask->pNext;
		if ( This->m_pFirst == NULL )
			This->m_pLast = NULL;
		else
			SetEvent( This->m_hTaskEvent );
	}

	LeaveCriticalSection( &This->m_csTasks );

	return pTask;
}

static DWORD WINAPI OutputPinAsync_ThreadEntry( LPVOID pv )
{
	OutputPinAsyncImpl* This = ((CPinBaseImpl*)pv)->pAsyncOut;
	OutputPinTask* pTask;
	BOOL bLoop = TRUE;
	BOOL bInFlush = FALSE;
	HRESULT hr;

	while ( bLoop )
	{
		WaitForSingleObject( This->m_hTaskEvent, INFINITE );
		ResetEvent( This->m_hTaskEvent );

		pTask = OutputPinAsync_GetNextTask( This );
		if ( pTask == NULL )
			continue;

		hr = S_OK;
		switch ( pTask->tasktype )
		{
		case OutTask_ExitThread:
			bLoop = FALSE;
			break;
		case OutTask_Receive:
			if ( !bInFlush )
				hr = IMemInputPin_Receive( This->m_pMemInputPin, pTask->pSample );
			break;
		case OutTask_EndOfStream:
			hr = IPin_EndOfStream( This->m_pPin );
			break;
		case OutTask_BeginFlush:
			bInFlush = TRUE;
			hr = IPin_BeginFlush( This->m_pPin );
			break;
		case OutTask_EndFlush:
			bInFlush = FALSE;
			hr = IPin_EndFlush( This->m_pPin );
			break;
		case OutTask_NewSegment:
			hr = IPin_NewSegment( This->m_pPin, pTask->rtStart, pTask->rtStop, pTask->rate );
			break;
		default:
			ERR( "unexpected task type %d.\n", pTask->tasktype );
			bLoop = FALSE;
			break;
		}

		OutputPinAsync_FreeTask( pTask );

		if ( FAILED(hr) )
		{
			ERR( "hresult %08lx\n", hr );
			bLoop = FALSE;
		}
	}

	return 0;
}

HRESULT OutputPinAsync_OnActive( CPinBaseImpl* pImpl )
{
	HRESULT hr;
	DWORD dwThreadId;

	FIXME("(%p)\n",pImpl);

	if ( pImpl->pMemInputPinConnectedTo == NULL )
		return NOERROR;

	pImpl->pAsyncOut = (OutputPinAsyncImpl*)
		QUARTZ_AllocMem( sizeof( OutputPinAsyncImpl ) );
	if ( pImpl->pAsyncOut == NULL )
		return E_OUTOFMEMORY;

	InitializeCriticalSection( &pImpl->pAsyncOut->m_csTasks );
	pImpl->pAsyncOut->m_hTaskThread = (HANDLE)NULL;
	pImpl->pAsyncOut->m_hTaskEvent = (HANDLE)NULL;
	pImpl->pAsyncOut->m_pFirst = NULL;
	pImpl->pAsyncOut->m_pLast = NULL;
	pImpl->pAsyncOut->m_pTaskExitThread = NULL;
	pImpl->pAsyncOut->m_pPin = pImpl->pPinConnectedTo;
	pImpl->pAsyncOut->m_pMemInputPin = pImpl->pMemInputPinConnectedTo;

	pImpl->pAsyncOut->m_hTaskEvent =
		CreateEventA( NULL, TRUE, FALSE, NULL );
	if ( pImpl->pAsyncOut->m_hTaskEvent == (HANDLE)NULL )
	{
		hr = E_FAIL;
		goto err;
	}

	pImpl->pAsyncOut->m_pTaskExitThread =
		OutputPinAsync_AllocTask( OutTask_ExitThread );
	if ( pImpl->pAsyncOut->m_pTaskExitThread == NULL )
	{
		hr = E_OUTOFMEMORY;
		goto err;
	}

	pImpl->pAsyncOut->m_hTaskThread = CreateThread(
		NULL, 0, OutputPinAsync_ThreadEntry, pImpl,
		0, &dwThreadId );
	if ( pImpl->pAsyncOut->m_hTaskThread == (HANDLE)NULL )
	{
		hr = E_FAIL;
		goto err;
	}

	return NOERROR;
err:
	OutputPinAsync_OnInactive( pImpl );
	return hr;
}

HRESULT OutputPinAsync_OnInactive( CPinBaseImpl* pImpl )
{
	OutputPinTask* pTask;

	FIXME("(%p)\n",pImpl);

	if ( pImpl->pAsyncOut == NULL )
		return NOERROR;

	if ( pImpl->pAsyncOut->m_pTaskExitThread != NULL )
	{
		OutputPinAsync_AddTask( pImpl->pAsyncOut, pImpl->pAsyncOut->m_pTaskExitThread, TRUE );
		pImpl->pAsyncOut->m_pTaskExitThread = NULL;
	}

	if ( pImpl->pAsyncOut->m_hTaskThread != (HANDLE)NULL )
	{
		WaitForSingleObject( pImpl->pAsyncOut->m_hTaskThread, INFINITE );
		CloseHandle( pImpl->pAsyncOut->m_hTaskThread );
	}
	if ( pImpl->pAsyncOut->m_hTaskEvent != (HANDLE)NULL )
		CloseHandle( pImpl->pAsyncOut->m_hTaskEvent );

	/* release all tasks. */
	while ( 1 )
	{
		pTask = OutputPinAsync_GetNextTask( pImpl->pAsyncOut );
		if ( pTask == NULL )
			break;
		OutputPinAsync_FreeTask( pTask );
	}

	DeleteCriticalSection( &pImpl->pAsyncOut->m_csTasks );

	QUARTZ_FreeMem( pImpl->pAsyncOut );
	pImpl->pAsyncOut = NULL;

	return NOERROR;
}

HRESULT OutputPinAsync_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
{
	OutputPinAsyncImpl* This = pImpl->pAsyncOut;
	OutputPinTask* pTask;

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

	if ( This == NULL )
		return NOERROR;

	pTask = OutputPinAsync_AllocTask( OutTask_Receive );
	if ( pTask == NULL )
		return E_OUTOFMEMORY;
	pTask->pSample = pSample; IMediaSample_AddRef( pSample );
	OutputPinAsync_AddTask( pImpl->pAsyncOut, pTask, FALSE );

	return NOERROR;
}

HRESULT OutputPinAsync_ReceiveCanBlock( CPinBaseImpl* pImpl )
{
	return S_FALSE;
}

HRESULT OutputPinAsync_EndOfStream( CPinBaseImpl* pImpl )
{
	OutputPinAsyncImpl* This = pImpl->pAsyncOut;
	OutputPinTask* pTask;

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

	if ( This == NULL )
		return NOERROR;

	pTask = OutputPinAsync_AllocTask( OutTask_EndOfStream );
	if ( pTask == NULL )
		return E_OUTOFMEMORY;
	OutputPinAsync_AddTask( pImpl->pAsyncOut, pTask, FALSE );

	return NOERROR;
}

HRESULT OutputPinAsync_BeginFlush( CPinBaseImpl* pImpl )
{
	OutputPinAsyncImpl* This = pImpl->pAsyncOut;
	OutputPinTask* pTask;

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

	if ( This == NULL )
		return NOERROR;

	pTask = OutputPinAsync_AllocTask( OutTask_BeginFlush );
	if ( pTask == NULL )
		return E_OUTOFMEMORY;
	OutputPinAsync_AddTask( pImpl->pAsyncOut, pTask, TRUE );

	return NOERROR;
}

HRESULT OutputPinAsync_EndFlush( CPinBaseImpl* pImpl )
{
	OutputPinAsyncImpl* This = pImpl->pAsyncOut;
	OutputPinTask* pTask;

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

	if ( This == NULL )
		return NOERROR;

	pTask = OutputPinAsync_AllocTask( OutTask_EndFlush );
	if ( pTask == NULL )
		return E_OUTOFMEMORY;
	OutputPinAsync_AddTask( pImpl->pAsyncOut, pTask, FALSE );

	return NOERROR;
}

HRESULT OutputPinAsync_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
{
	OutputPinAsyncImpl* This = pImpl->pAsyncOut;
	OutputPinTask* pTask;

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

	if ( This == NULL )
		return NOERROR;

	pTask = OutputPinAsync_AllocTask( OutTask_NewSegment );
	if ( pTask == NULL )
		return E_OUTOFMEMORY;
	pTask->rtStart = rtStart;
	pTask->rtStop = rtStop;
	pTask->rate = rate;
	OutputPinAsync_AddTask( pImpl->pAsyncOut, pTask, FALSE );

	return NOERROR;
}


