⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amfilter.h

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 H
📖 第 1 页 / 共 4 页
字号:
                        REFERENCE_TIME tStop,
                        double dRate);

    //================================================================================
    // IQualityControl methods
    //================================================================================

    // All inherited from CBasePin and not overridden here.
    // STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
    // STDMETHODIMP SetSink(IQualityControl * piqc);
};


//=====================================================================
//=====================================================================
// Defines CBaseInputPin
//
// derive your standard input pin from this.
// you need to supply GetMediaType and CheckConnect etc (see CBasePin),
// and you need to supply Receive to do something more useful.
//
//=====================================================================
//=====================================================================

class AM_NOVTABLE CBaseInputPin : public CBasePin,
                                  public IMemInputPin
{

protected:

    IMemAllocator *m_pAllocator;    // Default memory allocator

    // allocator is read-only, so received samples
    // cannot be modified (probably only relevant to in-place
    // transforms
    BYTE m_bReadOnly;

    // in flushing state (between BeginFlush and EndFlush)
    // if TRUE, all Receives are returned with S_FALSE
    BYTE m_bFlushing;

    // Sample properties - initalized in Receive
    AM_SAMPLE2_PROPERTIES m_SampleProps;

public:

    CBaseInputPin(
        TCHAR *pObjectName,
        CBaseFilter *pFilter,
        CCritSec *pLock,
        HRESULT *phr,
        LPCWSTR pName);
#ifdef UNICODE
    CBaseInputPin(
        CHAR *pObjectName,
        CBaseFilter *pFilter,
        CCritSec *pLock,
        HRESULT *phr,
        LPCWSTR pName);
#endif
    virtual ~CBaseInputPin();

    DECLARE_IUNKNOWN

    // override this to publicise our interfaces
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);

    // return the allocator interface that this input pin
    // would like the output pin to use
    STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator);

    // tell the input pin which allocator the output pin is actually
    // going to use.
    STDMETHODIMP NotifyAllocator(
                    IMemAllocator * pAllocator,
                    BOOL bReadOnly);

    // do something with this media sample
    STDMETHODIMP Receive(IMediaSample *pSample);

    // do something with these media samples
    STDMETHODIMP ReceiveMultiple (
        IMediaSample **pSamples,
        long nSamples,
        long *nSamplesProcessed);

    // See if Receive() blocks
    STDMETHODIMP ReceiveCanBlock();

    // Default handling for BeginFlush - call at the beginning
    // of your implementation (makes sure that all Receive calls
    // fail). After calling this, you need to free any queued data
    // and then call downstream.
    STDMETHODIMP BeginFlush(void);

    // default handling for EndFlush - call at end of your implementation
    // - before calling this, ensure that there is no queued data and no thread
    // pushing any more without a further receive, then call downstream,
    // then call this method to clear the m_bFlushing flag and re-enable
    // receives
    STDMETHODIMP EndFlush(void);

    // this method is optional (can return E_NOTIMPL).
    // default implementation returns E_NOTIMPL. Override if you have
    // specific alignment or prefix needs, but could use an upstream
    // allocator
    STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps);

    // Release the pin's allocator.
    HRESULT BreakConnect();

    // helper method to check the read-only flag
    BOOL IsReadOnly() {
        return m_bReadOnly;
    };

    // helper method to see if we are flushing
    BOOL IsFlushing() {
        return m_bFlushing;
    };

    //  Override this for checking whether it's OK to process samples
    //  Also call this from EndOfStream.
    virtual HRESULT CheckStreaming();

    // Pass a Quality notification on to the appropriate sink
    HRESULT PassNotify(Quality& q);


    //================================================================================
    // IQualityControl methods (from CBasePin)
    //================================================================================

    STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);

    // no need to override:
    // STDMETHODIMP SetSink(IQualityControl * piqc);


    // switch the pin to inactive state - may already be inactive
    virtual HRESULT Inactive(void);

    // Return sample properties pointer
    AM_SAMPLE2_PROPERTIES * SampleProps() {
        ASSERT(m_SampleProps.cbData != 0);
        return &m_SampleProps;
    }

};

///////////////////////////////////////////////////////////////////////////
// CDynamicOutputPin
//

class CDynamicOutputPin : public CBaseOutputPin,
                          public IPinFlowControl
{
public:
#ifdef UNICODE
    CDynamicOutputPin(
        CHAR *pObjectName,
        CBaseFilter *pFilter,
        CCritSec *pLock,
        HRESULT *phr,
        LPCWSTR pName);
#endif

    CDynamicOutputPin(
        TCHAR *pObjectName,
        CBaseFilter *pFilter,
        CCritSec *pLock,
        HRESULT *phr,
        LPCWSTR pName);

    ~CDynamicOutputPin();

    // IUnknown Methods
    DECLARE_IUNKNOWN
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);

    // IPin Methods
    STDMETHODIMP Disconnect(void);

    // IPinFlowControl Methods
    STDMETHODIMP Block(DWORD dwBlockFlags, HANDLE hEvent);

    //  Set graph config info
    void SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent);

    #ifdef DEBUG
    virtual HRESULT Deliver(IMediaSample *pSample);
    virtual HRESULT DeliverEndOfStream(void);
    virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
    #endif // DEBUG

    HRESULT DeliverBeginFlush(void);
    HRESULT DeliverEndFlush(void);

    HRESULT Inactive(void);
    HRESULT Active(void);
    virtual HRESULT CompleteConnect(IPin *pReceivePin);

    virtual HRESULT StartUsingOutputPin(void);
    virtual void StopUsingOutputPin(void);
    virtual bool StreamingThreadUsingOutputPin(void);

    HRESULT ChangeOutputFormat
        (
        const AM_MEDIA_TYPE *pmt,
        REFERENCE_TIME tSegmentStart,
        REFERENCE_TIME tSegmentStop,
        double dSegmentRate
        );
    HRESULT ChangeMediaType(const CMediaType *pmt);
    HRESULT DynamicReconnect(const CMediaType *pmt);

protected:
    HRESULT SynchronousBlockOutputPin(void);
    HRESULT AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent);
    HRESULT UnblockOutputPin(void);

    void BlockOutputPin(void);
    void ResetBlockState(void);

    static HRESULT WaitEvent(HANDLE hEvent);

    enum BLOCK_STATE
    {
        NOT_BLOCKED,
        PENDING,
        BLOCKED
    };

    // This lock should be held when the following class members are
    // being used: m_hNotifyCallerPinBlockedEvent, m_BlockState,
    // m_dwBlockCallerThreadID and m_dwNumOutstandingOutputPinUsers.
    CCritSec m_BlockStateLock;

    // This event should be signaled when the output pin is
    // not blocked.  This is a manual reset event.  For more
    // information on events, see the documentation for
    // CreateEvent() in the Windows SDK.
    HANDLE m_hUnblockOutputPinEvent;

    // This event will be signaled when block operation succeedes or
    // when the user cancels the block operation.  The block operation
    // can be canceled by calling IPinFlowControl2::Block( 0, NULL )
    // while the block operation is pending.
    HANDLE m_hNotifyCallerPinBlockedEvent;

    // The state of the current block operation.
    BLOCK_STATE m_BlockState;

    // The ID of the thread which last called IPinFlowControl::Block().
    // For more information on thread IDs, see the documentation for
    // GetCurrentThreadID() in the Windows SDK.
    DWORD m_dwBlockCallerThreadID;

    // The number of times StartUsingOutputPin() has been sucessfully
    // called and a corresponding call to StopUsingOutputPin() has not
    // been made.  When this variable is greater than 0, the streaming
    // thread is calling IPin::NewSegment(), IPin::EndOfStream(),
    // IMemInputPin::Receive() or IMemInputPin::ReceiveMultiple().  The
    // streaming thread could also be calling: DynamicReconnect(),
    // ChangeMediaType() or ChangeOutputFormat().  The output pin cannot
    // be blocked while the output pin is being used.
    DWORD m_dwNumOutstandingOutputPinUsers;

    // This event should be set when the IMediaFilter::Stop() is called.
    // This is a manual reset event.  It is also set when the output pin
    // delivers a flush to the connected input pin.
    HANDLE m_hStopEvent;
    IGraphConfig* m_pGraphConfig;

    // TRUE if the output pin's allocator's samples are read only.
    // Otherwise FALSE.  For more information, see the documentation
    // for IMemInputPin::NotifyAllocator().
    BOOL m_bPinUsesReadOnlyAllocator;

private:
    HRESULT Initialize(void);
    HRESULT ChangeMediaTypeHelper(const CMediaType *pmt);

    #ifdef DEBUG
    void AssertValid(void);
    #endif // DEBUG
};

class CAutoUsingOutputPin
{
public:
    CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr );
    ~CAutoUsingOutputPin();

private:
    CDynamicOutputPin* m_pOutputPin;
};

inline CAutoUsingOutputPin::CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr ) :
    m_pOutputPin(NULL)
{
    // The caller should always pass in valid pointers.
    ASSERT( NULL != pOutputPin );
    ASSERT( NULL != phr );

    // Make sure the user initialized phr.
    ASSERT( S_OK == *phr );

    HRESULT hr = pOutputPin->StartUsingOutputPin();
    if( FAILED( hr ) )
    {
        *phr = hr;
        return;
    }

    m_pOutputPin = pOutputPin;
}

inline CAutoUsingOutputPin::~CAutoUsingOutputPin()
{
    if( NULL != m_pOutputPin )
    {
        m_pOutputPin->StopUsingOutputPin();
    }
}

#ifdef DEBUG

inline HRESULT CDynamicOutputPin::Deliver(IMediaSample *pSample)
{
    // The caller should call StartUsingOutputPin() before calling this
    // method.
    ASSERT(StreamingThreadUsingOutputPin());

    return CBaseOutputPin::Deliver(pSample);
}

inline HRESULT CDynamicOutputPin::DeliverEndOfStream(void)
{
    // The caller should call StartUsingOutputPin() before calling this
    // method.
    ASSERT( StreamingThreadUsingOutputPin() );

    return CBaseOutputPin::DeliverEndOfStream();
}

inline HRESULT CDynamicOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
    // The caller should call StartUsingOutputPin() before calling this
    // method.
    ASSERT(StreamingThreadUsingOutputPin());

    return CBaseOutputPin::DeliverNewSegment(tStart, tStop, dRate);
}

#endif // DEBUG

//=====================================================================
//=====================================================================
// Memory allocators
//
// the shared memory transport between pins requires the input pin
// to provide a memory allocator that can provide sample objects. A
// sample object supports the IMediaSample interface.
//
// CBaseAllocator handles the management of free and busy samples. It
// allocates CMediaSample objects. CBaseAllocator is an abstract class:
// in particular it has no method of initializing the list of free
// samples. CMemAllocator is derived from CBaseAllocator and initializes
// the list of samples using memory from the standard IMalloc interface.
//
// If you want your buffers to live in some special area of memory,
// derive your allocator object from CBaseAllocator. If you derive your
// IMemInputPin interface object from CBaseMemInputPin, you will get
// CMemAllocator-based allocation etc for free and will just need to
// supply the Receive handling, and media type / format negotiation.
//=====================================================================
//=====================================================================


//=====================================================================
//=====================================================================
// Defines CMediaSample
//
// an object of this class supports IMediaSample and represents a buffer
// for media data with some associated properties. Releasing it returns
// it to a freelist managed by a CBaseAllocator derived object.
//=====================================================================
//=====================================================================

class CMediaSample : public IMediaSample2    // The interface we support
{

protected:

    friend class CBaseAllocator;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -