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