use core::ptr;
use apple_cf::cm::CMSampleBuffer;
use apple_cf::cv::CVPixelBuffer;
use crate::ffi;
pub struct TaggedBufferGroup {
inner: ffi::CMTaggedBufferGroupRef,
}
unsafe impl Send for TaggedBufferGroup {}
unsafe impl Sync for TaggedBufferGroup {}
impl TaggedBufferGroup {
#[must_use]
pub fn type_id() -> usize {
unsafe { ffi::CMTaggedBufferGroupGetTypeID() }
}
#[must_use]
pub unsafe fn from_raw(ptr: ffi::CMTaggedBufferGroupRef) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self { inner: ptr })
}
}
#[must_use]
pub unsafe fn from_raw_retained(ptr: ffi::CMTaggedBufferGroupRef) -> Option<Self> {
if ptr.is_null() {
None
} else {
unsafe { ffi::CFRetain(ptr.cast()) };
Self::from_raw(ptr)
}
}
#[must_use]
pub const fn as_ptr(&self) -> ffi::CMTaggedBufferGroupRef {
self.inner
}
#[must_use]
pub fn len(&self) -> usize {
usize::try_from(unsafe { ffi::CMTaggedBufferGroupGetCount(self.inner) }).unwrap_or(0)
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[must_use]
pub fn pixel_buffer_at(&self, index: usize) -> Option<CVPixelBuffer> {
let index = isize::try_from(index).ok()?;
let ptr = unsafe { ffi::CMTaggedBufferGroupGetCVPixelBufferAtIndex(self.inner, index) };
if ptr.is_null() {
None
} else {
unsafe { ffi::CFRetain(ptr.cast()) };
CVPixelBuffer::from_raw(ptr.cast())
}
}
#[must_use]
pub fn sample_buffer_at(&self, index: usize) -> Option<CMSampleBuffer> {
let index = isize::try_from(index).ok()?;
let ptr = unsafe { ffi::CMTaggedBufferGroupGetCMSampleBufferAtIndex(self.inner, index) };
unsafe { CMSampleBuffer::from_raw_retained(ptr.cast()) }
}
}
impl Clone for TaggedBufferGroup {
fn clone(&self) -> Self {
unsafe { Self::from_raw_retained(self.inner) }
.expect("tagged buffer group pointer must be non-null")
}
}
impl Drop for TaggedBufferGroup {
fn drop(&mut self) {
if !self.inner.is_null() {
unsafe { ffi::CFRelease(self.inner.cast()) };
self.inner = ptr::null_mut();
}
}
}
impl core::fmt::Debug for TaggedBufferGroup {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("TaggedBufferGroup")
.field("ptr", &self.inner)
.field("len", &self.len())
.finish()
}
}