use std::ffi::c_void;
use std::fmt;
pub use apple_cf::cm::CMTime;
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CMSampleTimingInfo {
pub duration: CMTime,
pub presentation_time_stamp: CMTime,
pub decode_time_stamp: CMTime,
}
impl std::hash::Hash for CMSampleTimingInfo {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.duration.hash(state);
self.presentation_time_stamp.hash(state);
self.decode_time_stamp.hash(state);
}
}
impl CMSampleTimingInfo {
pub const fn new() -> Self {
Self {
duration: CMTime::INVALID,
presentation_time_stamp: CMTime::INVALID,
decode_time_stamp: CMTime::INVALID,
}
}
pub const fn with_times(
duration: CMTime,
presentation_time_stamp: CMTime,
decode_time_stamp: CMTime,
) -> Self {
Self {
duration,
presentation_time_stamp,
decode_time_stamp,
}
}
pub const fn is_valid(&self) -> bool {
self.duration.is_valid()
&& self.presentation_time_stamp.is_valid()
&& self.decode_time_stamp.is_valid()
}
pub const fn has_valid_presentation_time(&self) -> bool {
self.presentation_time_stamp.is_valid()
}
pub const fn has_valid_decode_time(&self) -> bool {
self.decode_time_stamp.is_valid()
}
pub const fn has_valid_duration(&self) -> bool {
self.duration.is_valid()
}
pub fn presentation_seconds(&self) -> Option<f64> {
self.presentation_time_stamp.as_seconds()
}
pub fn decode_seconds(&self) -> Option<f64> {
self.decode_time_stamp.as_seconds()
}
pub fn duration_seconds(&self) -> Option<f64> {
self.duration.as_seconds()
}
}
impl Default for CMSampleTimingInfo {
fn default() -> Self {
Self::new()
}
}
impl fmt::Display for CMSampleTimingInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"CMSampleTimingInfo(pts: {}, dts: {}, duration: {})",
self.presentation_time_stamp, self.decode_time_stamp, self.duration
)
}
}
pub struct CMClock {
ptr: *const c_void,
}
impl PartialEq for CMClock {
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr
}
}
impl Eq for CMClock {}
impl std::hash::Hash for CMClock {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.ptr.hash(state);
}
}
impl CMClock {
pub fn from_raw(ptr: *const c_void) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self { ptr })
}
}
#[allow(dead_code)]
pub(crate) fn from_ptr(ptr: *const c_void) -> Self {
Self { ptr }
}
pub fn as_ptr(&self) -> *const c_void {
self.ptr
}
pub fn time(&self) -> CMTime {
CMTime::INVALID
}
}
impl Drop for CMClock {
fn drop(&mut self) {
if !self.ptr.is_null() {
extern "C" {
fn CFRelease(cf: *const c_void);
}
unsafe {
CFRelease(self.ptr);
}
}
}
}
impl Clone for CMClock {
fn clone(&self) -> Self {
if self.ptr.is_null() {
Self {
ptr: std::ptr::null(),
}
} else {
extern "C" {
fn CFRetain(cf: *const c_void) -> *const c_void;
}
unsafe {
Self {
ptr: CFRetain(self.ptr),
}
}
}
}
}
impl std::fmt::Debug for CMClock {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("CMClock").field("ptr", &self.ptr).finish()
}
}
impl fmt::Display for CMClock {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.ptr.is_null() {
write!(f, "CMClock(null)")
} else {
write!(f, "CMClock({:p})", self.ptr)
}
}
}
unsafe impl Send for CMClock {}
unsafe impl Sync for CMClock {}