forked from LeenkxTeam/LNXSDK
		
	
		
			
				
	
	
		
			305 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//------------------------------------------------------------------------------
 | 
						|
// File: Transfrm.h
 | 
						|
//
 | 
						|
// Desc: DirectShow base classes - defines classes from which simple 
 | 
						|
//       transform codecs may be derived.
 | 
						|
//
 | 
						|
// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
 | 
						|
//------------------------------------------------------------------------------
 | 
						|
 | 
						|
 | 
						|
// It assumes the codec has one input and one output stream, and has no
 | 
						|
// interest in memory management, interface negotiation or anything else.
 | 
						|
//
 | 
						|
// derive your class from this, and supply Transform and the media type/format
 | 
						|
// negotiation functions. Implement that class, compile and link and
 | 
						|
// you're done.
 | 
						|
 | 
						|
 | 
						|
#ifndef __TRANSFRM__
 | 
						|
#define __TRANSFRM__
 | 
						|
 | 
						|
// ======================================================================
 | 
						|
// This is the com object that represents a simple transform filter. It
 | 
						|
// supports IBaseFilter, IMediaFilter and two pins through nested interfaces
 | 
						|
// ======================================================================
 | 
						|
 | 
						|
class CTransformFilter;
 | 
						|
 | 
						|
// ==================================================
 | 
						|
// Implements the input pin
 | 
						|
// ==================================================
 | 
						|
 | 
						|
class CTransformInputPin : public CBaseInputPin
 | 
						|
{
 | 
						|
    friend class CTransformFilter;
 | 
						|
 | 
						|
protected:
 | 
						|
    CTransformFilter *m_pTransformFilter;
 | 
						|
 | 
						|
 | 
						|
public:
 | 
						|
 | 
						|
    CTransformInputPin(
 | 
						|
        __in_opt LPCTSTR pObjectName,
 | 
						|
        __inout CTransformFilter *pTransformFilter,
 | 
						|
        __inout HRESULT * phr,
 | 
						|
        __in_opt LPCWSTR pName);
 | 
						|
#ifdef UNICODE
 | 
						|
    CTransformInputPin(
 | 
						|
        __in_opt LPCSTR pObjectName,
 | 
						|
        __inout CTransformFilter *pTransformFilter,
 | 
						|
        __inout HRESULT * phr,
 | 
						|
        __in_opt LPCWSTR pName);
 | 
						|
#endif
 | 
						|
 | 
						|
    STDMETHODIMP QueryId(__deref_out LPWSTR * Id)
 | 
						|
    {
 | 
						|
        return AMGetWideString(L"In", Id);
 | 
						|
    }
 | 
						|
 | 
						|
    // Grab and release extra interfaces if required
 | 
						|
 | 
						|
    HRESULT CheckConnect(IPin *pPin);
 | 
						|
    HRESULT BreakConnect();
 | 
						|
    HRESULT CompleteConnect(IPin *pReceivePin);
 | 
						|
 | 
						|
    // check that we can support this output type
 | 
						|
    HRESULT CheckMediaType(const CMediaType* mtIn);
 | 
						|
 | 
						|
    // set the connection media type
 | 
						|
    HRESULT SetMediaType(const CMediaType* mt);
 | 
						|
 | 
						|
    // --- IMemInputPin -----
 | 
						|
 | 
						|
    // here's the next block of data from the stream.
 | 
						|
    // AddRef it yourself if you need to hold it beyond the end
 | 
						|
    // of this call.
 | 
						|
    STDMETHODIMP Receive(IMediaSample * pSample);
 | 
						|
 | 
						|
    // provide EndOfStream that passes straight downstream
 | 
						|
    // (there is no queued data)
 | 
						|
    STDMETHODIMP EndOfStream(void);
 | 
						|
 | 
						|
    // passes it to CTransformFilter::BeginFlush
 | 
						|
    STDMETHODIMP BeginFlush(void);
 | 
						|
 | 
						|
    // passes it to CTransformFilter::EndFlush
 | 
						|
    STDMETHODIMP EndFlush(void);
 | 
						|
 | 
						|
    STDMETHODIMP NewSegment(
 | 
						|
                        REFERENCE_TIME tStart,
 | 
						|
                        REFERENCE_TIME tStop,
 | 
						|
                        double dRate);
 | 
						|
 | 
						|
    // Check if it's OK to process samples
 | 
						|
    virtual HRESULT CheckStreaming();
 | 
						|
 | 
						|
    // Media type
 | 
						|
public:
 | 
						|
    CMediaType& CurrentMediaType() { return m_mt; };
 | 
						|
 | 
						|
};
 | 
						|
 | 
						|
// ==================================================
 | 
						|
// Implements the output pin
 | 
						|
// ==================================================
 | 
						|
 | 
						|
class CTransformOutputPin : public CBaseOutputPin
 | 
						|
{
 | 
						|
    friend class CTransformFilter;
 | 
						|
 | 
						|
protected:
 | 
						|
    CTransformFilter *m_pTransformFilter;
 | 
						|
 | 
						|
public:
 | 
						|
 | 
						|
    // implement IMediaPosition by passing upstream
 | 
						|
    IUnknown * m_pPosition;
 | 
						|
 | 
						|
    CTransformOutputPin(
 | 
						|
        __in_opt LPCTSTR pObjectName,
 | 
						|
        __inout CTransformFilter *pTransformFilter,
 | 
						|
        __inout HRESULT * phr,
 | 
						|
        __in_opt LPCWSTR pName);
 | 
						|
#ifdef UNICODE
 | 
						|
    CTransformOutputPin(
 | 
						|
        __in_opt LPCSTR pObjectName,
 | 
						|
        __inout CTransformFilter *pTransformFilter,
 | 
						|
        __inout HRESULT * phr,
 | 
						|
        __in_opt LPCWSTR pName);
 | 
						|
#endif
 | 
						|
    ~CTransformOutputPin();
 | 
						|
 | 
						|
    // override to expose IMediaPosition
 | 
						|
    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
 | 
						|
 | 
						|
    // --- CBaseOutputPin ------------
 | 
						|
 | 
						|
    STDMETHODIMP QueryId(__deref_out LPWSTR * Id)
 | 
						|
    {
 | 
						|
        return AMGetWideString(L"Out", Id);
 | 
						|
    }
 | 
						|
 | 
						|
    // Grab and release extra interfaces if required
 | 
						|
 | 
						|
    HRESULT CheckConnect(IPin *pPin);
 | 
						|
    HRESULT BreakConnect();
 | 
						|
    HRESULT CompleteConnect(IPin *pReceivePin);
 | 
						|
 | 
						|
    // check that we can support this output type
 | 
						|
    HRESULT CheckMediaType(const CMediaType* mtOut);
 | 
						|
 | 
						|
    // set the connection media type
 | 
						|
    HRESULT SetMediaType(const CMediaType *pmt);
 | 
						|
 | 
						|
    // called from CBaseOutputPin during connection to ask for
 | 
						|
    // the count and size of buffers we need.
 | 
						|
    HRESULT DecideBufferSize(
 | 
						|
                IMemAllocator * pAlloc,
 | 
						|
                __inout ALLOCATOR_PROPERTIES *pProp);
 | 
						|
 | 
						|
    // returns the preferred formats for a pin
 | 
						|
    HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType);
 | 
						|
 | 
						|
    // inherited from IQualityControl via CBasePin
 | 
						|
    STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
 | 
						|
 | 
						|
    // Media type
 | 
						|
public:
 | 
						|
    CMediaType& CurrentMediaType() { return m_mt; };
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
class AM_NOVTABLE CTransformFilter : public CBaseFilter
 | 
						|
{
 | 
						|
 | 
						|
public:
 | 
						|
 | 
						|
    // map getpin/getpincount for base enum of pins to owner
 | 
						|
    // override this to return more specialised pin objects
 | 
						|
 | 
						|
    virtual int GetPinCount();
 | 
						|
    virtual CBasePin * GetPin(int n);
 | 
						|
    STDMETHODIMP FindPin(LPCWSTR Id, __deref_out IPin **ppPin);
 | 
						|
 | 
						|
    // override state changes to allow derived transform filter
 | 
						|
    // to control streaming start/stop
 | 
						|
    STDMETHODIMP Stop();
 | 
						|
    STDMETHODIMP Pause();
 | 
						|
 | 
						|
public:
 | 
						|
 | 
						|
    CTransformFilter(__in_opt LPCTSTR , __inout_opt LPUNKNOWN, REFCLSID clsid);
 | 
						|
#ifdef UNICODE
 | 
						|
    CTransformFilter(__in_opt LPCSTR , __inout_opt LPUNKNOWN, REFCLSID clsid);
 | 
						|
#endif
 | 
						|
    ~CTransformFilter();
 | 
						|
 | 
						|
    // =================================================================
 | 
						|
    // ----- override these bits ---------------------------------------
 | 
						|
    // =================================================================
 | 
						|
 | 
						|
    // These must be supplied in a derived class
 | 
						|
 | 
						|
    virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut);
 | 
						|
 | 
						|
    // check if you can support mtIn
 | 
						|
    virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE;
 | 
						|
 | 
						|
    // check if you can support the transform from this input to this output
 | 
						|
    virtual HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut) PURE;
 | 
						|
 | 
						|
    // this goes in the factory template table to create new instances
 | 
						|
    // static CCOMObject * CreateInstance(__inout_opt LPUNKNOWN, HRESULT *);
 | 
						|
 | 
						|
    // call the SetProperties function with appropriate arguments
 | 
						|
    virtual HRESULT DecideBufferSize(
 | 
						|
                        IMemAllocator * pAllocator,
 | 
						|
                        __inout ALLOCATOR_PROPERTIES *pprop) PURE;
 | 
						|
 | 
						|
    // override to suggest OUTPUT pin media types
 | 
						|
    virtual HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType) PURE;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    // =================================================================
 | 
						|
    // ----- Optional Override Methods           -----------------------
 | 
						|
    // =================================================================
 | 
						|
 | 
						|
    // you can also override these if you want to know about streaming
 | 
						|
    virtual HRESULT StartStreaming();
 | 
						|
    virtual HRESULT StopStreaming();
 | 
						|
 | 
						|
    // override if you can do anything constructive with quality notifications
 | 
						|
    virtual HRESULT AlterQuality(Quality q);
 | 
						|
 | 
						|
    // override this to know when the media type is actually set
 | 
						|
    virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt);
 | 
						|
 | 
						|
    // chance to grab extra interfaces on connection
 | 
						|
    virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin);
 | 
						|
    virtual HRESULT BreakConnect(PIN_DIRECTION dir);
 | 
						|
    virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin);
 | 
						|
 | 
						|
    // chance to customize the transform process
 | 
						|
    virtual HRESULT Receive(IMediaSample *pSample);
 | 
						|
 | 
						|
    // Standard setup for output sample
 | 
						|
    HRESULT InitializeOutputSample(IMediaSample *pSample, __deref_out IMediaSample **ppOutSample);
 | 
						|
 | 
						|
    // if you override Receive, you may need to override these three too
 | 
						|
    virtual HRESULT EndOfStream(void);
 | 
						|
    virtual HRESULT BeginFlush(void);
 | 
						|
    virtual HRESULT EndFlush(void);
 | 
						|
    virtual HRESULT NewSegment(
 | 
						|
                        REFERENCE_TIME tStart,
 | 
						|
                        REFERENCE_TIME tStop,
 | 
						|
                        double dRate);
 | 
						|
 | 
						|
#ifdef PERF
 | 
						|
    // Override to register performance measurement with a less generic string
 | 
						|
    // You should do this to avoid confusion with other filters
 | 
						|
    virtual void RegisterPerfId()
 | 
						|
         {m_idTransform = MSR_REGISTER(TEXT("Transform"));}
 | 
						|
#endif // PERF
 | 
						|
 | 
						|
 | 
						|
// implementation details
 | 
						|
 | 
						|
protected:
 | 
						|
 | 
						|
#ifdef PERF
 | 
						|
    int m_idTransform;                 // performance measuring id
 | 
						|
#endif
 | 
						|
    BOOL m_bEOSDelivered;              // have we sent EndOfStream
 | 
						|
    BOOL m_bSampleSkipped;             // Did we just skip a frame
 | 
						|
    BOOL m_bQualityChanged;            // Have we degraded?
 | 
						|
 | 
						|
    // critical section protecting filter state.
 | 
						|
 | 
						|
    CCritSec m_csFilter;
 | 
						|
 | 
						|
    // critical section stopping state changes (ie Stop) while we're
 | 
						|
    // processing a sample.
 | 
						|
    //
 | 
						|
    // This critical section is held when processing
 | 
						|
    // events that occur on the receive thread - Receive() and EndOfStream().
 | 
						|
    //
 | 
						|
    // If you want to hold both m_csReceive and m_csFilter then grab
 | 
						|
    // m_csFilter FIRST - like CTransformFilter::Stop() does.
 | 
						|
 | 
						|
    CCritSec m_csReceive;
 | 
						|
 | 
						|
    // these hold our input and output pins
 | 
						|
 | 
						|
    friend class CTransformInputPin;
 | 
						|
    friend class CTransformOutputPin;
 | 
						|
    CTransformInputPin *m_pInput;
 | 
						|
    CTransformOutputPin *m_pOutput;
 | 
						|
};
 | 
						|
 | 
						|
#endif /* __TRANSFRM__ */
 | 
						|
 | 
						|
 |