1use crate::{ffi, ClockTime, Object};
7use glib::{
8 object::ObjectType as _,
9 prelude::*,
10 signal::{connect_raw, SignalHandlerId},
11 translate::*,
12};
13use std::boxed::Box as Box_;
14
15glib::wrapper! {
16 #[doc(alias = "GstClock")]
17 pub struct Clock(Object<ffi::GstClock, ffi::GstClockClass>) @extends Object;
18
19 match fn {
20 type_ => || ffi::gst_clock_get_type(),
21 }
22}
23
24impl Clock {
25 pub const NONE: Option<&'static Clock> = None;
26
27 }
76
77unsafe impl Send for Clock {}
78unsafe impl Sync for Clock {}
79
80mod sealed {
81 pub trait Sealed {}
82 impl<T: super::IsA<super::Clock>> Sealed for T {}
83}
84
85pub trait ClockExt: IsA<Clock> + sealed::Sealed + 'static {
86 #[doc(alias = "gst_clock_add_observation")]
87 fn add_observation(
88 &self,
89 observation_internal: ClockTime,
90 observation_external: ClockTime,
91 ) -> Option<f64> {
92 unsafe {
93 let mut r_squared = std::mem::MaybeUninit::uninit();
94 let ret = from_glib(ffi::gst_clock_add_observation(
95 self.as_ref().to_glib_none().0,
96 observation_internal.into_glib(),
97 observation_external.into_glib(),
98 r_squared.as_mut_ptr(),
99 ));
100 if ret {
101 Some(r_squared.assume_init())
102 } else {
103 None
104 }
105 }
106 }
107
108 #[doc(alias = "gst_clock_add_observation_unapplied")]
109 fn add_observation_unapplied(
110 &self,
111 observation_internal: ClockTime,
112 observation_external: ClockTime,
113 ) -> Option<(f64, ClockTime, ClockTime, ClockTime, ClockTime)> {
114 unsafe {
115 let mut r_squared = std::mem::MaybeUninit::uninit();
116 let mut internal = std::mem::MaybeUninit::uninit();
117 let mut external = std::mem::MaybeUninit::uninit();
118 let mut rate_num = std::mem::MaybeUninit::uninit();
119 let mut rate_denom = std::mem::MaybeUninit::uninit();
120 let ret = from_glib(ffi::gst_clock_add_observation_unapplied(
121 self.as_ref().to_glib_none().0,
122 observation_internal.into_glib(),
123 observation_external.into_glib(),
124 r_squared.as_mut_ptr(),
125 internal.as_mut_ptr(),
126 external.as_mut_ptr(),
127 rate_num.as_mut_ptr(),
128 rate_denom.as_mut_ptr(),
129 ));
130 if ret {
131 Some((
132 r_squared.assume_init(),
133 try_from_glib(internal.assume_init()).expect("mandatory glib value is None"),
134 try_from_glib(external.assume_init()).expect("mandatory glib value is None"),
135 try_from_glib(rate_num.assume_init()).expect("mandatory glib value is None"),
136 try_from_glib(rate_denom.assume_init()).expect("mandatory glib value is None"),
137 ))
138 } else {
139 None
140 }
141 }
142 }
143
144 #[doc(alias = "gst_clock_adjust_unlocked")]
145 fn adjust_unlocked(&self, internal: ClockTime) -> Option<ClockTime> {
146 unsafe {
147 from_glib(ffi::gst_clock_adjust_unlocked(
148 self.as_ref().to_glib_none().0,
149 internal.into_glib(),
150 ))
151 }
152 }
153
154 #[doc(alias = "gst_clock_get_internal_time")]
155 #[doc(alias = "get_internal_time")]
156 fn internal_time(&self) -> ClockTime {
157 unsafe {
158 try_from_glib(ffi::gst_clock_get_internal_time(
159 self.as_ref().to_glib_none().0,
160 ))
161 .expect("mandatory glib value is None")
162 }
163 }
164
165 #[doc(alias = "gst_clock_get_master")]
166 #[doc(alias = "get_master")]
167 #[must_use]
168 fn master(&self) -> Option<Clock> {
169 unsafe { from_glib_full(ffi::gst_clock_get_master(self.as_ref().to_glib_none().0)) }
170 }
171
172 #[doc(alias = "gst_clock_get_resolution")]
173 #[doc(alias = "get_resolution")]
174 fn resolution(&self) -> ClockTime {
175 unsafe {
176 try_from_glib(ffi::gst_clock_get_resolution(
177 self.as_ref().to_glib_none().0,
178 ))
179 .expect("mandatory glib value is None")
180 }
181 }
182
183 #[doc(alias = "gst_clock_get_time")]
184 #[doc(alias = "get_time")]
185 fn time(&self) -> Option<ClockTime> {
186 unsafe { from_glib(ffi::gst_clock_get_time(self.as_ref().to_glib_none().0)) }
187 }
188
189 #[doc(alias = "gst_clock_get_timeout")]
190 #[doc(alias = "get_timeout")]
191 fn timeout(&self) -> Option<ClockTime> {
192 unsafe { from_glib(ffi::gst_clock_get_timeout(self.as_ref().to_glib_none().0)) }
193 }
194
195 #[doc(alias = "gst_clock_is_synced")]
196 fn is_synced(&self) -> bool {
197 unsafe { from_glib(ffi::gst_clock_is_synced(self.as_ref().to_glib_none().0)) }
198 }
199
200 #[doc(alias = "gst_clock_set_master")]
201 fn set_master(&self, master: Option<&impl IsA<Clock>>) -> Result<(), glib::error::BoolError> {
202 unsafe {
203 glib::result_from_gboolean!(
204 ffi::gst_clock_set_master(
205 self.as_ref().to_glib_none().0,
206 master.map(|p| p.as_ref()).to_glib_none().0
207 ),
208 "Failed to set master clock"
209 )
210 }
211 }
212
213 #[doc(alias = "gst_clock_set_resolution")]
214 fn set_resolution(&self, resolution: ClockTime) -> ClockTime {
215 unsafe {
216 try_from_glib(ffi::gst_clock_set_resolution(
217 self.as_ref().to_glib_none().0,
218 resolution.into_glib(),
219 ))
220 .expect("mandatory glib value is None")
221 }
222 }
223
224 #[doc(alias = "gst_clock_set_synced")]
225 fn set_synced(&self, synced: bool) {
226 unsafe {
227 ffi::gst_clock_set_synced(self.as_ref().to_glib_none().0, synced.into_glib());
228 }
229 }
230
231 #[doc(alias = "gst_clock_set_timeout")]
232 #[doc(alias = "timeout")]
233 fn set_timeout(&self, timeout: impl Into<Option<ClockTime>>) {
234 unsafe {
235 ffi::gst_clock_set_timeout(self.as_ref().to_glib_none().0, timeout.into().into_glib());
236 }
237 }
238
239 #[doc(alias = "gst_clock_unadjust_unlocked")]
240 fn unadjust_unlocked(&self, external: ClockTime) -> Option<ClockTime> {
241 unsafe {
242 from_glib(ffi::gst_clock_unadjust_unlocked(
243 self.as_ref().to_glib_none().0,
244 external.into_glib(),
245 ))
246 }
247 }
248
249 #[doc(alias = "gst_clock_wait_for_sync")]
250 fn wait_for_sync(
251 &self,
252 timeout: impl Into<Option<ClockTime>>,
253 ) -> Result<(), glib::error::BoolError> {
254 unsafe {
255 glib::result_from_gboolean!(
256 ffi::gst_clock_wait_for_sync(
257 self.as_ref().to_glib_none().0,
258 timeout.into().into_glib()
259 ),
260 "Timed out waiting for sync"
261 )
262 }
263 }
264
265 #[doc(alias = "window-size")]
266 fn window_size(&self) -> i32 {
267 ObjectExt::property(self.as_ref(), "window-size")
268 }
269
270 #[doc(alias = "window-size")]
271 fn set_window_size(&self, window_size: i32) {
272 ObjectExt::set_property(self.as_ref(), "window-size", window_size)
273 }
274
275 #[doc(alias = "window-threshold")]
276 fn window_threshold(&self) -> i32 {
277 ObjectExt::property(self.as_ref(), "window-threshold")
278 }
279
280 #[doc(alias = "window-threshold")]
281 fn set_window_threshold(&self, window_threshold: i32) {
282 ObjectExt::set_property(self.as_ref(), "window-threshold", window_threshold)
283 }
284
285 #[doc(alias = "synced")]
286 fn connect_synced<F: Fn(&Self, bool) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
287 unsafe extern "C" fn synced_trampoline<
288 P: IsA<Clock>,
289 F: Fn(&P, bool) + Send + Sync + 'static,
290 >(
291 this: *mut ffi::GstClock,
292 synced: glib::ffi::gboolean,
293 f: glib::ffi::gpointer,
294 ) {
295 let f: &F = &*(f as *const F);
296 f(
297 Clock::from_glib_borrow(this).unsafe_cast_ref(),
298 from_glib(synced),
299 )
300 }
301 unsafe {
302 let f: Box_<F> = Box_::new(f);
303 connect_raw(
304 self.as_ptr() as *mut _,
305 b"synced\0".as_ptr() as *const _,
306 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
307 synced_trampoline::<Self, F> as *const (),
308 )),
309 Box_::into_raw(f),
310 )
311 }
312 }
313
314 #[doc(alias = "timeout")]
315 fn connect_timeout_notify<F: Fn(&Self) + Send + Sync + 'static>(
316 &self,
317 f: F,
318 ) -> SignalHandlerId {
319 unsafe extern "C" fn notify_timeout_trampoline<
320 P: IsA<Clock>,
321 F: Fn(&P) + Send + Sync + 'static,
322 >(
323 this: *mut ffi::GstClock,
324 _param_spec: glib::ffi::gpointer,
325 f: glib::ffi::gpointer,
326 ) {
327 let f: &F = &*(f as *const F);
328 f(Clock::from_glib_borrow(this).unsafe_cast_ref())
329 }
330 unsafe {
331 let f: Box_<F> = Box_::new(f);
332 connect_raw(
333 self.as_ptr() as *mut _,
334 b"notify::timeout\0".as_ptr() as *const _,
335 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
336 notify_timeout_trampoline::<Self, F> as *const (),
337 )),
338 Box_::into_raw(f),
339 )
340 }
341 }
342
343 #[doc(alias = "window-size")]
344 fn connect_window_size_notify<F: Fn(&Self) + Send + Sync + 'static>(
345 &self,
346 f: F,
347 ) -> SignalHandlerId {
348 unsafe extern "C" fn notify_window_size_trampoline<
349 P: IsA<Clock>,
350 F: Fn(&P) + Send + Sync + 'static,
351 >(
352 this: *mut ffi::GstClock,
353 _param_spec: glib::ffi::gpointer,
354 f: glib::ffi::gpointer,
355 ) {
356 let f: &F = &*(f as *const F);
357 f(Clock::from_glib_borrow(this).unsafe_cast_ref())
358 }
359 unsafe {
360 let f: Box_<F> = Box_::new(f);
361 connect_raw(
362 self.as_ptr() as *mut _,
363 b"notify::window-size\0".as_ptr() as *const _,
364 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
365 notify_window_size_trampoline::<Self, F> as *const (),
366 )),
367 Box_::into_raw(f),
368 )
369 }
370 }
371
372 #[doc(alias = "window-threshold")]
373 fn connect_window_threshold_notify<F: Fn(&Self) + Send + Sync + 'static>(
374 &self,
375 f: F,
376 ) -> SignalHandlerId {
377 unsafe extern "C" fn notify_window_threshold_trampoline<
378 P: IsA<Clock>,
379 F: Fn(&P) + Send + Sync + 'static,
380 >(
381 this: *mut ffi::GstClock,
382 _param_spec: glib::ffi::gpointer,
383 f: glib::ffi::gpointer,
384 ) {
385 let f: &F = &*(f as *const F);
386 f(Clock::from_glib_borrow(this).unsafe_cast_ref())
387 }
388 unsafe {
389 let f: Box_<F> = Box_::new(f);
390 connect_raw(
391 self.as_ptr() as *mut _,
392 b"notify::window-threshold\0".as_ptr() as *const _,
393 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
394 notify_window_threshold_trampoline::<Self, F> as *const (),
395 )),
396 Box_::into_raw(f),
397 )
398 }
399 }
400}
401
402impl<O: IsA<Clock>> ClockExt for O {}