Fixed some bugs.
Implemented AVI Decompressor. Started implementing Color Space Converter. Started implementing seeking.
This commit is contained in:
parent
f5a8b965f0
commit
17bee2ef58
|
@ -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 )
|
||||
|
@ -327,9 +346,31 @@ 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;
|
||||
|
|
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* Implements AVI Decompressor(CLSID_AVIDec).
|
||||
*
|
||||
* FIXME - insufficient buffer for ICDecompress!!!!
|
||||
*
|
||||
* hidenori@a2.ctktv.ne.jp
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "vfw.h"
|
||||
#include "strmif.h"
|
||||
#include "control.h"
|
||||
#include "amvideo.h"
|
||||
#include "vfwmsgs.h"
|
||||
#include "uuids.h"
|
||||
|
||||
#include "debugtools.h"
|
||||
DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
|
||||
#include "quartz_private.h"
|
||||
#include "xform.h"
|
||||
|
||||
|
||||
static const WCHAR AVIDec_FilterName[] =
|
||||
{'A','V','I',' ','D','e','c','o','m','p','r','e','s','s','o','r',0};
|
||||
|
||||
typedef struct CAVIDecImpl
|
||||
{
|
||||
HIC hicCached;
|
||||
HIC hicTrans;
|
||||
AM_MEDIA_TYPE m_mtOut;
|
||||
BITMAPINFO* m_pbiIn;
|
||||
BITMAPINFO* m_pbiOut;
|
||||
BYTE* m_pOutBuf;
|
||||
} CAVIDecImpl;
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CAVIDecImpl methods
|
||||
*
|
||||
*/
|
||||
|
||||
static void AVIDec_ReleaseDIBBuffers(CAVIDecImpl* This)
|
||||
{
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This->m_pbiIn != NULL )
|
||||
{
|
||||
QUARTZ_FreeMem(This->m_pbiIn); This->m_pbiIn = NULL;
|
||||
}
|
||||
if ( This->m_pbiOut != NULL )
|
||||
{
|
||||
QUARTZ_FreeMem(This->m_pbiOut); This->m_pbiOut = NULL;
|
||||
}
|
||||
if ( This->m_pOutBuf != NULL )
|
||||
{
|
||||
QUARTZ_FreeMem(This->m_pOutBuf); This->m_pOutBuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static BITMAPINFO* AVIDec_DuplicateBitmapInfo(const BITMAPINFO* pbi)
|
||||
{
|
||||
DWORD dwSize;
|
||||
BITMAPINFO* pbiRet;
|
||||
|
||||
dwSize = pbi->bmiHeader.biSize;
|
||||
if ( dwSize < sizeof(BITMAPINFOHEADER) )
|
||||
return NULL;
|
||||
if ( pbi->bmiHeader.biBitCount <= 8 )
|
||||
{
|
||||
if ( pbi->bmiHeader.biClrUsed == 0 )
|
||||
dwSize += sizeof(RGBQUAD)*(1<<pbi->bmiHeader.biBitCount);
|
||||
else
|
||||
dwSize += sizeof(RGBQUAD)*pbi->bmiHeader.biClrUsed;
|
||||
}
|
||||
if ( pbi->bmiHeader.biCompression == 3 &&
|
||||
dwSize == sizeof(BITMAPINFOHEADER) )
|
||||
dwSize += sizeof(DWORD)*3;
|
||||
|
||||
pbiRet = (BITMAPINFO*)QUARTZ_AllocMem(dwSize);
|
||||
if ( pbiRet != NULL )
|
||||
memcpy( pbiRet, pbi, dwSize );
|
||||
|
||||
return pbiRet;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_Init( CTransformBaseImpl* pImpl )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This != NULL )
|
||||
return NOERROR;
|
||||
|
||||
This = (CAVIDecImpl*)QUARTZ_AllocMem( sizeof(CAVIDecImpl) );
|
||||
if ( This == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
ZeroMemory( This, sizeof(CAVIDecImpl) );
|
||||
pImpl->m_pUserData = This;
|
||||
/* construct */
|
||||
This->hicCached = (HIC)NULL;
|
||||
This->hicTrans = (HIC)NULL;
|
||||
ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
|
||||
This->m_pbiIn = NULL;
|
||||
This->m_pbiOut = NULL;
|
||||
This->m_pOutBuf = NULL;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_Cleanup( CTransformBaseImpl* pImpl )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL )
|
||||
return NOERROR;
|
||||
|
||||
/* destruct */
|
||||
QUARTZ_MediaType_Free( &This->m_mtOut );
|
||||
|
||||
AVIDec_ReleaseDIBBuffers(This);
|
||||
|
||||
if ( This->hicCached != (HIC)NULL )
|
||||
ICClose(This->hicCached);
|
||||
if ( This->hicTrans != (HIC)NULL )
|
||||
ICClose(This->hicTrans);
|
||||
|
||||
QUARTZ_FreeMem( This );
|
||||
pImpl->m_pUserData = NULL;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_CheckMediaType( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
BITMAPINFO* pbiIn = NULL;
|
||||
BITMAPINFO* pbiOut = NULL;
|
||||
HIC hic;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if ( !IsEqualGUID( &pmtIn->majortype, &MEDIATYPE_Video ) )
|
||||
return E_FAIL;
|
||||
if ( !IsEqualGUID( &pmtIn->formattype, &FORMAT_VideoInfo ) )
|
||||
return E_FAIL;
|
||||
pbiIn = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
|
||||
if ( pmtOut != NULL )
|
||||
{
|
||||
if ( !IsEqualGUID( &pmtOut->majortype, &MEDIATYPE_Video ) )
|
||||
return E_FAIL;
|
||||
if ( !IsEqualGUID( &pmtOut->formattype, &FORMAT_VideoInfo ) )
|
||||
return E_FAIL;
|
||||
pbiOut = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
|
||||
}
|
||||
|
||||
if ( This->hicCached != (HIC)NULL &&
|
||||
ICDecompressQuery( This->hicCached, pbiIn, pbiOut ) == ICERR_OK )
|
||||
{
|
||||
TRACE("supported format\n");
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
TRACE("try to find a decoder...\n");
|
||||
hic = ICLocate(
|
||||
mmioFOURCC('V','I','D','C'), 0,
|
||||
&pbiIn->bmiHeader, &pbiOut->bmiHeader, ICMODE_DECOMPRESS );
|
||||
if ( hic == (HIC)NULL )
|
||||
{
|
||||
WARN("no decoder for %c%c%c%c\n",
|
||||
(int)(( pbiIn->bmiHeader.biCompression >> 0 ) & 0xff),
|
||||
(int)(( pbiIn->bmiHeader.biCompression >> 8 ) & 0xff),
|
||||
(int)(( pbiIn->bmiHeader.biCompression >> 16 ) & 0xff),
|
||||
(int)(( pbiIn->bmiHeader.biCompression >> 24 ) & 0xff) );
|
||||
return E_FAIL;
|
||||
}
|
||||
TRACE("found\n");
|
||||
|
||||
if ( This->hicCached != (HIC)NULL )
|
||||
ICClose(This->hicCached);
|
||||
This->hicCached = hic;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_GetOutputTypes( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE** ppmtAcceptTypes, ULONG* pcAcceptTypes )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
HRESULT hr;
|
||||
LONG cbFmt;
|
||||
BITMAPINFO* pbiIn = NULL;
|
||||
BITMAPINFO* pbiOut = NULL;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
hr = AVIDec_CheckMediaType( pImpl, pmtIn, NULL );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
TRACE("(%p) - get size of format\n",This);
|
||||
pbiIn = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
|
||||
cbFmt = (LONG)ICDecompressGetFormatSize( This->hicCached, pbiIn );
|
||||
if ( cbFmt < sizeof(BITMAPINFOHEADER) )
|
||||
return E_FAIL;
|
||||
|
||||
QUARTZ_MediaType_Free( &This->m_mtOut );
|
||||
ZeroMemory( &This->m_mtOut, sizeof(AM_MEDIA_TYPE) );
|
||||
|
||||
memcpy( &This->m_mtOut.majortype, &MEDIATYPE_Video, sizeof(GUID) );
|
||||
memcpy( &This->m_mtOut.formattype, &FORMAT_VideoInfo, sizeof(GUID) );
|
||||
This->m_mtOut.cbFormat = sizeof(VIDEOINFOHEADER) + cbFmt;
|
||||
This->m_mtOut.pbFormat = (BYTE*)CoTaskMemAlloc(This->m_mtOut.cbFormat);
|
||||
if ( This->m_mtOut.pbFormat == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
ZeroMemory( This->m_mtOut.pbFormat, This->m_mtOut.cbFormat );
|
||||
|
||||
pbiOut = (BITMAPINFO*)(&((VIDEOINFOHEADER*)This->m_mtOut.pbFormat)->bmiHeader);
|
||||
|
||||
TRACE("(%p) - get format\n",This);
|
||||
if ( ICDecompressGetFormat( This->hicCached, pbiIn, pbiOut ) != ICERR_OK )
|
||||
return E_FAIL;
|
||||
|
||||
hr = QUARTZ_MediaSubType_FromBitmap( &This->m_mtOut.subtype, &pbiOut->bmiHeader );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
if ( hr != S_OK )
|
||||
QUARTZ_MediaSubType_FromFourCC( &This->m_mtOut.subtype, pbiOut->bmiHeader.biCompression );
|
||||
|
||||
This->m_mtOut.bFixedSizeSamples = (pbiOut->bmiHeader.biCompression == 0) ? 1 : 0;
|
||||
This->m_mtOut.lSampleSize = (pbiOut->bmiHeader.biCompression == 0) ? DIBSIZE(pbiOut->bmiHeader) : pbiOut->bmiHeader.biSizeImage;
|
||||
|
||||
TRACE("(%p) - return format\n",This);
|
||||
*ppmtAcceptTypes = &This->m_mtOut;
|
||||
*pcAcceptTypes = 1;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_GetAllocProp( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, ALLOCATOR_PROPERTIES* pProp, BOOL* pbTransInPlace, BOOL* pbTryToReuseSample )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
BITMAPINFO* pbiOut = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = AVIDec_CheckMediaType( pImpl, pmtIn, pmtOut );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
pbiOut = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
|
||||
|
||||
pProp->cBuffers = 1;
|
||||
if ( pbiOut->bmiHeader.biCompression == 0 )
|
||||
pProp->cbBuffer = DIBSIZE(pbiOut->bmiHeader);
|
||||
else
|
||||
pProp->cbBuffer = pbiOut->bmiHeader.biSizeImage;
|
||||
|
||||
*pbTransInPlace = FALSE;
|
||||
*pbTryToReuseSample = TRUE;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_BeginTransform( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, BOOL bReuseSample )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
BITMAPINFO* pbiIn = NULL;
|
||||
BITMAPINFO* pbiOut = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p,%d)\n",This,pmtIn,pmtOut,bReuseSample);
|
||||
|
||||
if ( This == NULL ||
|
||||
This->hicTrans != (HIC)NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = AVIDec_CheckMediaType( pImpl, pmtIn, pmtOut );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
AVIDec_ReleaseDIBBuffers(This);
|
||||
|
||||
pbiIn = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
|
||||
pbiOut = (BITMAPINFO*)(&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
|
||||
This->m_pbiIn = AVIDec_DuplicateBitmapInfo(pbiIn);
|
||||
This->m_pbiOut = AVIDec_DuplicateBitmapInfo(pbiOut);
|
||||
if ( This->m_pbiIn == NULL || This->m_pbiOut == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
if ( This->m_pbiOut->bmiHeader.biCompression == 0 )
|
||||
This->m_pbiOut->bmiHeader.biSizeImage = DIBSIZE(This->m_pbiOut->bmiHeader);
|
||||
|
||||
if ( !bReuseSample )
|
||||
{
|
||||
This->m_pOutBuf = QUARTZ_AllocMem(This->m_pbiOut->bmiHeader.biSizeImage);
|
||||
if ( This->m_pOutBuf == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
ZeroMemory( This->m_pOutBuf, This->m_pbiOut->bmiHeader.biSizeImage );
|
||||
}
|
||||
|
||||
if ( ICERR_OK != ICDecompressBegin(
|
||||
This->hicCached, This->m_pbiIn, This->m_pbiOut ) )
|
||||
return E_FAIL;
|
||||
|
||||
This->hicTrans = This->hicCached;
|
||||
This->hicCached = (HIC)NULL;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_Transform( CTransformBaseImpl* pImpl, IMediaSample* pSampIn, IMediaSample* pSampOut )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
DWORD dwFlags;
|
||||
BYTE* pDataIn = NULL;
|
||||
BYTE* pDataOut = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL || pSampOut == NULL ||
|
||||
This->hicTrans == (HIC)NULL ||
|
||||
This->m_pbiIn == NULL ||
|
||||
This->m_pbiOut == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = IMediaSample_GetPointer( pSampIn, &pDataIn );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
hr = IMediaSample_GetPointer( pSampOut, &pDataOut );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
dwFlags = 0;
|
||||
/*** FIXME!!!
|
||||
*
|
||||
* if ( IMediaSample_IsSyncPoint(pSampIn) != S_OK )
|
||||
* dwFlags |= ICDECOMPRESS_NOTKEYFRAME;
|
||||
****/
|
||||
|
||||
if ( IMediaSample_IsPreroll(pSampIn) == S_OK )
|
||||
dwFlags |= ICDECOMPRESS_PREROLL;
|
||||
|
||||
if ( ICERR_OK != ICDecompress(
|
||||
This->hicTrans,
|
||||
dwFlags,
|
||||
&This->m_pbiIn->bmiHeader,
|
||||
pDataIn,
|
||||
&This->m_pbiOut->bmiHeader,
|
||||
( This->m_pOutBuf != NULL ) ? This->m_pOutBuf : pDataOut ) )
|
||||
return E_FAIL;
|
||||
|
||||
if ( This->m_pOutBuf != NULL )
|
||||
memcpy( pDataOut, This->m_pOutBuf,
|
||||
This->m_pbiOut->bmiHeader.biSizeImage );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT AVIDec_EndTransform( CTransformBaseImpl* pImpl )
|
||||
{
|
||||
CAVIDecImpl* This = pImpl->m_pUserData;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
if ( This->hicTrans == (HIC)NULL )
|
||||
return NOERROR;
|
||||
|
||||
ICDecompressEnd(This->hicTrans);
|
||||
|
||||
if ( This->hicCached != (HIC)NULL )
|
||||
ICClose(This->hicCached);
|
||||
This->hicCached = This->hicTrans;
|
||||
This->hicTrans = (HIC)NULL;
|
||||
|
||||
AVIDec_ReleaseDIBBuffers(This);
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
static const TransformBaseHandlers transhandlers =
|
||||
{
|
||||
AVIDec_Init,
|
||||
AVIDec_Cleanup,
|
||||
AVIDec_CheckMediaType,
|
||||
AVIDec_GetOutputTypes,
|
||||
AVIDec_GetAllocProp,
|
||||
AVIDec_BeginTransform,
|
||||
AVIDec_Transform,
|
||||
AVIDec_EndTransform,
|
||||
};
|
||||
|
||||
|
||||
HRESULT QUARTZ_CreateAVIDec(IUnknown* punkOuter,void** ppobj)
|
||||
{
|
||||
return QUARTZ_CreateTransformBase(
|
||||
punkOuter,ppobj,
|
||||
&CLSID_AVIDec,
|
||||
AVIDec_FilterName,
|
||||
NULL, NULL,
|
||||
&transhandlers );
|
||||
}
|
||||
|
|
@ -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 )
|
||||
|
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Implements Color Space Converter(CLSID_Colour).
|
||||
*
|
||||
* hidenori@a2.ctktv.ne.jp
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "vfw.h"
|
||||
#include "strmif.h"
|
||||
#include "control.h"
|
||||
#include "amvideo.h"
|
||||
#include "vfwmsgs.h"
|
||||
#include "uuids.h"
|
||||
|
||||
#include "debugtools.h"
|
||||
DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
|
||||
#include "quartz_private.h"
|
||||
#include "xform.h"
|
||||
#include "videoblt.h"
|
||||
|
||||
static const WCHAR ColorConv_FilterName[] =
|
||||
{'C','o','l','o','r',' ','S','p','a','c','e',' ','C','o','n','v','e','r','t','e','r',0};
|
||||
|
||||
struct BltHandler
|
||||
{
|
||||
const GUID* psubtypeIn;
|
||||
const GUID* psubtypeOut;
|
||||
pVIDEOBLT_Blt pBlt;
|
||||
};
|
||||
|
||||
static const struct BltHandler conv_handlers[] =
|
||||
{
|
||||
{ &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB32, VIDEOBLT_Blt_888_to_8888 },
|
||||
{ &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB565, VIDEOBLT_Blt_888_to_565 },
|
||||
{ &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB555, VIDEOBLT_Blt_888_to_555 },
|
||||
{ &MEDIASUBTYPE_RGB24, &MEDIASUBTYPE_RGB8, VIDEOBLT_Blt_888_to_332 },
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
typedef struct CColorConvImpl
|
||||
{
|
||||
pVIDEOBLT_Blt m_pBlt;
|
||||
AM_MEDIA_TYPE* m_pmtConv;
|
||||
DWORD m_cConv;
|
||||
LONG pitchIn;
|
||||
LONG pitchOut;
|
||||
} CColorConvImpl;
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CColorConvImpl methods
|
||||
*
|
||||
*/
|
||||
|
||||
static void ColorConv_FreeOutTypes(CColorConvImpl* This)
|
||||
{
|
||||
DWORD i;
|
||||
|
||||
if ( This->m_pmtConv == NULL )
|
||||
return;
|
||||
|
||||
TRACE("cConv = %lu\n",This->m_cConv);
|
||||
for ( i = 0; i < This->m_cConv; i++ )
|
||||
{
|
||||
QUARTZ_MediaType_Free(&This->m_pmtConv[i]);
|
||||
}
|
||||
QUARTZ_FreeMem(This->m_pmtConv);
|
||||
This->m_pmtConv = NULL;
|
||||
This->m_cConv = 0;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_FillBitmapInfo( BITMAPINFO* pbiOut, LONG biWidth, LONG biHeight, const GUID* psubtype )
|
||||
{
|
||||
int i;
|
||||
DWORD* pdwBitf;
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
pbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
pbiOut->bmiHeader.biWidth = biWidth;
|
||||
pbiOut->bmiHeader.biHeight = biHeight;
|
||||
pbiOut->bmiHeader.biPlanes = 1;
|
||||
|
||||
if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB8 ) )
|
||||
{
|
||||
pbiOut->bmiHeader.biBitCount = 8;
|
||||
for ( i = 0; i < 256; i++ )
|
||||
{
|
||||
pbiOut->bmiColors[i].rgbRed = ((i>>5)&7)*255/7;
|
||||
pbiOut->bmiColors[i].rgbGreen = ((i>>2)&7)*255/7;
|
||||
pbiOut->bmiColors[i].rgbBlue = (i&3)*255/3;
|
||||
}
|
||||
hr = S_OK;
|
||||
}
|
||||
if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB555 ) )
|
||||
{
|
||||
pbiOut->bmiHeader.biBitCount = 16;
|
||||
hr = S_OK;
|
||||
}
|
||||
if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB565 ) )
|
||||
{
|
||||
pbiOut->bmiHeader.biBitCount = 16;
|
||||
pbiOut->bmiHeader.biCompression = 3;
|
||||
pdwBitf = (DWORD*)(&pbiOut->bmiColors[0]);
|
||||
pdwBitf[0] = 0xf800;
|
||||
pdwBitf[1] = 0x07e0;
|
||||
pdwBitf[2] = 0x001f;
|
||||
hr = S_OK;
|
||||
}
|
||||
if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB24 ) )
|
||||
{
|
||||
pbiOut->bmiHeader.biBitCount = 24;
|
||||
hr = S_OK;
|
||||
}
|
||||
if ( IsEqualGUID( psubtype, &MEDIASUBTYPE_RGB32 ) )
|
||||
{
|
||||
pbiOut->bmiHeader.biBitCount = 32;
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
pbiOut->bmiHeader.biSizeImage = DIBSIZE(pbiOut->bmiHeader);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
static HRESULT ColorConv_Init( CTransformBaseImpl* pImpl )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
|
||||
if ( This != NULL )
|
||||
return NOERROR;
|
||||
|
||||
This = (CColorConvImpl*)QUARTZ_AllocMem( sizeof(CColorConvImpl) );
|
||||
if ( This == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
ZeroMemory( This, sizeof(CColorConvImpl) );
|
||||
pImpl->m_pUserData = This;
|
||||
/* construct */
|
||||
This->m_pBlt = NULL;
|
||||
This->m_pmtConv = NULL;
|
||||
This->m_cConv = 0;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_Cleanup( CTransformBaseImpl* pImpl )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
|
||||
if ( This == NULL )
|
||||
return NOERROR;
|
||||
/* destruct */
|
||||
ColorConv_FreeOutTypes(This);
|
||||
|
||||
QUARTZ_FreeMem( This );
|
||||
pImpl->m_pUserData = NULL;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_CheckMediaType( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
BITMAPINFOHEADER* pbiIn = NULL;
|
||||
BITMAPINFOHEADER* pbiOut = NULL;
|
||||
HRESULT hr;
|
||||
GUID stIn, stOut;
|
||||
const struct BltHandler* phandler;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if ( !IsEqualGUID( &pmtIn->majortype, &MEDIATYPE_Video ) )
|
||||
return E_FAIL;
|
||||
if ( !IsEqualGUID( &pmtIn->formattype, &FORMAT_VideoInfo ) )
|
||||
return E_FAIL;
|
||||
pbiIn = (&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
|
||||
if ( pbiIn->biCompression != 0 &&
|
||||
pbiIn->biCompression != 3 )
|
||||
return E_FAIL;
|
||||
|
||||
hr = QUARTZ_MediaSubType_FromBitmap( &stIn, pbiIn );
|
||||
if ( hr != S_OK || !IsEqualGUID( &pmtIn->subtype, &stIn ) )
|
||||
return E_FAIL;
|
||||
|
||||
if ( pmtOut != NULL )
|
||||
{
|
||||
if ( !IsEqualGUID( &pmtOut->majortype, &MEDIATYPE_Video ) )
|
||||
return E_FAIL;
|
||||
if ( !IsEqualGUID( &pmtOut->formattype, &FORMAT_VideoInfo ) )
|
||||
return E_FAIL;
|
||||
pbiOut = (&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
|
||||
if ( pbiOut->biCompression != 0 &&
|
||||
pbiOut->biCompression != 3 )
|
||||
return E_FAIL;
|
||||
hr = QUARTZ_MediaSubType_FromBitmap( &stOut, pbiOut );
|
||||
if ( hr != S_OK || !IsEqualGUID( &pmtOut->subtype, &stOut ) )
|
||||
return E_FAIL;
|
||||
if ( pbiIn->biWidth != pbiOut->biWidth ||
|
||||
pbiIn->biHeight != pbiOut->biHeight ||
|
||||
pbiIn->biPlanes != 1 || pbiOut->biPlanes != 1 )
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
phandler = conv_handlers;
|
||||
while ( phandler->psubtypeIn != NULL )
|
||||
{
|
||||
if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
|
||||
{
|
||||
if ( pmtOut == NULL )
|
||||
return S_OK;
|
||||
if ( IsEqualGUID( &pmtOut->subtype, phandler->psubtypeOut ) )
|
||||
return S_OK;
|
||||
}
|
||||
phandler ++;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_GetOutputTypes( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE** ppmtAcceptTypes, ULONG* pcAcceptTypes )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
HRESULT hr;
|
||||
const struct BltHandler* phandler;
|
||||
DWORD cConv;
|
||||
BITMAPINFOHEADER* pbiIn = NULL;
|
||||
BITMAPINFOHEADER* pbiOut = NULL;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = ColorConv_CheckMediaType( pImpl, pmtIn, NULL );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
pbiIn = (&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
|
||||
|
||||
ColorConv_FreeOutTypes(This);
|
||||
|
||||
cConv = 0;
|
||||
phandler = conv_handlers;
|
||||
while ( phandler->psubtypeIn != NULL )
|
||||
{
|
||||
if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
|
||||
cConv ++;
|
||||
phandler ++;
|
||||
}
|
||||
|
||||
This->m_cConv = cConv;
|
||||
This->m_pmtConv = (AM_MEDIA_TYPE*)QUARTZ_AllocMem(
|
||||
sizeof(AM_MEDIA_TYPE) * cConv );
|
||||
if ( This->m_pmtConv == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
ZeroMemory( This->m_pmtConv, sizeof(AM_MEDIA_TYPE) * cConv );
|
||||
|
||||
cConv = 0;
|
||||
phandler = conv_handlers;
|
||||
while ( phandler->psubtypeIn != NULL )
|
||||
{
|
||||
if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
|
||||
{
|
||||
memcpy( &This->m_pmtConv[cConv].majortype, &MEDIATYPE_Video, sizeof(GUID) );
|
||||
memcpy( &This->m_pmtConv[cConv].subtype, phandler->psubtypeOut, sizeof(GUID) );
|
||||
This->m_pmtConv[cConv].bFixedSizeSamples = 1;
|
||||
This->m_pmtConv[cConv].bTemporalCompression = 0;
|
||||
This->m_pmtConv[cConv].lSampleSize = DIBSIZE(*pbiIn);
|
||||
memcpy( &This->m_pmtConv[cConv].formattype, &FORMAT_VideoInfo, sizeof(GUID) );
|
||||
This->m_pmtConv[cConv].cbFormat = sizeof(VIDEOINFO);
|
||||
This->m_pmtConv[cConv].pbFormat = (BYTE*)CoTaskMemAlloc( This->m_pmtConv[cConv].cbFormat );
|
||||
if ( This->m_pmtConv[cConv].pbFormat == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
ZeroMemory( This->m_pmtConv[cConv].pbFormat, This->m_pmtConv[cConv].cbFormat );
|
||||
pbiOut = &(((VIDEOINFOHEADER*)(This->m_pmtConv[cConv].pbFormat))->bmiHeader);
|
||||
hr = ColorConv_FillBitmapInfo( (BITMAPINFO*)pbiOut, pbiIn->biWidth, pbiIn->biHeight, phandler->psubtypeOut );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
cConv ++;
|
||||
}
|
||||
phandler ++;
|
||||
}
|
||||
|
||||
*ppmtAcceptTypes = This->m_pmtConv;
|
||||
*pcAcceptTypes = This->m_cConv;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_GetAllocProp( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, ALLOCATOR_PROPERTIES* pProp, BOOL* pbTransInPlace, BOOL* pbTryToReuseSample )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
HRESULT hr;
|
||||
BITMAPINFOHEADER* pbiOut = NULL;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = ColorConv_CheckMediaType( pImpl, pmtIn, pmtOut );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
pbiOut = (&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
|
||||
|
||||
pProp->cBuffers = 1;
|
||||
pProp->cbBuffer = DIBSIZE(*pbiOut);
|
||||
TRACE("%ldx%ldx%u cbBuffer = %ld\n",pbiOut->biWidth,pbiOut->biHeight,(unsigned)pbiOut->biBitCount,pProp->cbBuffer);
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_BeginTransform( CTransformBaseImpl* pImpl, const AM_MEDIA_TYPE* pmtIn, const AM_MEDIA_TYPE* pmtOut, BOOL bReuseSample )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
HRESULT hr;
|
||||
BITMAPINFOHEADER* pbiIn = NULL;
|
||||
BITMAPINFOHEADER* pbiOut = NULL;
|
||||
const struct BltHandler* phandler;
|
||||
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = ColorConv_CheckMediaType( pImpl, pmtIn, pmtOut );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
pbiIn = (&((VIDEOINFOHEADER*)pmtIn->pbFormat)->bmiHeader);
|
||||
pbiOut = (&((VIDEOINFOHEADER*)pmtOut->pbFormat)->bmiHeader);
|
||||
|
||||
This->pitchIn = DIBWIDTHBYTES(*pbiIn);
|
||||
This->pitchOut = DIBWIDTHBYTES(*pbiOut);
|
||||
|
||||
This->m_pBlt = NULL;
|
||||
phandler = conv_handlers;
|
||||
while ( phandler->psubtypeIn != NULL )
|
||||
{
|
||||
if ( IsEqualGUID( &pmtIn->subtype, phandler->psubtypeIn ) )
|
||||
{
|
||||
if ( IsEqualGUID( &pmtOut->subtype, phandler->psubtypeOut ) )
|
||||
{
|
||||
This->m_pBlt = phandler->pBlt;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
phandler ++;
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_Transform( CTransformBaseImpl* pImpl, IMediaSample* pSampIn, IMediaSample* pSampOut )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
BYTE* pDataIn = NULL;
|
||||
BYTE* pDataOut = NULL;
|
||||
BITMAPINFO* pbiIn;
|
||||
BITMAPINFO* pbiOut;
|
||||
HRESULT hr;
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = IMediaSample_GetPointer( pSampIn, &pDataIn );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
hr = IMediaSample_GetPointer( pSampOut, &pDataOut );
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
|
||||
if ( This->m_pBlt != NULL )
|
||||
{
|
||||
pbiIn = (BITMAPINFO*)&(((VIDEOINFOHEADER*)pImpl->pInPin->pin.pmtConn->pbFormat)->bmiHeader);
|
||||
pbiOut = (BITMAPINFO*)&(((VIDEOINFOHEADER*)pImpl->pOutPin->pin.pmtConn->pbFormat)->bmiHeader);
|
||||
This->m_pBlt(
|
||||
pDataOut, This->pitchOut,
|
||||
pDataIn, This->pitchIn,
|
||||
pbiIn->bmiHeader.biWidth,
|
||||
abs(pbiIn->bmiHeader.biHeight),
|
||||
&pbiIn->bmiColors[0], pbiIn->bmiHeader.biClrUsed );
|
||||
hr = IMediaSample_SetActualDataLength(pSampOut,DIBSIZE(pbiOut->bmiHeader));
|
||||
if ( FAILED(hr) )
|
||||
return hr;
|
||||
}
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT ColorConv_EndTransform( CTransformBaseImpl* pImpl )
|
||||
{
|
||||
CColorConvImpl* This = pImpl->m_pUserData;
|
||||
|
||||
if ( This == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
This->m_pBlt = NULL;
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
|
||||
static const TransformBaseHandlers transhandlers =
|
||||
{
|
||||
ColorConv_Init,
|
||||
ColorConv_Cleanup,
|
||||
ColorConv_CheckMediaType,
|
||||
ColorConv_GetOutputTypes,
|
||||
ColorConv_GetAllocProp,
|
||||
ColorConv_BeginTransform,
|
||||
ColorConv_Transform,
|
||||
ColorConv_EndTransform,
|
||||
};
|
||||
|
||||
HRESULT QUARTZ_CreateColour(IUnknown* punkOuter,void** ppobj)
|
||||
{
|
||||
return QUARTZ_CreateTransformBase(
|
||||
punkOuter,ppobj,
|
||||
&CLSID_Colour,
|
||||
ColorConv_FilterName,
|
||||
NULL, NULL,
|
||||
&transhandlers );
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
/*
|
||||
* 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 );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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,15 +137,35 @@ 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)
|
||||
{
|
||||
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)\n",punkOuter,ppobj);
|
||||
TRACE("(%p,%p,%d,%p)\n",punkOuter,ppobj,(int)bRendering,pPin);
|
||||
|
||||
This = (CSeekingPassThru*)QUARTZ_AllocObj( sizeof(CSeekingPassThru) );
|
||||
if ( This == NULL )
|
||||
|
@ -153,6 +173,23 @@ HRESULT QUARTZ_CreateSeekingPassThru(IUnknown* punkOuter,void** ppobj)
|
|||
|
||||
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 */
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
#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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#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"
|
||||
|
||||
|
|
|
@ -0,0 +1,801 @@
|
|||
/*
|
||||
* Implements IBaseFilter for transform filters. (internal)
|
||||
*
|
||||
* hidenori@a2.ctktv.ne.jp
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "strmif.h"
|
||||
#include "control.h"
|
||||
#include "vfwmsgs.h"
|
||||
#include "uuids.h"
|
||||
|
||||
#include "debugtools.h"
|
||||
DEFAULT_DEBUG_CHANNEL(quartz);
|
||||
|
||||
#include "quartz_private.h"
|
||||
#include "xform.h"
|
||||
#include "sample.h"
|
||||
|
||||
|
||||
static const WCHAR XFORM_DefInName[] =
|
||||
{'X','F','o','r','m',' ','I','n',0};
|
||||
static const WCHAR XFORM_DefOutName[] =
|
||||
{'X','F','o','r','m',' ','O','u','t',0};
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CTransformBaseImpl methods
|
||||
*
|
||||
*/
|
||||
|
||||
static HRESULT CTransformBaseImpl_OnActive( CBaseFilterImpl* pImpl )
|
||||
{
|
||||
CTransformBaseImpl_THIS(pImpl,basefilter);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseImpl_OnInactive( CBaseFilterImpl* pImpl )
|
||||
{
|
||||
CTransformBaseImpl_THIS(pImpl,basefilter);
|
||||
HRESULT hr;
|
||||
IMemAllocator* pAllocator;
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
if ( This->pInPin->pin.pPinConnectedTo == NULL ||
|
||||
This->pOutPin->pin.pPinConnectedTo == NULL )
|
||||
return NOERROR;
|
||||
|
||||
EnterCriticalSection( &This->csFilter );
|
||||
|
||||
pAllocator = This->m_pOutPinAllocator;
|
||||
if ( pAllocator != NULL &&
|
||||
This->pInPin->meminput.pAllocator != pAllocator )
|
||||
{
|
||||
hr = IMemAllocator_Commit( pAllocator );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ( !This->m_bFiltering )
|
||||
{
|
||||
hr = This->m_pHandler->pBeginTransform( This, This->pInPin->pin.pmtConn, This->pOutPin->pin.pmtConn, This->m_bReuseSample );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
This->m_bFiltering = TRUE;
|
||||
}
|
||||
|
||||
hr = NOERROR;
|
||||
end:
|
||||
LeaveCriticalSection( &This->csFilter );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseImpl_OnStop( CBaseFilterImpl* pImpl )
|
||||
{
|
||||
CTransformBaseImpl_THIS(pImpl,basefilter);
|
||||
IMemAllocator* pAllocator;
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
EnterCriticalSection( &This->csFilter );
|
||||
|
||||
if ( This->m_bFiltering )
|
||||
{
|
||||
This->m_pHandler->pEndTransform( This );
|
||||
This->m_bFiltering = FALSE;
|
||||
}
|
||||
if ( This->m_pSample != NULL )
|
||||
{
|
||||
IMediaSample_Release( This->m_pSample );
|
||||
This->m_pSample = NULL;
|
||||
}
|
||||
|
||||
pAllocator = This->m_pOutPinAllocator;
|
||||
if ( pAllocator != NULL &&
|
||||
This->pInPin->meminput.pAllocator != pAllocator )
|
||||
{
|
||||
IMemAllocator_Decommit( pAllocator );
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &This->csFilter );
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static const CBaseFilterHandlers filterhandlers =
|
||||
{
|
||||
CTransformBaseImpl_OnActive, /* pOnActive */
|
||||
CTransformBaseImpl_OnInactive, /* pOnInactive */
|
||||
CTransformBaseImpl_OnStop, /* pOnStop */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CTransformBaseInPinImpl methods
|
||||
*
|
||||
*/
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE( "(%p,%p)\n", This, pPin );
|
||||
|
||||
EnterCriticalSection( &This->pFilter->csFilter );
|
||||
hr = This->pFilter->m_pHandler->pGetOutputTypes( This->pFilter, This->pFilter->pInPin->pin.pmtConn, &This->pFilter->pOutPin->pin.pmtAcceptTypes, &This->pFilter->pOutPin->pin.cAcceptTypes );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
hr = NOERROR;
|
||||
end:
|
||||
LeaveCriticalSection( &This->pFilter->csFilter );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CTransformBaseInPinImpl_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 CTransformBaseInPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE( "(%p,%p)\n", This, pmt );
|
||||
|
||||
EnterCriticalSection( &This->pFilter->csFilter );
|
||||
hr = This->pFilter->m_pHandler->pCheckMediaType( This->pFilter, pmt, (This->pFilter->pOutPin->pin.pPinConnectedTo != NULL) ? This->pFilter->pOutPin->pin.pmtConn : NULL );
|
||||
LeaveCriticalSection( &This->pFilter->csFilter );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_Receive( CPinBaseImpl* pImpl, IMediaSample* pSample )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE( "(%p,%p)\n", This, pSample );
|
||||
|
||||
if ( This->pin.pPinConnectedTo == NULL ||
|
||||
This->pFilter->pOutPin->pin.pPinConnectedTo == NULL )
|
||||
return NOERROR;
|
||||
|
||||
if ( !This->pFilter->m_bFiltering )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if ( This->pFilter->m_bInFlush )
|
||||
return S_FALSE;
|
||||
|
||||
if ( This->meminput.pAllocator != This->pFilter->m_pOutPinAllocator )
|
||||
{
|
||||
if ( This->pFilter->m_pSample == NULL )
|
||||
{
|
||||
hr = IMemAllocator_GetBuffer( This->pFilter->m_pOutPinAllocator, &This->pFilter->m_pSample, NULL, NULL, 0 );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
}
|
||||
hr = QUARTZ_IMediaSample_Copy(
|
||||
This->pFilter->m_pSample, pSample, This->pFilter->m_bPreCopy );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ( This->pFilter->m_bPreCopy )
|
||||
hr = This->pFilter->m_pHandler->pTransform( This->pFilter, This->pFilter->m_pSample, NULL );
|
||||
else
|
||||
hr = This->pFilter->m_pHandler->pTransform( This->pFilter, pSample, This->pFilter->m_pSample );
|
||||
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
if ( hr == NOERROR )
|
||||
{
|
||||
hr = CPinBaseImpl_SendSample(&This->pFilter->pOutPin->pin,This->pFilter->m_pSample);
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = NOERROR;
|
||||
end:
|
||||
if ( !This->pFilter->m_bReuseSample )
|
||||
{
|
||||
if ( This->pFilter->m_pSample != NULL )
|
||||
{
|
||||
IMediaSample_Release( This->pFilter->m_pSample );
|
||||
This->pFilter->m_pSample = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
/* Notify(ABORT) */
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_ReceiveCanBlock( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
if ( This->pin.pPinConnectedTo == NULL ||
|
||||
This->pFilter->pOutPin->pin.pPinConnectedTo == NULL )
|
||||
return S_FALSE;
|
||||
|
||||
return CPinBaseImpl_SendReceiveCanBlock( &This->pFilter->pOutPin->pin );
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_EndOfStream( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
if ( This->pin.pPinConnectedTo == NULL ||
|
||||
This->pFilter->pOutPin->pin.pPinConnectedTo == NULL )
|
||||
return NOERROR;
|
||||
|
||||
return CPinBaseImpl_SendEndOfStream( &This->pFilter->pOutPin->pin );
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_BeginFlush( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
if ( This->pin.pPinConnectedTo == NULL ||
|
||||
This->pFilter->pOutPin->pin.pPinConnectedTo == NULL )
|
||||
return NOERROR;
|
||||
|
||||
This->pFilter->m_bInFlush = TRUE;
|
||||
|
||||
return CPinBaseImpl_SendBeginFlush( &This->pFilter->pOutPin->pin );
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_EndFlush( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
if ( This->pin.pPinConnectedTo == NULL ||
|
||||
This->pFilter->pOutPin->pin.pPinConnectedTo == NULL )
|
||||
return NOERROR;
|
||||
|
||||
This->pFilter->m_bInFlush = FALSE;
|
||||
|
||||
return CPinBaseImpl_SendEndFlush( &This->pFilter->pOutPin->pin );
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseInPinImpl_NewSegment( CPinBaseImpl* pImpl, REFERENCE_TIME rtStart, REFERENCE_TIME rtStop, double rate )
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(pImpl,pin);
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
if ( This->pin.pPinConnectedTo == NULL ||
|
||||
This->pFilter->pOutPin->pin.pPinConnectedTo == NULL )
|
||||
return NOERROR;
|
||||
|
||||
return CPinBaseImpl_SendNewSegment( &This->pFilter->pOutPin->pin,
|
||||
rtStart, rtStop, rate );
|
||||
}
|
||||
|
||||
static const CBasePinHandlers inputpinhandlers =
|
||||
{
|
||||
NULL, /* pOnPreConnect */
|
||||
CTransformBaseInPinImpl_OnPostConnect, /* pOnPostConnect */
|
||||
CTransformBaseInPinImpl_OnDisconnect, /* pOnDisconnect */
|
||||
CTransformBaseInPinImpl_CheckMediaType, /* pCheckMediaType */
|
||||
NULL, /* pQualityNotify */
|
||||
CTransformBaseInPinImpl_Receive, /* pReceive */
|
||||
CTransformBaseInPinImpl_ReceiveCanBlock, /* pReceiveCanBlock */
|
||||
CTransformBaseInPinImpl_EndOfStream, /* pEndOfStream */
|
||||
CTransformBaseInPinImpl_BeginFlush, /* pBeginFlush */
|
||||
CTransformBaseInPinImpl_EndFlush, /* pEndFlush */
|
||||
CTransformBaseInPinImpl_NewSegment, /* pNewSegment */
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* CTransformBaseOutPinImpl methods
|
||||
*
|
||||
*/
|
||||
|
||||
static HRESULT CTransformBaseOutPinImpl_OnPostConnect( CPinBaseImpl* pImpl, IPin* pPin )
|
||||
{
|
||||
CTransformBaseOutPinImpl_THIS(pImpl,pin);
|
||||
HRESULT hr;
|
||||
ALLOCATOR_PROPERTIES propReqThis;
|
||||
ALLOCATOR_PROPERTIES propReqPeer;
|
||||
ALLOCATOR_PROPERTIES propActual;
|
||||
BOOL bTransInPlace = FALSE;
|
||||
BOOL bTryToReUseSample = FALSE;
|
||||
BOOL bOutReadonly = FALSE;
|
||||
IMemAllocator* pAllocator;
|
||||
|
||||
FIXME( "(%p,%p)\n", This, pPin );
|
||||
|
||||
if ( This->pFilter->pInPin->pin.pPinConnectedTo == NULL )
|
||||
return E_FAIL;
|
||||
if ( This->pin.pMemInputPinConnectedTo == NULL )
|
||||
return E_UNEXPECTED;
|
||||
|
||||
ZeroMemory( &propReqThis, sizeof(ALLOCATOR_PROPERTIES) );
|
||||
ZeroMemory( &propReqPeer, sizeof(ALLOCATOR_PROPERTIES) );
|
||||
ZeroMemory( &propActual, sizeof(ALLOCATOR_PROPERTIES) );
|
||||
|
||||
hr = This->pFilter->m_pHandler->pGetAllocProp( This->pFilter, This->pFilter->pInPin->pin.pmtConn, This->pin.pmtConn, &propReqThis, &bTransInPlace, &bTryToReUseSample );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
|
||||
if ( propReqThis.cbAlign == 0 )
|
||||
propReqThis.cbAlign = 1;
|
||||
|
||||
if ( bTransInPlace )
|
||||
{
|
||||
ZeroMemory( &propReqPeer, sizeof(ALLOCATOR_PROPERTIES) );
|
||||
hr = IMemInputPin_GetAllocatorRequirements(
|
||||
This->pin.pMemInputPinConnectedTo, &propReqPeer );
|
||||
if ( propReqPeer.cbAlign != 0 && propReqPeer.cbAlign != 1 )
|
||||
bTransInPlace = FALSE;
|
||||
if ( propReqPeer.cbPrefix != 0 )
|
||||
bTransInPlace = FALSE;
|
||||
|
||||
bOutReadonly = FALSE;
|
||||
if ( bTransInPlace && This->pFilter->pInPin->meminput.bReadonly )
|
||||
bOutReadonly = TRUE;
|
||||
|
||||
pAllocator = This->pFilter->pInPin->meminput.pAllocator;
|
||||
|
||||
hr = IMemInputPin_NotifyAllocator(
|
||||
This->pin.pMemInputPinConnectedTo,
|
||||
pAllocator, bOutReadonly );
|
||||
if ( hr == NOERROR )
|
||||
{
|
||||
This->pFilter->m_pOutPinAllocator = pAllocator;
|
||||
IMemAllocator_AddRef(pAllocator);
|
||||
bTryToReUseSample = FALSE;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
hr = IMemInputPin_GetAllocator(
|
||||
This->pin.pMemInputPinConnectedTo, &pAllocator );
|
||||
if ( FAILED(hr) )
|
||||
goto end;
|
||||
hr = IMemAllocator_SetProperties( pAllocator, &propReqThis, &propActual );
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
TRACE("cBuffers = %ld / cbBuffer = %ld\n",propActual.cBuffers,propActual.cbBuffer);
|
||||
hr = IMemInputPin_NotifyAllocator(
|
||||
This->pin.pMemInputPinConnectedTo, pAllocator,
|
||||
bTryToReUseSample );
|
||||
}
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
IMemAllocator_Release(pAllocator);
|
||||
goto end;
|
||||
}
|
||||
This->pFilter->m_pOutPinAllocator = pAllocator;
|
||||
|
||||
hr = NOERROR;
|
||||
end:
|
||||
This->pFilter->m_bPreCopy = FALSE;
|
||||
This->pFilter->m_bReuseSample = FALSE;
|
||||
if ( hr == NOERROR )
|
||||
{
|
||||
This->pFilter->m_bPreCopy = bTransInPlace && (This->pFilter->pInPin->meminput.pAllocator != This->pFilter->m_pOutPinAllocator);
|
||||
This->pFilter->m_bReuseSample = bTryToReUseSample;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseOutPinImpl_OnDisconnect( CPinBaseImpl* pImpl )
|
||||
{
|
||||
CTransformBaseOutPinImpl_THIS(pImpl,pin);
|
||||
|
||||
FIXME( "(%p)\n", This );
|
||||
|
||||
if ( This->pFilter->m_pOutPinAllocator != NULL )
|
||||
{
|
||||
IMemAllocator_Decommit(This->pFilter->m_pOutPinAllocator);
|
||||
IMemAllocator_Release(This->pFilter->m_pOutPinAllocator);
|
||||
This->pFilter->m_pOutPinAllocator = NULL;
|
||||
}
|
||||
|
||||
return NOERROR;
|
||||
}
|
||||
|
||||
static HRESULT CTransformBaseOutPinImpl_CheckMediaType( CPinBaseImpl* pImpl, const AM_MEDIA_TYPE* pmt )
|
||||
{
|
||||
CTransformBaseOutPinImpl_THIS(pImpl,pin);
|
||||
HRESULT hr;
|
||||
|
||||
TRACE( "(%p,%p)\n", This, pmt );
|
||||
|
||||
if ( This->pFilter->pInPin->pin.pPinConnectedTo == NULL )
|
||||
return E_FAIL;
|
||||
|
||||
EnterCriticalSection( &This->pFilter->csFilter );
|
||||
hr = This->pFilter->m_pHandler->pCheckMediaType( This->pFilter, This->pFilter->pInPin->pin.pmtConn, pmt );
|
||||
LeaveCriticalSection( &This->pFilter->csFilter );
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static const CBasePinHandlers outputpinhandlers =
|
||||
{
|
||||
NULL, /* pOnPreConnect */
|
||||
CTransformBaseOutPinImpl_OnPostConnect, /* pOnPostConnect */
|
||||
CTransformBaseOutPinImpl_OnDisconnect, /* pOnDisconnect */
|
||||
CTransformBaseOutPinImpl_CheckMediaType, /* pCheckMediaType */
|
||||
NULL, /* pQualityNotify */
|
||||
OutputPinSync_Receive, /* pReceive */
|
||||
OutputPinSync_ReceiveCanBlock, /* pReceiveCanBlock */
|
||||
OutputPinSync_EndOfStream, /* pEndOfStream */
|
||||
OutputPinSync_BeginFlush, /* pBeginFlush */
|
||||
OutputPinSync_EndFlush, /* pEndFlush */
|
||||
OutputPinSync_NewSegment, /* pNewSegment */
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* new/delete CTransformBaseImpl
|
||||
*
|
||||
*/
|
||||
|
||||
/* can I use offsetof safely? - FIXME? */
|
||||
static QUARTZ_IFEntry FilterIFEntries[] =
|
||||
{
|
||||
{ &IID_IPersist, offsetof(CTransformBaseImpl,basefilter)-offsetof(CTransformBaseImpl,unk) },
|
||||
{ &IID_IMediaFilter, offsetof(CTransformBaseImpl,basefilter)-offsetof(CTransformBaseImpl,unk) },
|
||||
{ &IID_IBaseFilter, offsetof(CTransformBaseImpl,basefilter)-offsetof(CTransformBaseImpl,unk) },
|
||||
};
|
||||
|
||||
static void QUARTZ_DestroyTransformBase(IUnknown* punk)
|
||||
{
|
||||
CTransformBaseImpl_THIS(punk,unk);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
This->m_pHandler->pCleanup(This);
|
||||
|
||||
if ( This->pInPin != NULL )
|
||||
{
|
||||
IUnknown_Release(This->pInPin->unk.punkControl);
|
||||
This->pInPin = NULL;
|
||||
}
|
||||
if ( This->pOutPin != NULL )
|
||||
{
|
||||
IUnknown_Release(This->pOutPin->unk.punkControl);
|
||||
This->pOutPin = NULL;
|
||||
}
|
||||
if ( This->pSeekPass != NULL )
|
||||
{
|
||||
IUnknown_Release((IUnknown*)&This->pSeekPass->unk);
|
||||
This->pSeekPass = NULL;
|
||||
}
|
||||
|
||||
CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
|
||||
|
||||
DeleteCriticalSection( &This->csFilter );
|
||||
}
|
||||
|
||||
HRESULT QUARTZ_CreateTransformBase(
|
||||
IUnknown* punkOuter,void** ppobj,
|
||||
const CLSID* pclsidTransformBase,
|
||||
LPCWSTR pwszTransformBaseName,
|
||||
LPCWSTR pwszInPinName,
|
||||
LPCWSTR pwszOutPinName,
|
||||
const TransformBaseHandlers* pHandler )
|
||||
{
|
||||
CTransformBaseImpl* This = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p)\n",punkOuter,ppobj);
|
||||
|
||||
if ( pwszInPinName == NULL )
|
||||
pwszInPinName = XFORM_DefInName;
|
||||
if ( pwszOutPinName == NULL )
|
||||
pwszOutPinName = XFORM_DefOutName;
|
||||
|
||||
This = (CTransformBaseImpl*)
|
||||
QUARTZ_AllocObj( sizeof(CTransformBaseImpl) );
|
||||
if ( This == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
This->pInPin = NULL;
|
||||
This->pOutPin = NULL;
|
||||
This->pSeekPass = NULL;
|
||||
This->m_pOutPinAllocator = NULL;
|
||||
This->m_bPreCopy = FALSE; /* sample must be copied */
|
||||
This->m_bReuseSample = FALSE; /* sample must be reused */
|
||||
This->m_bInFlush = FALSE;
|
||||
This->m_pSample = NULL;
|
||||
This->m_bFiltering = FALSE;
|
||||
This->m_pHandler = pHandler;
|
||||
This->m_pUserData = NULL;
|
||||
|
||||
QUARTZ_IUnkInit( &This->unk, punkOuter );
|
||||
|
||||
hr = CBaseFilterImpl_InitIBaseFilter(
|
||||
&This->basefilter,
|
||||
This->unk.punkControl,
|
||||
pclsidTransformBase,
|
||||
pwszTransformBaseName,
|
||||
&filterhandlers );
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
/* construct this class. */
|
||||
hr = This->m_pHandler->pInit( This );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
CBaseFilterImpl_UninitIBaseFilter(&This->basefilter);
|
||||
}
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
QUARTZ_FreeObj(This);
|
||||
return hr;
|
||||
}
|
||||
|
||||
This->unk.pEntries = FilterIFEntries;
|
||||
This->unk.dwEntries = sizeof(FilterIFEntries)/sizeof(FilterIFEntries[0]);
|
||||
This->unk.pOnFinalRelease = QUARTZ_DestroyTransformBase;
|
||||
InitializeCriticalSection( &This->csFilter );
|
||||
|
||||
/* create pins. */
|
||||
hr = QUARTZ_CreateTransformBaseInPin(
|
||||
This, &This->csFilter,
|
||||
&This->pInPin, pwszInPinName );
|
||||
if ( SUCCEEDED(hr) )
|
||||
hr = QUARTZ_CompList_AddComp(
|
||||
This->basefilter.pInPins,
|
||||
(IUnknown*)&(This->pInPin->pin),
|
||||
NULL, 0 );
|
||||
if ( SUCCEEDED(hr) )
|
||||
hr = QUARTZ_CreateTransformBaseOutPin(
|
||||
This, &This->csFilter,
|
||||
&This->pOutPin, pwszOutPinName );
|
||||
if ( SUCCEEDED(hr) )
|
||||
hr = QUARTZ_CompList_AddComp(
|
||||
This->basefilter.pOutPins,
|
||||
(IUnknown*)&(This->pOutPin->pin),
|
||||
NULL, 0 );
|
||||
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = QUARTZ_CreateSeekingPassThruInternal(
|
||||
(IUnknown*)&(This->pOutPin->unk), &This->pSeekPass,
|
||||
FALSE, (IPin*)&(This->pInPin->pin) );
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
IUnknown_Release( This->unk.punkControl );
|
||||
return hr;
|
||||
}
|
||||
|
||||
*ppobj = (void*)&(This->unk);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* new/delete CTransformBaseInPinImpl
|
||||
*
|
||||
*/
|
||||
|
||||
/* can I use offsetof safely? - FIXME? */
|
||||
static QUARTZ_IFEntry InPinIFEntries[] =
|
||||
{
|
||||
{ &IID_IPin, offsetof(CTransformBaseInPinImpl,pin)-offsetof(CTransformBaseInPinImpl,unk) },
|
||||
{ &IID_IMemInputPin, offsetof(CTransformBaseInPinImpl,meminput)-offsetof(CTransformBaseInPinImpl,unk) },
|
||||
};
|
||||
|
||||
static void QUARTZ_DestroyTransformBaseInPin(IUnknown* punk)
|
||||
{
|
||||
CTransformBaseInPinImpl_THIS(punk,unk);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
CPinBaseImpl_UninitIPin( &This->pin );
|
||||
CMemInputPinBaseImpl_UninitIMemInputPin( &This->meminput );
|
||||
}
|
||||
|
||||
HRESULT QUARTZ_CreateTransformBaseInPin(
|
||||
CTransformBaseImpl* pFilter,
|
||||
CRITICAL_SECTION* pcsPin,
|
||||
CTransformBaseInPinImpl** ppPin,
|
||||
LPCWSTR pwszPinName )
|
||||
{
|
||||
CTransformBaseInPinImpl* This = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
|
||||
|
||||
This = (CTransformBaseInPinImpl*)
|
||||
QUARTZ_AllocObj( sizeof(CTransformBaseInPinImpl) );
|
||||
if ( This == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
QUARTZ_IUnkInit( &This->unk, NULL );
|
||||
This->pFilter = pFilter;
|
||||
|
||||
hr = CPinBaseImpl_InitIPin(
|
||||
&This->pin,
|
||||
This->unk.punkControl,
|
||||
pcsPin,
|
||||
&pFilter->basefilter,
|
||||
pwszPinName,
|
||||
FALSE,
|
||||
&inputpinhandlers );
|
||||
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = CMemInputPinBaseImpl_InitIMemInputPin(
|
||||
&This->meminput,
|
||||
This->unk.punkControl,
|
||||
&This->pin );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
CPinBaseImpl_UninitIPin( &This->pin );
|
||||
}
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
QUARTZ_FreeObj(This);
|
||||
return hr;
|
||||
}
|
||||
|
||||
This->unk.pEntries = InPinIFEntries;
|
||||
This->unk.dwEntries = sizeof(InPinIFEntries)/sizeof(InPinIFEntries[0]);
|
||||
This->unk.pOnFinalRelease = QUARTZ_DestroyTransformBaseInPin;
|
||||
|
||||
*ppPin = This;
|
||||
|
||||
TRACE("returned successfully.\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* new/delete CTransformBaseOutPinImpl
|
||||
*
|
||||
*/
|
||||
|
||||
/* can I use offsetof safely? - FIXME? */
|
||||
static QUARTZ_IFEntry OutPinIFEntries[] =
|
||||
{
|
||||
{ &IID_IPin, offsetof(CTransformBaseOutPinImpl,pin)-offsetof(CTransformBaseOutPinImpl,unk) },
|
||||
{ &IID_IQualityControl, offsetof(CTransformBaseOutPinImpl,qcontrol)-offsetof(CTransformBaseOutPinImpl,unk) },
|
||||
};
|
||||
|
||||
static HRESULT CTransformBaseOutPinImpl_OnQueryInterface(
|
||||
IUnknown* punk, const IID* piid, void** ppobj )
|
||||
{
|
||||
CTransformBaseOutPinImpl_THIS(punk,unk);
|
||||
|
||||
if ( This->pFilter == NULL || This->pFilter->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->pFilter->pSeekPass->unk), piid, ppobj );
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static void QUARTZ_DestroyTransformBaseOutPin(IUnknown* punk)
|
||||
{
|
||||
CTransformBaseOutPinImpl_THIS(punk,unk);
|
||||
|
||||
TRACE( "(%p)\n", This );
|
||||
|
||||
CPinBaseImpl_UninitIPin( &This->pin );
|
||||
CQualityControlPassThruImpl_UninitIQualityControl( &This->qcontrol );
|
||||
}
|
||||
|
||||
HRESULT QUARTZ_CreateTransformBaseOutPin(
|
||||
CTransformBaseImpl* pFilter,
|
||||
CRITICAL_SECTION* pcsPin,
|
||||
CTransformBaseOutPinImpl** ppPin,
|
||||
LPCWSTR pwszPinName )
|
||||
{
|
||||
CTransformBaseOutPinImpl* This = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%p,%p)\n",pFilter,pcsPin,ppPin);
|
||||
|
||||
This = (CTransformBaseOutPinImpl*)
|
||||
QUARTZ_AllocObj( sizeof(CTransformBaseOutPinImpl) );
|
||||
if ( This == NULL )
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
QUARTZ_IUnkInit( &This->unk, NULL );
|
||||
This->qiext.pNext = NULL;
|
||||
This->qiext.pOnQueryInterface = &CTransformBaseOutPinImpl_OnQueryInterface;
|
||||
QUARTZ_IUnkAddDelegation( &This->unk, &This->qiext );
|
||||
|
||||
This->pFilter = pFilter;
|
||||
|
||||
hr = CPinBaseImpl_InitIPin(
|
||||
&This->pin,
|
||||
This->unk.punkControl,
|
||||
pcsPin,
|
||||
&pFilter->basefilter,
|
||||
pwszPinName,
|
||||
TRUE,
|
||||
&outputpinhandlers );
|
||||
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
hr = CQualityControlPassThruImpl_InitIQualityControl(
|
||||
&This->qcontrol,
|
||||
This->unk.punkControl,
|
||||
&This->pin );
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
CPinBaseImpl_UninitIPin( &This->pin );
|
||||
}
|
||||
}
|
||||
|
||||
if ( FAILED(hr) )
|
||||
{
|
||||
QUARTZ_FreeObj(This);
|
||||
return hr;
|
||||
}
|
||||
|
||||
This->unk.pEntries = OutPinIFEntries;
|
||||
This->unk.dwEntries = sizeof(OutPinIFEntries)/sizeof(OutPinIFEntries[0]);
|
||||
This->unk.pOnFinalRelease = QUARTZ_DestroyTransformBaseOutPin;
|
||||
|
||||
*ppPin = This;
|
||||
|
||||
TRACE("returned successfully.\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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 */
|
Loading…
Reference in New Issue