CBaseAllocator is an abstract base class that implements the basic mechanisms for an allocator with a fixed number of fixed-size buffers. The number of buffers and their size can be changed using the CBaseAllocator::SetProperties member function when an input pin and an output pin negotiate the allocator between them.
The class provides the basic functionality for a memory allocator by implementing the IMemAllocator interface. It provides support for managing a list of CMediaSample objects (or objects derived from this class), including support for the IMemAllocator::Commit and IMemAllocator::Decommit methods, and blocking the IMemAllocator::GetBuffer method.
Any class derived from this class (such as CMemAllocator) must create CMediaSample objects, which this base class does not.
A signaling mechanism employing a semaphore is used so that if there are no samples, a thread can wait until there are samples or until the allocator is decommitted. The m_lFree and m_hSem member variables are used to implement this simple signaling mechanism as follows.
When a thread calls CBaseAllocator::GetBuffer and there are no samples available, m_lWaiting is incremented and the thread calls the Microsoft® Win32® WaitForSingleObject function on the semaphore indicated by m_hSem.
When a sample is freed (by the IUnknown::Release method returning the reference count to zero) or CBaseAllocator::Decommit is called and m_lWaiting is nonzero, the Win32 ReleaseSemaphore function is called on m_hSem with a release count of m_lWaiting, and m_lWaiting is reset to zero.
All member functions in this class that return HRESULT and accept a pointer as a parameter return E_POINTER when passed a null pointer.
Protected Data Members
Name | Description |
m_bChanged | TRUE if the buffers have changed; otherwise, FALSE. |
m_lCount | Established number of buffers to provide. |
m_lAlignment | Agreed alignment of the buffer. |
m_lAllocated | Number of buffers actually allocated. |
m_lSize | Size of each buffer. |
m_lFree | List of CMediaSample objects that are currently free (free list). |
m_lPrefix | Agreed prefix of the buffer (precedes value returned by IMediaSample::GetPointer). |
m_bCommitted | If TRUE, the allocator is in a state in which all IMemAllocator::GetBuffer methods fail. The IMemAllocator::SetProperties method is the only member function permitted to operate in this state. |
m_bDecommitInProgress | If TRUE, the decommit process completes upon the return of all media samples. Until the decommit process has completed, any calls to IMemAllocator::GetBuffer return E_OUTOFMEMORY. |
m_hSem | Semaphore for signaling. |
m_lWaiting | Count of threads waiting for samples. |
Member Functions
Name | Description |
CBaseAllocator | Constructs a CBaseAllocator object. |
NotifySample | Notifies a waiting thread that a sample is available on the free list. |
SetWaiting | Increments the m_lWaiting data member to indicate that a thread is waiting for a sample. |
Overridable Member Functions
Name | Description |
Alloc | Allocates memory, instantiates CMediaSample objects, and adds them to the m_lAllocated and m_lFree data members. |
Free | Decommits memory when the last buffer is freed. |
Implemented IMemAllocator Methods
Name | Description |
Commit | Allocates memory by calling the CBaseAllocator::Alloc member function, which you must override. |
Decommit | Releases any resources and enters the inactive state. Any blocking calls to IMemAllocator::GetBuffer should return with an error value, and all further calls to GetBuffer fail when in the inactive state. |
GetBuffer | Retrieves a container for a sample. |
GetProperties | Determines the size, number, and alignment of blocks. |
ReleaseBuffer | Releases the CMediaSample object. |
SetProperties | Specifies a desired number of blocks, size of the blocks, and block alignment figure. This method returns the actual values for the same. |
Implemented INonDelegatingUnknown Methods
Name | Description |
NonDelegatingQueryInterface | Passes out pointers to any interfaces added to the derived filter class. |
Allocates a media sample object.
HRESULT Alloc(void);
Returns an HRESULT value.
Override this member function to allocate memory, instantiate CMediaSample objects, and add them to the free list represented by the m_lFree data member. The CMemAllocator::Alloc member function is an example of an override of this member function. It calls this member function first to ensure that allocator properties have been set.
This member function is called from the CBaseAllocator::Commit member function when entering the active state. The default implementation returns an error value if the IMemAllocator::SetProperties method has not been called yet, and checks that there are no outstanding buffers.
Constructs a CBaseAllocator object.
CBaseAllocator(
TCHAR * pName,
LPUNKNOWN lpUnk,
HRESULT * phr,
BOOL bListSemaphore = TRUE
);
No return value.
Commits the memory for the specified buffers.
HRESULT Commit(void);
Returns an HRESULT value.
This member function implements the IMemAllocator::Commit method. The IMemAllocator::SetProperties method must be called before calling this member function. This member function sets m_bCommitted to TRUE and overrides any pending decommit operation. It then calls the CBaseAllocator::Alloc member function to allocate memory (which should be overridden in the derived class to call the base class member function and then allocate the memory). The IMemAllocator::GetBuffer method fails if it is called before calling this member function.
Releases the memory for the specified buffers.
HRESULT Decommit(void);
Returns an HRESULT value.
This member function implements the IMemAllocator::Decommit method. Any threads waiting in the IMemAllocator::GetBuffer method return with an error after this method is called. The IMemAllocator::GetBuffer method fails if it is called before the IMemAllocator::Commit method or after this method.
Called to decommit the memory when the last buffer is freed.
virtual void Free(void) PURE;
No return value.
This member function must be implemented in the derived class. It is called from CBaseAllocator::ReleaseBuffer when a decommit is pending and the allocator has put its last buffer on the free list. It is also called from CBaseAllocator::Decommit.
The CMemAllocator::Free member function is an example of how this can be implemented in the derived class. In this case, it simply returns, because the CMemAllocator class releases memory from its destructor.
This member function is protected.
Retrieves a container for a sample.
HRESULT GetBuffer(
IMediaSample ** ppBuffer,
REFERENCE_TIME * pStartTime,
REFERENCE_TIME * pEndTime,
DWORD dwFlags
);
Value | Meaning |
AM_GBF_PREVFRAMESKIPPED | The buffer returned will not be filled with data contiguous to any previous data sent. |
AM_GBF_NOTASYNCPOINT | Dynamic format changes are not allowed on this buffer because it is not a key frame. |
Returns an HRESULT value.
This member function implements the IMemAllocator::GetBuffer method.
This is a blocking, synchronous call to access the next free buffer (as represented by an IMediaSample interface). Upon return, properties (such as the time and so on) are invalid, but the buffer pointer and size are correct.
If no buffers are available, CBaseAllocator::GetBuffer calls CBaseAllocator::SetWaiting and then calls the Microsoft® Win32® WaitForSingleObject function to wait for the list to signal that a sample is available. The list signals by calling CBaseAllocator::ReleaseBuffer, which in turn calls CBaseAllocator::NotifySample, which sets m_lWaiting to zero and calls the Win32 ReleaseSemaphore function.
This member function also takes two time parameters. These parameters are used in certain advanced buffering scenarios, when it is necessary to have an idea of the amount of time a buffer is required. The only place this is currently used is in the video renderer, when the time stamps are used as a guide to when the primary surfaces of Display Control Interface (DCI) and Microsoft® DirectDraw® should be returned (this is because filling a primary surface buffer corresponds directly to the actual rendering of the data). In all other cases, these parameters can be safely set to NULL. If one is non-NULL, both should be non-NULL; these times will not be set on the sample when it is subsequently returned.
Retrieves the size, number, and alignment of blocks.
HRESULT GetProperties(
ALLOCATOR_PROPERTIES * pProps
);
Returns an HRESULT value.
This member function implements the IMemAllocator::GetProperties method. The default implementation fills the ALLOCATOR_PROPERTIES structure passed in with the values of m_lSize, m_lCount, m_lAlignment, and m_lPrefix.
Retrieves an interface and increments the reference count.
HRESULT NonDelegatingQueryInterface(
REFIID riid,
void ** ppv
);
Returns a pointer to the interface.
This member function implements the INonDelegatingUnknown::NonDelegatingQueryInterface method and passes out references to the IMemAllocator and IUnknown interfaces. Override this member function to return other interfaces on the object in the derived class.
Notifies a waiting thread that a sample is available on the free list.
void NotifySample(void);
No return value.
If m_lWaiting has been incremented (is not zero), this indicates a thread is waiting. This member function checks for this condition and calls the Microsoft Win32 ReleaseSemaphore function with the semaphore value m_hSem to activate any waiting thread. It also sets m_lWaiting back to zero.
This member function is called from CBaseAllocator::ReleaseBuffer when putting a sample back on the free list and from CBaseAllocator::Decommit when decommitting the allocator (so that waiting threads can be denied).
Releases the object back to the list of free objects.
HRESULT ReleaseBuffer(
IMediaSample * pSample
);
No return value.
This member function implements the IMemAllocator::ReleaseBuffer method. It adds the sample to the free list (represented by m_lFree) and calls CBaseAllocator::NotifySample to notify any blocked thread waiting for a free sample. If there is a pending CBaseAllocator::Decommit call (indicated by m_bDecommitInProgress), the pure virtual CBaseAllocator::Free member function is called to decommit memory when the last buffer is placed on the free list.
Determines the size, number, and alignment of blocks.
HRESULT SetProperties(
ALLOCATOR_PROPERTIES * pRequest,
ALLOCATOR_PROPERTIES * pActual
);
Returns an HRESULT value.
The pRequest parameter is filled in by the caller with the requested values for the count, number, and alignment as specified by the ALLOCATOR_PROPERTIES structure. The pActual parameter is filled in by the allocator with the closest values that it can provide for the request. This method cannot be called unless the allocator has been decommitted using the IMemAllocator::Decommit method.
The values of data members m_lSize, m_lCount, m_lAlignment, and m_lPrefix are set to the corresponding members of the pActual parameter's ALLOCATOR_PROPERTIES structure.
Increments the m_lWaiting data member to indicate that a thread is waiting for a sample.
void SetWaiting( );
No return value.
This member function is called from CBaseAllocator::GetBuffer if no samples are available on the free list. After calling this, CBaseAllocator::GetBuffer calls the Microsoft® Win32® WaitForSingleObject function to wait for the list to signal that a sample is available. The list signals by calling CBaseAllocator::ReleaseBuffer, which in turn calls CBaseAllocator::NotifySample, which sets m_lWaiting to zero and calls the Win32 ReleaseSemaphore function.
© 1997 Microsoft Corporation. All rights reserved. Terms of Use.