A queue of timed buffers.


CMBufferQueues are Core Foundation objects that implement a queue of timed buffers. These buffers can be of any Core Foundation-based type (CFTypeRef), but must have a concept of duration. During CMBufferQueue creation, a set of callbacks is provided, one of which is a required callback that returns the duration of the Core Foundation-based buffer object. A standard callback struct for CMSampleBuffers is provided as a convenience. These callbacks are called synchronously from within various CMBufferQueue APIs, on the thread that called the API.

CMBufferQueues are designed to be read and written from different threads in a producer/consumer model. While this is generally two threads (one producer/enqueuer, one dequeuer/consumer), CMBufferQueues can service any number of threads enqueueing and/or dequeueing buffers. In the CMBufferQueue APIs, all operations (not just CMBufferQueueEnqueue(_:buffer:) and CMBufferQueueDequeue(_:), but Inspecting Buffer Queues, CMBufferQueueInstallTrigger(_:callback:refcon:condition:time:triggerTokenOut:) and so on) are made atomic by use of a single mutex (one mutex per created queue object).

By default, a CMBufferQueue is a FIFO queue, but if a comparison callback is provided, the resulting CMBufferQueue will be sorted based on that callback. For example, one might create a CMBufferQueue where the buffers are enqueued in decode order, and dequeued in presentation order, by providing a comparison callback that sorts by presentation timestamp.

CMBufferQueues retain the enqueued buffer during Enqueue, so the client can release the buffer if it has no further need of the reference. During CMBufferQueueDequeue(_:), the buffer is retained on behalf of the client, and released by the queue. The result is that the retain count remains the same, and the ownership of the buffer is transferred from the queue to the client.

If provided with a buffer-readiness callback, CMBufferQueues can check for buffer readiness during CMBufferQueueDequeueIfDataReady(_:). If that callback is not provided, all buffers are assumed to be ready, and there is no difference between CMBufferQueueDequeue(_:), and CMBufferQueueDequeueIfDataReady(_:).

CMBufferQueues also implement CMBufferQueueIsEmpty(_:) and CMBufferQueueTestTrigger(_:triggerToken:), with the help of optional callbacks that get decode and presentation timestamps from a buffer. If either or both of these callbacks is not provided, kCMTimeInvalid will be returned for the missing timestamp(s).

CMBufferQueues can be marked with an end-of-data (CMBufferQueueMarkEndOfData(_:)). Once so marked, further enqueues will fail, and once all the buffers have been dequeued, the queue is permanently empty ("at end of data") until Reset is called. Reset empties the queue and undoes the end-of-data marking.

The current status of a CMBufferQueue can be interrogated. You can test for emptiness (CMBufferQueueCreate(allocator:capacity:callbacks:queueOut:)), current queue duration (Inspecting Buffer Queues), and end-of-data status (CMBufferQueueContainsEndOfData(_:) and CMBufferQueueIsAtEndOfData(_:)).

You can install trigger callbacks (using CMBufferQueueInstallTrigger(_:callback:refcon:condition:time:triggerTokenOut:)) to get notifications of various queue state transitions, such as “duration becomes less than 1 second”. The queue cannot be modified during a trigger callback, but it can be interrogated. Trigger conditions can be tested explicitly as well (CMBufferQueue). Triggers with NULL callbacks can be added to a queue for this type of use, but triggers with callbacks can also have their conditions explicitly tested.

Trigger callbacks may be called from any CMBufferQueue API that modifies the total duration of the queue (such as Enqueue/Dequeue/Reset). Trigger callbacks are called synchronously, on the thread that called the API.

Modifying the state of the queue in any way from within a trigger callback is forbidden, and will fail, returning kCMBufferQueueError_CannotModifyQueueFromTriggerCallback.

An attempt to Enqueue onto a full queue or to Dequeue from an empty queue will not block, but will return immediately with an error (or with a NULL buffer). Triggers should be installed by the client to manage the client's knowledge of queue fullness. The use of repeated retries (polling) is discouraged as an inefficient use of resources.


Configuring Buffer Queues

func CMBufferQueueDequeue(CMBufferQueue) -> CMBuffer?

Dequeues a buffer from a CMBufferQueue.

func CMBufferQueueDequeueIfDataReady(CMBufferQueue) -> CMBuffer?

Dequeues a buffer from a CMBufferQueue if it is ready.

func CMBufferQueueReset(CMBufferQueue) -> OSStatus

Resets a CMBufferQueue. Empties the queue, and clears any EndOfData mark.

Inspecting Buffer Queues

func CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS() -> UnsafePointer<CMBufferCallbacks>

Returns a pointer to a callback struct for CMSampleBuffers sorted by output presentation timestamp.

func CMBufferQueueGetTotalSize(CMBufferQueue) -> Int

Gets the total size of all sample buffers of a CMBufferQueue.

func CMBufferQueueGetMaxPresentationTimeStamp(CMBufferQueue) -> CMTime

Gets the greatest presentation timestamp of a CMBufferQueue.

func CMBufferQueueGetCallbacksForUnsortedSampleBuffers() -> UnsafePointer<CMBufferCallbacks>

Returns a pointer to a callback struct for unsorted CMSampleBuffers, provided as a convenience.

func CMBufferQueueGetDuration(CMBufferQueue) -> CMTime

Gets the duration of a CMBufferQueue.

func CMBufferQueueGetEndPresentationTimeStamp(CMBufferQueue) -> CMTime

Gets the greatest end presentation timestamp of a CMBufferQueue.

func CMBufferQueueGetFirstDecodeTimeStamp(CMBufferQueue) -> CMTime

Gets the decode timestamp of the first buffer in a CMBufferQueue.

func CMBufferQueueGetMinDecodeTimeStamp(CMBufferQueue) -> CMTime

Gets the earliest decode timestamp of a CMBufferQueue.

func CMBufferQueueGetFirstPresentationTimeStamp(CMBufferQueue) -> CMTime

Gets the presentation timestamp of the first buffer in a CMBufferQueue.

func CMBufferQueueGetHead(CMBufferQueue) -> CMBuffer?

Retrieves the next-to-dequeue buffer from a CMBufferQueue but leaves it in the queue.

func CMBufferQueueGetMinPresentationTimeStamp(CMBufferQueue) -> CMTime

Gets the earliest presentation timestamp of a CMBufferQueue.

func CMBufferQueueGetTypeID() -> CFTypeID

Returns the CFTypeID of CMBufferQueue objects.

func CMBufferQueueContainsEndOfData(CMBufferQueue) -> Bool

Returns whether or not a CMBufferQueue has been marked with EndOfData.

func CMBufferQueueIsAtEndOfData(CMBufferQueue) -> Bool

Returns whether or not a CMBufferQueue has been marked with EndOfData, and is now empty.

func CMBufferQueueIsEmpty(CMBufferQueue) -> Bool

Returns whether or not a CMBufferQueue is empty.

func CMBufferQueueTestTrigger(CMBufferQueue, triggerToken: CMBufferQueueTriggerToken) -> Bool

Tests whether the trigger condition is true fot the given CMBufferQueue.


struct CMBufferCallbacks

Callbacks provided to Creating Buffer Queues, for use by the queue in interrogating the buffers that it will see.

typealias CMBufferValidationCallback

Tests whether a buffer is in a valid state to add to a queue.

typealias CMBufferGetTimeCallback

Callback that returns a CMTime from a CMBuffer.

typealias CMBufferGetBooleanCallback

Callback that returns a Boolean value from a CMBuffer.

typealias CMBufferCompareCallback

Callback that compares one CMBuffer with another.


A trigger is a callback function that a queue calls every time the triggering condition becomes true. Trigger conditions include things like queue duration, queue buffer count, and so on. Trigger callbacks are called from within CMBufferQueue routines that modify the trigger condition (for example, Enqueue/Dequeue/Reset).

Trigger callbacks cannot modify the queue that called them; they can, however, interrogate it. Trigger callbacks should perform as little processing as possible, preferably arranging for processing to occur by, for example, signaling a semaphore, or rescheduling a runloop timer.

You can install as many triggers as you like. The order in which they are called is non-deterministic.

Triggers with a NULL callback are valid, since even though no trigger callback will be called, the trigger condition can still be explicitly tested.

typealias CMBufferQueueTriggerToken

A reference to a CMBufferQueueTriggerToken object.

typealias CMBufferQueueTriggerCallback

A callback to be called when a CMBufferQueue trigger condition becomes true.

typealias CMBufferQueueTriggerCondition

A type to specify conditions to be associated with a CMBufferQueueTrigger.


Buffer Queue Error Codes

Error codes generated by CMBufferQueue operations.

Trigger Conditions

Conditions to be associated with a CMBufferQueueTrigger.

See Also



A simple, lockless FIFO queue of (void *) elements.


A pool used for optimizing memory allocation when large blocks of memory must be repeatedly allocated, deallocated, and then reallocated.