| //------------------------------------------------------------------------------ | |
| // 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 * CTransInPlaceFilter::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__ */ | |