1 //------------------------------------------------------------------------------
4 // Desc: DirectShow base classes - defines classes from which simple
5 // transform codecs may be derived.
7 // Copyright (c) 1992-2002 Microsoft Corporation. All rights reserved.
8 //------------------------------------------------------------------------------
11 // It assumes the codec has one input and one output stream, and has no
12 // interest in memory management, interface negotiation or anything else.
14 // derive your class from this, and supply Transform and the media type/format
15 // negotiation functions. Implement that class, compile and link and
22 // ======================================================================
23 // This is the com object that represents a simple transform filter. It
24 // supports IBaseFilter, IMediaFilter and two pins through nested interfaces
25 // ======================================================================
27 class CTransformFilter
;
29 // ==================================================
30 // Implements the input pin
31 // ==================================================
33 class CTransformInputPin
: public CBaseInputPin
35 friend class CTransformFilter
;
38 CTransformFilter
*m_pTransformFilter
;
45 CTransformFilter
*pTransformFilter
,
51 CTransformFilter
*pTransformFilter
,
56 STDMETHODIMP
QueryId(LPWSTR
* Id
)
58 return AMGetWideString(L
"In", Id
);
61 // Grab and release extra interfaces if required
63 HRESULT
CheckConnect(IPin
*pPin
);
64 HRESULT
BreakConnect();
65 HRESULT
CompleteConnect(IPin
*pReceivePin
);
67 // check that we can support this output type
68 HRESULT
CheckMediaType(const CMediaType
* mtIn
);
70 // set the connection media type
71 HRESULT
SetMediaType(const CMediaType
* mt
);
73 // --- IMemInputPin -----
75 // here's the next block of data from the stream.
76 // AddRef it yourself if you need to hold it beyond the end
78 STDMETHODIMP
Receive(IMediaSample
* pSample
);
80 // provide EndOfStream that passes straight downstream
81 // (there is no queued data)
82 STDMETHODIMP
EndOfStream(void);
84 // passes it to CTransformFilter::BeginFlush
85 STDMETHODIMP
BeginFlush(void);
87 // passes it to CTransformFilter::EndFlush
88 STDMETHODIMP
EndFlush(void);
90 STDMETHODIMP
NewSegment(
91 REFERENCE_TIME tStart
,
95 // Check if it's OK to process samples
96 virtual HRESULT
CheckStreaming();
100 CMediaType
& CurrentMediaType() { return m_mt
; };
104 // ==================================================
105 // Implements the output pin
106 // ==================================================
108 class CTransformOutputPin
: public CBaseOutputPin
110 friend class CTransformFilter
;
113 CTransformFilter
*m_pTransformFilter
;
117 // implement IMediaPosition by passing upstream
118 IUnknown
* m_pPosition
;
122 CTransformFilter
*pTransformFilter
,
128 CTransformFilter
*pTransformFilter
,
132 ~CTransformOutputPin();
134 // override to expose IMediaPosition
135 STDMETHODIMP
NonDelegatingQueryInterface(REFIID riid
, void **ppv
);
137 // --- CBaseOutputPin ------------
139 STDMETHODIMP
QueryId(LPWSTR
* Id
)
141 return AMGetWideString(L
"Out", Id
);
144 // Grab and release extra interfaces if required
146 HRESULT
CheckConnect(IPin
*pPin
);
147 HRESULT
BreakConnect();
148 HRESULT
CompleteConnect(IPin
*pReceivePin
);
150 // check that we can support this output type
151 HRESULT
CheckMediaType(const CMediaType
* mtOut
);
153 // set the connection media type
154 HRESULT
SetMediaType(const CMediaType
*pmt
);
156 // called from CBaseOutputPin during connection to ask for
157 // the count and size of buffers we need.
158 HRESULT
DecideBufferSize(
159 IMemAllocator
* pAlloc
,
160 ALLOCATOR_PROPERTIES
*pProp
);
162 // returns the preferred formats for a pin
163 HRESULT
GetMediaType(int iPosition
,CMediaType
*pMediaType
);
165 // inherited from IQualityControl via CBasePin
166 STDMETHODIMP
Notify(IBaseFilter
* pSender
, Quality q
);
170 CMediaType
& CurrentMediaType() { return m_mt
; };
174 class AM_NOVTABLE CTransformFilter
: public CBaseFilter
179 // map getpin/getpincount for base enum of pins to owner
180 // override this to return more specialised pin objects
182 virtual int GetPinCount();
183 virtual CBasePin
* GetPin(int n
);
184 STDMETHODIMP
FindPin(LPCWSTR Id
, IPin
**ppPin
);
186 // override state changes to allow derived transform filter
187 // to control streaming start/stop
189 STDMETHODIMP
Pause();
193 CTransformFilter(TCHAR
*, LPUNKNOWN
, REFCLSID clsid
);
195 CTransformFilter(CHAR
*, LPUNKNOWN
, REFCLSID clsid
);
199 // =================================================================
200 // ----- override these bits ---------------------------------------
201 // =================================================================
203 // These must be supplied in a derived class
205 virtual HRESULT
Transform(IMediaSample
* pIn
, IMediaSample
*pOut
);
207 // check if you can support mtIn
208 virtual HRESULT
CheckInputType(const CMediaType
* mtIn
) PURE
;
210 // check if you can support the transform from this input to this output
211 virtual HRESULT
CheckTransform(const CMediaType
* mtIn
, const CMediaType
* mtOut
) PURE
;
213 // this goes in the factory template table to create new instances
214 // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *);
216 // call the SetProperties function with appropriate arguments
217 virtual HRESULT
DecideBufferSize(
218 IMemAllocator
* pAllocator
,
219 ALLOCATOR_PROPERTIES
*pprop
) PURE
;
221 // override to suggest OUTPUT pin media types
222 virtual HRESULT
GetMediaType(int iPosition
, CMediaType
*pMediaType
) PURE
;
226 // =================================================================
227 // ----- Optional Override Methods -----------------------
228 // =================================================================
230 // you can also override these if you want to know about streaming
231 virtual HRESULT
StartStreaming();
232 virtual HRESULT
StopStreaming();
234 // override if you can do anything constructive with quality notifications
235 virtual HRESULT
AlterQuality(Quality q
);
237 // override this to know when the media type is actually set
238 virtual HRESULT
SetMediaType(PIN_DIRECTION direction
,const CMediaType
*pmt
);
240 // chance to grab extra interfaces on connection
241 virtual HRESULT
CheckConnect(PIN_DIRECTION dir
,IPin
*pPin
);
242 virtual HRESULT
BreakConnect(PIN_DIRECTION dir
);
243 virtual HRESULT
CompleteConnect(PIN_DIRECTION direction
,IPin
*pReceivePin
);
245 // chance to customize the transform process
246 virtual HRESULT
Receive(IMediaSample
*pSample
);
248 // Standard setup for output sample
249 HRESULT
InitializeOutputSample(IMediaSample
*pSample
, IMediaSample
**ppOutSample
);
251 // if you override Receive, you may need to override these three too
252 virtual HRESULT
EndOfStream(void);
253 virtual HRESULT
BeginFlush(void);
254 virtual HRESULT
EndFlush(void);
255 virtual HRESULT
NewSegment(
256 REFERENCE_TIME tStart
,
257 REFERENCE_TIME tStop
,
261 // Override to register performance measurement with a less generic string
262 // You should do this to avoid confusion with other filters
263 virtual void RegisterPerfId()
264 {m_idTransform
= MSR_REGISTER(TEXT("Transform"));}
268 // implementation details
273 int m_idTransform
; // performance measuring id
275 BOOL m_bEOSDelivered
; // have we sent EndOfStream
276 BOOL m_bSampleSkipped
; // Did we just skip a frame
277 BOOL m_bQualityChanged
; // Have we degraded?
279 // critical section protecting filter state.
283 // critical section stopping state changes (ie Stop) while we're
284 // processing a sample.
286 // This critical section is held when processing
287 // events that occur on the receive thread - Receive() and EndOfStream().
289 // If you want to hold both m_csReceive and m_csFilter then grab
290 // m_csFilter FIRST - like CTransformFilter::Stop() does.
292 CCritSec m_csReceive
;
294 // these hold our input and output pins
296 friend class CTransformInputPin
;
297 friend class CTransformOutputPin
;
298 CTransformInputPin
*m_pInput
;
299 CTransformOutputPin
*m_pOutput
;
302 #endif /* __TRANSFRM__ */