1#![allow(clippy::missing_errors_doc)]
4
5use super::{CMClock, CMTime};
16use std::ffi::c_void;
17use std::fmt;
18
19pub struct CMTimebase {
21 ptr: *const c_void,
22}
23
24impl CMTimebase {
25 pub fn with_source_clock(source_clock: &CMClock) -> Result<Self, i32> {
27 extern "C" {
28 fn CMTimebaseCreateWithSourceClock(
29 allocator: *const c_void,
30 sourceClock: *const c_void,
31 timebaseOut: *mut *const c_void,
32 ) -> i32;
33 }
34 let mut ptr = std::ptr::null();
35 let status = unsafe {
36 CMTimebaseCreateWithSourceClock(std::ptr::null(), source_clock.as_ptr(), &raw mut ptr)
37 };
38 if status == 0 && !ptr.is_null() {
39 Ok(Self { ptr })
40 } else {
41 Err(status)
42 }
43 }
44
45 #[must_use]
53 pub unsafe fn from_raw(ptr: *const c_void) -> Option<Self> {
54 if ptr.is_null() {
55 None
56 } else {
57 Some(Self { ptr })
58 }
59 }
60
61 #[must_use]
68 pub unsafe fn from_raw_borrowed(ptr: *const c_void) -> Option<Self> {
69 if ptr.is_null() {
70 None
71 } else {
72 extern "C" {
73 fn CFRetain(cf: *const c_void) -> *const c_void;
74 }
75 let retained = unsafe { CFRetain(ptr) };
76 unsafe { Self::from_raw(retained) }
77 }
78 }
79
80 #[must_use]
82 pub const fn as_ptr(&self) -> *const c_void {
83 self.ptr
84 }
85
86 #[must_use]
88 pub fn time(&self) -> CMTime {
89 extern "C" {
90 fn CMTimebaseGetTime(timebase: *const c_void) -> CMTime;
91 }
92 unsafe { CMTimebaseGetTime(self.ptr) }
93 }
94
95 #[must_use]
97 pub fn set_time(&self, time: CMTime) -> i32 {
98 extern "C" {
99 fn CMTimebaseSetTime(timebase: *const c_void, time: CMTime) -> i32;
100 }
101 unsafe { CMTimebaseSetTime(self.ptr, time) }
102 }
103
104 #[must_use]
106 pub fn rate(&self) -> f64 {
107 extern "C" {
108 fn CMTimebaseGetRate(timebase: *const c_void) -> f64;
109 }
110 unsafe { CMTimebaseGetRate(self.ptr) }
111 }
112
113 #[must_use]
115 pub fn set_rate(&self, rate: f64) -> i32 {
116 extern "C" {
117 fn CMTimebaseSetRate(timebase: *const c_void, rate: f64) -> i32;
118 }
119 unsafe { CMTimebaseSetRate(self.ptr, rate) }
120 }
121
122 #[must_use]
124 pub fn source_clock(&self) -> Option<CMClock> {
125 extern "C" {
126 fn CMTimebaseCopySourceClock(timebase: *const c_void) -> *const c_void;
127 }
128 let ptr = unsafe { CMTimebaseCopySourceClock(self.ptr) };
129 unsafe { CMClock::from_raw(ptr) }
130 }
131}
132
133impl Clone for CMTimebase {
134 fn clone(&self) -> Self {
135 extern "C" {
136 fn CFRetain(cf: *const c_void) -> *const c_void;
137 }
138 let ptr = unsafe { CFRetain(self.ptr) };
139 Self { ptr }
140 }
141}
142
143impl Drop for CMTimebase {
144 fn drop(&mut self) {
145 extern "C" {
146 fn CFRelease(cf: *const c_void);
147 }
148 unsafe { CFRelease(self.ptr) };
149 }
150}
151
152impl PartialEq for CMTimebase {
153 fn eq(&self, other: &Self) -> bool {
154 self.ptr == other.ptr
155 }
156}
157
158impl Eq for CMTimebase {}
159
160impl std::hash::Hash for CMTimebase {
161 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
162 self.ptr.hash(state);
163 }
164}
165
166impl fmt::Debug for CMTimebase {
167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
168 f.debug_struct("CMTimebase")
169 .field("ptr", &self.ptr)
170 .field("time", &self.time())
171 .field("rate", &self.rate())
172 .finish()
173 }
174}
175
176unsafe impl Send for CMTimebase {}
180unsafe impl Sync for CMTimebase {}