screencapturekit/cm/
time.rs1use std::ffi::c_void;
4use std::fmt;
5
6pub use apple_cf::cm::CMTime;
7
8#[repr(C)]
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct CMSampleTimingInfo {
29 pub duration: CMTime,
30 pub presentation_time_stamp: CMTime,
31 pub decode_time_stamp: CMTime,
32}
33
34impl std::hash::Hash for CMSampleTimingInfo {
35 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
36 self.duration.hash(state);
37 self.presentation_time_stamp.hash(state);
38 self.decode_time_stamp.hash(state);
39 }
40}
41
42impl CMSampleTimingInfo {
43 pub const fn new() -> Self {
54 Self {
55 duration: CMTime::INVALID,
56 presentation_time_stamp: CMTime::INVALID,
57 decode_time_stamp: CMTime::INVALID,
58 }
59 }
60
61 pub const fn with_times(
63 duration: CMTime,
64 presentation_time_stamp: CMTime,
65 decode_time_stamp: CMTime,
66 ) -> Self {
67 Self {
68 duration,
69 presentation_time_stamp,
70 decode_time_stamp,
71 }
72 }
73
74 pub const fn is_valid(&self) -> bool {
76 self.duration.is_valid()
77 && self.presentation_time_stamp.is_valid()
78 && self.decode_time_stamp.is_valid()
79 }
80
81 pub const fn has_valid_presentation_time(&self) -> bool {
83 self.presentation_time_stamp.is_valid()
84 }
85
86 pub const fn has_valid_decode_time(&self) -> bool {
88 self.decode_time_stamp.is_valid()
89 }
90
91 pub const fn has_valid_duration(&self) -> bool {
93 self.duration.is_valid()
94 }
95
96 pub fn presentation_seconds(&self) -> Option<f64> {
98 self.presentation_time_stamp.as_seconds()
99 }
100
101 pub fn decode_seconds(&self) -> Option<f64> {
103 self.decode_time_stamp.as_seconds()
104 }
105
106 pub fn duration_seconds(&self) -> Option<f64> {
108 self.duration.as_seconds()
109 }
110}
111
112impl Default for CMSampleTimingInfo {
113 fn default() -> Self {
114 Self::new()
115 }
116}
117
118impl fmt::Display for CMSampleTimingInfo {
119 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120 write!(
121 f,
122 "CMSampleTimingInfo(pts: {}, dts: {}, duration: {})",
123 self.presentation_time_stamp, self.decode_time_stamp, self.duration
124 )
125 }
126}
127
128pub struct CMClock {
133 ptr: *const c_void,
134}
135
136impl PartialEq for CMClock {
137 fn eq(&self, other: &Self) -> bool {
138 self.ptr == other.ptr
139 }
140}
141
142impl Eq for CMClock {}
143
144impl std::hash::Hash for CMClock {
145 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
146 self.ptr.hash(state);
147 }
148}
149
150impl CMClock {
151 pub fn from_raw(ptr: *const c_void) -> Option<Self> {
153 if ptr.is_null() {
154 None
155 } else {
156 Some(Self { ptr })
157 }
158 }
159
160 #[allow(dead_code)]
165 pub(crate) fn from_ptr(ptr: *const c_void) -> Self {
166 Self { ptr }
167 }
168
169 pub fn as_ptr(&self) -> *const c_void {
171 self.ptr
172 }
173
174 pub fn time(&self) -> CMTime {
179 CMTime::INVALID
182 }
183}
184
185impl Drop for CMClock {
186 fn drop(&mut self) {
187 if !self.ptr.is_null() {
188 extern "C" {
190 fn CFRelease(cf: *const c_void);
191 }
192 unsafe {
193 CFRelease(self.ptr);
194 }
195 }
196 }
197}
198
199impl Clone for CMClock {
200 fn clone(&self) -> Self {
201 if self.ptr.is_null() {
202 Self {
203 ptr: std::ptr::null(),
204 }
205 } else {
206 extern "C" {
207 fn CFRetain(cf: *const c_void) -> *const c_void;
208 }
209 unsafe {
210 Self {
211 ptr: CFRetain(self.ptr),
212 }
213 }
214 }
215 }
216}
217
218impl std::fmt::Debug for CMClock {
219 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
220 f.debug_struct("CMClock").field("ptr", &self.ptr).finish()
221 }
222}
223
224impl fmt::Display for CMClock {
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 if self.ptr.is_null() {
227 write!(f, "CMClock(null)")
228 } else {
229 write!(f, "CMClock({:p})", self.ptr)
230 }
231 }
232}
233
234unsafe impl Send for CMClock {}
236unsafe impl Sync for CMClock {}