Commit 17bee2ef authored by Hidenori Takeshima's avatar Hidenori Takeshima Committed by Alexandre Julliard

Fixed some bugs.

Implemented AVI Decompressor. Started implementing Color Space Converter. Started implementing seeking.
parent f5a8b965
......@@ -566,8 +566,8 @@ psapi/libpsapi.$(LIBEXT): dummy libkernel32.$(LIBEXT) libntdll.$(LIBEXT)
@cd psapi && $(MAKE) libpsapi.$(LIBEXT)
quartz/libquartz.$(LIBEXT): dummy liboleaut32.$(LIBEXT) libole32.$(LIBEXT) \
libwinmm.$(LIBEXT) libuser32.$(LIBEXT) libgdi32.$(LIBEXT) libadvapi32.$(LIBEXT) \
libkernel32.$(LIBEXT) libntdll.$(LIBEXT)
libmsvfw32.$(LIBEXT) libwinmm.$(LIBEXT) libuser32.$(LIBEXT) libgdi32.$(LIBEXT) \
libadvapi32.$(LIBEXT) libkernel32.$(LIBEXT) libntdll.$(LIBEXT)
@cd quartz && $(MAKE) libquartz.$(LIBEXT)
rasapi32/librasapi32.$(LIBEXT): dummy libkernel32.$(LIBEXT) libntdll.$(LIBEXT)
......
......@@ -13,10 +13,12 @@ C_SRCS = \
asyncsrc.c \
audioutl.c \
audren.c \
avidec.c \
aviparse.c \
basefilt.c \
basepin.c \
complist.c \
csconv.c \
devenum.c \
devmon.c \
enumunk.c \
......@@ -38,8 +40,10 @@ C_SRCS = \
sample.c \
seekpass.c \
sysclock.c \
videoblt.c \
vidren.c \
wavparse.c
wavparse.c \
xform.c
@MAKE_DLL_RULES@
......
......@@ -142,10 +142,13 @@ void CAsyncReaderImpl_PostReply( CAsyncReaderImpl* This, AsyncSourceRequest* pRe
}
static
void CAsyncReaderImpl_ReleaseReqList( CAsyncReaderImpl* This, AsyncSourceRequest* pReq, BOOL bReleaseMem )
void CAsyncReaderImpl_ReleaseReqList( CAsyncReaderImpl* This, AsyncSourceRequest** ppReq, BOOL bReleaseMem )
{
AsyncSourceRequest* pReq;
AsyncSourceRequest* pReqNext;
TRACE("(%p,%p,%d)\n",This,*ppReq,bReleaseMem);
pReq = *ppReq; *ppReq = NULL;
while ( pReq != NULL )
{
pReqNext = pReq->pNext;
......@@ -544,7 +547,7 @@ CAsyncReaderImpl_fnBeginFlush(IAsyncReader* iface)
EnterCriticalSection( &This->m_csRequest );
This->m_bInFlushing = TRUE;
SetEvent( This->m_hEventCancel );
CAsyncReaderImpl_ReleaseReqList(This,This->m_pRequestFirst,FALSE);
CAsyncReaderImpl_ReleaseReqList(This,&This->m_pRequestFirst,FALSE);
LeaveCriticalSection( &This->m_csRequest );
return NOERROR;
......@@ -622,16 +625,18 @@ HRESULT CAsyncReaderImpl_InitIAsyncReader(
void CAsyncReaderImpl_UninitIAsyncReader(
CAsyncReaderImpl* This )
{
TRACE("(%p)\n",This);
TRACE("(%p) enter\n",This);
CAsyncReaderImpl_ReleaseReqList(This,This->m_pRequestFirst,TRUE);
CAsyncReaderImpl_ReleaseReqList(This,This->m_pReplyFirst,TRUE);
CAsyncReaderImpl_ReleaseReqList(This,This->m_pFreeFirst,TRUE);
CAsyncReaderImpl_ReleaseReqList(This,&This->m_pRequestFirst,TRUE);
CAsyncReaderImpl_ReleaseReqList(This,&This->m_pReplyFirst,TRUE);
CAsyncReaderImpl_ReleaseReqList(This,&This->m_pFreeFirst,TRUE);
DeleteCriticalSection( &This->m_csReader );
DeleteCriticalSection( &This->m_csRequest );
DeleteCriticalSection( &This->m_csReply );
DeleteCriticalSection( &This->m_csFree );
TRACE("(%p) leave\n",This);
}
/***************************************************************************
......
......@@ -134,7 +134,7 @@ HRESULT QUARTZ_CreateAsyncSourcePin(
HRESULT QUARTZ_CreateAsyncReader(IUnknown* punkOuter,void** ppobj);
HRESULT QUARTZ_CreateURLReader(IUnknown* punkOuter,void** ppobj);
#define ASYNCSRC_FILE_BLOCKSIZE 4096
#define ASYNCSRC_FILE_BLOCKSIZE 16384
#endif /* WINE_DSHOW_ASYNCSRC_H */
......@@ -27,6 +27,7 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "audren.h"
#include "seekpass.h"
static const WCHAR QUARTZ_AudioRender_Name[] =
......@@ -132,7 +133,7 @@ HRESULT CAudioRendererImpl_waveOutInit(
DWORD dwBlockSize;
if ( This->m_fWaveOutInit )
return E_UNEXPECTED;
return NOERROR;
if ( pwfx == NULL )
return E_POINTER;
......@@ -194,6 +195,24 @@ err:
return hr;
}
static HRESULT CAudioRendererImpl_waveOutPause( CAudioRendererImpl* This )
{
if ( !This->m_fWaveOutInit )
return E_UNEXPECTED;
return QUARTZ_HRESULT_From_MMRESULT( waveOutPause(
This->m_hWaveOut ) );
}
static HRESULT CAudioRendererImpl_waveOutRun( CAudioRendererImpl* This )
{
if ( !This->m_fWaveOutInit )
return E_UNEXPECTED;
return QUARTZ_HRESULT_From_MMRESULT( waveOutRestart(
This->m_hWaveOut ) );
}
static
WAVEHDR* CAudioRendererImpl_waveOutGetBuffer(
CAudioRendererImpl* This )
......@@ -329,7 +348,29 @@ HRESULT CAudioRendererImpl_waveOutSetVolume(
static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
{
CAudioRendererImpl_THIS(pImpl,basefilter);
HRESULT hr;
FIXME( "(%p)\n", This );
if ( This->pPin->pin.pmtConn == NULL )
return NOERROR;
This->m_fInFlush = FALSE;
/* FIXME - don't work correctly.
hr = CAudioRendererImpl_waveOutRun(This);
if ( FAILED(hr) )
return hr;
*/
return NOERROR;
}
static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
{
CAudioRendererImpl_THIS(pImpl,basefilter);
WAVEFORMATEX* pwfx;
HRESULT hr;
FIXME( "(%p)\n", This );
......@@ -342,10 +383,20 @@ static HRESULT CAudioRendererImpl_OnActive( CBaseFilterImpl* pImpl )
This->m_fInFlush = FALSE;
return CAudioRendererImpl_waveOutInit(This,pwfx);
hr = CAudioRendererImpl_waveOutInit(This,pwfx);
if ( FAILED(hr) )
return hr;
/* FIXME - may cause deadlock.
hr = CAudioRendererImpl_waveOutPause(This);
if ( FAILED(hr) )
return hr;
*/
return NOERROR;
}
static HRESULT CAudioRendererImpl_OnInactive( CBaseFilterImpl* pImpl )
static HRESULT CAudioRendererImpl_OnStop( CBaseFilterImpl* pImpl )
{
CAudioRendererImpl_THIS(pImpl,basefilter);
......@@ -364,7 +415,7 @@ static const CBaseFilterHandlers filterhandlers =
{
CAudioRendererImpl_OnActive, /* pOnActive */
CAudioRendererImpl_OnInactive, /* pOnInactive */
NULL, /* pOnStop */
CAudioRendererImpl_OnStop, /* pOnStop */
};
/***************************************************************************
......@@ -373,6 +424,23 @@ static const CBaseFilterHandlers filterhandlers =
*
*/
static HRESULT CAudioRendererPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
{
CAudioRendererPinImpl_THIS(pImpl,pin);
TRACE("(%p)\n",This);
if ( This->meminput.pAllocator != NULL )
{
IMemAllocator_Decommit(This->meminput.pAllocator);
IMemAllocator_Release(This->meminput.pAllocator);
This->meminput.pAllocator = NULL;
}
return NOERROR;
}
static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
{
CAudioRendererPinImpl_THIS(pImpl,pin);
......@@ -381,11 +449,24 @@ static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const
TRACE("(%p,%p)\n",This,pmt);
if ( !IsEqualGUID( &pmt->majortype, &MEDIATYPE_Audio ) )
{
TRACE("not audio\n");
return E_FAIL;
if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
}
if ( !IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_NULL ) &&
!IsEqualGUID( &pmt->subtype, &MEDIASUBTYPE_PCM ) )
{
TRACE("not PCM\n");
return E_FAIL;
}
if ( !IsEqualGUID( &pmt->formattype, &FORMAT_WaveFormatEx ) )
{
TRACE("not WAVE\n");
return E_FAIL;
}
TRACE("testing WAVE header\n");
if ( pmt->cbFormat < (sizeof(WAVEFORMATEX)-sizeof(WORD)) )
return E_FAIL;
......@@ -395,6 +476,8 @@ static HRESULT CAudioRendererPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const
if ( pwfx->wFormatTag != 1 )
return E_FAIL;
TRACE("returned successfully.\n");
return NOERROR;
}
......@@ -508,7 +591,7 @@ static const CBasePinHandlers pinhandlers =
{
NULL, /* pOnPreConnect */
NULL, /* pOnPostConnect */
NULL, /* pOnDisconnect */
CAudioRendererPinImpl_OnDisconnect, /* pOnDisconnect */
CAudioRendererPinImpl_CheckMediaType, /* pCheckMediaType */
NULL, /* pQualityNotify */
CAudioRendererPinImpl_Receive, /* pReceive */
......@@ -535,6 +618,24 @@ static QUARTZ_IFEntry FilterIFEntries[] =
{ &IID_IBasicAudio, offsetof(CAudioRendererImpl,basaud)-offsetof(CAudioRendererImpl,unk) },
};
static HRESULT CAudioRendererImpl_OnQueryInterface(
IUnknown* punk, const IID* piid, void** ppobj )
{
CAudioRendererImpl_THIS(punk,unk);
if ( This->pSeekPass == NULL )
return E_NOINTERFACE;
if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
IsEqualGUID( &IID_IMediaSeeking, piid ) )
{
TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
}
return E_NOINTERFACE;
}
static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
{
CAudioRendererImpl_THIS(punk,unk);
......@@ -546,6 +647,11 @@ static void QUARTZ_DestroyAudioRenderer(IUnknown* punk)
IUnknown_Release(This->pPin->unk.punkControl);
This->pPin = NULL;
}
if ( This->pSeekPass != NULL )
{
IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
This->pSeekPass = NULL;
}
CAudioRendererImpl_UninitIBasicAudio(This);
CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
......@@ -562,12 +668,16 @@ HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
QUARTZ_AllocObj( sizeof(CAudioRendererImpl) );
if ( This == NULL )
return E_OUTOFMEMORY;
This->pSeekPass = NULL;
This->pPin = NULL;
This->m_fInFlush = FALSE;
This->m_fWaveOutInit = FALSE;
This->m_hEventRender = (HANDLE)NULL;
QUARTZ_IUnkInit( &This->unk, punkOuter );
This->qiext.pNext = NULL;
This->qiext.pOnQueryInterface = &CAudioRendererImpl_OnQueryInterface;
QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );
hr = CBaseFilterImpl_InitIBaseFilter(
&This->basefilter,
......@@ -603,6 +713,11 @@ HRESULT QUARTZ_CreateAudioRenderer(IUnknown* punkOuter,void** ppobj)
This->basefilter.pInPins,
(IUnknown*)&This->pPin->pin,
NULL, 0 );
if ( SUCCEEDED(hr) )
hr = QUARTZ_CreateSeekingPassThruInternal(
(IUnknown*)&(This->unk), &This->pSeekPass,
TRUE, (IPin*)&(This->pPin->pin) );
if ( FAILED(hr) )
{
IUnknown_Release( This->unk.punkControl );
......
......@@ -12,6 +12,7 @@
#include "iunk.h"
#include "basefilt.h"
#include "seekpass.h"
#define WINE_QUARTZ_WAVEOUT_COUNT 4
......@@ -29,7 +30,9 @@ struct CAudioRendererImpl
QUARTZ_IUnkImpl unk;
CBaseFilterImpl basefilter;
AudRen_IBasicAudioImpl basaud;
QUARTZ_IFDelegation qiext;
CSeekingPassThru* pSeekPass;
CAudioRendererPinImpl* pPin;
BOOL m_fInFlush;
......
......@@ -14,6 +14,7 @@
#include "vfw.h"
#include "winerror.h"
#include "strmif.h"
#include "control.h"
#include "vfwmsgs.h"
#include "amvideo.h"
#include "uuids.h"
......@@ -385,10 +386,9 @@ static HRESULT CAVIParseImpl_GetStreamType( CParserImpl* pImpl, ULONG nStreamInd
if ( hr != S_OK )
QUARTZ_MediaSubType_FromFourCC( &pmt->subtype, (DWORD)pbi->biCompression );
pmt->bFixedSizeSamples = ( pbi->biCompression == 0 || pbi->biCompression == 3 ) ? 1 : 0;
pmt->bTemporalCompression = 0;
pmt->lSampleSize = ( pbi->biCompression == 0 || pbi->biCompression == 3 ) ?
DIBSIZE(*pbi) : pbi->biSize;
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;
......@@ -545,6 +545,7 @@ static HRESULT CAVIParseImpl_GetAllocProp( CParserImpl* pImpl, ALLOCATOR_PROPERT
{
CAVIParseImpl* This = (CAVIParseImpl*)pImpl->m_pUserData;
TRACE("(%p,%p)\n",This,pReqProp);
if ( This == NULL )
return E_UNEXPECTED;
......
......@@ -85,6 +85,7 @@ CBaseFilterImpl_fnStop(IBaseFilter* iface)
hr = NOERROR;
EnterCriticalSection( &This->csFilter );
TRACE("(%p) state = %d\n",This,This->fstate);
if ( This->fstate == State_Running )
{
......@@ -117,6 +118,8 @@ CBaseFilterImpl_fnPause(IBaseFilter* iface)
hr = NOERROR;
EnterCriticalSection( &This->csFilter );
TRACE("(%p) state = %d\n",This,This->fstate);
if ( This->fstate != State_Paused )
{
if ( This->pHandlers->pOnInactive != NULL )
......@@ -142,6 +145,7 @@ CBaseFilterImpl_fnRun(IBaseFilter* iface,REFERENCE_TIME rtStart)
hr = NOERROR;
EnterCriticalSection( &This->csFilter );
TRACE("(%p) state = %d\n",This,This->fstate);
This->rtStart = rtStart;
......@@ -178,7 +182,7 @@ CBaseFilterImpl_fnGetState(IBaseFilter* iface,DWORD dw,FILTER_STATE* pState)
/* FIXME - ignore 'intermediate state' now */
EnterCriticalSection( &This->csFilter );
TRACE("state %d\n",This->fstate);
TRACE("(%p) state = %d\n",This,This->fstate);
*pState = This->fstate;
LeaveCriticalSection( &This->csFilter );
......
......@@ -159,6 +159,7 @@ void CQualityControlPassThruImpl_UninitIQualityControl(
HRESULT CPinBaseImpl_SendSample( CPinBaseImpl* This, IMediaSample* pSample );
HRESULT CPinBaseImpl_SendReceiveCanBlock( CPinBaseImpl* This );
HRESULT CPinBaseImpl_SendEndOfStream( CPinBaseImpl* This );
HRESULT CPinBaseImpl_SendBeginFlush( CPinBaseImpl* This );
HRESULT CPinBaseImpl_SendEndFlush( CPinBaseImpl* This );
......
......@@ -64,11 +64,15 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
ICOM_THIS(CPinBaseImpl,iface);
HRESULT hr = E_NOTIMPL;
ULONG i;
FILTER_STATE fs;
FIXME("(%p)->(%p,%p)\n",This,pPin,pmt);
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;
......@@ -82,13 +86,23 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
goto err;
}
/* FIXME - return fail if running */
/* 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 )
......@@ -109,6 +123,7 @@ CPinBaseImpl_fnConnect(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt)
if ( SUCCEEDED(hr) )
{
hr = IPin_ReceiveConnection(pPin,iface,pmt);
TRACE("ReceiveConnection - %08lx\n",hr);
if ( SUCCEEDED(hr) )
{
goto connected;
......@@ -133,6 +148,7 @@ connected:;
hr = IPin_QueryInterface(pPin,&IID_IMemInputPin,(void**)&This->pMemInputPinConnectedTo);
if ( FAILED(hr) )
{
TRACE("no IMemInputPin\n");
IPin_Disconnect(pPin);
goto err;
}
......@@ -142,6 +158,7 @@ connected:;
hr = This->pHandlers->pOnPostConnect(This,pPin);
if ( FAILED(hr) )
{
TRACE("OnPostConnect() failed hr = %08lx\n",hr);
IPin_Disconnect(pPin);
goto err;
}
......@@ -156,6 +173,8 @@ err:
}
LeaveCriticalSection( This->pcsPin );
TRACE("return %08lx\n",hr);
return hr;
}
......@@ -164,11 +183,15 @@ CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt
{
ICOM_THIS(CPinBaseImpl,iface);
HRESULT hr = E_NOTIMPL;
FILTER_STATE fs;
FIXME("(%p)->(%p,%p)\n",This,pPin,pmt);
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;
......@@ -180,13 +203,23 @@ CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt
goto err;
}
/* FIXME - return fail if running */
/* 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);
......@@ -204,7 +237,10 @@ CPinBaseImpl_fnReceiveConnection(IPin* iface,IPin* pPin,const AM_MEDIA_TYPE* pmt
{
hr = This->pHandlers->pOnPostConnect(This,pPin);
if ( FAILED(hr) )
{
TRACE("OnPostConnect() failed hr = %08lx\n",hr);
goto err;
}
}
hr = S_OK;
......@@ -223,12 +259,20 @@ CPinBaseImpl_fnDisconnect(IPin* iface)
{
ICOM_THIS(CPinBaseImpl,iface);
HRESULT hr = NOERROR;
FILTER_STATE fs;
FIXME("(%p)->() stub!\n",This);
TRACE("(%p)->()\n",This);
EnterCriticalSection( This->pcsPin );
/* FIXME - return fail if running */
/* 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);
......@@ -256,6 +300,7 @@ CPinBaseImpl_fnDisconnect(IPin* iface)
hr = S_FALSE; /* FIXME - is this correct??? */
}
err:
LeaveCriticalSection( This->pcsPin );
return hr;
......@@ -741,8 +786,6 @@ CMemInputPinBaseImpl_fnReceiveMultiple(IMemInputPin* iface,IMediaSample** ppSamp
if ( ppSample == NULL || pnSampleProcessed == NULL )
return E_POINTER;
EnterCriticalSection( This->pPin->pcsPin );
hr = NOERROR;
for ( n = 0; n < nSample; n++ )
{
......@@ -751,8 +794,6 @@ CMemInputPinBaseImpl_fnReceiveMultiple(IMemInputPin* iface,IMediaSample** ppSamp
break;
}
LeaveCriticalSection( This->pPin->pcsPin );
*pnSampleProcessed = n;
return hr;
}
......@@ -941,6 +982,14 @@ HRESULT CPinBaseImpl_SendSample( CPinBaseImpl* This, IMediaSample* pSample )
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 )
......
/*
* Implementation of IBasicAudio, IBasicVideo2, IVideoWindow for FilterGraph.
*
* FIXME - stub.
*
* hidenori@a2.ctktv.ne.jp
*/
......@@ -24,33 +22,53 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "fgraph.h"
static HRESULT CFilterGraph_QIFilters(
CFilterGraph* This, REFIID riid, void** ppvobj )
{
QUARTZ_CompListItem* pItem;
HRESULT hr = E_NOINTERFACE;
TRACE( "(%p,%p,%p)\n",This,riid,ppvobj);
QUARTZ_CompList_Lock( This->m_pFilterList );
pItem = QUARTZ_CompList_GetLast( This->m_pFilterList );
while ( pItem != NULL )
{
if ( IUnknown_QueryInterface( QUARTZ_CompList_GetItemPtr(pItem),riid,ppvobj) == S_OK )
{
hr = S_OK;
break;
}
pItem = QUARTZ_CompList_GetPrev( This->m_pFilterList, pItem );
}
QUARTZ_CompList_Unlock( This->m_pFilterList );
return hr;
}
static HRESULT CFilterGraph_QueryBasicAudio(
CFilterGraph* This, IBasicAudio** ppAudio )
{
FIXME("(%p,%p) stub!\n",This,ppAudio);
return E_NOTIMPL;
return CFilterGraph_QIFilters(This,&IID_IBasicAudio,(void**)ppAudio);
}
static HRESULT CFilterGraph_QueryBasicVideo(
CFilterGraph* This, IBasicVideo** ppVideo )
{
FIXME("(%p,%p) stub!\n",This,ppVideo);
return E_NOTIMPL;
return CFilterGraph_QIFilters(This,&IID_IBasicVideo,(void**)ppVideo);
}
static HRESULT CFilterGraph_QueryBasicVideo2(
CFilterGraph* This, IBasicVideo2** ppVideo )
{
FIXME("(%p,%p) stub!\n",This,ppVideo);
return E_NOTIMPL;
return CFilterGraph_QIFilters(This,&IID_IBasicVideo2,(void**)ppVideo);
}
static HRESULT CFilterGraph_QueryVideoWindow(
CFilterGraph* This, IVideoWindow** ppVidWin )
{
FIXME("(%p,%p) stub!\n",This,ppVidWin);
return E_NOTIMPL;
return CFilterGraph_QIFilters(This,&IID_IVideoWindow,(void**)ppVidWin);
}
......
......@@ -40,6 +40,7 @@ HRESULT CFilterGraph_PollGraphState(
IBaseFilter* pFilter;
hr = S_OK;
*pState = State_Stopped;
EnterCriticalSection( &This->m_csGraphState );
QUARTZ_CompList_Lock( This->m_pFilterList );
......
......@@ -35,6 +35,8 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "vidren.h"
#include "parser.h"
#include "asyncsrc.h"
#include "xform.h"
typedef struct QUARTZ_CLASSENTRY
{
......@@ -84,6 +86,8 @@ static const QUARTZ_CLASSENTRY QUARTZ_ClassList[] =
{ &CLSID_AviSplitter, &QUARTZ_CreateAVISplitter },
{ &CLSID_AsyncReader, &QUARTZ_CreateAsyncReader },
{ &CLSID_URLReader, &QUARTZ_CreateURLReader },
{ &CLSID_AVIDec, &QUARTZ_CreateAVIDec },
{ &CLSID_Colour, &QUARTZ_CreateColour },
{ NULL, NULL },
};
......
......@@ -13,6 +13,7 @@
#include "winerror.h"
#include "strmif.h"
#include "uuids.h"
#include "vfwmsgs.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
......@@ -75,6 +76,91 @@ HRESULT QUARTZ_CreateMemoryAllocator(IUnknown* punkOuter,void** ppobj)
*
*/
static HRESULT
IMemAllocator_LockUnusedBuffer(CMemoryAllocator* This,IMediaSample** ppSample)
{
HRESULT hr = E_FAIL;
LONG i;
TRACE("(%p) try to enter critical section\n",This);
EnterCriticalSection( &This->csMem );
TRACE("(%p) enter critical section\n",This);
if ( This->pData == NULL || This->ppSamples == NULL ||
This->prop.cBuffers <= 0 )
{
hr = VFW_E_NOT_COMMITTED;
goto end;
}
for ( i = 0; i < This->prop.cBuffers; i++ )
{
if ( This->ppSamples[i] == NULL )
{
hr = VFW_E_NOT_COMMITTED;
goto end;
}
if ( This->ppSamples[i]->ref == 0 )
{
*ppSample = (IMediaSample*)(This->ppSamples[i]);
IMediaSample_AddRef( *ppSample );
hr = NOERROR;
goto end;
}
}
hr = VFW_E_TIMEOUT;
end:
LeaveCriticalSection( &This->csMem );
TRACE("(%p) leave critical section\n",This);
return hr;
}
/* TRUE = all samples are released */
static BOOL
IMemAllocator_ReleaseUnusedBuffer(CMemoryAllocator* This)
{
LONG i;
BOOL bRet = TRUE;
TRACE("(%p) try to enter critical section\n",This);
EnterCriticalSection( &This->csMem );
TRACE("(%p) enter critical section\n",This);
if ( This->pData == NULL || This->ppSamples == NULL ||
This->prop.cBuffers <= 0 )
goto end;
for ( i = 0; i < This->prop.cBuffers; i++ )
{
if ( This->ppSamples[i]->ref == 0 )
{
QUARTZ_DestroyMemMediaSample( This->ppSamples[i] );
This->ppSamples[i] = NULL;
}
else
{
bRet = FALSE;
}
}
if ( bRet )
{
QUARTZ_FreeMem(This->ppSamples);
This->ppSamples = NULL;
QUARTZ_FreeMem(This->pData);
This->pData = NULL;
}
end:
LeaveCriticalSection( &This->csMem );
TRACE("(%p) leave critical section\n",This);
return bRet;
}
static HRESULT WINAPI
IMemAllocator_fnQueryInterface(IMemAllocator* iface,REFIID riid,void** ppobj)
......@@ -121,10 +207,17 @@ IMemAllocator_fnSetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pPropRe
pPropReq->cbBuffer < 0 ||
pPropReq->cbAlign < 0 ||
pPropReq->cbPrefix < 0 )
{
TRACE("pPropReq is invalid\n");
return E_INVALIDARG;
}
if ( ( pPropReq->cbAlign & (pPropReq->cbAlign-1) ) != 0 )
return E_INVALIDARG;
if ( pPropReq->cbAlign == 0 ||
( pPropReq->cbAlign & (pPropReq->cbAlign-1) ) != 0 )
{
WARN("cbAlign is invalid - %ld\n",pPropReq->cbAlign);
return VFW_E_BADALIGN;
}
hr = NOERROR;
......@@ -133,6 +226,7 @@ IMemAllocator_fnSetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pPropRe
if ( This->pData != NULL || This->ppSamples != NULL )
{
/* if commited, properties must not be changed. */
TRACE("already commited\n");
hr = E_UNEXPECTED;
goto end;
}
......@@ -154,6 +248,8 @@ IMemAllocator_fnSetProperties(IMemAllocator* iface,ALLOCATOR_PROPERTIES* pPropRe
end:
LeaveCriticalSection( &This->csMem );
TRACE("returned successfully.\n");
return hr;
}
......@@ -190,6 +286,7 @@ IMemAllocator_fnCommit(IMemAllocator* iface)
EnterCriticalSection( &This->csMem );
hr = NOERROR;
/* FIXME - handle in Decommitting */
if ( This->pData != NULL || This->ppSamples != NULL ||
This->prop.cBuffers <= 0 )
goto end;
......@@ -244,70 +341,27 @@ static HRESULT WINAPI
IMemAllocator_fnDecommit(IMemAllocator* iface)
{
CMemoryAllocator_THIS(iface,memalloc);
HRESULT hr;
LONG i;
BOOL bBlock;
TRACE( "(%p)->()\n", This );
EnterCriticalSection( &This->csMem );
hr = NOERROR;
if ( This->pData == NULL && This->ppSamples == NULL )
goto end;
while ( 1 )
{
bBlock = FALSE;
i = 0;
ResetEvent( This->hEventSample );
while ( 1 )
{
if ( i >= This->prop.cBuffers )
break;
if ( This->ppSamples[i] != NULL )
{
if ( This->ppSamples[i]->ref == 0 )
{
QUARTZ_DestroyMemMediaSample( This->ppSamples[i] );
This->ppSamples[i] = NULL;
}
else
{
bBlock = TRUE;
}
}
i++;
}
if ( !bBlock )
{
QUARTZ_FreeMem(This->ppSamples);
This->ppSamples = NULL;
QUARTZ_FreeMem(This->pData);
This->pData = NULL;
hr = NOERROR;
/* to avoid deadlock, don't hold critical section while blocking */
if ( IMemAllocator_ReleaseUnusedBuffer(This) )
break;
}
WaitForSingleObject( This->hEventSample, INFINITE );
}
end:
LeaveCriticalSection( &This->csMem );
return hr;
return NOERROR;
}
static HRESULT WINAPI
IMemAllocator_fnGetBuffer(IMemAllocator* iface,IMediaSample** ppSample,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd,DWORD dwFlags)
{
CMemoryAllocator_THIS(iface,memalloc);
LONG i;
HRESULT hr;
TRACE( "(%p)->(%p,%p,%p,%lu)\n", This, ppSample, prtStart, prtEnd, dwFlags );
......@@ -315,46 +369,19 @@ IMemAllocator_fnGetBuffer(IMemAllocator* iface,IMediaSample** ppSample,REFERENCE
if ( ppSample == NULL )
return E_POINTER;
EnterCriticalSection( &This->csMem );
TRACE("(%p) enter critical section\n",This);
hr = NOERROR;
if ( This->pData == NULL || This->ppSamples == NULL ||
This->prop.cBuffers <= 0 )
{
hr = E_FAIL; /* FIXME? */
goto end;
}
while ( 1 )
{
ResetEvent( This->hEventSample );
for ( i = 0; i < This->prop.cBuffers; i++ )
{
if ( This->ppSamples[i]->ref == 0 )
{
*ppSample = (IMediaSample*)(This->ppSamples[i]);
IMediaSample_AddRef( *ppSample );
hr = NOERROR;
goto end;
}
}
if ( dwFlags & AM_GBF_NOWAIT )
{
hr = E_FAIL; /* FIXME? */
/* to avoid deadlock, don't hold critical section while blocking */
hr = IMemAllocator_LockUnusedBuffer(This,ppSample);
if ( ( hr != VFW_E_TIMEOUT ) || ( dwFlags & AM_GBF_NOWAIT ) )
goto end;
}
WaitForSingleObject( This->hEventSample, INFINITE );
}
end:
LeaveCriticalSection( &This->csMem );
TRACE("(%p) leave critical section\n",This);
return hr;
}
......
......@@ -219,6 +219,28 @@ HRESULT QUARTZ_MediaSubType_FromBitmap(
return hr;
}
BOOL QUARTZ_BitmapHasFixedSample( const BITMAPINFOHEADER* pbi )
{
switch ( pbi->biCompression )
{
case 0:
case 3:
case mmioFOURCC('I','4','2','0'):
case mmioFOURCC('I','Y','U','V'):
case mmioFOURCC('Y','U','Y','V'):
case mmioFOURCC('Y','V','U','9'):
case mmioFOURCC('Y','4','1','1'):
case mmioFOURCC('Y','4','1','P'):
case mmioFOURCC('Y','U','Y','2'):
case mmioFOURCC('Y','V','Y','U'):
case mmioFOURCC('U','Y','V','Y'):
case mmioFOURCC('Y','2','1','1'):
case mmioFOURCC('Y','V','1','2'):
return TRUE;
}
return FALSE;
}
/****************************************************************************/
......
......@@ -25,6 +25,9 @@ BOOL QUARTZ_MediaSubType_IsFourCC(
HRESULT QUARTZ_MediaSubType_FromBitmap(
GUID* psubtype, const BITMAPINFOHEADER* pbi );
BOOL QUARTZ_BitmapHasFixedSample( const BITMAPINFOHEADER* pbi );
HRESULT QUARTZ_CreateEnumMediaTypes(
IEnumMediaTypes** ppobj,
const AM_MEDIA_TYPE* pTypes, ULONG cTypes );
......
......@@ -35,8 +35,9 @@ struct CParserImpl
HANDLE m_hEventInit;
DWORD m_dwThreadId;
HANDLE m_hThread;
const ParserHandlers* m_pHandler;
BOOL m_bSendEOS;
const ParserHandlers* m_pHandler;
void* m_pUserData;
};
......@@ -54,6 +55,8 @@ struct CParserOutPinImpl
QUARTZ_IUnkImpl unk;
CPinBaseImpl pin;
CQualityControlPassThruImpl qcontrol;
struct { ICOM_VFIELD(IMediaSeeking); } mediaseeking;
struct { ICOM_VFIELD(IMediaPosition); } mediaposition;
CParserImpl* pParser;
ULONG nStreamIndex;
......@@ -64,6 +67,7 @@ struct CParserOutPinImpl
/* for parser */
BOOL m_bReqUsed;
IMediaSample* m_pReqSample;
LONGLONG m_llReqStart;
LONG m_lReqLength;
REFERENCE_TIME m_rtReqStart;
......@@ -105,6 +109,9 @@ struct ParserHandlers
#define CParserOutPinImpl_THIS(iface,member) CParserOutPinImpl* This = ((CParserOutPinImpl*)(((char*)iface)-offsetof(CParserOutPinImpl,member)))
#define CParserOutPinImpl_IMediaSeeking(th) ((IMediaSeeking*)&((th)->mediaseeking))
#define CParserOutPinImpl_IMediaPosition(th) ((IMediaPosition*)&((th)->mediaposition))
HRESULT QUARTZ_CreateParser(
IUnknown* punkOuter,void** ppobj,
const CLSID* pclsidParser,
......
......@@ -4,6 +4,7 @@ init QUARTZ_DllMain
import oleaut32.dll
import ole32.dll
import msvfw32.dll
import winmm.dll
import user32.dll
import gdi32.dll
......
......@@ -112,7 +112,10 @@ HRESULT QUARTZ_IMediaSample_SetProperties(
hr = IMediaSample_SetDiscontinuity(pSample,
(prop.dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) ? TRUE : FALSE);
if ( SUCCEEDED(hr) )
{
TRACE("length = %ld/%ld\n",prop.lActual,pProp->cbBuffer);
hr = IMediaSample_SetActualDataLength(pSample,prop.lActual);
}
if ( SUCCEEDED(hr) )
{
if ( ( prop.dwSampleFlags & AM_SAMPLE_TIMEVALID) &&
......@@ -142,6 +145,8 @@ HRESULT QUARTZ_IMediaSample_Copy(
hr = QUARTZ_IMediaSample_GetProperties( pSrcSample, &prop );
if ( FAILED(hr) )
return hr;
if ( !bCopyData )
prop.lActual = 0;
hr = QUARTZ_IMediaSample_SetProperties( pDstSample, &prop );
if ( prop.pMediaType != NULL )
QUARTZ_MediaType_Destroy( prop.pMediaType );
......
......@@ -137,22 +137,59 @@ static void QUARTZ_DestroySeekingPassThru(IUnknown* punk)
{
CSeekingPassThru_THIS(punk,unk);
TRACE("(%p)\n",This);
CPassThruImpl_UninitIMediaSeeking( &This->passthru );
CPassThruImpl_UninitIMediaPosition( &This->passthru );
CSeekingPassThru_UninitISeekingPassThru(This);
}
HRESULT QUARTZ_CreateSeekingPassThru(IUnknown* punkOuter,void** ppobj)
{
CSeekingPassThru* This;
HRESULT hr;
CSeekingPassThru* This;
TRACE("(%p,%p)\n",punkOuter,ppobj);
hr = QUARTZ_CreateSeekingPassThruInternal(punkOuter,&This,FALSE,NULL);
if ( hr != S_OK )
return hr;
ppobj = (void*)(&This->unk);
return NOERROR;
}
HRESULT QUARTZ_CreateSeekingPassThruInternal(IUnknown* punkOuter,CSeekingPassThru** ppobj,BOOL bRendering,IPin* pPin)
{
CSeekingPassThru* This;
HRESULT hr;
TRACE("(%p,%p,%d,%p)\n",punkOuter,ppobj,(int)bRendering,pPin);
This = (CSeekingPassThru*)QUARTZ_AllocObj( sizeof(CSeekingPassThru) );
if ( This == NULL )
return E_OUTOFMEMORY;
QUARTZ_IUnkInit( &This->unk, punkOuter );
hr = CSeekingPassThru_InitISeekingPassThru(This);
if ( SUCCEEDED(hr) )
{
hr = CPassThruImpl_InitIMediaPosition( &This->passthru );
if ( SUCCEEDED(hr) )
{
hr = CPassThruImpl_InitIMediaSeeking( &This->passthru );
if ( FAILED(hr) )
{
CPassThruImpl_UninitIMediaPosition( &This->passthru );
}
}
else
{
CSeekingPassThru_UninitISeekingPassThru(This);
}
}
if ( FAILED(hr) )
{
QUARTZ_FreeObj( This );
......@@ -163,7 +200,17 @@ HRESULT QUARTZ_CreateSeekingPassThru(IUnknown* punkOuter,void** ppobj)
This->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
This->unk.pOnFinalRelease = QUARTZ_DestroySeekingPassThru;
*ppobj = (void*)(&This->unk);
*ppobj = This;
if ( pPin != NULL )
{
hr = ISeekingPassThru_Init((ISeekingPassThru*)(&This->seekpass),bRendering,pPin);
if ( FAILED(hr) )
{
IUnknown_Release(This->unk.punkControl);
return hr;
}
}
return S_OK;
}
......
......@@ -57,6 +57,7 @@ typedef struct CSeekingPassThru
#define CSeekingPassThru_THIS(iface,member) CSeekingPassThru* This = ((CSeekingPassThru*)(((char*)iface)-offsetof(CSeekingPassThru,member)))
HRESULT QUARTZ_CreateSeekingPassThru(IUnknown* punkOuter,void** ppobj);
HRESULT QUARTZ_CreateSeekingPassThruInternal(IUnknown* punkOuter,CSeekingPassThru** ppobj,BOOL bRendering,IPin* pPin);
#endif /* WINE_DSHOW_SEEKPASS_H */
#include "config.h"
#include "windef.h"
#include "wingdi.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(quartz);
#include "videoblt.h"
#define QUARTZ_LOBYTE(pix) ((BYTE)((pix)&0xff))
#define QUARTZ_HIBYTE(pix) ((BYTE)((pix)>>8))
void VIDEOBLT_Blt_888_to_332(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed )
{
LONG x,y;
for ( y = 0; y < height; y++ )
{
for ( x = 0; x < width; x++ )
{
*pDst++ = ((pSrc[2]&0xe0) ) |
((pSrc[1]&0xe0)>>3) |
((pSrc[0]&0xc0)>>6);
pSrc += 3;
}
pDst += pitchDst - width;
pSrc += pitchSrc - width*3;
}
}
void VIDEOBLT_Blt_888_to_555(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed )
{
LONG x,y;
unsigned pix;
for ( y = 0; y < height; y++ )
{
for ( x = 0; x < width; x++ )
{
pix = ((unsigned)(pSrc[2]&0xf8)<<7) |
((unsigned)(pSrc[1]&0xf8)<<2) |
((unsigned)(pSrc[0]&0xf8)>>3);
*pDst++ = QUARTZ_LOBYTE(pix);
*pDst++ = QUARTZ_HIBYTE(pix);
pSrc += 3;
}
pDst += pitchDst - width*2;
pSrc += pitchSrc - width*3;
}
}
void VIDEOBLT_Blt_888_to_565(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed )
{
LONG x,y;
unsigned pix;
for ( y = 0; y < height; y++ )
{
for ( x = 0; x < width; x++ )
{
pix = ((unsigned)(pSrc[2]&0xf8)<<8) |
((unsigned)(pSrc[1]&0xfc)<<3) |
((unsigned)(pSrc[0]&0xf8)>>3);
*pDst++ = QUARTZ_LOBYTE(pix);
*pDst++ = QUARTZ_HIBYTE(pix);
pSrc += 3;
}
pDst += pitchDst - width*2;
pSrc += pitchSrc - width*3;
}
}
void VIDEOBLT_Blt_888_to_8888(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed )
{
LONG x,y;
for ( y = 0; y < height; y++ )
{
for ( x = 0; x < width; x++ )
{
*pDst++ = *pSrc++;
*pDst++ = *pSrc++;
*pDst++ = *pSrc++;
*pDst++ = (BYTE)0xff;
}
pDst += pitchDst - width*4;
pSrc += pitchSrc - width*3;
}
}
#ifndef QUARTZ_VIDEOBLT_H
#define QUARTZ_VIDEOBLT_H
typedef void (*pVIDEOBLT_Blt)(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed );
void VIDEOBLT_Blt_888_to_332(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed );
void VIDEOBLT_Blt_888_to_555(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed );
void VIDEOBLT_Blt_888_to_565(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed );
void VIDEOBLT_Blt_888_to_8888(
BYTE* pDst, LONG pitchDst,
const BYTE* pSrc, LONG pitchSrc,
LONG width, LONG height,
const RGBQUAD* prgbSrc, LONG nClrUsed );
#endif /* QUARTZ_VIDEOBLT_H */
......@@ -27,6 +27,7 @@ DEFAULT_DEBUG_CHANNEL(quartz);
#include "quartz_private.h"
#include "vidren.h"
#include "seekpass.h"
static const WCHAR QUARTZ_VideoRenderer_Name[] =
......@@ -392,6 +393,13 @@ static HRESULT CVideoRendererPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
This->pRender->m_cbSampleData = 0;
This->pRender->m_bSampleIsValid = FALSE;
if ( This->meminput.pAllocator != NULL )
{
IMemAllocator_Decommit(This->meminput.pAllocator);
IMemAllocator_Release(This->meminput.pAllocator);
This->meminput.pAllocator = NULL;
}
return NOERROR;
}
......@@ -577,6 +585,24 @@ static QUARTZ_IFEntry FilterIFEntries[] =
{ &IID_IVideoWindow, offsetof(CVideoRendererImpl,vidwin)-offsetof(CVideoRendererImpl,unk) },
};
static HRESULT CVideoRendererImpl_OnQueryInterface(
IUnknown* punk, const IID* piid, void** ppobj )
{
CVideoRendererImpl_THIS(punk,unk);
if ( This->pSeekPass == NULL )
return E_NOINTERFACE;
if ( IsEqualGUID( &IID_IMediaPosition, piid ) ||
IsEqualGUID( &IID_IMediaSeeking, piid ) )
{
TRACE( "IMediaSeeking(or IMediaPosition) is queried\n" );
return IUnknown_QueryInterface( (IUnknown*)(&This->pSeekPass->unk), piid, ppobj );
}
return E_NOINTERFACE;
}
static void QUARTZ_DestroyVideoRenderer(IUnknown* punk)
{
CVideoRendererImpl_THIS(punk,unk);
......@@ -590,6 +616,11 @@ static void QUARTZ_DestroyVideoRenderer(IUnknown* punk)
IUnknown_Release(This->pPin->unk.punkControl);
This->pPin = NULL;
}
if ( This->pSeekPass != NULL )
{
IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
This->pSeekPass = NULL;
}
CVideoRendererImpl_UninitIBasicVideo2(This);
CVideoRendererImpl_UninitIVideoWindow(This);
......@@ -609,6 +640,7 @@ HRESULT QUARTZ_CreateVideoRenderer(IUnknown* punkOuter,void** ppobj)
QUARTZ_AllocObj( sizeof(CVideoRendererImpl) );
if ( This == NULL )
return E_OUTOFMEMORY;
This->pSeekPass = NULL;
This->pPin = NULL;
This->m_fInFlush = FALSE;
......@@ -620,6 +652,9 @@ HRESULT QUARTZ_CreateVideoRenderer(IUnknown* punkOuter,void** ppobj)
This->m_cbSampleData = 0;
QUARTZ_IUnkInit( &This->unk, punkOuter );
This->qiext.pNext = NULL;
This->qiext.pOnQueryInterface = &CVideoRendererImpl_OnQueryInterface;
QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );
hr = CBaseFilterImpl_InitIBaseFilter(
&This->basefilter,
......@@ -654,6 +689,8 @@ HRESULT QUARTZ_CreateVideoRenderer(IUnknown* punkOuter,void** ppobj)
This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
This->unk.pOnFinalRelease = QUARTZ_DestroyVideoRenderer;
InitializeCriticalSection( &This->m_csSample );
hr = QUARTZ_CreateVideoRendererPin(
This,
&This->basefilter.csFilter,
......@@ -663,14 +700,17 @@ HRESULT QUARTZ_CreateVideoRenderer(IUnknown* punkOuter,void** ppobj)
This->basefilter.pInPins,
(IUnknown*)&This->pPin->pin,
NULL, 0 );
if ( SUCCEEDED(hr) )
hr = QUARTZ_CreateSeekingPassThruInternal(
(IUnknown*)&(This->unk), &This->pSeekPass,
TRUE, (IPin*)&(This->pPin->pin) );
if ( FAILED(hr) )
{
IUnknown_Release( This->unk.punkControl );
return hr;
}
InitializeCriticalSection( &This->m_csSample );
*ppobj = (void*)&(This->unk);
return S_OK;
......
......@@ -9,6 +9,7 @@
#include "iunk.h"
#include "basefilt.h"
#include "seekpass.h"
typedef struct CVideoRendererImpl CVideoRendererImpl;
typedef struct CVideoRendererPinImpl CVideoRendererPinImpl;
......@@ -30,7 +31,9 @@ struct CVideoRendererImpl
CBaseFilterImpl basefilter;
VidRen_IBasicVideo basvid;
VidRen_IVideoWindow vidwin;
QUARTZ_IFDelegation qiext;
CSeekingPassThru* pSeekPass;
CVideoRendererPinImpl* pPin;
BOOL m_fInFlush;
......
......@@ -14,6 +14,7 @@
#include "mmreg.h"
#include "winerror.h"
#include "strmif.h"
#include "control.h"
#include "vfwmsgs.h"
#include "uuids.h"
......
/*
* Implements IBaseFilter for transform filters. (internal)
*
* hidenori@a2.ctktv.ne.jp
*/
#ifndef WINE_DSHOW_XFORM_H
#define WINE_DSHOW_XFORM_H
#include "iunk.h"
#include "basefilt.h"
#include "seekpass.h"
typedef struct CTransformBaseImpl CTransformBaseImpl;
typedef struct CTransformBaseInPinImpl CTransformBaseInPinImpl;
typedef struct CTransformBaseOutPinImpl CTransformBaseOutPinImpl;
typedef struct TransformBaseHandlers TransformBaseHandlers;
struct CTransformBaseImpl
{
QUARTZ_IUnkImpl unk;
CBaseFilterImpl basefilter;
CTransformBaseInPinImpl* pInPin;
CTransformBaseOutPinImpl* pOutPin;
CSeekingPassThru* pSeekPass;
CRITICAL_SECTION csFilter;
IMemAllocator* m_pOutPinAllocator;
BOOL m_bPreCopy; /* sample must be copied */
BOOL m_bReuseSample; /* sample must be reused */
BOOL m_bInFlush;
IMediaSample* m_pSample;
BOOL m_bFiltering;
const TransformBaseHandlers* m_pHandler;
void* m_pUserData;
};
struct CTransformBaseInPinImpl
{
QUARTZ_IUnkImpl unk;
CPinBaseImpl pin;
CMemInputPinBaseImpl meminput;
CTransformBaseImpl* pFilter;
};
struct CTransformBaseOutPinImpl
{
QUARTZ_IUnkImpl unk;
CPinBaseImpl pin;
CQualityControlPassThruImpl qcontrol;
QUARTZ_IFDelegation qiext;
CTransformBaseImpl* pFilter;
};
struct TransformBaseHandlers
{
/* all methods must be implemented */
HRESULT (*pInit)( CTransformBaseImpl* pImpl );
HRESULT (*pCleanup)( CTransformBaseImpl* pImpl );
/* pmtOut may be NULL */
HRESULT (*pCheckMediaType)( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut );
/* get output types */
HRESULT (*pGetOutputTypes)( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE** ppmtAcceptTypes, ULONG* pcAcceptTypes );
/* get allocator properties */
HRESULT (*pGetAllocProp)( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, ALLOCATOR_PROPERTIES* pProp, BOOL* pbTransInPlace, BOOL* pbTryToReuseSample );
/* prepare the filter */
HRESULT (*pBeginTransform)( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, BOOL bReuseSample );
/* process a sample */
HRESULT (*pTransform)( CTransformBaseImpl* pImpl, IMediaSample* pSampIn, IMediaSample* pSampOut );
/* unprepare the filter */
HRESULT (*pEndTransform)( CTransformBaseImpl* pImpl );
};
#define CTransformBaseImpl_THIS(iface,member) CTransformBaseImpl* This = ((CTransformBaseImpl*)(((char*)iface)-offsetof(CTransformBaseImpl,member)))
#define CTransformBaseInPinImpl_THIS(iface,member) CTransformBaseInPinImpl* This = ((CTransformBaseInPinImpl*)(((char*)iface)-offsetof(CTransformBaseInPinImpl,member)))
#define CTransformBaseOutPinImpl_THIS(iface,member) CTransformBaseOutPinImpl* This = ((CTransformBaseOutPinImpl*)(((char*)iface)-offsetof(CTransformBaseOutPinImpl,member)))
HRESULT QUARTZ_CreateTransformBase(
IUnknown* punkOuter,void** ppobj,
const CLSID* pclsidTransformBase,
LPCWSTR pwszTransformBaseName,
LPCWSTR pwszInPinName,
LPCWSTR pwszOutPinName,
const TransformBaseHandlers* pHandler );
HRESULT QUARTZ_CreateTransformBaseInPin(
CTransformBaseImpl* pFilter,
CRITICAL_SECTION* pcsPin,
CTransformBaseInPinImpl** ppPin,
LPCWSTR pwszPinName );
HRESULT QUARTZ_CreateTransformBaseOutPin(
CTransformBaseImpl* pFilter,
CRITICAL_SECTION* pcsPin,
CTransformBaseOutPinImpl** ppPin,
LPCWSTR pwszPinName );
HRESULT QUARTZ_CreateAVIDec(IUnknown* punkOuter,void** ppobj);
HRESULT QUARTZ_CreateColour(IUnknown* punkOuter,void** ppobj);
#endif /* WINE_DSHOW_XFORM_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment