📄 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.dll
STDAPI 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 implementation
STDAPI
AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata
, IFilterMapper * pIFM
, BOOL bRegister );
///////////////////////////////////////////////////////////////////////////
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////
#endif /* __FILTER__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -