305 lines
9.1 KiB
C++
305 lines
9.1 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(
|
|
TCHAR *pObjectName,
|
|
CTransformFilter *pTransformFilter,
|
|
HRESULT * phr,
|
|
LPCWSTR pName);
|
|
#ifdef UNICODE
|
|
CTransformInputPin(
|
|
char *pObjectName,
|
|
CTransformFilter *pTransformFilter,
|
|
HRESULT * phr,
|
|
LPCWSTR pName);
|
|
#endif
|
|
|
|
STDMETHODIMP QueryId(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(
|
|
TCHAR *pObjectName,
|
|
CTransformFilter *pTransformFilter,
|
|
HRESULT * phr,
|
|
LPCWSTR pName);
|
|
#ifdef UNICODE
|
|
CTransformOutputPin(
|
|
CHAR *pObjectName,
|
|
CTransformFilter *pTransformFilter,
|
|
HRESULT * phr,
|
|
LPCWSTR pName);
|
|
#endif
|
|
~CTransformOutputPin();
|
|
|
|
// override to expose IMediaPosition
|
|
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
|
|
|
|
// --- CBaseOutputPin ------------
|
|
|
|
STDMETHODIMP QueryId(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,
|
|
ALLOCATOR_PROPERTIES *pProp);
|
|
|
|
// returns the preferred formats for a pin
|
|
HRESULT GetMediaType(int iPosition,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, IPin **ppPin);
|
|
|
|
// override state changes to allow derived transform filter
|
|
// to control streaming start/stop
|
|
STDMETHODIMP Stop();
|
|
STDMETHODIMP Pause();
|
|
|
|
public:
|
|
|
|
CTransformFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid);
|
|
#ifdef UNICODE
|
|
CTransformFilter(CHAR *, 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(LPUNKNOWN, HRESULT *);
|
|
|
|
// call the SetProperties function with appropriate arguments
|
|
virtual HRESULT DecideBufferSize(
|
|
IMemAllocator * pAllocator,
|
|
ALLOCATOR_PROPERTIES *pprop) PURE;
|
|
|
|
// override to suggest OUTPUT pin media types
|
|
virtual HRESULT GetMediaType(int iPosition, 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, 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__ */
|
|
|
|
|