## CBaseAllocator Class

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_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_lAlignment | Agreed alignment of the buffer.
m_lAllocated | Number of buffers actually allocated.
m_lCount | Established number of buffers to provide.
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_lSize | Size of each buffer.
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.

###

CBaseAllocator::Alloc

CBaseAllocator Class

Allocates a media sample object.

HRESULT Alloc(void);

##### Return Values

Returns an HRESULT value.

##### Remarks

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.

###

CBaseAllocator::CBaseAllocator

CBaseAllocator Class

Constructs a CBaseAllocator object.

CBaseAllocator(
TCHAR * pName,
LPUNKNOWN lpUnk,
HRESULT * phr,
BOOL bListSemaphore = TRUE
);

##### Parameters

pName
  Name of the allocator object.
lpUnk
  Pointer to LPUNKNOWN.
phr
  Pointer to an HRESULT for return values. This is not modified unless this member function fails.
bListSemaphore
  If TRUE, the free list in the allocator has a semaphore associated with it. If FALSE, no semaphore is created for the list. Setting this to FALSE can be useful for subclassing CBaseAllocator when the semaphore is not required for blocking. The semaphore is used for the waiting and signaling mechanism.

##### Return Values

No return value.

###

CBaseAllocator::Commit

CBaseAllocator Class

Commits the memory for the specified buffers.

HRESULT Commit(void);

##### Return Values

Returns an HRESULT value.

##### Remarks

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.

Call CBaseAllocator::Decommit to release memory when done with the buffers.

###

CBaseAllocator::Decommit

CBaseAllocator Class

Releases the memory for the specified buffers.

HRESULT Decommit(void);

##### Return Values

Returns an HRESULT value.

##### Remarks

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.

##### See Also

CBaseAllocator::Commit

###

CBaseAllocator::Free

CBaseAllocator Class

Called to decommit the memory when the last buffer is freed.

virtual void Free(void) PURE;

##### Return Values

No return value.

##### Remarks

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.

###

CBaseAllocator::GetBuffer

CBaseAllocator Class

Retrieves a container for a sample.

HRESULT GetBuffer(
IMediaSample ** ppBuffer,
REFERENCE_TIME * pStartTime,
REFERENCE_TIME * pEndTime,
DWORD dwFlags
);

##### Parameters

ppBuffer
  Pointer to a retrieved media sample buffer.
pStartTime
  Either NULL or set to the beginning time of the sample to retrieve.
pEndTime
  Either NULL or set to the ending time of the sample to retrieve.
dwFlags
  The following flags are supported.

  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.

##### Return Values

Returns an HRESULT value.

##### Remarks

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.

###

CBaseAllocator::GetProperties

CBaseAllocator Class

Retrieves the size, number, and alignment of blocks.

HRESULT GetProperties(
ALLOCATOR_PROPERTIES * pProps
);

##### Parameters

pProps
  Structure to be filled in with allocator properties.

##### Return Values

Returns an HRESULT value. The default implementation returns NOERROR.

##### Remarks

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.

###

CBaseAllocator::NonDelegatingQueryInterface

CBaseAllocator Class

Retrieves an interface and increments the reference count.

HRESULT NonDelegatingQueryInterface(
REFIID riid,
void ** ppv
);

##### Parameters

riid
  Reference identifier.
ppv
  Pointer to the interface.

##### Return Values

Returns E_POINTER if ppv is invalid. Returns NOERROR if the query is successful or E_NOINTERFACE if it is not.

##### Remarks

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.

###

CBaseAllocator::NotifySample

CBaseAllocator Class

Notifies a waiting thread that a sample is available on the free list.

void NotifySample(void);

##### Return Values

No return value.

##### Remarks

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).

###

CBaseAllocator::ReleaseBuffer

CBaseAllocator Class

Releases the object back to the list of free objects.

HRESULT ReleaseBuffer(
IMediaSample * pSample
);

##### Parameters

pSample
  Pointer to the IMediaSample interface of the media sample object.

##### Return Values

No return value.

##### Remarks

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.

###

CBaseAllocator::SetProperties

CBaseAllocator Class

Determines the size, number, and alignment of blocks.

HRESULT SetProperties(
ALLOCATOR_PROPERTIES * pRequest,
ALLOCATOR_PROPERTIES * pActual
);

##### Parameters

pRequest
  Allocator properties requested to be set.
pActual
  Allocator properties actually set.

##### Return Values

Returns an HRESULT value.

##### Remarks

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.

###

CBaseAllocator::SetWaiting

CBaseAllocator Class

Increments the m_lWaiting data member to indicate that a thread is waiting for a sample.

void SetWaiting( );

##### Return Values

No return value.

##### Remarks

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.