CMBufferQueue

A queue of timed buffers.

Overview

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(_:_:) and CMBufferQueueDequeueAndRetain, but Inspecting Buffer Queues, CMBufferQueueInstallTrigger(_:_:_:_:_:_:) 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 CMBufferQueueDequeueAndRetain, 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 CMBufferQueueDequeueIfDataReadyAndRetain. If that callback is not provided, all buffers are assumed to be ready, and there is no difference between CMBufferQueueDequeueAndRetain, and CMBufferQueueDequeueIfDataReadyAndRetain.

CMBufferQueues also implement CMBufferQueueIsEmpty(_:) and CMBufferQueueTestTrigger(_:_:), 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(_:_:_:_:)), current queue duration (Inspecting Buffer Queues), and end-of-data status (CMBufferQueueContainsEndOfData(_:) and CMBufferQueueIsAtEndOfData(_:)).

You can install trigger callbacks (using CMBufferQueueInstallTrigger(_:_:_:_:_:_:)) 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.

Topics

Configuring Buffer Queues

func CMBufferQueueEnqueue(CMBufferQueue, CMBuffer)

Enqueues a buffer onto a CMBufferQueue.

func CMBufferQueueMarkEndOfData(CMBufferQueue)

Marks a CMBufferQueue with EndOfData.

func CMBufferQueueRemoveTrigger(CMBufferQueue, CMBufferQueueTriggerToken)

Removes a previously installed trigger from a CMBufferQueue.

func CMBufferQueueReset(CMBufferQueue)

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

func CMBufferQueueResetWithCallback(CMBufferQueue, (CMBuffer, UnsafeMutableRawPointer?) -> Void, UnsafeMutableRawPointer?)

A function callback that calls a function for every buffer in a queue and then resets the queue.

func CMBufferQueueSetValidationCallback(CMBufferQueue, CMBufferValidationCallback, UnsafeMutableRawPointer?)

A function callback that sets a function that CMBufferQueueEnqueue(_:_:) will call to validate buffers before adding them to the queue.

Inspecting Buffer Queues

func CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS()

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

func CMBufferQueueGetTotalSize(CMBufferQueue)

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

func CMBufferQueueGetBufferCount(CMBufferQueue)

Gets the number of buffers in the queue.

func CMBufferQueueGetMaxPresentationTimeStamp(CMBufferQueue)

Gets the greatest presentation timestamp of a CMBufferQueue.

func CMBufferQueueGetCallbacksForUnsortedSampleBuffers()

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

func CMBufferQueueGetDuration(CMBufferQueue)

Gets the duration of a CMBufferQueue.

func CMBufferQueueGetEndPresentationTimeStamp(CMBufferQueue)

Gets the greatest end presentation timestamp of a CMBufferQueue.

func CMBufferQueueGetFirstDecodeTimeStamp(CMBufferQueue)

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

func CMBufferQueueGetMinDecodeTimeStamp(CMBufferQueue)

Gets the earliest decode timestamp of a CMBufferQueue.

func CMBufferQueueGetFirstPresentationTimeStamp(CMBufferQueue)

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

func CMBufferQueueGetHead(CMBufferQueue)

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

func CMBufferQueueGetMinPresentationTimeStamp(CMBufferQueue)

Gets the earliest presentation timestamp of a CMBufferQueue.

func CMBufferQueueGetTypeID()

Returns the CFTypeID of CMBufferQueue objects.

func CMBufferQueueContainsEndOfData(CMBufferQueue)

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

func CMBufferQueueIsAtEndOfData(CMBufferQueue)

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

func CMBufferQueueIsEmpty(CMBufferQueue)

Returns whether or not a CMBufferQueue is empty.

func CMBufferQueueTestTrigger(CMBufferQueue, CMBufferQueueTriggerToken)

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

Data Types

class CMBufferQueue

A reference to a CMBufferQueueRef object.

Callbacks

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.

Triggers

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.

Constants

Buffer Queue Error Codes

Error codes generated by CMBufferQueue operations.

Trigger Conditions

Conditions to be associated with a CMBufferQueueTrigger.

See Also

Queues

CMSimpleQueue

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

CMMemoryPool

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