Contents

CMBufferQueue

A queue of timed buffers.

Overview

Buffer queues are Core Foundation objects that implement a queue of timed buffers. The buffers can be of any Core Foundation-based type (CFTypeRef), but must have a concept of duration. When you create a buffer queue, you pass a set of callbacks, one of which is a required callback that returns the duration of the Core Foundation-based buffer object. The system invokes these callbacks synchronously on the thread that called the API.

Buffer queues support reading and writing data from different threads in a producer-consumer model. While this model typically has two threads (a producer and a consumer), a buffer queue can service any number of threads to enqueue and dequeue buffers. The system makes all operations atomic by use of a single mutex (one mutex per created queue object).

By default, a CMBufferQueue is a FIFO queue, but you can change that order by providing a comparison callback. For example, you might create a buffer queue where you enqueue buffers in decode order, and dequeue them in presentation order, by providing a comparison callback that sorts by presentation timestamp.

A buffer queue retains its enqueued buffers. When you call CMBufferQueueDequeue(_:), the system retains the buffer on behalf of the app, and the queue releases it. The retain count remains the same, but the app takes ownership of the buffer.

If you provide a buffer-readiness callback, an instance of CMBufferQueue can check for buffer readiness when calling the CMBufferQueueDequeueIfDataReady(_:) function. If you don’t provide that callback, the system assumes all buffers are ready, and there’s no difference between CMBufferQueueDequeue(_:) and CMBufferQueueDequeueIfDataReady(_:).

Buffer queues also provide the CMBufferQueueIsEmpty(_:) and CMBufferQueueTestTrigger(_:triggerToken:) functions that, with the help of optional callbacks, get decode and presentation timestamps from a buffer. The system returns a value of invalid if you don’t provide these callbacks.

You can set an end-of-data marker on a buffer queue, which causes further enqueues to fail. After the queue has dequeued all buffers, the queue is permanently empty (“at end of data”) until you call the CMBufferQueueReset(_:)function. Reset empties the queue and undoes the end-of-data marking.

You can interrogate the current status of a buffer queue. For example, 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 by calling the CMBufferQueueInstallTriggerHandler(_:_:_:_:_:) function to get notifications of various queue state transitions, such as when the duration becomes less than a second. You can inspect a buffer queue during trigger callback, but you can’t modify it. You can test trigger conditions explicitly as well. You can invoke trigger callbacks from any buffer queue API that modifies the total duration of the queue, such as enqueuing, dequeuing, or resetting the queue. The system invokes trigger callbacks synchronously on the thread that called the API.

You can’t modify the state of the queue from within a trigger callback. The operation fails, returning a kCMBufferQueueError_CannotModifyQueueFromTriggerCallback error. Attempting to enqueue a buffer when the queue is full, or dequeue from an empty queue, immediately returns an error (or a NULL buffer).

Install triggers to observe the queue’s fullness rather than repeatedly polling the queue to get this state.

Topics

Creating a Queue

Managing a Queue

Managing Triggers

Inspecting Duration and Timing

Inspecting a Queue

Validating a Queue

Accessing the Type Identifier

Data Types

Error Codes

See Also

Queues