📄 amfilter.h
字号:
/* Values for dwFlags - these are used for backward compatiblity only now - use AM_SAMPLE_xxx */ enum { Sample_SyncPoint = 0x01, /* Is this a sync point */ Sample_Preroll = 0x02, /* Is this a preroll sample */ Sample_Discontinuity = 0x04, /* Set if start of new segment */ Sample_TypeChanged = 0x08, /* Has the type changed */ Sample_TimeValid = 0x10, /* Set if time is valid */ Sample_MediaTimeValid = 0x20, /* Is the media time valid */ Sample_TimeDiscontinuity = 0x40, /* Time discontinuity */ Sample_StopValid = 0x100, /* Stop time valid */ Sample_ValidFlags = 0x1FF }; /* Properties, the media sample class can be a container for a format change in which case we take a copy of a type through the SetMediaType interface function and then return it when GetMediaType is called. As we do no internal processing on it we leave it as a pointer */ DWORD m_dwFlags; /* Flags for this sample */ /* Type specific flags are packed into the top word */ DWORD m_dwTypeSpecificFlags; /* Media type specific flags */ LPBYTE m_pBuffer; /* Pointer to the complete buffer */ LONG m_lActual; /* Length of data in this sample */ LONG m_cbBuffer; /* Size of the buffer */ CBaseAllocator *m_pAllocator; /* The allocator who owns us */ CMediaSample *m_pNext; /* Chaining in free list */ REFERENCE_TIME m_Start; /* Start sample time */ REFERENCE_TIME m_End; /* End sample time */ LONGLONG m_MediaStart; /* Real media start position */ LONG m_MediaEnd; /* A difference to get the end */ AM_MEDIA_TYPE *m_pMediaType; /* Media type change data */ DWORD m_dwStreamId; /* Stream id */public: LONG m_cRef; /* Reference count */public: CMediaSample( TCHAR *pName, CBaseAllocator *pAllocator, HRESULT *phr, LPBYTE pBuffer = NULL, LONG length = 0);#ifdef UNICODE CMediaSample( CHAR *pName, CBaseAllocator *pAllocator, HRESULT *phr, LPBYTE pBuffer = NULL, LONG length = 0);#endif virtual ~CMediaSample(); /* Note the media sample does not delegate to its owner */ STDMETHODIMP QueryInterface(REFIID riid, void **ppv); STDMETHODIMP_(ULONG) AddRef(); STDMETHODIMP_(ULONG) Release(); // set the buffer pointer and length. Used by allocators that // want variable sized pointers or pointers into already-read data. // This is only available through a CMediaSample* not an IMediaSample* // and so cannot be changed by clients. HRESULT SetPointer(BYTE * ptr, LONG cBytes); // Get me a read/write pointer to this buffer's memory. STDMETHODIMP GetPointer(BYTE ** ppBuffer); STDMETHODIMP_(LONG) GetSize(void); // get the stream time at which this sample should start and finish. STDMETHODIMP GetTime( REFERENCE_TIME * pTimeStart, // put time here REFERENCE_TIME * pTimeEnd ); // Set the stream time at which this sample should start and finish. STDMETHODIMP SetTime( REFERENCE_TIME * pTimeStart, // put time here REFERENCE_TIME * pTimeEnd ); STDMETHODIMP IsSyncPoint(void); STDMETHODIMP SetSyncPoint(BOOL bIsSyncPoint); STDMETHODIMP IsPreroll(void); STDMETHODIMP SetPreroll(BOOL bIsPreroll); STDMETHODIMP_(LONG) GetActualDataLength(void); STDMETHODIMP SetActualDataLength(LONG lActual); // these allow for limited format changes in band STDMETHODIMP GetMediaType(AM_MEDIA_TYPE **ppMediaType); STDMETHODIMP SetMediaType(AM_MEDIA_TYPE *pMediaType); // returns S_OK if there is a discontinuity in the data (this same is // not a continuation of the previous stream of data // - there has been a seek). STDMETHODIMP IsDiscontinuity(void); // set the discontinuity property - TRUE if this sample is not a // continuation, but a new sample after a seek. STDMETHODIMP SetDiscontinuity(BOOL bDiscontinuity); // get the media times for this sample STDMETHODIMP GetMediaTime( LONGLONG * pTimeStart, LONGLONG * pTimeEnd ); // Set the media times for this sample STDMETHODIMP SetMediaTime( LONGLONG * pTimeStart, LONGLONG * pTimeEnd ); // Set and get properties (IMediaSample2) STDMETHODIMP GetProperties( DWORD cbProperties, BYTE * pbProperties ); STDMETHODIMP SetProperties( DWORD cbProperties, const BYTE * pbProperties );};//=====================================================================//=====================================================================// Defines CBaseAllocator//// Abstract base class that manages a list of media samples//// This class provides support for getting buffers from the free list,// including handling of commit and (asynchronous) decommit.//// Derive from this class and override the Alloc and Free functions to// allocate your CMediaSample (or derived) objects and add them to the// free list, preparing them as necessary.//=====================================================================//=====================================================================class AM_NOVTABLE CBaseAllocator : public CUnknown,// A non delegating IUnknown public IMemAllocatorCallbackTemp, // The interface we support public CCritSec // Provides object locking{ class CSampleList; friend class CSampleList; /* Trick to get at protected member in CMediaSample */ static CMediaSample * &NextSample(CMediaSample *pSample) { return pSample->m_pNext; }; /* Mini list class for the free list */ class CSampleList { public: CSampleList() : m_List(NULL), m_nOnList(0) {};#ifdef DEBUG ~CSampleList() { ASSERT(m_nOnList == 0); };#endif CMediaSample *Head() const { return m_List; }; CMediaSample *Next(CMediaSample *pSample) const { return CBaseAllocator::NextSample(pSample); }; int GetCount() const { return m_nOnList; }; void Add(CMediaSample *pSample) { ASSERT(pSample != NULL); CBaseAllocator::NextSample(pSample) = m_List; m_List = pSample; m_nOnList++; }; CMediaSample *RemoveHead() { CMediaSample *pSample = m_List; if (pSample != NULL) { m_List = CBaseAllocator::NextSample(m_List); m_nOnList--; } return pSample; }; void Remove(CMediaSample *pSample); public: CMediaSample *m_List; int m_nOnList; };protected: CSampleList m_lFree; // Free list /* Note to overriders of CBaseAllocator. We use a lazy signalling mechanism for waiting for samples. This means we don't call the OS if no waits occur. In order to implement this: 1. When a new sample is added to m_lFree call NotifySample() which calls ReleaseSemaphore on m_hSem with a count of m_lWaiting and sets m_lWaiting to 0. This must all be done holding the allocator's critical section. 2. When waiting for a sample call SetWaiting() which increments m_lWaiting BEFORE leaving the allocator's critical section. 3. Actually wait by calling WaitForSingleObject(m_hSem, INFINITE) having left the allocator's critical section. The effect of this is to remove 1 from the semaphore's count. You MUST call this once having incremented m_lWaiting. The following are then true when the critical section is not held : (let nWaiting = number about to wait or waiting) (1) if (m_lFree.GetCount() != 0) then (m_lWaiting == 0) (2) m_lWaiting + Semaphore count == nWaiting We would deadlock if nWaiting != 0 && m_lFree.GetCount() != 0 && Semaphore count == 0 But from (1) if m_lFree.GetCount() != 0 then m_lWaiting == 0 so from (2) Semaphore count == nWaiting (which is non-0) so the deadlock can't happen. */ HANDLE m_hSem; // For signalling long m_lWaiting; // Waiting for a free element long m_lCount; // how many buffers we have agreed to provide long m_lAllocated; // how many buffers are currently allocated long m_lSize; // agreed size of each buffer long m_lAlignment; // agreed alignment long m_lPrefix; // agreed prefix (preceeds GetPointer() value) BOOL m_bChanged; // Have the buffer requirements changed // if true, we are decommitted and can't allocate memory BOOL m_bCommitted; // if true, the decommit has happened, but we haven't called Free yet // as there are still outstanding buffers BOOL m_bDecommitInProgress; // Notification interface IMemAllocatorNotifyCallbackTemp *m_pNotify; BOOL m_fEnableReleaseCallback; // called to decommit the memory when the last buffer is freed // pure virtual - need to override this virtual void Free(void) PURE; // override to allocate the memory when commit called virtual HRESULT Alloc(void);public: CBaseAllocator( TCHAR *, LPUNKNOWN, HRESULT *, BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);#ifdef UNICODE CBaseAllocator( CHAR *, LPUNKNOWN, HRESULT *, BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE);#endif virtual ~CBaseAllocator(); DECLARE_IUNKNOWN // override this to publicise our interfaces STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); STDMETHODIMP SetProperties( ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual); // return the properties actually being used on this allocator STDMETHODIMP GetProperties( ALLOCATOR_PROPERTIES* pProps); // override Commit to allocate memory. We handle the GetBuffer //state changes STDMETHODIMP Commit(); // override this to handle the memory freeing. We handle any outstanding // GetBuffer calls STDMETHODIMP Decommit(); // get container for a sample. Blocking, synchronous call to get the // next free buffer (as represented by an IMediaSample interface). // on return, the time etc properties will be invalid, but the buffer // pointer and size will be correct. The two time parameters are // optional and either may be NULL, they may alternatively be set to // the start and end times the sample will have attached to it // bPrevFramesSkipped is not used (used only by the video renderer's // allocator where it affects quality management in direct draw). STDMETHODIMP GetBuffer(IMediaSample **ppBuffer, REFERENCE_TIME * pStartTime, REFERENCE_TIME * pEndTime, DWORD dwFlags); // final release of a CMediaSample will call this STDMETHODIMP ReleaseBuffer(IMediaSample *pBuffer); // obsolete:: virtual void PutOnFreeList(CMediaSample * pSample); STDMETHODIMP SetNotify(IMemAllocatorNotifyCallbackTemp *pNotify); STDMETHODIMP GetFreeCount(LONG *plBuffersFree); // Notify that a sample is available void NotifySample(); // Notify that we're waiting for a sample void SetWaiting() { m_lWaiting++; };};//=====================================================================//=====================================================================// Defines CMemAllocator//// this is an allocator based on CBaseAllocator that allocates sample// buffers in main memory (from 'new'). You must call SetProperties// before calling Commit.//// we don't free the memory when going into Decommit state. The simplest// way to implement this without complicating CBaseAllocator is to// have a Free() function, called to go into decommit state, that does// nothing and a ReallyFree function called from our destructor that// actually frees the memory.//=====================================================================//=====================================================================// Make me one from quartz.dllSTDAPI CreateMemoryAllocator(IMemAllocator **ppAllocator);class CMemAllocator : public CBaseAllocator{protected: LPBYTE m_pBuffer; // combined memory for all buffers // override to free the memory when decommit completes // - we actually do nothing, and save the memory until deletion. void Free(void); // called from the destructor (and from Alloc if changing size/count) to // actually free up the memory void ReallyFree(void); // overriden to allocate the memory when commit called HRESULT Alloc(void);public: /* This goes in the factory template table to create new instances */ static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *); STDMETHODIMP SetProperties( ALLOCATOR_PROPERTIES* pRequest, ALLOCATOR_PROPERTIES* pActual); CMemAllocator(TCHAR *, LPUNKNOWN, HRESULT *);#ifdef UNICODE CMemAllocator(CHAR *, LPUNKNOWN, HRESULT *);#endif ~CMemAllocator();};// helper used by IAMovieSetup implementationSTDAPIAMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata , IFilterMapper * pIFM , BOOL bRegister );///////////////////////////////////////////////////////////////////////////// ------------------------------------------------------------------------// ------------------------------------------------------------------------// ------------------------------------------------------------------------// ------------------------------------------------------------------------///////////////////////////////////////////////////////////////////////////#endif /* __FILTER__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -