1
//------------------------------------------------------------------------------
4
// Desc: DirectShow base classes - efines class hierarchy for streams
7
// Copyright (c) 1992-2001 Microsoft Corporation. All rights reserved.
8
//------------------------------------------------------------------------------
14
/* The following classes are declared in this header: */
16
class CBaseMediaFilter; // IMediaFilter support
17
class CBaseFilter; // IBaseFilter,IMediaFilter support
18
class CBasePin; // Abstract base class for IPin interface
19
class CEnumPins; // Enumerate input and output pins
20
class CEnumMediaTypes; // Enumerate the pin's preferred formats
21
class CBaseOutputPin; // Adds data provider member functions
22
class CBaseInputPin; // Implements IMemInputPin interface
23
class CMediaSample; // Basic transport unit for IMemInputPin
24
class CBaseAllocator; // General list guff for most allocators
25
class CMemAllocator; // Implements memory buffer allocation
28
//=====================================================================
29
//=====================================================================
31
// QueryFilterInfo and QueryPinInfo AddRef the interface pointers
32
// they return. You can use the macro below to release the interface.
34
//=====================================================================
35
//=====================================================================
37
#define QueryFilterInfoReleaseGraph(fi) if ((fi).pGraph) (fi).pGraph->Release();
39
#define QueryPinInfoReleaseFilter(pi) if ((pi).pFilter) (pi).pFilter->Release();
41
//=====================================================================
42
//=====================================================================
43
// Defines CBaseMediaFilter
45
// Abstract base class implementing IMediaFilter.
47
// Typically you will derive your filter from CBaseFilter rather than
48
// this, unless you are implementing an object such as a plug-in
49
// distributor that needs to support IMediaFilter but not IBaseFilter.
51
// Note that IMediaFilter is derived from IPersist to allow query of
53
//=====================================================================
54
//=====================================================================
56
class AM_NOVTABLE CBaseMediaFilter : public CUnknown,
62
FILTER_STATE m_State; // current state: running, paused
63
IReferenceClock *m_pClock; // this filter's reference clock
64
// note: all filters in a filter graph use the same clock
66
// offset from stream time to reference time
69
CLSID m_clsid; // This filters clsid
70
// used for serialization
71
CCritSec *m_pLock; // Object we use for locking
76
__in_opt LPCTSTR pName,
77
__inout_opt LPUNKNOWN pUnk,
81
virtual ~CBaseMediaFilter();
85
// override this to say what interfaces we support where
86
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
89
// --- IPersist method ---
92
STDMETHODIMP GetClassID(__out CLSID *pClsID);
94
// --- IMediaFilter methods ---
96
STDMETHODIMP GetState(DWORD dwMSecs, __out FILTER_STATE *State);
98
STDMETHODIMP SetSyncSource(__inout_opt IReferenceClock *pClock);
100
STDMETHODIMP GetSyncSource(__deref_out_opt IReferenceClock **pClock);
102
// default implementation of Stop and Pause just record the
103
// state. Override to activate or de-activate your filter.
104
// Note that Run when called from Stopped state will call Pause
105
// to ensure activation, so if you are a source or transform
106
// you will probably not need to override Run.
108
STDMETHODIMP Pause();
111
// the start parameter is the difference to be added to the
112
// sample's stream time to get the reference time for
114
STDMETHODIMP Run(REFERENCE_TIME tStart);
116
// --- helper methods ---
118
// return the current stream time - ie find out what
119
// stream time should be appearing now
120
virtual HRESULT StreamTime(CRefTime& rtStream);
122
// Is the filter currently active? (running or paused)
124
CAutoLock cObjectLock(m_pLock);
125
return ((m_State == State_Paused) || (m_State == State_Running));
129
//=====================================================================
130
//=====================================================================
131
// Defines CBaseFilter
133
// An abstract class providing basic IBaseFilter support for pin
134
// enumeration and filter information reading.
136
// We cannot derive from CBaseMediaFilter since methods in IMediaFilter
137
// are also in IBaseFilter and would be ambiguous. Since much of the code
138
// assumes that they derive from a class that has m_State and other state
139
// directly available, we duplicate code from CBaseMediaFilter rather than
140
// having a member variable.
142
// Derive your filter from this, or from a derived object such as
144
//=====================================================================
145
//=====================================================================
148
class AM_NOVTABLE CBaseFilter : public CUnknown, // Handles an IUnknown
149
public IBaseFilter, // The Filter Interface
150
public IAMovieSetup // For un/registration
153
friend class CBasePin;
156
FILTER_STATE m_State; // current state: running, paused
157
IReferenceClock *m_pClock; // this graph's ref clock
158
CRefTime m_tStart; // offset from stream time to reference time
159
CLSID m_clsid; // This filters clsid
160
// used for serialization
161
CCritSec *m_pLock; // Object we use for locking
163
WCHAR *m_pName; // Full filter name
164
IFilterGraph *m_pGraph; // Graph we belong to
165
IMediaEventSink *m_pSink; // Called with notify events
166
LONG m_PinVersion; // Current pin version
171
__in_opt LPCTSTR pName, // Object description
172
__inout_opt LPUNKNOWN pUnk, // IUnknown of delegating object
173
__in CCritSec *pLock, // Object who maintains lock
174
REFCLSID clsid); // The clsid to be used to serialize this filter
177
__in_opt LPCTSTR pName, // Object description
178
__in_opt LPUNKNOWN pUnk, // IUnknown of delegating object
179
__in CCritSec *pLock, // Object who maintains lock
180
REFCLSID clsid, // The clsid to be used to serialize this filter
181
__inout HRESULT *phr); // General OLE return code
184
__in_opt LPCSTR pName, // Object description
185
__in_opt LPUNKNOWN pUnk, // IUnknown of delegating object
186
__in CCritSec *pLock, // Object who maintains lock
187
REFCLSID clsid); // The clsid to be used to serialize this filter
190
__in_opt LPCSTR pName, // Object description
191
__in_opt LPUNKNOWN pUnk, // IUnknown of delegating object
192
__in CCritSec *pLock, // Object who maintains lock
193
REFCLSID clsid, // The clsid to be used to serialize this filter
194
__inout HRESULT *phr); // General OLE return code
200
// override this to say what interfaces we support where
201
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
203
STDMETHODIMP_(ULONG) NonDelegatingRelease();
207
// --- IPersist method ---
210
STDMETHODIMP GetClassID(__out CLSID *pClsID);
212
// --- IMediaFilter methods ---
214
STDMETHODIMP GetState(DWORD dwMSecs, __out FILTER_STATE *State);
216
STDMETHODIMP SetSyncSource(__in_opt IReferenceClock *pClock);
218
STDMETHODIMP GetSyncSource(__deref_out_opt IReferenceClock **pClock);
221
// override Stop and Pause so we can activate the pins.
222
// Note that Run will call Pause first if activation needed.
223
// Override these if you want to activate your filter rather than
226
STDMETHODIMP Pause();
228
// the start parameter is the difference to be added to the
229
// sample's stream time to get the reference time for
231
STDMETHODIMP Run(REFERENCE_TIME tStart);
233
// --- helper methods ---
235
// return the current stream time - ie find out what
236
// stream time should be appearing now
237
virtual HRESULT StreamTime(CRefTime& rtStream);
239
// Is the filter currently active?
241
CAutoLock cObjectLock(m_pLock);
242
return ((m_State == State_Paused) || (m_State == State_Running));
245
// Is this filter stopped (without locking)
247
return (m_State == State_Stopped);
251
// --- IBaseFilter methods ---
255
STDMETHODIMP EnumPins(
256
__deref_out IEnumPins ** ppEnum);
259
// default behaviour of FindPin assumes pin ids are their names
260
STDMETHODIMP FindPin(
262
__deref_out IPin ** ppPin
265
STDMETHODIMP QueryFilterInfo(
266
__out FILTER_INFO * pInfo);
268
STDMETHODIMP JoinFilterGraph(
269
__inout_opt IFilterGraph * pGraph,
270
__in_opt LPCWSTR pName);
272
// return a Vendor information string. Optional - may return E_NOTIMPL.
273
// memory returned should be freed using CoTaskMemFree
274
// default implementation returns E_NOTIMPL
275
STDMETHODIMP QueryVendorInfo(
276
__deref_out LPWSTR* pVendorInfo
279
// --- helper methods ---
281
// send an event notification to the filter graph if we know about it.
282
// returns S_OK if delivered, S_FALSE if the filter graph does not sink
283
// events, or an error otherwise.
286
LONG_PTR EventParam1,
287
LONG_PTR EventParam2);
289
// return the filter graph we belong to
290
__out_opt IFilterGraph *GetFilterGraph() {
295
// pPin is the pin to reconnect
296
// pmt is the type to reconnect with - can be NULL
297
// Calls ReconnectEx on the filter graph
298
HRESULT ReconnectPin(IPin *pPin, __in_opt AM_MEDIA_TYPE const *pmt);
300
// find out the current pin version (used by enumerators)
301
virtual LONG GetPinVersion();
302
void IncrementPinVersion();
304
// you need to supply these to access the pins from the enumerator
305
// and for default Stop and Pause/Run activation.
306
virtual int GetPinCount() PURE;
307
virtual CBasePin *GetPin(int n) PURE;
309
// --- IAMovieSetup methods ---
311
STDMETHODIMP Register(); // ask filter to register itself
312
STDMETHODIMP Unregister(); // and unregister itself
314
// --- setup helper methods ---
315
// (override to return filters setup data)
317
virtual __out_opt LPAMOVIESETUP_FILTER GetSetupData(){ return NULL; }
322
//=====================================================================
323
//=====================================================================
326
// Abstract class that supports the basics of IPin
327
//=====================================================================
328
//=====================================================================
330
class AM_NOVTABLE CBasePin : public CUnknown, public IPin, public IQualityControl
335
WCHAR * m_pName; // This pin's name
336
IPin *m_Connected; // Pin we have connected to
337
PIN_DIRECTION m_dir; // Direction of this pin
338
CCritSec *m_pLock; // Object we use for locking
339
bool m_bRunTimeError; // Run time error generated
340
bool m_bCanReconnectWhenActive; // OK to reconnect when active
341
bool m_bTryMyTypesFirst; // When connecting enumerate
342
// this pin's types first
343
CBaseFilter *m_pFilter; // Filter we were created by
344
IQualityControl *m_pQSink; // Target for Quality messages
345
LONG m_TypeVersion; // Holds current type version
346
CMediaType m_mt; // Media type of connection
348
CRefTime m_tStart; // time from NewSegment call
349
CRefTime m_tStop; // time from NewSegment
350
double m_dRate; // rate from NewSegment
353
LONG m_cRef; // Ref count tracing
356
// displays pin connection information
359
void DisplayPinInfo(IPin *pReceivePin);
360
void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt);
362
void DisplayPinInfo(IPin *pReceivePin) {};
363
void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt) {};
366
// used to agree a media type for a pin connection
368
// given a specific media type, attempt a connection (includes
369
// checking that the type is acceptable to this pin)
372
IPin* pReceivePin, // connect to this pin
373
const CMediaType* pmt // using this type
376
// try all the media types in this enumerator - for each that
377
// we accept, try to connect using ReceiveConnection.
378
HRESULT TryMediaTypes(
379
IPin *pReceivePin, // connect to this pin
380
__in_opt const CMediaType *pmt, // proposed type from Connect
381
IEnumMediaTypes *pEnum); // try this enumerator
383
// establish a connection with a suitable mediatype. Needs to
384
// propose a media type if the pmt pointer is null or partially
385
// specified - use TryMediaTypes on both our and then the other pin's
386
// enumerator until we find one that works.
387
HRESULT AgreeMediaType(
388
IPin *pReceivePin, // connect to this pin
389
const CMediaType *pmt); // proposed type from Connect
394
__in_opt LPCTSTR pObjectName, // Object description
395
__in CBaseFilter *pFilter, // Owning filter who knows about pins
396
__in CCritSec *pLock, // Object who implements the lock
397
__inout HRESULT *phr, // General OLE return code
398
__in_opt LPCWSTR pName, // Pin name for us
399
PIN_DIRECTION dir); // Either PINDIR_INPUT or PINDIR_OUTPUT
402
__in_opt LPCSTR pObjectName, // Object description
403
__in CBaseFilter *pFilter, // Owning filter who knows about pins
404
__in CCritSec *pLock, // Object who implements the lock
405
__inout HRESULT *phr, // General OLE return code
406
__in_opt LPCWSTR pName, // Pin name for us
407
PIN_DIRECTION dir); // Either PINDIR_INPUT or PINDIR_OUTPUT
413
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void ** ppv);
414
STDMETHODIMP_(ULONG) NonDelegatingRelease();
415
STDMETHODIMP_(ULONG) NonDelegatingAddRef();
417
// --- IPin methods ---
419
// take lead role in establishing a connection. Media type pointer
420
// may be null, or may point to partially-specified mediatype
421
// (subtype or format type may be GUID_NULL).
422
STDMETHODIMP Connect(
424
__in_opt const AM_MEDIA_TYPE *pmt // optional media type
427
// (passive) accept a connection from another pin
428
STDMETHODIMP ReceiveConnection(
429
IPin * pConnector, // this is the initiating connecting pin
430
const AM_MEDIA_TYPE *pmt // this is the media type we will exchange
433
STDMETHODIMP Disconnect();
435
STDMETHODIMP ConnectedTo(__deref_out IPin **pPin);
437
STDMETHODIMP ConnectionMediaType(__out AM_MEDIA_TYPE *pmt);
439
STDMETHODIMP QueryPinInfo(
440
__out PIN_INFO * pInfo
443
STDMETHODIMP QueryDirection(
444
__out PIN_DIRECTION * pPinDir
447
STDMETHODIMP QueryId(
448
__deref_out LPWSTR * Id
451
// does the pin support this media type
452
STDMETHODIMP QueryAccept(
453
const AM_MEDIA_TYPE *pmt
456
// return an enumerator for this pins preferred media types
457
STDMETHODIMP EnumMediaTypes(
458
__deref_out IEnumMediaTypes **ppEnum
461
// return an array of IPin* - the pins that this pin internally connects to
462
// All pins put in the array must be AddReffed (but no others)
463
// Errors: "Can't say" - FAIL, not enough slots - return S_FALSE
464
// Default: return E_NOTIMPL
465
// The filter graph will interpret NOT_IMPL as any input pin connects to
466
// all visible output pins and vice versa.
467
// apPin can be NULL if nPin==0 (not otherwise).
468
STDMETHODIMP QueryInternalConnections(
469
__out_ecount_part(*nPin,*nPin) IPin* *apPin, // array of IPin*
470
__inout ULONG *nPin // on input, the number of slots
471
// on output the number of pins
472
) { return E_NOTIMPL; }
474
// Called when no more data will be sent
475
STDMETHODIMP EndOfStream(void);
477
// Begin/EndFlush still PURE
479
// NewSegment notifies of the start/stop/rate applying to the data
480
// about to be received. Default implementation records data and
482
// Override this to pass downstream.
483
STDMETHODIMP NewSegment(
484
REFERENCE_TIME tStart,
485
REFERENCE_TIME tStop,
488
//================================================================================
489
// IQualityControl methods
490
//================================================================================
492
STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
494
STDMETHODIMP SetSink(IQualityControl * piqc);
496
// --- helper methods ---
498
// Returns true if the pin is connected. false otherwise.
499
BOOL IsConnected(void) {return (m_Connected != NULL); };
500
// Return the pin this is connected to (if any)
501
IPin * GetConnected() { return m_Connected; };
503
// Check if our filter is currently stopped
505
return (m_pFilter->m_State == State_Stopped);
508
// find out the current type version (used by enumerators)
509
virtual LONG GetMediaTypeVersion();
510
void IncrementTypeVersion();
512
// switch the pin to active (paused or running) mode
513
// not an error to call this if already active
514
virtual HRESULT Active(void);
516
// switch the pin to inactive state - may already be inactive
517
virtual HRESULT Inactive(void);
519
// Notify of Run() from filter
520
virtual HRESULT Run(REFERENCE_TIME tStart);
522
// check if the pin can support this specific proposed type and format
523
virtual HRESULT CheckMediaType(const CMediaType *) PURE;
525
// set the connection to use this format (previously agreed)
526
virtual HRESULT SetMediaType(const CMediaType *);
528
// check that the connection is ok before verifying it
529
// can be overridden eg to check what interfaces will be supported.
530
virtual HRESULT CheckConnect(IPin *);
532
// Set and release resources required for a connection
533
virtual HRESULT BreakConnect();
534
virtual HRESULT CompleteConnect(IPin *pReceivePin);
536
// returns the preferred formats for a pin
537
virtual HRESULT GetMediaType(int iPosition, __inout CMediaType *pMediaType);
539
// access to NewSegment values
540
REFERENCE_TIME CurrentStopTime() {
543
REFERENCE_TIME CurrentStartTime() {
546
double CurrentRate() {
551
LPWSTR Name() { return m_pName; };
553
// Can reconnectwhen active?
554
void SetReconnectWhenActive(bool bCanReconnect)
556
m_bCanReconnectWhenActive = bCanReconnect;
559
bool CanReconnectWhenActive()
561
return m_bCanReconnectWhenActive;
565
STDMETHODIMP DisconnectInternal();
569
//=====================================================================
570
//=====================================================================
573
// Pin enumerator class that works by calling CBaseFilter. This interface
574
// is provided by CBaseFilter::EnumPins and calls GetPinCount() and
575
// GetPin() to enumerate existing pins. Needs to be a separate object so
576
// that it can be cloned (creating an existing object at the same
577
// position in the enumeration)
579
//=====================================================================
580
//=====================================================================
582
class CEnumPins : public IEnumPins // The interface we support
584
int m_Position; // Current ordinal position
585
int m_PinCount; // Number of pins available
586
CBaseFilter *m_pFilter; // The filter who owns us
587
LONG m_Version; // Pin version information
590
typedef CGenericList<CBasePin> CPinList;
592
CPinList m_PinCache; // These pointers have not been AddRef'ed and
593
// so they should not be dereferenced. They are
594
// merely kept to ID which pins have been enumerated.
600
/* If while we are retrieving a pin for example from the filter an error
601
occurs we assume that our internal state is stale with respect to the
602
filter (someone may have deleted all the pins). We can check before
603
starting whether or not the operation is likely to fail by asking the
604
filter what it's current version number is. If the filter has not
605
overriden the GetPinVersion method then this will always match */
607
BOOL AreWeOutOfSync() {
608
return (m_pFilter->GetPinVersion() == m_Version ? FALSE : TRUE);
611
/* This method performs the same operations as Reset, except is does not clear
612
the cache of pins already enumerated. */
614
STDMETHODIMP Refresh();
619
__in CBaseFilter *pFilter,
620
__in_opt CEnumPins *pEnumPins);
622
virtual ~CEnumPins();
625
STDMETHODIMP QueryInterface(REFIID riid, __deref_out void **ppv);
626
STDMETHODIMP_(ULONG) AddRef();
627
STDMETHODIMP_(ULONG) Release();
631
ULONG cPins, // place this many pins...
632
__out_ecount(cPins) IPin ** ppPins, // ...in this array of IPin*
633
__out_opt ULONG * pcFetched // actual count passed returned here
636
STDMETHODIMP Skip(ULONG cPins);
637
STDMETHODIMP Reset();
638
STDMETHODIMP Clone(__deref_out IEnumPins **ppEnum);
644
//=====================================================================
645
//=====================================================================
646
// Defines CEnumMediaTypes
648
// Enumerates the preferred formats for input and output pins
649
//=====================================================================
650
//=====================================================================
652
class CEnumMediaTypes : public IEnumMediaTypes // The interface we support
654
int m_Position; // Current ordinal position
655
CBasePin *m_pPin; // The pin who owns us
656
LONG m_Version; // Media type version value
662
/* The media types a filter supports can be quite dynamic so we add to
663
the general IEnumXXXX interface the ability to be signaled when they
664
change via an event handle the connected filter supplies. Until the
665
Reset method is called after the state changes all further calls to
666
the enumerator (except Reset) will return E_UNEXPECTED error code */
668
BOOL AreWeOutOfSync() {
669
return (m_pPin->GetMediaTypeVersion() == m_Version ? FALSE : TRUE);
676
__in_opt CEnumMediaTypes *pEnumMediaTypes);
678
virtual ~CEnumMediaTypes();
681
STDMETHODIMP QueryInterface(REFIID riid, __deref_out void **ppv);
682
STDMETHODIMP_(ULONG) AddRef();
683
STDMETHODIMP_(ULONG) Release();
687
ULONG cMediaTypes, // place this many pins...
688
__out_ecount(cMediaTypes) AM_MEDIA_TYPE ** ppMediaTypes, // ...in this array
689
__out_opt ULONG * pcFetched // actual count passed
692
STDMETHODIMP Skip(ULONG cMediaTypes);
693
STDMETHODIMP Reset();
694
STDMETHODIMP Clone(__deref_out IEnumMediaTypes **ppEnum);
700
//=====================================================================
701
//=====================================================================
702
// Defines CBaseOutputPin
704
// class derived from CBasePin that can pass buffers to a connected pin
705
// that supports IMemInputPin. Supports IPin.
707
// Derive your output pin from this.
709
//=====================================================================
710
//=====================================================================
712
class AM_NOVTABLE CBaseOutputPin : public CBasePin
717
IMemAllocator *m_pAllocator;
718
IMemInputPin *m_pInputPin; // interface on the downstreaminput pin
719
// set up in CheckConnect when we connect.
724
__in_opt LPCTSTR pObjectName,
725
__in CBaseFilter *pFilter,
726
__in CCritSec *pLock,
727
__inout HRESULT *phr,
728
__in_opt LPCWSTR pName);
731
__in_opt LPCSTR pObjectName,
732
__in CBaseFilter *pFilter,
733
__in CCritSec *pLock,
734
__inout HRESULT *phr,
735
__in_opt LPCWSTR pName);
737
// override CompleteConnect() so we can negotiate an allocator
738
virtual HRESULT CompleteConnect(IPin *pReceivePin);
740
// negotiate the allocator and its buffer size/count and other properties
741
// Calls DecideBufferSize to set properties
742
virtual HRESULT DecideAllocator(IMemInputPin * pPin, __deref_out IMemAllocator ** pAlloc);
744
// override this to set the buffer size and count. Return an error
745
// if the size/count is not to your liking.
746
// The allocator properties passed in are those requested by the
747
// input pin - use eg the alignment and prefix members if you have
748
// no preference on these.
749
virtual HRESULT DecideBufferSize(
750
IMemAllocator * pAlloc,
751
__inout ALLOCATOR_PROPERTIES * ppropInputRequest
754
// returns an empty sample buffer from the allocator
755
virtual HRESULT GetDeliveryBuffer(__deref_out IMediaSample ** ppSample,
756
__in_opt REFERENCE_TIME * pStartTime,
757
__in_opt REFERENCE_TIME * pEndTime,
760
// deliver a filled-in sample to the connected input pin
761
// note - you need to release it after calling this. The receiving
762
// pin will addref the sample if it needs to hold it beyond the
764
virtual HRESULT Deliver(IMediaSample *);
766
// override this to control the connection
767
virtual HRESULT InitAllocator(__deref_out IMemAllocator **ppAlloc);
768
HRESULT CheckConnect(IPin *pPin);
769
HRESULT BreakConnect();
771
// override to call Commit and Decommit
772
HRESULT Active(void);
773
HRESULT Inactive(void);
775
// we have a default handling of EndOfStream which is to return
776
// an error, since this should be called on input pins only
777
STDMETHODIMP EndOfStream(void);
779
// called from elsewhere in our filter to pass EOS downstream to
780
// our connected input pin
781
virtual HRESULT DeliverEndOfStream(void);
783
// same for Begin/EndFlush - we handle Begin/EndFlush since it
784
// is an error on an output pin, and we have Deliver methods to
785
// call the methods on the connected pin
786
STDMETHODIMP BeginFlush(void);
787
STDMETHODIMP EndFlush(void);
788
virtual HRESULT DeliverBeginFlush(void);
789
virtual HRESULT DeliverEndFlush(void);
791
// deliver NewSegment to connected pin - you will need to
792
// override this if you queue any data in your output pin.
793
virtual HRESULT DeliverNewSegment(
794
REFERENCE_TIME tStart,
795
REFERENCE_TIME tStop,
798
//================================================================================
799
// IQualityControl methods
800
//================================================================================
802
// All inherited from CBasePin and not overridden here.
803
// STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
804
// STDMETHODIMP SetSink(IQualityControl * piqc);
808
//=====================================================================
809
//=====================================================================
810
// Defines CBaseInputPin
812
// derive your standard input pin from this.
813
// you need to supply GetMediaType and CheckConnect etc (see CBasePin),
814
// and you need to supply Receive to do something more useful.
816
//=====================================================================
817
//=====================================================================
819
class AM_NOVTABLE CBaseInputPin : public CBasePin,
825
IMemAllocator *m_pAllocator; // Default memory allocator
827
// allocator is read-only, so received samples
828
// cannot be modified (probably only relevant to in-place
832
// in flushing state (between BeginFlush and EndFlush)
833
// if TRUE, all Receives are returned with S_FALSE
836
// Sample properties - initalized in Receive
837
AM_SAMPLE2_PROPERTIES m_SampleProps;
842
__in_opt LPCTSTR pObjectName,
843
__in CBaseFilter *pFilter,
844
__in CCritSec *pLock,
845
__inout HRESULT *phr,
846
__in_opt LPCWSTR pName);
849
__in_opt LPCSTR pObjectName,
850
__in CBaseFilter *pFilter,
851
__in CCritSec *pLock,
852
__inout HRESULT *phr,
853
__in_opt LPCWSTR pName);
855
virtual ~CBaseInputPin();
859
// override this to publicise our interfaces
860
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
862
// return the allocator interface that this input pin
863
// would like the output pin to use
864
STDMETHODIMP GetAllocator(__deref_out IMemAllocator ** ppAllocator);
866
// tell the input pin which allocator the output pin is actually
868
STDMETHODIMP NotifyAllocator(
869
IMemAllocator * pAllocator,
872
// do something with this media sample
873
STDMETHODIMP Receive(IMediaSample *pSample);
875
// do something with these media samples
876
STDMETHODIMP ReceiveMultiple (
877
__in_ecount(nSamples) IMediaSample **pSamples,
879
__out long *nSamplesProcessed);
881
// See if Receive() blocks
882
STDMETHODIMP ReceiveCanBlock();
884
// Default handling for BeginFlush - call at the beginning
885
// of your implementation (makes sure that all Receive calls
886
// fail). After calling this, you need to free any queued data
887
// and then call downstream.
888
STDMETHODIMP BeginFlush(void);
890
// default handling for EndFlush - call at end of your implementation
891
// - before calling this, ensure that there is no queued data and no thread
892
// pushing any more without a further receive, then call downstream,
893
// then call this method to clear the m_bFlushing flag and re-enable
895
STDMETHODIMP EndFlush(void);
897
// this method is optional (can return E_NOTIMPL).
898
// default implementation returns E_NOTIMPL. Override if you have
899
// specific alignment or prefix needs, but could use an upstream
901
STDMETHODIMP GetAllocatorRequirements(__out ALLOCATOR_PROPERTIES*pProps);
903
// Release the pin's allocator.
904
HRESULT BreakConnect();
906
// helper method to check the read-only flag
911
// helper method to see if we are flushing
916
// Override this for checking whether it's OK to process samples
917
// Also call this from EndOfStream.
918
virtual HRESULT CheckStreaming();
920
// Pass a Quality notification on to the appropriate sink
921
HRESULT PassNotify(Quality& q);
924
//================================================================================
925
// IQualityControl methods (from CBasePin)
926
//================================================================================
928
STDMETHODIMP Notify(IBaseFilter * pSender, Quality q);
930
// no need to override:
931
// STDMETHODIMP SetSink(IQualityControl * piqc);
934
// switch the pin to inactive state - may already be inactive
935
virtual HRESULT Inactive(void);
937
// Return sample properties pointer
938
AM_SAMPLE2_PROPERTIES * SampleProps() {
939
ASSERT(m_SampleProps.cbData != 0);
940
return &m_SampleProps;
945
///////////////////////////////////////////////////////////////////////////
949
class CDynamicOutputPin : public CBaseOutputPin,
950
public IPinFlowControl
955
__in_opt LPCSTR pObjectName,
956
__in CBaseFilter *pFilter,
957
__in CCritSec *pLock,
958
__inout HRESULT *phr,
959
__in_opt LPCWSTR pName);
963
__in_opt LPCTSTR pObjectName,
964
__in CBaseFilter *pFilter,
965
__in CCritSec *pLock,
966
__inout HRESULT *phr,
967
__in_opt LPCWSTR pName);
969
~CDynamicOutputPin();
973
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
976
STDMETHODIMP Disconnect(void);
978
// IPinFlowControl Methods
979
STDMETHODIMP Block(DWORD dwBlockFlags, HANDLE hEvent);
981
// Set graph config info
982
void SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent);
985
virtual HRESULT Deliver(IMediaSample *pSample);
986
virtual HRESULT DeliverEndOfStream(void);
987
virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
990
HRESULT DeliverBeginFlush(void);
991
HRESULT DeliverEndFlush(void);
993
HRESULT Inactive(void);
994
HRESULT Active(void);
995
virtual HRESULT CompleteConnect(IPin *pReceivePin);
997
virtual HRESULT StartUsingOutputPin(void);
998
virtual void StopUsingOutputPin(void);
999
virtual bool StreamingThreadUsingOutputPin(void);
1001
HRESULT ChangeOutputFormat
1003
const AM_MEDIA_TYPE *pmt,
1004
REFERENCE_TIME tSegmentStart,
1005
REFERENCE_TIME tSegmentStop,
1008
HRESULT ChangeMediaType(const CMediaType *pmt);
1009
HRESULT DynamicReconnect(const CMediaType *pmt);
1012
HRESULT SynchronousBlockOutputPin(void);
1013
HRESULT AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent);
1014
HRESULT UnblockOutputPin(void);
1016
void BlockOutputPin(void);
1017
void ResetBlockState(void);
1019
static HRESULT WaitEvent(HANDLE hEvent);
1028
// This lock should be held when the following class members are
1029
// being used: m_hNotifyCallerPinBlockedEvent, m_BlockState,
1030
// m_dwBlockCallerThreadID and m_dwNumOutstandingOutputPinUsers.
1031
CCritSec m_BlockStateLock;
1033
// This event should be signaled when the output pin is
1034
// not blocked. This is a manual reset event. For more
1035
// information on events, see the documentation for
1036
// CreateEvent() in the Windows SDK.
1037
HANDLE m_hUnblockOutputPinEvent;
1039
// This event will be signaled when block operation succeedes or
1040
// when the user cancels the block operation. The block operation
1041
// can be canceled by calling IPinFlowControl2::Block( 0, NULL )
1042
// while the block operation is pending.
1043
HANDLE m_hNotifyCallerPinBlockedEvent;
1045
// The state of the current block operation.
1046
BLOCK_STATE m_BlockState;
1048
// The ID of the thread which last called IPinFlowControl::Block().
1049
// For more information on thread IDs, see the documentation for
1050
// GetCurrentThreadID() in the Windows SDK.
1051
DWORD m_dwBlockCallerThreadID;
1053
// The number of times StartUsingOutputPin() has been sucessfully
1054
// called and a corresponding call to StopUsingOutputPin() has not
1055
// been made. When this variable is greater than 0, the streaming
1056
// thread is calling IPin::NewSegment(), IPin::EndOfStream(),
1057
// IMemInputPin::Receive() or IMemInputPin::ReceiveMultiple(). The
1058
// streaming thread could also be calling: DynamicReconnect(),
1059
// ChangeMediaType() or ChangeOutputFormat(). The output pin cannot
1060
// be blocked while the output pin is being used.
1061
DWORD m_dwNumOutstandingOutputPinUsers;
1063
// This event should be set when the IMediaFilter::Stop() is called.
1064
// This is a manual reset event. It is also set when the output pin
1065
// delivers a flush to the connected input pin.
1066
HANDLE m_hStopEvent;
1067
IGraphConfig* m_pGraphConfig;
1069
// TRUE if the output pin's allocator's samples are read only.
1070
// Otherwise FALSE. For more information, see the documentation
1071
// for IMemInputPin::NotifyAllocator().
1072
BOOL m_bPinUsesReadOnlyAllocator;
1075
HRESULT Initialize(void);
1076
HRESULT ChangeMediaTypeHelper(const CMediaType *pmt);
1079
void AssertValid(void);
1083
class CAutoUsingOutputPin
1086
CAutoUsingOutputPin( __in CDynamicOutputPin* pOutputPin, __inout HRESULT* phr );
1087
~CAutoUsingOutputPin();
1090
CDynamicOutputPin* m_pOutputPin;
1093
inline CAutoUsingOutputPin::CAutoUsingOutputPin( __in CDynamicOutputPin* pOutputPin, __inout HRESULT* phr ) :
1096
// The caller should always pass in valid pointers.
1097
ASSERT( NULL != pOutputPin );
1098
ASSERT( NULL != phr );
1100
// Make sure the user initialized phr.
1101
ASSERT( S_OK == *phr );
1103
HRESULT hr = pOutputPin->StartUsingOutputPin();
1110
m_pOutputPin = pOutputPin;
1113
inline CAutoUsingOutputPin::~CAutoUsingOutputPin()
1115
if( NULL != m_pOutputPin )
1117
m_pOutputPin->StopUsingOutputPin();
1123
inline HRESULT CDynamicOutputPin::Deliver(IMediaSample *pSample)
1125
// The caller should call StartUsingOutputPin() before calling this
1127
ASSERT(StreamingThreadUsingOutputPin());
1129
return CBaseOutputPin::Deliver(pSample);
1132
inline HRESULT CDynamicOutputPin::DeliverEndOfStream(void)
1134
// The caller should call StartUsingOutputPin() before calling this
1136
ASSERT( StreamingThreadUsingOutputPin() );
1138
return CBaseOutputPin::DeliverEndOfStream();
1141
inline HRESULT CDynamicOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
1143
// The caller should call StartUsingOutputPin() before calling this
1145
ASSERT(StreamingThreadUsingOutputPin());
1147
return CBaseOutputPin::DeliverNewSegment(tStart, tStop, dRate);
1152
//=====================================================================
1153
//=====================================================================
1154
// Memory allocators
1156
// the shared memory transport between pins requires the input pin
1157
// to provide a memory allocator that can provide sample objects. A
1158
// sample object supports the IMediaSample interface.
1160
// CBaseAllocator handles the management of free and busy samples. It
1161
// allocates CMediaSample objects. CBaseAllocator is an abstract class:
1162
// in particular it has no method of initializing the list of free
1163
// samples. CMemAllocator is derived from CBaseAllocator and initializes
1164
// the list of samples using memory from the standard IMalloc interface.
1166
// If you want your buffers to live in some special area of memory,
1167
// derive your allocator object from CBaseAllocator. If you derive your
1168
// IMemInputPin interface object from CBaseMemInputPin, you will get
1169
// CMemAllocator-based allocation etc for free and will just need to
1170
// supply the Receive handling, and media type / format negotiation.
1171
//=====================================================================
1172
//=====================================================================
1175
//=====================================================================
1176
//=====================================================================
1177
// Defines CMediaSample
1179
// an object of this class supports IMediaSample and represents a buffer
1180
// for media data with some associated properties. Releasing it returns
1181
// it to a freelist managed by a CBaseAllocator derived object.
1182
//=====================================================================
1183
//=====================================================================
1185
class CMediaSample : public IMediaSample2 // The interface we support
1190
friend class CBaseAllocator;
1192
/* Values for dwFlags - these are used for backward compatiblity
1193
only now - use AM_SAMPLE_xxx
1195
enum { Sample_SyncPoint = 0x01, /* Is this a sync point */
1196
Sample_Preroll = 0x02, /* Is this a preroll sample */
1197
Sample_Discontinuity = 0x04, /* Set if start of new segment */
1198
Sample_TypeChanged = 0x08, /* Has the type changed */
1199
Sample_TimeValid = 0x10, /* Set if time is valid */
1200
Sample_MediaTimeValid = 0x20, /* Is the media time valid */
1201
Sample_TimeDiscontinuity = 0x40, /* Time discontinuity */
1202
Sample_StopValid = 0x100, /* Stop time valid */
1203
Sample_ValidFlags = 0x1FF
1206
/* Properties, the media sample class can be a container for a format
1207
change in which case we take a copy of a type through the SetMediaType
1208
interface function and then return it when GetMediaType is called. As
1209
we do no internal processing on it we leave it as a pointer */
1211
DWORD m_dwFlags; /* Flags for this sample */
1212
/* Type specific flags are packed
1215
DWORD m_dwTypeSpecificFlags; /* Media type specific flags */
1216
__field_ecount_opt(m_cbBuffer) LPBYTE m_pBuffer; /* Pointer to the complete buffer */
1217
LONG m_lActual; /* Length of data in this sample */
1218
LONG m_cbBuffer; /* Size of the buffer */
1219
CBaseAllocator *m_pAllocator; /* The allocator who owns us */
1220
CMediaSample *m_pNext; /* Chaining in free list */
1221
REFERENCE_TIME m_Start; /* Start sample time */
1222
REFERENCE_TIME m_End; /* End sample time */
1223
LONGLONG m_MediaStart; /* Real media start position */
1224
LONG m_MediaEnd; /* A difference to get the end */
1225
AM_MEDIA_TYPE *m_pMediaType; /* Media type change data */
1226
DWORD m_dwStreamId; /* Stream id */
1228
LONG m_cRef; /* Reference count */
1234
__in_opt LPCTSTR pName,
1235
__in_opt CBaseAllocator *pAllocator,
1236
__inout_opt HRESULT *phr,
1237
__in_bcount_opt(length) LPBYTE pBuffer = NULL,
1241
__in_opt LPCSTR pName,
1242
__in_opt CBaseAllocator *pAllocator,
1243
__inout_opt HRESULT *phr,
1244
__in_bcount_opt(length) LPBYTE pBuffer = NULL,
1248
virtual ~CMediaSample();
1250
/* Note the media sample does not delegate to its owner */
1252
STDMETHODIMP QueryInterface(REFIID riid, __deref_out void **ppv);
1253
STDMETHODIMP_(ULONG) AddRef();
1254
STDMETHODIMP_(ULONG) Release();
1256
// set the buffer pointer and length. Used by allocators that
1257
// want variable sized pointers or pointers into already-read data.
1258
// This is only available through a CMediaSample* not an IMediaSample*
1259
// and so cannot be changed by clients.
1260
HRESULT SetPointer(__in_bcount(cBytes) BYTE * ptr, LONG cBytes);
1262
// Get me a read/write pointer to this buffer's memory.
1263
STDMETHODIMP GetPointer(__deref_out BYTE ** ppBuffer);
1265
STDMETHODIMP_(LONG) GetSize(void);
1267
// get the stream time at which this sample should start and finish.
1268
STDMETHODIMP GetTime(
1269
__out REFERENCE_TIME * pTimeStart, // put time here
1270
__out REFERENCE_TIME * pTimeEnd
1273
// Set the stream time at which this sample should start and finish.
1274
STDMETHODIMP SetTime(
1275
__in_opt REFERENCE_TIME * pTimeStart, // put time here
1276
__in_opt REFERENCE_TIME * pTimeEnd
1278
STDMETHODIMP IsSyncPoint(void);
1279
STDMETHODIMP SetSyncPoint(BOOL bIsSyncPoint);
1280
STDMETHODIMP IsPreroll(void);
1281
STDMETHODIMP SetPreroll(BOOL bIsPreroll);
1283
STDMETHODIMP_(LONG) GetActualDataLength(void);
1284
STDMETHODIMP SetActualDataLength(LONG lActual);
1286
// these allow for limited format changes in band
1288
STDMETHODIMP GetMediaType(__deref_out AM_MEDIA_TYPE **ppMediaType);
1289
STDMETHODIMP SetMediaType(__in_opt AM_MEDIA_TYPE *pMediaType);
1291
// returns S_OK if there is a discontinuity in the data (this same is
1292
// not a continuation of the previous stream of data
1293
// - there has been a seek).
1294
STDMETHODIMP IsDiscontinuity(void);
1295
// set the discontinuity property - TRUE if this sample is not a
1296
// continuation, but a new sample after a seek.
1297
STDMETHODIMP SetDiscontinuity(BOOL bDiscontinuity);
1299
// get the media times for this sample
1300
STDMETHODIMP GetMediaTime(
1301
__out LONGLONG * pTimeStart,
1302
__out LONGLONG * pTimeEnd
1305
// Set the media times for this sample
1306
STDMETHODIMP SetMediaTime(
1307
__in_opt LONGLONG * pTimeStart,
1308
__in_opt LONGLONG * pTimeEnd
1311
// Set and get properties (IMediaSample2)
1312
STDMETHODIMP GetProperties(
1314
__out_bcount(cbProperties) BYTE * pbProperties
1317
STDMETHODIMP SetProperties(
1319
__in_bcount(cbProperties) const BYTE * pbProperties
1324
//=====================================================================
1325
//=====================================================================
1326
// Defines CBaseAllocator
1328
// Abstract base class that manages a list of media samples
1330
// This class provides support for getting buffers from the free list,
1331
// including handling of commit and (asynchronous) decommit.
1333
// Derive from this class and override the Alloc and Free functions to
1334
// allocate your CMediaSample (or derived) objects and add them to the
1335
// free list, preparing them as necessary.
1336
//=====================================================================
1337
//=====================================================================
1339
class AM_NOVTABLE CBaseAllocator : public CUnknown,// A non delegating IUnknown
1340
public IMemAllocatorCallbackTemp, // The interface we support
1341
public CCritSec // Provides object locking
1344
friend class CSampleList;
1346
/* Trick to get at protected member in CMediaSample */
1347
static CMediaSample * &NextSample(__in CMediaSample *pSample)
1349
return pSample->m_pNext;
1352
/* Mini list class for the free list */
1356
CSampleList() : m_List(NULL), m_nOnList(0) {};
1360
ASSERT(m_nOnList == 0);
1363
CMediaSample *Head() const { return m_List; };
1364
CMediaSample *Next(__in CMediaSample *pSample) const { return CBaseAllocator::NextSample(pSample); };
1365
int GetCount() const { return m_nOnList; };
1366
void Add(__inout CMediaSample *pSample)
1368
ASSERT(pSample != NULL);
1369
CBaseAllocator::NextSample(pSample) = m_List;
1373
CMediaSample *RemoveHead()
1375
CMediaSample *pSample = m_List;
1376
if (pSample != NULL) {
1377
m_List = CBaseAllocator::NextSample(m_List);
1382
void Remove(__inout CMediaSample *pSample);
1385
CMediaSample *m_List;
1390
CSampleList m_lFree; // Free list
1392
/* Note to overriders of CBaseAllocator.
1394
We use a lazy signalling mechanism for waiting for samples.
1395
This means we don't call the OS if no waits occur.
1397
In order to implement this:
1399
1. When a new sample is added to m_lFree call NotifySample() which
1400
calls ReleaseSemaphore on m_hSem with a count of m_lWaiting and
1401
sets m_lWaiting to 0.
1402
This must all be done holding the allocator's critical section.
1404
2. When waiting for a sample call SetWaiting() which increments
1405
m_lWaiting BEFORE leaving the allocator's critical section.
1407
3. Actually wait by calling WaitForSingleObject(m_hSem, INFINITE)
1408
having left the allocator's critical section. The effect of
1409
this is to remove 1 from the semaphore's count. You MUST call
1410
this once having incremented m_lWaiting.
1412
The following are then true when the critical section is not held :
1413
(let nWaiting = number about to wait or waiting)
1415
(1) if (m_lFree.GetCount() != 0) then (m_lWaiting == 0)
1416
(2) m_lWaiting + Semaphore count == nWaiting
1418
We would deadlock if
1420
m_lFree.GetCount() != 0 &&
1421
Semaphore count == 0
1423
But from (1) if m_lFree.GetCount() != 0 then m_lWaiting == 0 so
1424
from (2) Semaphore count == nWaiting (which is non-0) so the
1425
deadlock can't happen.
1428
HANDLE m_hSem; // For signalling
1429
long m_lWaiting; // Waiting for a free element
1430
long m_lCount; // how many buffers we have agreed to provide
1431
long m_lAllocated; // how many buffers are currently allocated
1432
long m_lSize; // agreed size of each buffer
1433
long m_lAlignment; // agreed alignment
1434
long m_lPrefix; // agreed prefix (preceeds GetPointer() value)
1435
BOOL m_bChanged; // Have the buffer requirements changed
1437
// if true, we are decommitted and can't allocate memory
1439
// if true, the decommit has happened, but we haven't called Free yet
1440
// as there are still outstanding buffers
1441
BOOL m_bDecommitInProgress;
1443
// Notification interface
1444
IMemAllocatorNotifyCallbackTemp *m_pNotify;
1446
BOOL m_fEnableReleaseCallback;
1448
// called to decommit the memory when the last buffer is freed
1449
// pure virtual - need to override this
1450
virtual void Free(void) PURE;
1452
// override to allocate the memory when commit called
1453
virtual HRESULT Alloc(void);
1458
__in_opt LPCTSTR , __inout_opt LPUNKNOWN, __inout HRESULT *,
1459
BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);
1462
__in_opt LPCSTR , __inout_opt LPUNKNOWN, __inout HRESULT *,
1463
BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);
1465
virtual ~CBaseAllocator();
1469
// override this to publicise our interfaces
1470
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, __deref_out void **ppv);
1472
STDMETHODIMP SetProperties(
1473
__in ALLOCATOR_PROPERTIES* pRequest,
1474
__out ALLOCATOR_PROPERTIES* pActual);
1476
// return the properties actually being used on this allocator
1477
STDMETHODIMP GetProperties(
1478
__out ALLOCATOR_PROPERTIES* pProps);
1480
// override Commit to allocate memory. We handle the GetBuffer
1482
STDMETHODIMP Commit();
1484
// override this to handle the memory freeing. We handle any outstanding
1486
STDMETHODIMP Decommit();
1488
// get container for a sample. Blocking, synchronous call to get the
1489
// next free buffer (as represented by an IMediaSample interface).
1490
// on return, the time etc properties will be invalid, but the buffer
1491
// pointer and size will be correct. The two time parameters are
1492
// optional and either may be NULL, they may alternatively be set to
1493
// the start and end times the sample will have attached to it
1494
// bPrevFramesSkipped is not used (used only by the video renderer's
1495
// allocator where it affects quality management in direct draw).
1497
STDMETHODIMP GetBuffer(__deref_out IMediaSample **ppBuffer,
1498
__in_opt REFERENCE_TIME * pStartTime,
1499
__in_opt REFERENCE_TIME * pEndTime,
1502
// final release of a CMediaSample will call this
1503
STDMETHODIMP ReleaseBuffer(IMediaSample *pBuffer);
1504
// obsolete:: virtual void PutOnFreeList(CMediaSample * pSample);
1506
STDMETHODIMP SetNotify(IMemAllocatorNotifyCallbackTemp *pNotify);
1508
STDMETHODIMP GetFreeCount(__out LONG *plBuffersFree);
1510
// Notify that a sample is available
1511
void NotifySample();
1513
// Notify that we're waiting for a sample
1514
void SetWaiting() { m_lWaiting++; };
1518
//=====================================================================
1519
//=====================================================================
1520
// Defines CMemAllocator
1522
// this is an allocator based on CBaseAllocator that allocates sample
1523
// buffers in main memory (from 'new'). You must call SetProperties
1524
// before calling Commit.
1526
// we don't free the memory when going into Decommit state. The simplest
1527
// way to implement this without complicating CBaseAllocator is to
1528
// have a Free() function, called to go into decommit state, that does
1529
// nothing and a ReallyFree function called from our destructor that
1530
// actually frees the memory.
1531
//=====================================================================
1532
//=====================================================================
1534
// Make me one from quartz.dll
1535
STDAPI CreateMemoryAllocator(__deref_out IMemAllocator **ppAllocator);
1537
class CMemAllocator : public CBaseAllocator
1542
LPBYTE m_pBuffer; // combined memory for all buffers
1544
// override to free the memory when decommit completes
1545
// - we actually do nothing, and save the memory until deletion.
1548
// called from the destructor (and from Alloc if changing size/count) to
1549
// actually free up the memory
1550
void ReallyFree(void);
1552
// overriden to allocate the memory when commit called
1553
HRESULT Alloc(void);
1556
/* This goes in the factory template table to create new instances */
1557
static CUnknown *CreateInstance(__inout_opt LPUNKNOWN, __inout HRESULT *);
1559
STDMETHODIMP SetProperties(
1560
__in ALLOCATOR_PROPERTIES* pRequest,
1561
__out ALLOCATOR_PROPERTIES* pActual);
1563
CMemAllocator(__in_opt LPCTSTR , __inout_opt LPUNKNOWN, __inout HRESULT *);
1565
CMemAllocator(__in_opt LPCSTR , __inout_opt LPUNKNOWN, __inout HRESULT *);
1570
// helper used by IAMovieSetup implementation
1572
AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata
1573
, IFilterMapper * pIFM
1577
///////////////////////////////////////////////////////////////////////////
1578
// ------------------------------------------------------------------------
1579
// ------------------------------------------------------------------------
1580
// ------------------------------------------------------------------------
1581
// ------------------------------------------------------------------------
1582
///////////////////////////////////////////////////////////////////////////
1584
#endif /* __FILTER__ */