amfilter.cpp.svn-base
来自「ffshow源码」· SVN-BASE 代码 · 共 2,432 行 · 第 1/5 页
SVN-BASE
2,432 行
//------------------------------------------------------------------------------// File: AMFilter.cpp//// Desc: DirectShow base classes - implements class hierarchy for streams// architecture.//// Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.//------------------------------------------------------------------------------//=====================================================================//=====================================================================// The following classes are declared in this header:////// CBaseMediaFilter Basic IMediaFilter support (abstract class)// CBaseFilter Support for IBaseFilter (incl. IMediaFilter)// CEnumPins Enumerate input and output pins// CEnumMediaTypes Enumerate the preferred pin formats// CBasePin Abstract base class for IPin interface// CBaseOutputPin Adds data provider member functions// CBaseInputPin Implements IMemInputPin interface// CMediaSample Basic transport unit for IMemInputPin// CBaseAllocator General list guff for most allocators// CMemAllocator Implements memory buffer allocation////=====================================================================//=====================================================================#include "stdafx.h"//=====================================================================// Helpers//=====================================================================STDAPI CreateMemoryAllocator(IMemAllocator **ppAllocator){ return CoCreateInstance(CLSID_MemoryAllocator, 0, CLSCTX_INPROC_SERVER, IID_IMemAllocator, (void **)ppAllocator);}// Put this one here rather than in ctlutil.cpp to avoid linking// anything brought in by ctlutil.cppSTDAPI CreatePosPassThru( LPUNKNOWN pAgg, BOOL bRenderer, IPin *pPin, IUnknown **ppPassThru){ *ppPassThru = NULL; IUnknown *pUnkSeek; HRESULT hr = CoCreateInstance(CLSID_SeekingPassThru, pAgg, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)&pUnkSeek ); if (FAILED(hr)) { return hr; } ISeekingPassThru *pPassThru; hr = pUnkSeek->QueryInterface(IID_ISeekingPassThru, (void**)&pPassThru); if (FAILED(hr)) { pUnkSeek->Release(); return hr; } hr = pPassThru->Init(bRenderer, pPin); pPassThru->Release(); if (FAILED(hr)) { pUnkSeek->Release(); return hr; } *ppPassThru = pUnkSeek; return S_OK;}//=====================================================================//=====================================================================// Implements CBaseMediaFilter//=====================================================================//=====================================================================/* Constructor */CBaseMediaFilter::CBaseMediaFilter(const TCHAR *pName, LPUNKNOWN pUnk, CCritSec *pLock, REFCLSID clsid) : CUnknown(pName, pUnk), m_pLock(pLock), m_clsid(clsid), m_State(State_Stopped), m_pClock(NULL){}/* Destructor */CBaseMediaFilter::~CBaseMediaFilter(){ // must be stopped, but can't call Stop here since // our critsec has been destroyed. /* Release any clock we were using */ if (m_pClock) { m_pClock->Release(); m_pClock = NULL; }}/* Override this to say what interfaces we support and where */STDMETHODIMPCBaseMediaFilter::NonDelegatingQueryInterface( REFIID riid, void ** ppv){ if (riid == IID_IMediaFilter) { return GetInterface((IMediaFilter *) this, ppv); } else if (riid == IID_IPersist) { return GetInterface((IPersist *) this, ppv); } else { return CUnknown::NonDelegatingQueryInterface(riid, ppv); }}/* Return the filter's clsid */STDMETHODIMPCBaseMediaFilter::GetClassID(CLSID *pClsID){ CheckPointer(pClsID,E_POINTER); ValidateReadWritePtr(pClsID,sizeof(CLSID)); *pClsID = m_clsid; return NOERROR;}/* Override this if your state changes are not done synchronously */STDMETHODIMPCBaseMediaFilter::GetState(DWORD dwMSecs, FILTER_STATE *State){ UNREFERENCED_PARAMETER(dwMSecs); CheckPointer(State,E_POINTER); ValidateReadWritePtr(State,sizeof(FILTER_STATE)); *State = m_State; return S_OK;}/* Set the clock we will use for synchronisation */STDMETHODIMPCBaseMediaFilter::SetSyncSource(IReferenceClock *pClock){ CAutoLock cObjectLock(m_pLock); // Ensure the new one does not go away - even if the same as the old if (pClock) { pClock->AddRef(); } // if we have a clock, release it if (m_pClock) { m_pClock->Release(); } // Set the new reference clock (might be NULL) // Should we query it to ensure it is a clock? Consider for a debug build. m_pClock = pClock; return NOERROR;}/* Return the clock we are using for synchronisation */STDMETHODIMPCBaseMediaFilter::GetSyncSource(IReferenceClock **pClock){ CheckPointer(pClock,E_POINTER); ValidateReadWritePtr(pClock,sizeof(IReferenceClock *)); CAutoLock cObjectLock(m_pLock); if (m_pClock) { // returning an interface... addref it... m_pClock->AddRef(); } *pClock = (IReferenceClock*)m_pClock; return NOERROR;}/* Put the filter into a stopped state */STDMETHODIMPCBaseMediaFilter::Stop(){ CAutoLock cObjectLock(m_pLock); m_State = State_Stopped; return S_OK;}/* Put the filter into a paused state */STDMETHODIMPCBaseMediaFilter::Pause(){ CAutoLock cObjectLock(m_pLock); m_State = State_Paused; return S_OK;}// Put the filter into a running state.// The time parameter is the offset to be added to the samples'// stream time to get the reference time at which they should be presented.//// you can either add these two and compare it against the reference clock,// or you can call CBaseMediaFilter::StreamTime and compare that against// the sample timestamp.STDMETHODIMPCBaseMediaFilter::Run(REFERENCE_TIME tStart){ CAutoLock cObjectLock(m_pLock); // remember the stream time offset m_tStart = tStart; if (m_State == State_Stopped){ HRESULT hr = Pause(); if (FAILED(hr)) { return hr; } } m_State = State_Running; return S_OK;}//// return the current stream time - samples with start timestamps of this// time or before should be rendered by nowHRESULTCBaseMediaFilter::StreamTime(CRefTime& rtStream){ // Caller must lock for synchronization // We can't grab the filter lock because we want to be able to call // this from worker threads without deadlocking if (m_pClock == NULL) { return VFW_E_NO_CLOCK; } // get the current reference time HRESULT hr = m_pClock->GetTime((REFERENCE_TIME*)&rtStream); if (FAILED(hr)) { return hr; } // subtract the stream offset to get stream time rtStream -= m_tStart; return S_OK;}//=====================================================================//=====================================================================// Implements CBaseFilter//=====================================================================//=====================================================================/* Override this to say what interfaces we support and where */STDMETHODIMP CBaseFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv){ /* Do we have this interface */ if (riid == IID_IBaseFilter) { return GetInterface((IBaseFilter *) this, ppv); } else if (riid == IID_IMediaFilter) { return GetInterface((IMediaFilter *) this, ppv); } else if (riid == IID_IPersist) { return GetInterface((IPersist *) this, ppv); } else if (riid == IID_IAMovieSetup) { return GetInterface((IAMovieSetup *) this, ppv); } else { return CUnknown::NonDelegatingQueryInterface(riid, ppv); }}#ifdef DEBUGSTDMETHODIMP_(ULONG) CBaseFilter::NonDelegatingRelease(){ if (m_cRef == 1) { KASSERT(m_pGraph == NULL); } return CUnknown::NonDelegatingRelease();}#endif/* Constructor */CBaseFilter::CBaseFilter(const TCHAR *pName, LPUNKNOWN pUnk, CCritSec *pLock, REFCLSID clsid) : CUnknown( pName, pUnk ), m_pLock(pLock), m_clsid(clsid), m_State(State_Stopped), m_pClock(NULL), m_pGraph(NULL), m_pSink(NULL), m_pName(NULL), m_PinVersion(1){ ASSERT(pLock != NULL);}/* Passes in a redundant HRESULT argument */CBaseFilter::CBaseFilter(const TCHAR *pName, LPUNKNOWN pUnk, CCritSec *pLock, REFCLSID clsid, HRESULT *phr) : CUnknown( pName, pUnk ), m_pLock(pLock), m_clsid(clsid), m_State(State_Stopped), m_pClock(NULL), m_pGraph(NULL), m_pSink(NULL), m_pName(NULL), m_PinVersion(1){ ASSERT(pLock != NULL); UNREFERENCED_PARAMETER(phr);}#ifdef UNICODECBaseFilter::CBaseFilter(const CHAR *pName, LPUNKNOWN pUnk, CCritSec *pLock, REFCLSID clsid) : CUnknown( pName, pUnk ), m_pLock(pLock), m_clsid(clsid), m_State(State_Stopped), m_pClock(NULL), m_pGraph(NULL), m_pSink(NULL), m_pName(NULL), m_PinVersion(1){ ASSERT(pLock != NULL);}CBaseFilter::CBaseFilter(const CHAR *pName, LPUNKNOWN pUnk, CCritSec *pLock, REFCLSID clsid, HRESULT *phr) : CUnknown( pName, pUnk ), m_pLock(pLock), m_clsid(clsid), m_State(State_Stopped), m_pClock(NULL), m_pGraph(NULL), m_pSink(NULL), m_pName(NULL), m_PinVersion(1){ ASSERT(pLock != NULL); UNREFERENCED_PARAMETER(phr);}#endif/* Destructor */CBaseFilter::~CBaseFilter(){ // NOTE we do NOT hold references on the filtergraph for m_pGraph or m_pSink // When we did we had the circular reference problem. Nothing would go away. delete[] m_pName; // must be stopped, but can't call Stop here since // our critsec has been destroyed. /* Release any clock we were using */ if (m_pClock) { m_pClock->Release(); m_pClock = NULL; }}/* Return the filter's clsid */STDMETHODIMPCBaseFilter::GetClassID(CLSID *pClsID){ CheckPointer(pClsID,E_POINTER); ValidateReadWritePtr(pClsID,sizeof(CLSID)); *pClsID = m_clsid; return NOERROR;}/* Override this if your state changes are not done synchronously */STDMETHODIMPCBaseFilter::GetState(DWORD dwMSecs, FILTER_STATE *State){ UNREFERENCED_PARAMETER(dwMSecs); CheckPointer(State,E_POINTER); ValidateReadWritePtr(State,sizeof(FILTER_STATE)); *State = m_State; return S_OK;}/* Set the clock we will use for synchronisation */STDMETHODIMPCBaseFilter::SetSyncSource(IReferenceClock *pClock){ CAutoLock cObjectLock(m_pLock); // Ensure the new one does not go away - even if the same as the old if (pClock) { pClock->AddRef(); } // if we have a clock, release it if (m_pClock) { m_pClock->Release(); } // Set the new reference clock (might be NULL) // Should we query it to ensure it is a clock? Consider for a debug build. m_pClock = pClock; return NOERROR;}/* Return the clock we are using for synchronisation */STDMETHODIMPCBaseFilter::GetSyncSource(IReferenceClock **pClock){ CheckPointer(pClock,E_POINTER); ValidateReadWritePtr(pClock,sizeof(IReferenceClock *)); CAutoLock cObjectLock(m_pLock); if (m_pClock) { // returning an interface... addref it... m_pClock->AddRef(); } *pClock = (IReferenceClock*)m_pClock; return NOERROR;}// override CBaseMediaFilter Stop method, to deactivate any pins this// filter has.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?