forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			251 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			251 lines
		
	
	
		
			8.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | //------------------------------------------------------------------------------
 | ||
|  | // File: TransIP.h
 | ||
|  | //
 | ||
|  | // Desc: DirectShow base classes - defines classes from which simple
 | ||
|  | //       Transform-In-Place filters may be derived.
 | ||
|  | //
 | ||
|  | // Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
 | ||
|  | //------------------------------------------------------------------------------
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //
 | ||
|  | // The difference between this and Transfrm.h is that Transfrm copies the data.
 | ||
|  | //
 | ||
|  | // It assumes the filter 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 __TRANSIP__
 | ||
|  | #define __TRANSIP__
 | ||
|  | 
 | ||
|  | // ======================================================================
 | ||
|  | // This is the com object that represents a simple transform filter. It
 | ||
|  | // supports IBaseFilter, IMediaFilter and two pins through nested interfaces
 | ||
|  | // ======================================================================
 | ||
|  | 
 | ||
|  | class CTransInPlaceFilter; | ||
|  | 
 | ||
|  | // Several of the pin functions call filter functions to do the work,
 | ||
|  | // so you can often use the pin classes unaltered, just overriding the
 | ||
|  | // functions in CTransInPlaceFilter.  If that's not enough and you want
 | ||
|  | // to derive your own pin class, override GetPin in the filter to supply
 | ||
|  | // your own pin classes to the filter.
 | ||
|  | 
 | ||
|  | // ==================================================
 | ||
|  | // Implements the input pin
 | ||
|  | // ==================================================
 | ||
|  | 
 | ||
|  | class CTransInPlaceInputPin : public CTransformInputPin | ||
|  | { | ||
|  | 
 | ||
|  | protected: | ||
|  |     CTransInPlaceFilter * const m_pTIPFilter;    // our filter
 | ||
|  |     BOOL                 m_bReadOnly;    // incoming stream is read only
 | ||
|  | 
 | ||
|  | public: | ||
|  | 
 | ||
|  |     CTransInPlaceInputPin( | ||
|  |         __in_opt LPCTSTR     pObjectName, | ||
|  |         __inout CTransInPlaceFilter *pFilter, | ||
|  |         __inout HRESULT             *phr, | ||
|  |         __in_opt LPCWSTR              pName); | ||
|  | 
 | ||
|  |     // --- IMemInputPin -----
 | ||
|  | 
 | ||
|  |     // Provide an enumerator for media types by getting one from downstream
 | ||
|  |     STDMETHODIMP EnumMediaTypes( __deref_out IEnumMediaTypes **ppEnum ); | ||
|  | 
 | ||
|  |     // Say whether media type is acceptable.
 | ||
|  |     HRESULT CheckMediaType(const CMediaType* pmt); | ||
|  | 
 | ||
|  |     // Return our upstream allocator
 | ||
|  |     STDMETHODIMP GetAllocator(__deref_out IMemAllocator ** ppAllocator); | ||
|  | 
 | ||
|  |     // get told which allocator the upstream output pin is actually
 | ||
|  |     // going to use.
 | ||
|  |     STDMETHODIMP NotifyAllocator(IMemAllocator * pAllocator, | ||
|  |                                  BOOL bReadOnly); | ||
|  | 
 | ||
|  |     // Allow the filter to see what allocator we have
 | ||
|  |     // N.B. This does NOT AddRef
 | ||
|  |     __out IMemAllocator * PeekAllocator() const | ||
|  |         {  return m_pAllocator; } | ||
|  | 
 | ||
|  |     // Pass this on downstream if it ever gets called.
 | ||
|  |     STDMETHODIMP GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES *pProps); | ||
|  | 
 | ||
|  |     HRESULT CompleteConnect(IPin *pReceivePin); | ||
|  | 
 | ||
|  |     inline const BOOL ReadOnly() { return m_bReadOnly ; } | ||
|  | 
 | ||
|  | };  // CTransInPlaceInputPin
 | ||
|  | 
 | ||
|  | // ==================================================
 | ||
|  | // Implements the output pin
 | ||
|  | // ==================================================
 | ||
|  | 
 | ||
|  | class CTransInPlaceOutputPin : public CTransformOutputPin | ||
|  | { | ||
|  | 
 | ||
|  | protected: | ||
|  |     // m_pFilter points to our CBaseFilter
 | ||
|  |     CTransInPlaceFilter * const m_pTIPFilter; | ||
|  | 
 | ||
|  | public: | ||
|  | 
 | ||
|  |     CTransInPlaceOutputPin( | ||
|  |         __in_opt LPCTSTR     pObjectName, | ||
|  |         __inout CTransInPlaceFilter *pFilter, | ||
|  |         __inout HRESULT             *phr, | ||
|  |         __in_opt LPCWSTR              pName); | ||
|  | 
 | ||
|  | 
 | ||
|  |     // --- CBaseOutputPin ------------
 | ||
|  | 
 | ||
|  |     // negotiate the allocator and its buffer size/count
 | ||
|  |     // Insists on using our own allocator.  (Actually the one upstream of us).
 | ||
|  |     // We don't override this - instead we just agree the default
 | ||
|  |     // then let the upstream filter decide for itself on reconnect
 | ||
|  |     // virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc);
 | ||
|  | 
 | ||
|  |     // Provide a media type enumerator.  Get it from upstream.
 | ||
|  |     STDMETHODIMP EnumMediaTypes( __deref_out IEnumMediaTypes **ppEnum ); | ||
|  | 
 | ||
|  |     // Say whether media type is acceptable.
 | ||
|  |     HRESULT CheckMediaType(const CMediaType* pmt); | ||
|  | 
 | ||
|  |     //  This just saves the allocator being used on the output pin
 | ||
|  |     //  Also called by input pin's GetAllocator()
 | ||
|  |     void SetAllocator(IMemAllocator * pAllocator); | ||
|  | 
 | ||
|  |     __out_opt IMemInputPin * ConnectedIMemInputPin() | ||
|  |         { return m_pInputPin; } | ||
|  | 
 | ||
|  |     // Allow the filter to see what allocator we have
 | ||
|  |     // N.B. This does NOT AddRef
 | ||
|  |     __out IMemAllocator * PeekAllocator() const | ||
|  |         {  return m_pAllocator; } | ||
|  | 
 | ||
|  |     HRESULT CompleteConnect(IPin *pReceivePin); | ||
|  | 
 | ||
|  | };  // CTransInPlaceOutputPin
 | ||
|  | 
 | ||
|  | 
 | ||
|  | class AM_NOVTABLE CTransInPlaceFilter : public CTransformFilter | ||
|  | { | ||
|  | 
 | ||
|  | public: | ||
|  | 
 | ||
|  |     // map getpin/getpincount for base enum of pins to owner
 | ||
|  |     // override this to return more specialised pin objects
 | ||
|  | 
 | ||
|  |     virtual CBasePin *GetPin(int n); | ||
|  | 
 | ||
|  | public: | ||
|  | 
 | ||
|  |     //  Set bModifiesData == false if your derived filter does
 | ||
|  |     //  not modify the data samples (for instance it's just copying
 | ||
|  |     //  them somewhere else or looking at the timestamps).
 | ||
|  | 
 | ||
|  |     CTransInPlaceFilter(__in_opt LPCTSTR, __inout_opt LPUNKNOWN, REFCLSID clsid, __inout HRESULT *, | ||
|  |                         bool bModifiesData = true); | ||
|  | #ifdef UNICODE
 | ||
|  |     CTransInPlaceFilter(__in_opt LPCSTR, __inout_opt LPUNKNOWN, REFCLSID clsid, __inout HRESULT *, | ||
|  |                         bool bModifiesData = true); | ||
|  | #endif
 | ||
|  |     // The following are defined to avoid undefined pure virtuals.
 | ||
|  |     // Even if they are never called, they will give linkage warnings/errors
 | ||
|  | 
 | ||
|  |     // We override EnumMediaTypes to bypass the transform class enumerator
 | ||
|  |     // which would otherwise call this.
 | ||
|  |     HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType) | ||
|  |         {   DbgBreak("CTransInPlaceFilter::GetMediaType should never be called"); | ||
|  |             return E_UNEXPECTED; | ||
|  |         } | ||
|  | 
 | ||
|  |     // This is called when we actually have to provide our own allocator.
 | ||
|  |     HRESULT DecideBufferSize(IMemAllocator*, __inout ALLOCATOR_PROPERTIES *); | ||
|  | 
 | ||
|  |     // The functions which call this in CTransform are overridden in this
 | ||
|  |     // class to call CheckInputType with the assumption that the type
 | ||
|  |     // does not change.  In Debug builds some calls will be made and
 | ||
|  |     // we just ensure that they do not assert.
 | ||
|  |     HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut) | ||
|  |     { | ||
|  |         return S_OK; | ||
|  |     }; | ||
|  | 
 | ||
|  | 
 | ||
|  |     // =================================================================
 | ||
|  |     // ----- You may want to override this -----------------------------
 | ||
|  |     // =================================================================
 | ||
|  | 
 | ||
|  |     HRESULT CompleteConnect(PIN_DIRECTION dir,IPin *pReceivePin); | ||
|  | 
 | ||
|  |     // chance to customize the transform process
 | ||
|  |     virtual HRESULT Receive(IMediaSample *pSample); | ||
|  | 
 | ||
|  |     // =================================================================
 | ||
|  |     // ----- You MUST override these -----------------------------------
 | ||
|  |     // =================================================================
 | ||
|  | 
 | ||
|  |     virtual HRESULT Transform(IMediaSample *pSample) PURE; | ||
|  | 
 | ||
|  |     // this goes in the factory template table to create new instances
 | ||
|  |     // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *);
 | ||
|  | 
 | ||
|  | 
 | ||
|  | #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_idTransInPlace = MSR_REGISTER(TEXT("TransInPlace"));} | ||
|  | #endif // PERF
 | ||
|  | 
 | ||
|  | 
 | ||
|  | // implementation details
 | ||
|  | 
 | ||
|  | protected: | ||
|  | 
 | ||
|  |     __out_opt IMediaSample * Copy(IMediaSample *pSource); | ||
|  | 
 | ||
|  | #ifdef PERF
 | ||
|  |     int m_idTransInPlace;                 // performance measuring id
 | ||
|  | #endif // PERF
 | ||
|  |     bool  m_bModifiesData;                // Does this filter change the data?
 | ||
|  | 
 | ||
|  |     // these hold our input and output pins
 | ||
|  | 
 | ||
|  |     friend class CTransInPlaceInputPin; | ||
|  |     friend class CTransInPlaceOutputPin; | ||
|  | 
 | ||
|  |     __out CTransInPlaceInputPin  *InputPin() const | ||
|  |     { | ||
|  |         return (CTransInPlaceInputPin *)m_pInput; | ||
|  |     }; | ||
|  |     __out CTransInPlaceOutputPin *OutputPin() const | ||
|  |     { | ||
|  |         return (CTransInPlaceOutputPin *)m_pOutput; | ||
|  |     }; | ||
|  | 
 | ||
|  |     //  Helper to see if the input and output types match
 | ||
|  |     BOOL TypesMatch() | ||
|  |     { | ||
|  |         return InputPin()->CurrentMediaType() == | ||
|  |                OutputPin()->CurrentMediaType(); | ||
|  |     } | ||
|  | 
 | ||
|  |     //  Are the input and output allocators different?
 | ||
|  |     BOOL UsingDifferentAllocators() const | ||
|  |     { | ||
|  |         return InputPin()->PeekAllocator() != OutputPin()->PeekAllocator(); | ||
|  |     } | ||
|  | }; // CTransInPlaceFilter
 | ||
|  | 
 | ||
|  | #endif /* __TRANSIP__ */
 | ||
|  | 
 |