Utility Filter

LiuYinChina發表於2013-02-18
Utility Filter,誰用誰知道!

#ifndef UtilityFilter_H
#define UtilityFilter_H
 
//////////////////////////////////////////////////////////////////////////
 
#include <Streams.h>
 
//////////////////////////////////////////////////////////////////////////
 
#include "OwnerPolicy.h"
 
//////////////////////////////////////////////////////////////////////////
 
template <typename OwnerT>
class SourcePinT    :   public CSourceStream,
                        public OwnerPolicy<OwnerT>
{
public:
    SourcePinT(OwnerT *pOwner, CSource *pFilter, HRESULT *phr)
        :   CSourceStream(NULL, phr, pFilter, NULL),
            m_lFrameCount(0),
            m_rtFrameLength(UNITS / 1)
    {
        owner(pOwner);
    }
 
public:
    VOID SetFPS(DWORD dwFPS)
    {
        m_rtFrameLength = UNITS / ((dwFPS == 0) ? 1 : dwFPS);
    }
 
private:
    HRESULT GetMediaType(CMediaType *pMediaType)
    {
        CAutoLock cAutoLock(m_pFilter->pStateLock());
        return owner()->GetMediaType(this, pMediaType);
    }
 
    HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest)
    {
        CAutoLock cAutoLock(m_pFilter->pStateLock());
        pRequest->cbBuffer = owner()->DecideBufferSize(this, &m_mt);
        if (pRequest->cBuffers == 0) {
            pRequest->cBuffers = 1;
        }
 
        ALLOCATOR_PROPERTIES actual = { 0 };
        HRESULT hr = pAlloc->SetProperties(pRequest, &actual);
        if (FAILED(hr)) {
            return hr;
        }
        return (actual.cbBuffer < pRequest->cbBuffer) ? E_FAIL : S_OK;
    }
    HRESULT CompleteConnect(IPin *pReceivePin)
    {
        HRESULT hr = CSourceStream::CompleteConnect(pReceivePin);
        if (FAILED(hr)) {
            goto Exit;
        }
        {
            CMediaType mediaType;
            hr = ConnectionMediaType(&mediaType);
            if (FAILED(hr)) {
                goto Exit;
            }
            owner()->OnCompleteConnect(this, &mediaType);
        }
    Exit:
        return hr;
    }
 
    HRESULT FillBuffer(IMediaSample *pSample)
    {
        LPBYTE lpBuffer         = NULL;
        LONG lBufferLength      = 0;
        REFERENCE_TIME rtStart  = 0;
        REFERENCE_TIME rtFinish = 0;
        HRESULT hr = pSample->GetPointer(&lpBuffer);
        if (FAILED(hr) || lpBuffer == NULL) {
            goto Exit;
        }
 
        {
            CAutoLock cAutoLockShared(&m_cSharedState);
            owner()->FillBuffer(this, lpBuffer, &lBufferLength);
        }
        hr = pSample->SetActualDataLength(lBufferLength);
        if (FAILED(hr)) {
            goto Exit;
        }
 
        rtStart = m_rtFrameLength * m_lFrameCount++;
        rtFinish= rtStart + m_rtFrameLength;
        pSample->SetTime(&rtStart, &rtFinish);
        pSample->SetSyncPoint(TRUE);
 
    Exit:
        return hr;
    }
 
private:
    CCritSec m_cSharedState;
 
    LONG m_lFrameCount;
    REFERENCE_TIME m_rtFrameLength;
};
 
//////////////////////////////////////////////////////////////////////////
 
template <DWORD>
class SourceFilterT :   public CSource
{
public:
    SourceFilterT(REFGUID refFilterGUID)
        :   CSource(NAME("SourceFilter"), NULL, refFilterGUID)
    {
        AddRef();
    }
    ~SourceFilterT()
    {
    }
};
 
//////////////////////////////////////////////////////////////////////////
 
typedef SourceFilterT<0> CSourceFilter;
 
//////////////////////////////////////////////////////////////////////////
 
template <typename OwnerT>
class TransInPlaceFilterT   :   public CTransInPlaceFilter,
                                public OwnerPolicy<OwnerT>
{
public:
    TransInPlaceFilterT(OwnerT *pOwner, REFGUID refFilterGUID, HRESULT *phr)
        :   CTransInPlaceFilter(NAME("TransInPlaceFilter"), NULL, refFilterGUID, phr)
    {
        owner(pOwner);
 
        AddRef();
    }
    ~TransInPlaceFilterT()
    {
    }
 
private:
    HRESULT CompleteConnect(IPin *pReceivePin)
    {
        HRESULT hr = CSourceStream::CompleteConnect(pReceivePin);
        if (FAILED(hr)) {
            goto Exit;
        }
        {
            CMediaType mediaType;
            hr = ConnectionMediaType(&mediaType);
            if (FAILED(hr)) {
                goto Exit;
            }
            owner()->OnCompleteConnect(this, &mediaType);
        }
    Exit:
        return hr;
    }
 
    HRESULT Transform(IMediaSample *pSample)
    {
        LPBYTE lpBuffer = NULL;
        pSample->GetPointer(&lpBuffer);
 
        return owner()->Transform(this, lpBuffer, pSample->GetActualDataLength());
    }
 
    HRESULT CheckInputType(const CMediaType *mtIn)
    {
        return owner()->CheckInputType(this, mtIn);
    }
};
 
//////////////////////////////////////////////////////////////////////////
 
template <typename OwnerT>
class TransformFilterT  :   public CTransformFilter,
                            public OwnerPolicy<OwnerT>
{
public:
    TransformFilterT(OwnerT *pOwner, REFGUID refFilterGUID)
        :   CTransformFilter(NAME("TransformFilter"), NULL, refFilterGUID)
    {
        owner(pOwner);
 
        AddRef();
    }
    ~TransformFilterT()
    {
    }
 
private:
    HRESULT CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
    {
        CMediaType mediaType;
 
        HRESULT hr = CTransformFilter::CompleteConnect(direction, pReceivePin);
        if (FAILED(hr)) {
            goto Exit;
        }
        switch (direction) {
            case PINDIR_INPUT:
                hr = m_pInput->ConnectionMediaType(&mediaType);
                break;
            case PINDIR_OUTPUT:
                hr = m_pOutput->ConnectionMediaType(&mediaType);
                break;
        }
        owner()->OnCompleteConnect(this, direction, &mediaType);
 
    Exit:
        return hr;
    }
    HRESULT Transform(IMediaSample *pSrc, IMediaSample *pDst)
    {
        return owner()->Transform(this, pSrc, pDst);
    }
    HRESULT CheckInputType(const CMediaType *mtIn)
    {
        return owner()->CheckInputType(this, mtIn);
    }
    HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
    {
        return owner()->CheckTransform(this, mtIn, mtOut);
    }
    HRESULT DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest)
    {
        AM_MEDIA_TYPE mediaTypeInput    = { 0 };
        AM_MEDIA_TYPE mediaTypeOutput   = { 0 };
 
        HRESULT hr = E_FAIL;
        hr = m_pInput->ConnectionMediaType(&mediaTypeInput);
        hr = m_pOutput->ConnectionMediaType(&mediaTypeOutput);
 
        pRequest->cbBuffer = owner()->DecideBufferSize(this, &mediaTypeInput, &mediaTypeOutput);
        if (pRequest->cBuffers == 0) {
            pRequest->cBuffers = 1;
        }
 
        ALLOCATOR_PROPERTIES actual = { 0 };
        hr = pAlloc->SetProperties(pRequest, &actual);
        if (FAILED(hr)) {
            return hr;
        }
        return (actual.cbBuffer < pRequest->cbBuffer) ? E_FAIL : S_OK;
    }
    HRESULT GetMediaType(int iPosition, CMediaType *pMediaType)
    {
        return owner()->GetMediaType(this, iPosition, pMediaType, &(m_pInput->CurrentMediaType()));
    }
};
 
//////////////////////////////////////////////////////////////////////////
 
template <typename OwnerT>
class RenderedFilterPinT    :   public CRenderedInputPin,
                                public OwnerPolicy<OwnerT>
{
public:
    RenderedFilterPinT(CBaseFilter *pFilter, CCritSec *pLock, HRESULT *phr)
        :   CRenderedInputPin(NAME("RenderedFilterPin"), pFilter, pLock, phr, NULL)
    {
    }
 
private:
    STDMETHODIMP Receive(IMediaSample *pSample)
    {
        LPBYTE lpBuffer = NULL;
        pSample->GetPointer(&lpBuffer);
 
        CAutoLock lock(m_csReceive);
        owner()->Receive(this, lpBuffer, pSample->GetActualDataLength());
        return S_OK;
    }
    STDMETHODIMP EndOfStream()
    {
        CAutoLock lock(m_csReceive);
        owner()->EndOfStream(this);
    }
    STDMETHODIMP ReceiveCanBlock()
    {
        return S_FALSE;
    }
    HRESULT CheckMediaType(const CMediaType *mtType)
    {
        return owner()->CheckMediaType(this, mtType);
    }
 
private:
    CCritSec m_csReceive;
};
 
//////////////////////////////////////////////////////////////////////////
 
template <typename OwnerT>
class RenderedFilterT   :   public CBaseFilter,
                            public OwnerPolicy<OwnerT>
{
public:
    RenderedFilterT(OwnerT *pOwner, REFGUID refFilterGUID, CCritSec *pLock)
        :   CBaseFilter(NAME("RenderedFilter"), NULL, pLock, refFilterGUID)
    {
        owner(pOwner);
 
        AddRef();
    }
 
private:
    CBasePin * GetPin(int nIndex)
    {
        return owner()->GetPin(this, nIndex);
    }
    int GetPinCount()
    {
        return owner()->GetPinCount(this);
    }
};
 
//////////////////////////////////////////////////////////////////////////
 
#endif

相關文章