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 + -
显示快捷键?