objc2_core_media/generated/
CMBufferQueue.rs

1//! This file has been automatically generated by `objc2`'s `header-translator`.
2//! DO NOT EDIT
3use core::cell::UnsafeCell;
4use core::ffi::*;
5use core::marker::{PhantomData, PhantomPinned};
6use core::ptr::NonNull;
7#[cfg(feature = "objc2")]
8use objc2::__framework_prelude::*;
9use objc2_core_foundation::*;
10
11use crate::*;
12
13/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_allocationfailed?language=objc)
14pub const kCMBufferQueueError_AllocationFailed: OSStatus = -12760;
15/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_requiredparametermissing?language=objc)
16pub const kCMBufferQueueError_RequiredParameterMissing: OSStatus = -12761;
17/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_invalidcmbuffercallbacksstruct?language=objc)
18pub const kCMBufferQueueError_InvalidCMBufferCallbacksStruct: OSStatus = -12762;
19/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_enqueueafterendofdata?language=objc)
20pub const kCMBufferQueueError_EnqueueAfterEndOfData: OSStatus = -12763;
21/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_queueisfull?language=objc)
22pub const kCMBufferQueueError_QueueIsFull: OSStatus = -12764;
23/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_badtriggerduration?language=objc)
24pub const kCMBufferQueueError_BadTriggerDuration: OSStatus = -12765;
25/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_cannotmodifyqueuefromtriggercallback?language=objc)
26pub const kCMBufferQueueError_CannotModifyQueueFromTriggerCallback: OSStatus = -12766;
27/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_invalidtriggercondition?language=objc)
28pub const kCMBufferQueueError_InvalidTriggerCondition: OSStatus = -12767;
29/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_invalidtriggertoken?language=objc)
30pub const kCMBufferQueueError_InvalidTriggerToken: OSStatus = -12768;
31/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueueerror_invalidbuffer?language=objc)
32pub const kCMBufferQueueError_InvalidBuffer: OSStatus = -12769;
33
34/// A reference to a CMBufferQueue, a CF object that implements a queue of timed buffers.
35///
36/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbufferqueue?language=objc)
37#[doc(alias = "CMBufferQueueRef")]
38#[repr(C)]
39pub struct CMBufferQueue {
40    inner: [u8; 0],
41    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
42}
43
44cf_type!(
45    unsafe impl CMBufferQueue {}
46);
47#[cfg(feature = "objc2")]
48cf_objc2_type!(
49    unsafe impl RefEncode<"opaqueCMBufferQueue"> for CMBufferQueue {}
50);
51
52/// A reference to a CMBuffer.
53///
54/// A CMBuffer can be any CFTypeRef, as long as a getDuration callback can be provided.  Commonly used
55/// types are CMSampleBufferRef and CVPixelBufferRef.
56///
57/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffer?language=objc)
58#[doc(alias = "CMBufferRef")]
59pub type CMBuffer = CFType;
60
61/// Client callback that returns a CMTime from a CMBufferRef
62///
63/// There are three callbacks of this type that can be provided to CMBufferQueueCreate: getDuration (required),
64/// getDecodeTimeStamp (optional), and getPresentationTimeStamp (optional).
65///
66/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffergettimecallback?language=objc)
67#[cfg(feature = "CMTime")]
68pub type CMBufferGetTimeCallback =
69    Option<unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void) -> CMTime>;
70
71/// Client block that returns a CMTime from a CMBufferRef
72///
73/// There are three blocks of this type that can be provided to CMBufferQueueCreate: getDuration (required),
74/// getDecodeTimeStamp (optional), and getPresentationTimeStamp (optional).
75///
76/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffergettimehandler?language=objc)
77#[cfg(all(feature = "CMTime", feature = "block2"))]
78pub type CMBufferGetTimeHandler = *mut block2::DynBlock<dyn Fn(NonNull<CMBuffer>) -> CMTime>;
79
80/// Client callback that returns a Boolean from a CMBufferRef
81///
82/// There is one callback of this type that can be provided to CMBufferQueueCreate: isDataReady (optional).
83///
84/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffergetbooleancallback?language=objc)
85pub type CMBufferGetBooleanCallback =
86    Option<unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void) -> Boolean>;
87
88/// Client block that returns a Boolean from a CMBufferRef
89///
90/// There is one callback of this type that can be provided to CMBufferQueueCreate: isDataReady (optional).
91///
92/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffergetbooleanhandler?language=objc)
93#[cfg(feature = "block2")]
94pub type CMBufferGetBooleanHandler = *mut block2::DynBlock<dyn Fn(NonNull<CMBuffer>) -> Boolean>;
95
96/// Client callback that compares one CMBufferRef with another.
97///
98/// Note that a CFComparatorFunction can be used here.
99///
100/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffercomparecallback?language=objc)
101pub type CMBufferCompareCallback = Option<
102    unsafe extern "C-unwind" fn(
103        NonNull<CMBuffer>,
104        NonNull<CMBuffer>,
105        *mut c_void,
106    ) -> CFComparisonResult,
107>;
108
109/// Client block that compares one CMBufferRef with another.
110///
111/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffercomparehandler?language=objc)
112#[cfg(feature = "block2")]
113pub type CMBufferCompareHandler =
114    *mut block2::DynBlock<dyn Fn(NonNull<CMBuffer>, NonNull<CMBuffer>) -> CFComparisonResult>;
115
116/// Client callback that returns a size_t from a CMBufferRef
117///
118/// There is one callback of this type that can be provided to CMBufferQueueCreate: getTotalSize.
119///
120/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffergetsizecallback?language=objc)
121pub type CMBufferGetSizeCallback =
122    Option<unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void) -> usize>;
123
124/// Client block that returns a size_t from a CMBufferRef
125///
126/// There is one block of this type that can be provided to CMBufferQueueCreate: getTotalSize.
127///
128/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffergetsizehandler?language=objc)
129#[cfg(feature = "block2")]
130pub type CMBufferGetSizeHandler = *mut block2::DynBlock<dyn Fn(NonNull<CMBuffer>) -> usize>;
131
132/// Callbacks provided to CMBufferQueueCreate, for use by the queue in interrogating the buffers that it will see.
133///
134/// With the exception of isDataReady, all these callbacks must always return the same result for the same arguments.
135/// A buffer's duration, timestamps, or position relative to other buffers must not appear to change while it is in
136/// the queue.  Once isDataReady has returned true for a given CMBuffer, it must always return true for that
137/// CMBuffer.  Durations must always be positive.
138///
139/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffercallbacks?language=objc)
140#[cfg(feature = "CMTime")]
141#[repr(C, packed(4))]
142#[allow(unpredictable_function_pointer_comparisons)]
143#[derive(Clone, Copy, Debug, PartialEq)]
144pub struct CMBufferCallbacks {
145    /// Must be 0 or 1.
146    pub version: u32,
147    /// Client refcon to be passed to all callbacks (can be NULL,
148    /// if the callbacks don't require it).
149    pub refcon: *mut c_void,
150    /// This callback is called from CMBufferQueueGetFirstDecodeTimeStamp (once),
151    /// and from CMBufferQueueGetMinDecodeTimeStamp (multiple times).  It should
152    /// return the decode timestamp of the buffer.  If there are multiple samples
153    /// in the buffer, this callback should return the minimum decode timestamp
154    /// in the buffer. Can be NULL (CMBufferQueueGetFirstDecodeTimeStamp and
155    /// CMBufferQueueGetMinDecodeTimeStamp will return kCMTimeInvalid).
156    pub getDecodeTimeStamp: CMBufferGetTimeCallback,
157    /// This callback is called from CMBufferQueueGetFirstPresentationTimeStamp
158    /// (once) and from CMBufferQueueGetMinPresentationTimeStamp (multiple times).
159    /// It should return the presentation timestamp of the buffer.  If there are
160    /// multiple samples in the buffer, this callback should return the minimum
161    /// presentation timestamp in the buffer. Can be NULL
162    /// (CMBufferQueueGetFirstPresentationTimeStamp and
163    /// CMBufferQueueGetMinPresentationTimeStamp will return kCMTimeInvalid).
164    pub getPresentationTimeStamp: CMBufferGetTimeCallback,
165    /// This callback is called (once) during enqueue and dequeue operations to
166    /// update the total duration of the queue.  Must not be NULL.
167    pub getDuration: CMBufferGetTimeCallback,
168    /// This callback is called from CMBufferQueueDequeueIfDataReadyAndRetain, to
169    /// ask if the buffer that is about to be dequeued is ready.  Can be NULL
170    /// (data will be assumed to be ready).
171    pub isDataReady: CMBufferGetBooleanCallback,
172    /// This callback is called (multiple times) from CMBufferQueueEnqueue, to
173    /// perform an insertion sort. Can be NULL (queue will be FIFO).
174    pub compare: CMBufferCompareCallback,
175    /// If triggers of type kCMBufferQueueTrigger_WhenDataBecomesReady are installed,
176    /// the queue will listen for this notification on the head buffer.
177    /// Can be NULL (then the queue won't listen for it).
178    pub dataBecameReadyNotification: *const CFString,
179    /// This callback is called (once) during enqueue and dequeue operation to
180    /// update the total size of the queue. Can be NULL.  Ignored if version
181    /// <
182    /// 1.
183    pub getSize: CMBufferGetSizeCallback,
184}
185
186#[cfg(all(feature = "CMTime", feature = "objc2"))]
187unsafe impl Encode for CMBufferCallbacks {
188    const ENCODING: Encoding = Encoding::Struct(
189        "?",
190        &[
191            <u32>::ENCODING,
192            <*mut c_void>::ENCODING,
193            <CMBufferGetTimeCallback>::ENCODING,
194            <CMBufferGetTimeCallback>::ENCODING,
195            <CMBufferGetTimeCallback>::ENCODING,
196            <CMBufferGetBooleanCallback>::ENCODING,
197            <CMBufferCompareCallback>::ENCODING,
198            <*const CFString>::ENCODING,
199            <CMBufferGetSizeCallback>::ENCODING,
200        ],
201    );
202}
203
204#[cfg(all(feature = "CMTime", feature = "objc2"))]
205unsafe impl RefEncode for CMBufferCallbacks {
206    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
207}
208
209/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbufferhandlers?language=objc)
210#[cfg(all(feature = "CMTime", feature = "block2"))]
211#[repr(C)]
212#[derive(Clone, Copy, Debug, PartialEq)]
213pub struct CMBufferHandlers {
214    /// Must be 1.
215    pub version: usize,
216    /// This block is called from CMBufferQueueGetFirstDecodeTimeStamp (once),
217    /// and from CMBufferQueueGetMinDecodeTimeStamp (multiple times).  It should
218    /// return the decode timestamp of the buffer.  If there are multiple samples
219    /// in the buffer, this block should return the minimum decode timestamp
220    /// in the buffer. Can be NULL (CMBufferQueueGetFirstDecodeTimeStamp and
221    /// CMBufferQueueGetMinDecodeTimeStamp will return kCMTimeInvalid).
222    pub getDecodeTimeStamp: CMBufferGetTimeHandler,
223    /// This block is called from CMBufferQueueGetFirstPresentationTimeStamp
224    /// (once) and from CMBufferQueueGetMinPresentationTimeStamp (multiple times).
225    /// It should return the presentation timestamp of the buffer.  If there are
226    /// multiple samples in the buffer, this block should return the minimum
227    /// presentation timestamp in the buffer. Can be NULL
228    /// (CMBufferQueueGetFirstPresentationTimeStamp and
229    /// CMBufferQueueGetMinPresentationTimeStamp will return kCMTimeInvalid).
230    pub getPresentationTimeStamp: CMBufferGetTimeHandler,
231    /// This block is called (once) during enqueue and dequeue operations to
232    /// update the total duration of the queue.  Must not be NULL.
233    pub getDuration: CMBufferGetTimeHandler,
234    /// This block is called from CMBufferQueueDequeueIfDataReadyAndRetain, to
235    /// ask if the buffer that is about to be dequeued is ready.  Can be NULL
236    /// (data will be assumed to be ready).
237    pub isDataReady: CMBufferGetBooleanHandler,
238    /// This block is called (multiple times) from CMBufferQueueEnqueue, to
239    /// perform an insertion sort. Can be NULL (queue will be FIFO).
240    pub compare: CMBufferCompareHandler,
241    /// If triggers of type kCMBufferQueueTrigger_WhenDataBecomesReady are installed,
242    /// the queue will listen for this notification on the head buffer.
243    /// Can be NULL (then the queue won't listen for it).
244    pub dataBecameReadyNotification: *const CFString,
245    /// This block is called (once) during enqueue and dequeue operation to
246    /// update the total size of the queue. Can be NULL.
247    pub getSize: CMBufferGetSizeHandler,
248}
249
250#[cfg(all(feature = "CMTime", feature = "block2", feature = "objc2"))]
251unsafe impl Encode for CMBufferHandlers {
252    const ENCODING: Encoding = Encoding::Struct(
253        "?",
254        &[
255            <usize>::ENCODING,
256            <CMBufferGetTimeHandler>::ENCODING,
257            <CMBufferGetTimeHandler>::ENCODING,
258            <CMBufferGetTimeHandler>::ENCODING,
259            <CMBufferGetBooleanHandler>::ENCODING,
260            <CMBufferCompareHandler>::ENCODING,
261            <*const CFString>::ENCODING,
262            <CMBufferGetSizeHandler>::ENCODING,
263        ],
264    );
265}
266
267#[cfg(all(feature = "CMTime", feature = "block2", feature = "objc2"))]
268unsafe impl RefEncode for CMBufferHandlers {
269    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
270}
271
272impl CMBufferQueue {
273    /// Returns a pointer to a callback struct for unsorted CMSampleBuffers, provided as a convenience.
274    #[doc(alias = "CMBufferQueueGetCallbacksForUnsortedSampleBuffers")]
275    #[cfg(feature = "CMTime")]
276    #[inline]
277    pub unsafe fn callbacks_for_unsorted_sample_buffers() -> NonNull<CMBufferCallbacks> {
278        extern "C-unwind" {
279            fn CMBufferQueueGetCallbacksForUnsortedSampleBuffers(
280            ) -> Option<NonNull<CMBufferCallbacks>>;
281        }
282        let ret = unsafe { CMBufferQueueGetCallbacksForUnsortedSampleBuffers() };
283        ret.expect("function was marked as returning non-null, but actually returned NULL")
284    }
285
286    /// Returns a pointer to a callback struct for CMSampleBuffers sorted by output presentation timestamp, provided as a convenience.
287    #[doc(alias = "CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS")]
288    #[cfg(feature = "CMTime")]
289    #[inline]
290    pub unsafe fn callbacks_for_sample_buffers_sorted_by_output_pts() -> NonNull<CMBufferCallbacks>
291    {
292        extern "C-unwind" {
293            fn CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS(
294            ) -> Option<NonNull<CMBufferCallbacks>>;
295        }
296        let ret = unsafe { CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS() };
297        ret.expect("function was marked as returning non-null, but actually returned NULL")
298    }
299
300    /// Creates a CMBufferQueue object.
301    ///
302    /// On return, the caller owns the returned CMBufferQueue, and must release it when done with it.
303    ///
304    /// # Safety
305    ///
306    /// - `callbacks` must be a valid pointer.
307    /// - `queue_out` must be a valid pointer.
308    #[doc(alias = "CMBufferQueueCreate")]
309    #[cfg(all(feature = "CMBase", feature = "CMTime"))]
310    #[inline]
311    pub unsafe fn create(
312        allocator: Option<&CFAllocator>,
313        capacity: CMItemCount,
314        callbacks: NonNull<CMBufferCallbacks>,
315        queue_out: NonNull<*mut CMBufferQueue>,
316    ) -> OSStatus {
317        extern "C-unwind" {
318            fn CMBufferQueueCreate(
319                allocator: Option<&CFAllocator>,
320                capacity: CMItemCount,
321                callbacks: NonNull<CMBufferCallbacks>,
322                queue_out: NonNull<*mut CMBufferQueue>,
323            ) -> OSStatus;
324        }
325        unsafe { CMBufferQueueCreate(allocator, capacity, callbacks, queue_out) }
326    }
327
328    /// Creates a CMBufferQueue object.
329    ///
330    /// On return, the caller owns the returned CMBufferQueue, and must release it when done with it.
331    ///
332    /// # Safety
333    ///
334    /// - `handlers` must be a valid pointer.
335    /// - `queue_out` must be a valid pointer.
336    #[doc(alias = "CMBufferQueueCreateWithHandlers")]
337    #[cfg(all(feature = "CMBase", feature = "CMTime", feature = "block2"))]
338    #[inline]
339    pub unsafe fn create_with_handlers(
340        allocator: Option<&CFAllocator>,
341        capacity: CMItemCount,
342        handlers: NonNull<CMBufferHandlers>,
343        queue_out: NonNull<*mut CMBufferQueue>,
344    ) -> OSStatus {
345        extern "C-unwind" {
346            fn CMBufferQueueCreateWithHandlers(
347                allocator: Option<&CFAllocator>,
348                capacity: CMItemCount,
349                handlers: NonNull<CMBufferHandlers>,
350                queue_out: NonNull<*mut CMBufferQueue>,
351            ) -> OSStatus;
352        }
353        unsafe { CMBufferQueueCreateWithHandlers(allocator, capacity, handlers, queue_out) }
354    }
355}
356
357unsafe impl ConcreteType for CMBufferQueue {
358    /// Returns the CFTypeID of CMBufferQueue objects.
359    ///
360    /// You can check if a CFTypeRef object is actually a CMBufferQueue by comparing CFGetTypeID(object) with CMBufferQueueGetTypeID().
361    ///
362    /// Returns: CFTypeID of CMBufferQueue objects.
363    #[doc(alias = "CMBufferQueueGetTypeID")]
364    #[inline]
365    fn type_id() -> CFTypeID {
366        extern "C-unwind" {
367            fn CMBufferQueueGetTypeID() -> CFTypeID;
368        }
369        unsafe { CMBufferQueueGetTypeID() }
370    }
371}
372
373impl CMBufferQueue {
374    /// Enqueues a buffer onto a CMBufferQueue.
375    ///
376    /// The buffer is retained by the queue, so the client can safely release the buffer if it has no further use for it.
377    /// If the compare callback is non-NULL, this API performs an insertion sort using that compare operation.
378    /// If the validation callback is non-NULL, this API calls it; if it returns a nonzero OSStatus,
379    /// the buffer will not be enqueued and this API will return the same error OSStatus.
380    ///
381    /// # Safety
382    ///
383    /// `buf` should be of the correct type.
384    #[doc(alias = "CMBufferQueueEnqueue")]
385    #[inline]
386    pub unsafe fn enqueue(&self, buf: &CMBuffer) -> OSStatus {
387        extern "C-unwind" {
388            fn CMBufferQueueEnqueue(queue: &CMBufferQueue, buf: &CMBuffer) -> OSStatus;
389        }
390        unsafe { CMBufferQueueEnqueue(self, buf) }
391    }
392
393    /// Dequeues a buffer from a CMBufferQueue.
394    ///
395    /// The buffer is released by the queue, but it is also retained for the client. Buffer ownership is thereby
396    /// transferred from queue to client.  The client need not retain the buffer, but is responsible to release
397    /// it when done with it.
398    ///
399    /// Returns: The dequeued buffer.  Will be NULL if the queue is empty.
400    #[doc(alias = "CMBufferQueueDequeueAndRetain")]
401    #[inline]
402    pub unsafe fn dequeue_and_retain(&self) -> Option<CFRetained<CMBuffer>> {
403        extern "C-unwind" {
404            fn CMBufferQueueDequeueAndRetain(queue: &CMBufferQueue) -> Option<NonNull<CMBuffer>>;
405        }
406        let ret = unsafe { CMBufferQueueDequeueAndRetain(self) };
407        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
408    }
409
410    /// Dequeues a buffer from a CMBufferQueue if it is ready.
411    ///
412    /// The buffer is released by the queue, but it is also retained for the client. Buffer ownership is thereby
413    /// transferred from queue to client.  The client need not retain the buffer, but is responsible to release
414    /// it when done with it.
415    ///
416    /// Returns: The dequeued buffer.  Will be NULL if the queue is empty, or if the buffer to be dequeued is not yet ready.
417    #[doc(alias = "CMBufferQueueDequeueIfDataReadyAndRetain")]
418    #[inline]
419    pub unsafe fn dequeue_if_data_ready_and_retain(&self) -> Option<CFRetained<CMBuffer>> {
420        extern "C-unwind" {
421            fn CMBufferQueueDequeueIfDataReadyAndRetain(
422                queue: &CMBufferQueue,
423            ) -> Option<NonNull<CMBuffer>>;
424        }
425        let ret = unsafe { CMBufferQueueDequeueIfDataReadyAndRetain(self) };
426        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
427    }
428
429    /// Retrieves the next-to-dequeue buffer from a CMBufferQueue but leaves it in the queue.
430    ///
431    /// This follows CF "Get" semantics -- it does not retain the returned buffer.
432    /// Note that with non-FIFO queues it's not guaranteed that the next dequeue will return
433    /// this particular buffer (if an intervening Enqueue adds a buffer that will dequeue next).
434    /// This function is deprecated in favor of CMBufferQueueCopyHead() which returns a
435    /// retained buffer. When adopting CMBufferQueueCopyHead(), existing CFRetain() call
436    /// on the buffer returned from this function must be removed.
437    ///
438    /// Returns: The buffer.  Will be NULL if the queue is empty.
439    #[doc(alias = "CMBufferQueueGetHead")]
440    #[deprecated]
441    #[inline]
442    pub unsafe fn get_head(&self) -> Option<CFRetained<CMBuffer>> {
443        extern "C-unwind" {
444            fn CMBufferQueueGetHead(queue: &CMBufferQueue) -> Option<NonNull<CMBuffer>>;
445        }
446        let ret = unsafe { CMBufferQueueGetHead(self) };
447        ret.map(|ret| unsafe { CFRetained::retain(ret) })
448    }
449
450    /// Retrieves
451    /// &
452    /// retains the next-to-dequeue buffer from a CMBufferQueue but leaves it in the queue.
453    ///
454    /// This follows CF "Copy" semantics -- it retains the returned buffer.
455    /// Note that with non-FIFO queues it's not guaranteed that the next dequeue will return
456    /// this particular buffer (if an intervening Enqueue adds a buffer that will dequeue next).
457    ///
458    /// Returns: The retained buffer.  Will be NULL if the queue is empty.
459    #[doc(alias = "CMBufferQueueCopyHead")]
460    #[inline]
461    pub unsafe fn head(&self) -> Option<CFRetained<CMBuffer>> {
462        extern "C-unwind" {
463            fn CMBufferQueueCopyHead(queue: &CMBufferQueue) -> Option<NonNull<CMBuffer>>;
464        }
465        let ret = unsafe { CMBufferQueueCopyHead(self) };
466        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
467    }
468
469    /// Returns whether or not a CMBufferQueue is empty.
470    ///
471    /// Returns: Whether or not the CMBufferQueue is empty. If queue is NULL, true is returned.
472    #[doc(alias = "CMBufferQueueIsEmpty")]
473    #[inline]
474    pub unsafe fn is_empty(&self) -> bool {
475        extern "C-unwind" {
476            fn CMBufferQueueIsEmpty(queue: &CMBufferQueue) -> Boolean;
477        }
478        let ret = unsafe { CMBufferQueueIsEmpty(self) };
479        ret != 0
480    }
481
482    /// Marks a CMBufferQueue with EOD.
483    ///
484    /// All subsequent Enqueues will be rejected until CMBufferQueueReset is called.
485    /// Subsequent Dequeues will succeed as long as the queue is not empty.
486    #[doc(alias = "CMBufferQueueMarkEndOfData")]
487    #[inline]
488    pub unsafe fn mark_end_of_data(&self) -> OSStatus {
489        extern "C-unwind" {
490            fn CMBufferQueueMarkEndOfData(queue: &CMBufferQueue) -> OSStatus;
491        }
492        unsafe { CMBufferQueueMarkEndOfData(self) }
493    }
494
495    /// Returns whether or not a CMBufferQueue has been marked with EOD.
496    ///
497    /// Returns: Whether or not the CMBufferQueue has been marked with EOD.
498    /// If queue is NULL, true is returned (a NULL queue is considered to
499    /// be empty, and permanently at EOD).
500    #[doc(alias = "CMBufferQueueContainsEndOfData")]
501    #[inline]
502    pub unsafe fn contains_end_of_data(&self) -> bool {
503        extern "C-unwind" {
504            fn CMBufferQueueContainsEndOfData(queue: &CMBufferQueue) -> Boolean;
505        }
506        let ret = unsafe { CMBufferQueueContainsEndOfData(self) };
507        ret != 0
508    }
509
510    /// Returns whether or not a CMBufferQueue has been marked with EOD, and is now empty.
511    ///
512    /// Returns: Whether or not the CMBufferQueue has been marked with EOD, and is now empty.
513    /// If queue is NULL, true is returned (a NULL queue is considered to
514    /// be empty, and permanently at EOD).
515    #[doc(alias = "CMBufferQueueIsAtEndOfData")]
516    #[inline]
517    pub unsafe fn is_at_end_of_data(&self) -> bool {
518        extern "C-unwind" {
519            fn CMBufferQueueIsAtEndOfData(queue: &CMBufferQueue) -> Boolean;
520        }
521        let ret = unsafe { CMBufferQueueIsAtEndOfData(self) };
522        ret != 0
523    }
524
525    /// Resets a CMBufferQueue. Empties the queue, and clears any EOD mark.
526    ///
527    /// All buffers in the queue are released.  Triggers are not removed, however,
528    /// and will be called appropriately as the queue duration goes to zero.
529    #[doc(alias = "CMBufferQueueReset")]
530    #[inline]
531    pub unsafe fn reset(&self) -> OSStatus {
532        extern "C-unwind" {
533            fn CMBufferQueueReset(queue: &CMBufferQueue) -> OSStatus;
534        }
535        unsafe { CMBufferQueueReset(self) }
536    }
537
538    /// Calls a function for every buffer in a queue, then resets the queue.
539    ///
540    /// # Safety
541    ///
542    /// - `callback` must be implemented correctly.
543    /// - `refcon` must be a valid pointer or null.
544    #[doc(alias = "CMBufferQueueResetWithCallback")]
545    #[inline]
546    pub unsafe fn reset_with_callback(
547        &self,
548        callback: unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void),
549        refcon: *mut c_void,
550    ) -> OSStatus {
551        extern "C-unwind" {
552            fn CMBufferQueueResetWithCallback(
553                queue: &CMBufferQueue,
554                callback: unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void),
555                refcon: *mut c_void,
556            ) -> OSStatus;
557        }
558        unsafe { CMBufferQueueResetWithCallback(self, callback, refcon) }
559    }
560
561    /// Gets the number of buffers in the queue.
562    #[doc(alias = "CMBufferQueueGetBufferCount")]
563    #[cfg(feature = "CMBase")]
564    #[inline]
565    pub unsafe fn buffer_count(&self) -> CMItemCount {
566        extern "C-unwind" {
567            fn CMBufferQueueGetBufferCount(queue: &CMBufferQueue) -> CMItemCount;
568        }
569        unsafe { CMBufferQueueGetBufferCount(self) }
570    }
571
572    /// Gets the duration of a CMBufferQueue.
573    ///
574    /// The duration of the CMBufferQueue is the sum of all the individual
575    /// buffer durations, as reported by the getDuration callback (provided to
576    /// CMBufferQueueCreate).  If there are no buffers in the queue,
577    /// kCMTimeZero will be returned.
578    #[doc(alias = "CMBufferQueueGetDuration")]
579    #[cfg(feature = "CMTime")]
580    #[inline]
581    pub unsafe fn duration(&self) -> CMTime {
582        extern "C-unwind" {
583            fn CMBufferQueueGetDuration(queue: &CMBufferQueue) -> CMTime;
584        }
585        unsafe { CMBufferQueueGetDuration(self) }
586    }
587
588    /// Gets the earliest decode timestamp of a CMBufferQueue.
589    ///
590    /// The search for earliest decode timstamp is performed in this API.
591    /// If you know your queue is in decode order, GetFirstDecodeTimeStamp
592    /// is a faster alternative.  If the getDecodeTimeStamp callback is
593    /// NULL, kCMTimeInvalid will be returned.
594    #[doc(alias = "CMBufferQueueGetMinDecodeTimeStamp")]
595    #[cfg(feature = "CMTime")]
596    #[inline]
597    pub unsafe fn min_decode_time_stamp(&self) -> CMTime {
598        extern "C-unwind" {
599            fn CMBufferQueueGetMinDecodeTimeStamp(queue: &CMBufferQueue) -> CMTime;
600        }
601        unsafe { CMBufferQueueGetMinDecodeTimeStamp(self) }
602    }
603
604    /// Gets the decode timestamp of the first buffer in a CMBufferQueue.
605    ///
606    /// This API is is a faster alternative to GetMinDecodeTimeStamp,
607    /// but only gives the same answer if your queue is in decode order.
608    /// If the getDecodeTimeStamp callback is NULL, kCMTimeInvalid will
609    /// be returned.
610    #[doc(alias = "CMBufferQueueGetFirstDecodeTimeStamp")]
611    #[cfg(feature = "CMTime")]
612    #[inline]
613    pub unsafe fn first_decode_time_stamp(&self) -> CMTime {
614        extern "C-unwind" {
615            fn CMBufferQueueGetFirstDecodeTimeStamp(queue: &CMBufferQueue) -> CMTime;
616        }
617        unsafe { CMBufferQueueGetFirstDecodeTimeStamp(self) }
618    }
619
620    /// Gets the earliest presentation timestamp of a CMBufferQueue.
621    ///
622    /// The search for earliest presentation timstamp is performed in
623    /// this API. If you know your queue is sorted by presentation time,
624    /// GetFirstPresentationTimeStamp is a faster alternative. If the
625    /// getPresentationTimeStamp callback is NULL, kCMTimeInvalid will
626    /// be returned.
627    #[doc(alias = "CMBufferQueueGetMinPresentationTimeStamp")]
628    #[cfg(feature = "CMTime")]
629    #[inline]
630    pub unsafe fn min_presentation_time_stamp(&self) -> CMTime {
631        extern "C-unwind" {
632            fn CMBufferQueueGetMinPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
633        }
634        unsafe { CMBufferQueueGetMinPresentationTimeStamp(self) }
635    }
636
637    /// Gets the presentation timestamp of the first buffer in a CMBufferQueue.
638    ///
639    /// This API is is a faster alternative to GetMinPresentationTimeStamp,
640    /// but only works if you know your queue is sorted by presentation
641    /// timestamp. If the getPresentationTimeStamp callback is NULL,
642    /// kCMTimeInvalid will be returned.
643    #[doc(alias = "CMBufferQueueGetFirstPresentationTimeStamp")]
644    #[cfg(feature = "CMTime")]
645    #[inline]
646    pub unsafe fn first_presentation_time_stamp(&self) -> CMTime {
647        extern "C-unwind" {
648            fn CMBufferQueueGetFirstPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
649        }
650        unsafe { CMBufferQueueGetFirstPresentationTimeStamp(self) }
651    }
652
653    /// Gets the greatest presentation timestamp of a CMBufferQueue.
654    ///
655    /// If the getPresentationTimeStamp callback is NULL, kCMTimeInvalid will
656    /// be returned.
657    #[doc(alias = "CMBufferQueueGetMaxPresentationTimeStamp")]
658    #[cfg(feature = "CMTime")]
659    #[inline]
660    pub unsafe fn max_presentation_time_stamp(&self) -> CMTime {
661        extern "C-unwind" {
662            fn CMBufferQueueGetMaxPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
663        }
664        unsafe { CMBufferQueueGetMaxPresentationTimeStamp(self) }
665    }
666
667    /// Gets the greatest end presentation timestamp of a CMBufferQueue.
668    ///
669    /// This is the maximum end time (PTS + duration) of buffers in the queue.
670    /// If the getPresentationTimeStamp callback is NULL, kCMTimeInvalid will
671    /// be returned.
672    #[doc(alias = "CMBufferQueueGetEndPresentationTimeStamp")]
673    #[cfg(feature = "CMTime")]
674    #[inline]
675    pub unsafe fn end_presentation_time_stamp(&self) -> CMTime {
676        extern "C-unwind" {
677            fn CMBufferQueueGetEndPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
678        }
679        unsafe { CMBufferQueueGetEndPresentationTimeStamp(self) }
680    }
681
682    /// Gets the total size of all sample buffers of a CMBufferQueue.
683    ///
684    /// The total size of the CMBufferQueue is the sum of all the individual
685    /// buffer sizes, as reported by the getTotalSize callback (provided to
686    /// CMBufferQueueCreate).  If there are no buffers in the queue,
687    /// 0 will be returned.
688    #[doc(alias = "CMBufferQueueGetTotalSize")]
689    #[inline]
690    pub unsafe fn total_size(&self) -> usize {
691        extern "C-unwind" {
692            fn CMBufferQueueGetTotalSize(queue: &CMBufferQueue) -> usize;
693        }
694        unsafe { CMBufferQueueGetTotalSize(self) }
695    }
696}
697
698/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/opaquecmbufferqueuetriggertoken?language=objc)
699#[repr(C)]
700#[derive(Debug)]
701pub struct opaqueCMBufferQueueTriggerToken {
702    inner: [u8; 0],
703    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
704}
705
706#[cfg(feature = "objc2")]
707unsafe impl RefEncode for opaqueCMBufferQueueTriggerToken {
708    const ENCODING_REF: Encoding =
709        Encoding::Pointer(&Encoding::Struct("opaqueCMBufferQueueTriggerToken", &[]));
710}
711
712/// A reference to a CMBufferQueueTrigger object.  It is not a CF type; do not CFRetain or CFRelease it.
713///
714/// A trigger is a callback function that the queue calls every time the triggering condition becomes true.
715/// Trigger conditions include things like queue duration, queue buffer count, etc.
716/// Trigger callbacks are called from within CMBufferQueue routines that modify the trigger condition
717/// (eg. Enqueue/Dequeue/Reset).
718///
719/// Trigger callbacks cannot modify the queue that called them; they can, however, interrogate it.
720/// Trigger callbacks should not block waiting for other threads to modify or interrogate the queue either.
721/// In fact, trigger callbacks should perform as little processing as possible, preferably arranging
722/// for processing to occur by signalling a semaphore, rescheduling a runloop timer, calling dispatch_async(), etc.
723///
724/// Clients can install as many triggers as they like.  The order in which they are called is non-deterministic.
725///
726/// Triggers with a NULL callback are valid, since even though no trigger callback will be called, the
727/// trigger condition can still be explicitly tested.
728///
729/// The CMBufferQueueTriggerToken is returned from CMBufferQueueInstallTrigger, so clients can remove
730/// it later if necessary.  Triggers will automatically be removed when the queue is finalized.  Note
731/// that if more than one module has access to a queue, it may be hard for an individual module to know
732/// when the queue is finalized since other modules may retain it.  To address this concern, modules
733/// should remove their triggers before they themselves are finalized.
734///
735/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbufferqueuetriggertoken?language=objc)
736pub type CMBufferQueueTriggerToken = *mut opaqueCMBufferQueueTriggerToken;
737
738/// A callback to be called when a CMBufferQueue trigger condition becomes true.
739///
740/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbufferqueuetriggercallback?language=objc)
741pub type CMBufferQueueTriggerCallback =
742    Option<unsafe extern "C-unwind" fn(*mut c_void, CMBufferQueueTriggerToken)>;
743
744/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbufferqueuetriggerhandler?language=objc)
745#[cfg(feature = "block2")]
746pub type CMBufferQueueTriggerHandler = *mut block2::DynBlock<dyn Fn(CMBufferQueueTriggerToken)>;
747
748/// A condition to be associated with a CMBufferQueueTrigger.
749///
750/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbufferqueuetriggercondition?language=objc)
751pub type CMBufferQueueTriggerCondition = i32;
752
753/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whendurationbecomeslessthan?language=objc)
754pub const kCMBufferQueueTrigger_WhenDurationBecomesLessThan: CMBufferQueueTriggerCondition = 1;
755/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whendurationbecomeslessthanorequalto?language=objc)
756pub const kCMBufferQueueTrigger_WhenDurationBecomesLessThanOrEqualTo:
757    CMBufferQueueTriggerCondition = 2;
758/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whendurationbecomesgreaterthan?language=objc)
759pub const kCMBufferQueueTrigger_WhenDurationBecomesGreaterThan: CMBufferQueueTriggerCondition = 3;
760/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whendurationbecomesgreaterthanorequalto?language=objc)
761pub const kCMBufferQueueTrigger_WhenDurationBecomesGreaterThanOrEqualTo:
762    CMBufferQueueTriggerCondition = 4;
763/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whenminpresentationtimestampchanges?language=objc)
764pub const kCMBufferQueueTrigger_WhenMinPresentationTimeStampChanges: CMBufferQueueTriggerCondition =
765    5;
766/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whenmaxpresentationtimestampchanges?language=objc)
767pub const kCMBufferQueueTrigger_WhenMaxPresentationTimeStampChanges: CMBufferQueueTriggerCondition =
768    6;
769/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whendatabecomesready?language=objc)
770pub const kCMBufferQueueTrigger_WhenDataBecomesReady: CMBufferQueueTriggerCondition = 7;
771/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whenendofdatareached?language=objc)
772pub const kCMBufferQueueTrigger_WhenEndOfDataReached: CMBufferQueueTriggerCondition = 8;
773/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whenreset?language=objc)
774pub const kCMBufferQueueTrigger_WhenReset: CMBufferQueueTriggerCondition = 9;
775/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whenbuffercountbecomeslessthan?language=objc)
776pub const kCMBufferQueueTrigger_WhenBufferCountBecomesLessThan: CMBufferQueueTriggerCondition = 10;
777/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whenbuffercountbecomesgreaterthan?language=objc)
778pub const kCMBufferQueueTrigger_WhenBufferCountBecomesGreaterThan: CMBufferQueueTriggerCondition =
779    11;
780/// [Apple's documentation](https://developer.apple.com/documentation/coremedia/kcmbufferqueuetrigger_whendurationbecomesgreaterthanorequaltoandbuffercountbecomesgreaterthan?language=objc)
781pub const kCMBufferQueueTrigger_WhenDurationBecomesGreaterThanOrEqualToAndBufferCountBecomesGreaterThan: CMBufferQueueTriggerCondition = 12;
782
783impl CMBufferQueue {
784    /// Installs a trigger on a CMBufferQueue.
785    ///
786    /// The returned trigger token can be passed to CMBufferQueueTestTrigger and CMBufferQueueRemoveTrigger.
787    /// The triggerTokenOut parameter can be NULL (client doesn't need to test or remove trigger), and the
788    /// callback parameter can be NULL (client doesn't need callbacks, but rather will explicitly
789    /// test the trigger).  One of these two parameters must be non-NULL, however, since an untestable
790    /// trigger that does not perform a callback is meaningless.  If the trigger condition is already true,
791    /// CMBufferQueueInstallTrigger will call the callback.  If it does this, it will first write
792    /// the trigger token to *triggerTokenOut.
793    ///
794    /// # Safety
795    ///
796    /// - `callback` must be implemented correctly.
797    /// - `refcon` must be a valid pointer or null.
798    /// - `trigger_token_out` must be a valid pointer or null.
799    #[doc(alias = "CMBufferQueueInstallTrigger")]
800    #[cfg(feature = "CMTime")]
801    #[inline]
802    pub unsafe fn install_trigger(
803        &self,
804        callback: CMBufferQueueTriggerCallback,
805        refcon: *mut c_void,
806        condition: CMBufferQueueTriggerCondition,
807        time: CMTime,
808        trigger_token_out: *mut CMBufferQueueTriggerToken,
809    ) -> OSStatus {
810        extern "C-unwind" {
811            fn CMBufferQueueInstallTrigger(
812                queue: &CMBufferQueue,
813                callback: CMBufferQueueTriggerCallback,
814                refcon: *mut c_void,
815                condition: CMBufferQueueTriggerCondition,
816                time: CMTime,
817                trigger_token_out: *mut CMBufferQueueTriggerToken,
818            ) -> OSStatus;
819        }
820        unsafe {
821            CMBufferQueueInstallTrigger(self, callback, refcon, condition, time, trigger_token_out)
822        }
823    }
824
825    /// Installs a trigger on a CMBufferQueue.
826    ///
827    /// This function behaves the same way as CMBufferQueueInstallTrigger() except the trigger is evaluated against
828    /// the integer value rather than the time value.
829    ///
830    /// # Safety
831    ///
832    /// - `callback` must be implemented correctly.
833    /// - `refcon` must be a valid pointer or null.
834    /// - `trigger_token_out` must be a valid pointer or null.
835    #[doc(alias = "CMBufferQueueInstallTriggerWithIntegerThreshold")]
836    #[cfg(feature = "CMBase")]
837    #[inline]
838    pub unsafe fn install_trigger_with_integer_threshold(
839        &self,
840        callback: CMBufferQueueTriggerCallback,
841        refcon: *mut c_void,
842        condition: CMBufferQueueTriggerCondition,
843        threshold: CMItemCount,
844        trigger_token_out: *mut CMBufferQueueTriggerToken,
845    ) -> OSStatus {
846        extern "C-unwind" {
847            fn CMBufferQueueInstallTriggerWithIntegerThreshold(
848                queue: &CMBufferQueue,
849                callback: CMBufferQueueTriggerCallback,
850                refcon: *mut c_void,
851                condition: CMBufferQueueTriggerCondition,
852                threshold: CMItemCount,
853                trigger_token_out: *mut CMBufferQueueTriggerToken,
854            ) -> OSStatus;
855        }
856        unsafe {
857            CMBufferQueueInstallTriggerWithIntegerThreshold(
858                self,
859                callback,
860                refcon,
861                condition,
862                threshold,
863                trigger_token_out,
864            )
865        }
866    }
867
868    /// Installs a trigger on a CMBufferQueue.
869    ///
870    /// The returned trigger token can be passed to CMBufferQueueTestTrigger and CMBufferQueueRemoveTrigger.
871    /// The triggerTokenOut parameter can be NULL (client doesn't need to test or remove trigger), and the
872    /// handler parameter can be NULL (client doesn't need callbacks, but rather will explicitly
873    /// test the trigger).  One of these two parameters must be non-NULL, however, since an untestable
874    /// trigger that does not perform a callback is meaningless.  If the trigger condition is already true,
875    /// CMBufferQueueInstallTrigger will call the handler.  If it does this, it will first write
876    /// the trigger token to *triggerTokenOut.
877    ///
878    /// # Safety
879    ///
880    /// - `trigger_token_out` must be a valid pointer or null.
881    /// - `handler` must be a valid pointer or null.
882    #[doc(alias = "CMBufferQueueInstallTriggerHandler")]
883    #[cfg(all(feature = "CMTime", feature = "block2"))]
884    #[inline]
885    pub unsafe fn install_trigger_handler(
886        &self,
887        condition: CMBufferQueueTriggerCondition,
888        time: CMTime,
889        trigger_token_out: *mut CMBufferQueueTriggerToken,
890        handler: CMBufferQueueTriggerHandler,
891    ) -> OSStatus {
892        extern "C-unwind" {
893            fn CMBufferQueueInstallTriggerHandler(
894                queue: &CMBufferQueue,
895                condition: CMBufferQueueTriggerCondition,
896                time: CMTime,
897                trigger_token_out: *mut CMBufferQueueTriggerToken,
898                handler: CMBufferQueueTriggerHandler,
899            ) -> OSStatus;
900        }
901        unsafe {
902            CMBufferQueueInstallTriggerHandler(self, condition, time, trigger_token_out, handler)
903        }
904    }
905
906    /// Installs a trigger on a CMBufferQueue.
907    ///
908    /// This function behaves the same way as CMBufferQueueInstallTriggerHandler() except the trigger is evaluated against
909    /// the integer value rather than the time value.
910    ///
911    /// # Safety
912    ///
913    /// - `trigger_token_out` must be a valid pointer or null.
914    /// - `handler` must be a valid pointer or null.
915    #[doc(alias = "CMBufferQueueInstallTriggerHandlerWithIntegerThreshold")]
916    #[cfg(all(feature = "CMBase", feature = "block2"))]
917    #[inline]
918    pub unsafe fn install_trigger_handler_with_integer_threshold(
919        &self,
920        condition: CMBufferQueueTriggerCondition,
921        threshold: CMItemCount,
922        trigger_token_out: *mut CMBufferQueueTriggerToken,
923        handler: CMBufferQueueTriggerHandler,
924    ) -> OSStatus {
925        extern "C-unwind" {
926            fn CMBufferQueueInstallTriggerHandlerWithIntegerThreshold(
927                queue: &CMBufferQueue,
928                condition: CMBufferQueueTriggerCondition,
929                threshold: CMItemCount,
930                trigger_token_out: *mut CMBufferQueueTriggerToken,
931                handler: CMBufferQueueTriggerHandler,
932            ) -> OSStatus;
933        }
934        unsafe {
935            CMBufferQueueInstallTriggerHandlerWithIntegerThreshold(
936                self,
937                condition,
938                threshold,
939                trigger_token_out,
940                handler,
941            )
942        }
943    }
944
945    /// Removes a previously installed trigger from a CMBufferQueue.
946    ///
947    /// Triggers will automatically be removed when a queue is finalized.  However, if more
948    /// than one module has access to a queue, it may be hard for an individual module to know
949    /// when the queue is finalized since other modules may retain it.  To address this concern,
950    /// modules should remove their triggers before they themselves are finalized.
951    ///
952    /// # Safety
953    ///
954    /// `trigger_token` must be a valid pointer.
955    #[doc(alias = "CMBufferQueueRemoveTrigger")]
956    #[inline]
957    pub unsafe fn remove_trigger(&self, trigger_token: CMBufferQueueTriggerToken) -> OSStatus {
958        extern "C-unwind" {
959            fn CMBufferQueueRemoveTrigger(
960                queue: &CMBufferQueue,
961                trigger_token: CMBufferQueueTriggerToken,
962            ) -> OSStatus;
963        }
964        unsafe { CMBufferQueueRemoveTrigger(self, trigger_token) }
965    }
966
967    /// Tests whether the trigger condition is true.
968    ///
969    /// Whereas the trigger callback will only be called when the condition goes from false
970    /// to true, CMBufferQueueTestTrigger always returns the condition's current status.
971    /// The triggerToken must be one that has been installed on this queue.
972    ///
973    /// # Safety
974    ///
975    /// `trigger_token` must be a valid pointer.
976    #[doc(alias = "CMBufferQueueTestTrigger")]
977    #[inline]
978    pub unsafe fn test_trigger(&self, trigger_token: CMBufferQueueTriggerToken) -> bool {
979        extern "C-unwind" {
980            fn CMBufferQueueTestTrigger(
981                queue: &CMBufferQueue,
982                trigger_token: CMBufferQueueTriggerToken,
983            ) -> Boolean;
984        }
985        let ret = unsafe { CMBufferQueueTestTrigger(self, trigger_token) };
986        ret != 0
987    }
988
989    /// Calls a function for every buffer in a queue.
990    ///
991    /// If the callback function returns an error, iteration will stop immediately
992    /// and the error will be returned.
993    ///
994    /// # Safety
995    ///
996    /// - `callback` must be implemented correctly.
997    /// - `refcon` must be a valid pointer or null.
998    #[doc(alias = "CMBufferQueueCallForEachBuffer")]
999    #[inline]
1000    pub unsafe fn call_for_each_buffer(
1001        &self,
1002        callback: unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void) -> OSStatus,
1003        refcon: *mut c_void,
1004    ) -> OSStatus {
1005        extern "C-unwind" {
1006            fn CMBufferQueueCallForEachBuffer(
1007                queue: &CMBufferQueue,
1008                callback: unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void) -> OSStatus,
1009                refcon: *mut c_void,
1010            ) -> OSStatus;
1011        }
1012        unsafe { CMBufferQueueCallForEachBuffer(self, callback, refcon) }
1013    }
1014}
1015
1016/// Tests whether a buffer is OK to add to a queue.
1017///
1018/// CMBufferQueueEnqueue will call this function to validate buffers.
1019/// Return noErr if the buffer is OK to add.
1020/// Return a nonzero error code if the buffer should be rejected;
1021/// CMBufferQueueEnqueue will return this error to the caller.
1022/// If you do not have a more descriptive error code, use kCMBufferQueueError_InvalidBuffer.
1023///
1024/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffervalidationcallback?language=objc)
1025pub type CMBufferValidationCallback = Option<
1026    unsafe extern "C-unwind" fn(NonNull<CMBufferQueue>, NonNull<CMBuffer>, *mut c_void) -> OSStatus,
1027>;
1028
1029/// Tests whether a buffer is OK to add to a queue.
1030///
1031/// CMBufferQueueEnqueue will call this block to validate buffers.
1032/// Return noErr if the buffer is OK to add.
1033/// Return a nonzero error code if the buffer should be rejected;
1034/// CMBufferQueueEnqueue will return this error to the caller.
1035/// If you do not have a more descriptive error code, use kCMBufferQueueError_InvalidBuffer.
1036///
1037/// See also [Apple's documentation](https://developer.apple.com/documentation/coremedia/cmbuffervalidationhandler?language=objc)
1038#[cfg(feature = "block2")]
1039pub type CMBufferValidationHandler =
1040    *mut block2::DynBlock<dyn Fn(NonNull<CMBufferQueue>, NonNull<CMBuffer>) -> OSStatus>;
1041
1042impl CMBufferQueue {
1043    /// Sets a function that CMBufferQueueEnqueue will call to validate buffers before adding them to the queue.
1044    ///
1045    /// # Safety
1046    ///
1047    /// - `callback` must be implemented correctly.
1048    /// - `refcon` must be a valid pointer or null.
1049    #[doc(alias = "CMBufferQueueSetValidationCallback")]
1050    #[inline]
1051    pub unsafe fn set_validation_callback(
1052        &self,
1053        callback: CMBufferValidationCallback,
1054        refcon: *mut c_void,
1055    ) -> OSStatus {
1056        extern "C-unwind" {
1057            fn CMBufferQueueSetValidationCallback(
1058                queue: &CMBufferQueue,
1059                callback: CMBufferValidationCallback,
1060                refcon: *mut c_void,
1061            ) -> OSStatus;
1062        }
1063        unsafe { CMBufferQueueSetValidationCallback(self, callback, refcon) }
1064    }
1065
1066    /// Sets a block that CMBufferQueueEnqueue will call to validate buffers before adding them to the queue.
1067    ///
1068    /// Both a validation callback and a validation handler can be set at the
1069    /// same time, in which case they will both be called when enqueueing
1070    /// buffers. They both need to return noErr for the buffer to be enqueued.
1071    ///
1072    /// # Safety
1073    ///
1074    /// `handler` must be a valid pointer.
1075    #[doc(alias = "CMBufferQueueSetValidationHandler")]
1076    #[cfg(feature = "block2")]
1077    #[inline]
1078    pub unsafe fn set_validation_handler(&self, handler: CMBufferValidationHandler) -> OSStatus {
1079        extern "C-unwind" {
1080            fn CMBufferQueueSetValidationHandler(
1081                queue: &CMBufferQueue,
1082                handler: CMBufferValidationHandler,
1083            ) -> OSStatus;
1084        }
1085        unsafe { CMBufferQueueSetValidationHandler(self, handler) }
1086    }
1087}
1088
1089#[cfg(feature = "CMTime")]
1090#[deprecated = "renamed to `CMBufferQueue::callbacks_for_unsorted_sample_buffers`"]
1091#[inline]
1092pub unsafe extern "C-unwind" fn CMBufferQueueGetCallbacksForUnsortedSampleBuffers(
1093) -> NonNull<CMBufferCallbacks> {
1094    extern "C-unwind" {
1095        fn CMBufferQueueGetCallbacksForUnsortedSampleBuffers() -> Option<NonNull<CMBufferCallbacks>>;
1096    }
1097    let ret = unsafe { CMBufferQueueGetCallbacksForUnsortedSampleBuffers() };
1098    ret.expect("function was marked as returning non-null, but actually returned NULL")
1099}
1100
1101#[cfg(feature = "CMTime")]
1102#[deprecated = "renamed to `CMBufferQueue::callbacks_for_sample_buffers_sorted_by_output_pts`"]
1103#[inline]
1104pub unsafe extern "C-unwind" fn CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS(
1105) -> NonNull<CMBufferCallbacks> {
1106    extern "C-unwind" {
1107        fn CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS(
1108        ) -> Option<NonNull<CMBufferCallbacks>>;
1109    }
1110    let ret = unsafe { CMBufferQueueGetCallbacksForSampleBuffersSortedByOutputPTS() };
1111    ret.expect("function was marked as returning non-null, but actually returned NULL")
1112}
1113
1114extern "C-unwind" {
1115    #[cfg(all(feature = "CMBase", feature = "CMTime"))]
1116    #[deprecated = "renamed to `CMBufferQueue::create`"]
1117    pub fn CMBufferQueueCreate(
1118        allocator: Option<&CFAllocator>,
1119        capacity: CMItemCount,
1120        callbacks: NonNull<CMBufferCallbacks>,
1121        queue_out: NonNull<*mut CMBufferQueue>,
1122    ) -> OSStatus;
1123}
1124
1125extern "C-unwind" {
1126    #[cfg(all(feature = "CMBase", feature = "CMTime", feature = "block2"))]
1127    #[deprecated = "renamed to `CMBufferQueue::create_with_handlers`"]
1128    pub fn CMBufferQueueCreateWithHandlers(
1129        allocator: Option<&CFAllocator>,
1130        capacity: CMItemCount,
1131        handlers: NonNull<CMBufferHandlers>,
1132        queue_out: NonNull<*mut CMBufferQueue>,
1133    ) -> OSStatus;
1134}
1135
1136extern "C-unwind" {
1137    #[deprecated = "renamed to `CMBufferQueue::enqueue`"]
1138    pub fn CMBufferQueueEnqueue(queue: &CMBufferQueue, buf: &CMBuffer) -> OSStatus;
1139}
1140
1141#[deprecated = "renamed to `CMBufferQueue::dequeue_and_retain`"]
1142#[inline]
1143pub unsafe extern "C-unwind" fn CMBufferQueueDequeueAndRetain(
1144    queue: &CMBufferQueue,
1145) -> Option<CFRetained<CMBuffer>> {
1146    extern "C-unwind" {
1147        fn CMBufferQueueDequeueAndRetain(queue: &CMBufferQueue) -> Option<NonNull<CMBuffer>>;
1148    }
1149    let ret = unsafe { CMBufferQueueDequeueAndRetain(queue) };
1150    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
1151}
1152
1153#[deprecated = "renamed to `CMBufferQueue::dequeue_if_data_ready_and_retain`"]
1154#[inline]
1155pub unsafe extern "C-unwind" fn CMBufferQueueDequeueIfDataReadyAndRetain(
1156    queue: &CMBufferQueue,
1157) -> Option<CFRetained<CMBuffer>> {
1158    extern "C-unwind" {
1159        fn CMBufferQueueDequeueIfDataReadyAndRetain(
1160            queue: &CMBufferQueue,
1161        ) -> Option<NonNull<CMBuffer>>;
1162    }
1163    let ret = unsafe { CMBufferQueueDequeueIfDataReadyAndRetain(queue) };
1164    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
1165}
1166
1167#[deprecated = "renamed to `CMBufferQueue::get_head`"]
1168#[inline]
1169pub unsafe extern "C-unwind" fn CMBufferQueueGetHead(
1170    queue: &CMBufferQueue,
1171) -> Option<CFRetained<CMBuffer>> {
1172    extern "C-unwind" {
1173        fn CMBufferQueueGetHead(queue: &CMBufferQueue) -> Option<NonNull<CMBuffer>>;
1174    }
1175    let ret = unsafe { CMBufferQueueGetHead(queue) };
1176    ret.map(|ret| unsafe { CFRetained::retain(ret) })
1177}
1178
1179#[deprecated = "renamed to `CMBufferQueue::head`"]
1180#[inline]
1181pub unsafe extern "C-unwind" fn CMBufferQueueCopyHead(
1182    queue: &CMBufferQueue,
1183) -> Option<CFRetained<CMBuffer>> {
1184    extern "C-unwind" {
1185        fn CMBufferQueueCopyHead(queue: &CMBufferQueue) -> Option<NonNull<CMBuffer>>;
1186    }
1187    let ret = unsafe { CMBufferQueueCopyHead(queue) };
1188    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
1189}
1190
1191#[deprecated = "renamed to `CMBufferQueue::is_empty`"]
1192#[inline]
1193pub unsafe extern "C-unwind" fn CMBufferQueueIsEmpty(queue: &CMBufferQueue) -> bool {
1194    extern "C-unwind" {
1195        fn CMBufferQueueIsEmpty(queue: &CMBufferQueue) -> Boolean;
1196    }
1197    let ret = unsafe { CMBufferQueueIsEmpty(queue) };
1198    ret != 0
1199}
1200
1201extern "C-unwind" {
1202    #[deprecated = "renamed to `CMBufferQueue::mark_end_of_data`"]
1203    pub fn CMBufferQueueMarkEndOfData(queue: &CMBufferQueue) -> OSStatus;
1204}
1205
1206#[deprecated = "renamed to `CMBufferQueue::contains_end_of_data`"]
1207#[inline]
1208pub unsafe extern "C-unwind" fn CMBufferQueueContainsEndOfData(queue: &CMBufferQueue) -> bool {
1209    extern "C-unwind" {
1210        fn CMBufferQueueContainsEndOfData(queue: &CMBufferQueue) -> Boolean;
1211    }
1212    let ret = unsafe { CMBufferQueueContainsEndOfData(queue) };
1213    ret != 0
1214}
1215
1216#[deprecated = "renamed to `CMBufferQueue::is_at_end_of_data`"]
1217#[inline]
1218pub unsafe extern "C-unwind" fn CMBufferQueueIsAtEndOfData(queue: &CMBufferQueue) -> bool {
1219    extern "C-unwind" {
1220        fn CMBufferQueueIsAtEndOfData(queue: &CMBufferQueue) -> Boolean;
1221    }
1222    let ret = unsafe { CMBufferQueueIsAtEndOfData(queue) };
1223    ret != 0
1224}
1225
1226extern "C-unwind" {
1227    #[deprecated = "renamed to `CMBufferQueue::reset`"]
1228    pub fn CMBufferQueueReset(queue: &CMBufferQueue) -> OSStatus;
1229}
1230
1231extern "C-unwind" {
1232    #[deprecated = "renamed to `CMBufferQueue::reset_with_callback`"]
1233    pub fn CMBufferQueueResetWithCallback(
1234        queue: &CMBufferQueue,
1235        callback: unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void),
1236        refcon: *mut c_void,
1237    ) -> OSStatus;
1238}
1239
1240extern "C-unwind" {
1241    #[cfg(feature = "CMBase")]
1242    #[deprecated = "renamed to `CMBufferQueue::buffer_count`"]
1243    pub fn CMBufferQueueGetBufferCount(queue: &CMBufferQueue) -> CMItemCount;
1244}
1245
1246extern "C-unwind" {
1247    #[cfg(feature = "CMTime")]
1248    #[deprecated = "renamed to `CMBufferQueue::duration`"]
1249    pub fn CMBufferQueueGetDuration(queue: &CMBufferQueue) -> CMTime;
1250}
1251
1252extern "C-unwind" {
1253    #[cfg(feature = "CMTime")]
1254    #[deprecated = "renamed to `CMBufferQueue::min_decode_time_stamp`"]
1255    pub fn CMBufferQueueGetMinDecodeTimeStamp(queue: &CMBufferQueue) -> CMTime;
1256}
1257
1258extern "C-unwind" {
1259    #[cfg(feature = "CMTime")]
1260    #[deprecated = "renamed to `CMBufferQueue::first_decode_time_stamp`"]
1261    pub fn CMBufferQueueGetFirstDecodeTimeStamp(queue: &CMBufferQueue) -> CMTime;
1262}
1263
1264extern "C-unwind" {
1265    #[cfg(feature = "CMTime")]
1266    #[deprecated = "renamed to `CMBufferQueue::min_presentation_time_stamp`"]
1267    pub fn CMBufferQueueGetMinPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
1268}
1269
1270extern "C-unwind" {
1271    #[cfg(feature = "CMTime")]
1272    #[deprecated = "renamed to `CMBufferQueue::first_presentation_time_stamp`"]
1273    pub fn CMBufferQueueGetFirstPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
1274}
1275
1276extern "C-unwind" {
1277    #[cfg(feature = "CMTime")]
1278    #[deprecated = "renamed to `CMBufferQueue::max_presentation_time_stamp`"]
1279    pub fn CMBufferQueueGetMaxPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
1280}
1281
1282extern "C-unwind" {
1283    #[cfg(feature = "CMTime")]
1284    #[deprecated = "renamed to `CMBufferQueue::end_presentation_time_stamp`"]
1285    pub fn CMBufferQueueGetEndPresentationTimeStamp(queue: &CMBufferQueue) -> CMTime;
1286}
1287
1288extern "C-unwind" {
1289    #[deprecated = "renamed to `CMBufferQueue::total_size`"]
1290    pub fn CMBufferQueueGetTotalSize(queue: &CMBufferQueue) -> usize;
1291}
1292
1293extern "C-unwind" {
1294    #[cfg(feature = "CMTime")]
1295    #[deprecated = "renamed to `CMBufferQueue::install_trigger`"]
1296    pub fn CMBufferQueueInstallTrigger(
1297        queue: &CMBufferQueue,
1298        callback: CMBufferQueueTriggerCallback,
1299        refcon: *mut c_void,
1300        condition: CMBufferQueueTriggerCondition,
1301        time: CMTime,
1302        trigger_token_out: *mut CMBufferQueueTriggerToken,
1303    ) -> OSStatus;
1304}
1305
1306extern "C-unwind" {
1307    #[cfg(feature = "CMBase")]
1308    #[deprecated = "renamed to `CMBufferQueue::install_trigger_with_integer_threshold`"]
1309    pub fn CMBufferQueueInstallTriggerWithIntegerThreshold(
1310        queue: &CMBufferQueue,
1311        callback: CMBufferQueueTriggerCallback,
1312        refcon: *mut c_void,
1313        condition: CMBufferQueueTriggerCondition,
1314        threshold: CMItemCount,
1315        trigger_token_out: *mut CMBufferQueueTriggerToken,
1316    ) -> OSStatus;
1317}
1318
1319extern "C-unwind" {
1320    #[cfg(all(feature = "CMTime", feature = "block2"))]
1321    #[deprecated = "renamed to `CMBufferQueue::install_trigger_handler`"]
1322    pub fn CMBufferQueueInstallTriggerHandler(
1323        queue: &CMBufferQueue,
1324        condition: CMBufferQueueTriggerCondition,
1325        time: CMTime,
1326        trigger_token_out: *mut CMBufferQueueTriggerToken,
1327        handler: CMBufferQueueTriggerHandler,
1328    ) -> OSStatus;
1329}
1330
1331extern "C-unwind" {
1332    #[cfg(all(feature = "CMBase", feature = "block2"))]
1333    #[deprecated = "renamed to `CMBufferQueue::install_trigger_handler_with_integer_threshold`"]
1334    pub fn CMBufferQueueInstallTriggerHandlerWithIntegerThreshold(
1335        queue: &CMBufferQueue,
1336        condition: CMBufferQueueTriggerCondition,
1337        threshold: CMItemCount,
1338        trigger_token_out: *mut CMBufferQueueTriggerToken,
1339        handler: CMBufferQueueTriggerHandler,
1340    ) -> OSStatus;
1341}
1342
1343extern "C-unwind" {
1344    #[deprecated = "renamed to `CMBufferQueue::remove_trigger`"]
1345    pub fn CMBufferQueueRemoveTrigger(
1346        queue: &CMBufferQueue,
1347        trigger_token: CMBufferQueueTriggerToken,
1348    ) -> OSStatus;
1349}
1350
1351#[deprecated = "renamed to `CMBufferQueue::test_trigger`"]
1352#[inline]
1353pub unsafe extern "C-unwind" fn CMBufferQueueTestTrigger(
1354    queue: &CMBufferQueue,
1355    trigger_token: CMBufferQueueTriggerToken,
1356) -> bool {
1357    extern "C-unwind" {
1358        fn CMBufferQueueTestTrigger(
1359            queue: &CMBufferQueue,
1360            trigger_token: CMBufferQueueTriggerToken,
1361        ) -> Boolean;
1362    }
1363    let ret = unsafe { CMBufferQueueTestTrigger(queue, trigger_token) };
1364    ret != 0
1365}
1366
1367extern "C-unwind" {
1368    #[deprecated = "renamed to `CMBufferQueue::call_for_each_buffer`"]
1369    pub fn CMBufferQueueCallForEachBuffer(
1370        queue: &CMBufferQueue,
1371        callback: unsafe extern "C-unwind" fn(NonNull<CMBuffer>, *mut c_void) -> OSStatus,
1372        refcon: *mut c_void,
1373    ) -> OSStatus;
1374}
1375
1376extern "C-unwind" {
1377    #[deprecated = "renamed to `CMBufferQueue::set_validation_callback`"]
1378    pub fn CMBufferQueueSetValidationCallback(
1379        queue: &CMBufferQueue,
1380        callback: CMBufferValidationCallback,
1381        refcon: *mut c_void,
1382    ) -> OSStatus;
1383}
1384
1385extern "C-unwind" {
1386    #[cfg(feature = "block2")]
1387    #[deprecated = "renamed to `CMBufferQueue::set_validation_handler`"]
1388    pub fn CMBufferQueueSetValidationHandler(
1389        queue: &CMBufferQueue,
1390        handler: CMBufferValidationHandler,
1391    ) -> OSStatus;
1392}