//==========================================================================; // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1992 - 1998 Microsoft Corporation. All Rights Reserved. // //--------------------------------------------------------------------------; // // base class from which you can derive a simple Transform-In-Place filter. // 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 *m_pTIPFilter; // our filter BOOL m_bReadOnly; // incoming stream is read only public: CTransInPlaceInputPin( TCHAR *pObjectName, CTransInPlaceFilter *pFilter, HRESULT *phr, LPCWSTR pName); // --- IMemInputPin ----- // Provide an enumerator for media types by getting one from downstream STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum ); // Say whether media type is acceptable. HRESULT CheckMediaType(const CMediaType* pmt); // Return our upstream allocator STDMETHODIMP GetAllocator(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 IMemAllocator * PeekAllocator() { return m_pAllocator; } // Pass this on downstream if it ever gets called. STDMETHODIMP CTransInPlaceInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); inline const BOOL ReadOnly() { return m_bReadOnly; } }; // CTransInPlaceInputPin // ================================================== // Implements the output pin // ================================================== class CTransInPlaceOutputPin : public CTransformOutputPin { protected: // m_pFilter points to our CBaseFilter CTransInPlaceFilter *m_pTIPFilter; public: CTransInPlaceOutputPin( TCHAR *pObjectName, CTransInPlaceFilter *pFilter, HRESULT *phr, LPCWSTR pName); // --- CBaseOutputPin ------------ // negotiate the allocator and its buffer size/count // Insists on using our own allocator. (Actually the one upstream of us). virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc); // Provide a media type enumerator. Get it from upstream. STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum ); // Say whether media type is acceptable. HRESULT CheckMediaType(const CMediaType* pmt); // This is like NotifyAllocator - only output pins do not normally have those // This is only called internally by our own input pin to propagate // allocator decisions downstream. ReadOnly allocators are not propagated // but we check the properties and propagate those. HRESULT ReceiveAllocator(IMemAllocator * pAllocator, BOOL bReadONly); IMemInputPin * ConnectedIMemInputPin() { return m_pInputPin; } // Allow the filter to see what allocator we have // N.B. This does NOT AddRef IMemAllocator * PeekAllocator() { return m_pAllocator; } }; // 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: CTransInPlaceFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid, HRESULT *); // 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, CMediaType *pMediaType) { DbgBreak("CTransInPlaceFilter::GetMediaType should never be called"); return E_UNEXPECTED; } // This is called when we actually have to provide out own allocator. HRESULT DecideBufferSize(IMemAllocator*, 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: IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource); int m_idTransInPlace; // performance measuring id // these hold our input and output pins friend class CTransInPlaceInputPin; friend class CTransInPlaceOutputPin; CTransInPlaceInputPin *InputPin() { return (CTransInPlaceInputPin *)m_pInput; }; CTransInPlaceOutputPin *OutputPin() { return (CTransInPlaceOutputPin *)m_pOutput; }; }; // CTransInPlaceFilter #endif /* __TRANSIP__ */