blob: 3fc335effddb131ffb5d77149a28a910dd4954c2 [file] [log] [blame]
//------------------------------------------------------------------------------
// 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__ */