A queue of timed buffers.
- Core Media
CMBuffer are Core Foundation objects that implement a queue of timed buffers. These buffers can be of any Core Foundation-based type (
CFType), but must have a concept of duration. During
CMBuffer 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
CMSample is provided as a convenience. These callbacks are called synchronously from within various
CMBuffer APIs, on the thread that called the API.
CMBuffer 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),
CMBuffer can service any number of threads enqueueing and/or dequeueing buffers. In the
CMBuffer APIs, all operations (not just
CMBuffer, but Inspecting Buffer Queues,
CMBuffer and so on) are made atomic by use of a single mutex (one mutex per created queue object).
By default, a
CMBuffer is a FIFO queue, but if a comparison callback is provided, the resulting
CMBuffer will be sorted based on that callback. For example, one might create a
CMBuffer where the buffers are enqueued in decode order, and dequeued in presentation order, by providing a comparison callback that sorts by presentation timestamp.
CMBuffer retain the enqueued buffer during Enqueue, so the client can release the buffer if it has no further need of the reference. During
CMBuffer, 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,
CMBuffer can check for buffer readiness during
CMBuffer. If that callback is not provided, all buffers are assumed to be ready, and there is no difference between
CMBuffer also implement
CMBuffer, 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,
k will be returned for the missing timestamp(s).
CMBuffer can be marked with an end-of-data (
CMBuffer). 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
CMBuffer can be interrogated. You can test for emptiness (
CMBuffer), current queue duration (Inspecting Buffer Queues), and end-of-data status (
You can install trigger callbacks (using
CMBuffer) 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
CMBuffer 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
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.