gstreamer/auto/clock.rs
1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6use 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 /// GStreamer uses a global clock to synchronize the plugins in a pipeline.
17 /// Different clock implementations are possible by implementing this abstract
18 /// base class or, more conveniently, by subclassing [`SystemClock`][crate::SystemClock].
19 ///
20 /// The [`Clock`][crate::Clock] returns a monotonically increasing time with the method
21 /// [`ClockExt::time()`][crate::prelude::ClockExt::time()]. Its accuracy and base time depend on the specific
22 /// clock implementation but time is always expressed in nanoseconds. Since the
23 /// baseline of the clock is undefined, the clock time returned is not
24 /// meaningful in itself, what matters are the deltas between two clock times.
25 /// The time returned by a clock is called the absolute time.
26 ///
27 /// The pipeline uses the clock to calculate the running time. Usually all
28 /// renderers synchronize to the global clock using the buffer timestamps, the
29 /// [`EventType::Segment`][crate::EventType::Segment] events and the element's base time, see [`Pipeline`][crate::Pipeline].
30 ///
31 /// A clock implementation can support periodic and single shot clock
32 /// notifications both synchronous and asynchronous.
33 ///
34 /// One first needs to create a `GstClockID` for the periodic or single shot
35 /// notification using [`ClockExtManual::new_single_shot_id()`][crate::prelude::ClockExtManual::new_single_shot_id()] or
36 /// [`ClockExtManual::new_periodic_id()`][crate::prelude::ClockExtManual::new_periodic_id()].
37 ///
38 /// To perform a blocking wait for the specific time of the `GstClockID` use
39 /// `gst_clock_id_wait()`. To receive a callback when the specific time is reached
40 /// in the clock use `gst_clock_id_wait_async()`. Both these calls can be
41 /// interrupted with the `gst_clock_id_unschedule()` call. If the blocking wait is
42 /// unscheduled a return value of [`ClockReturn::Unscheduled`][crate::ClockReturn::Unscheduled] is returned.
43 ///
44 /// Periodic callbacks scheduled async will be repeatedly called automatically
45 /// until they are unscheduled. To schedule a sync periodic callback,
46 /// `gst_clock_id_wait()` should be called repeatedly.
47 ///
48 /// The async callbacks can happen from any thread, either provided by the core
49 /// or from a streaming thread. The application should be prepared for this.
50 ///
51 /// A `GstClockID` that has been unscheduled cannot be used again for any wait
52 /// operation, a new `GstClockID` should be created and the old unscheduled one
53 /// should be destroyed with `gst_clock_id_unref()`.
54 ///
55 /// It is possible to perform a blocking wait on the same `GstClockID` from
56 /// multiple threads. However, registering the same `GstClockID` for multiple
57 /// async notifications is not possible, the callback will only be called for
58 /// the thread registering the entry last.
59 ///
60 /// None of the wait operations unref the `GstClockID`, the owner is responsible
61 /// for unreffing the ids itself. This holds for both periodic and single shot
62 /// notifications. The reason being that the owner of the `GstClockID` has to
63 /// keep a handle to the `GstClockID` to unblock the wait on FLUSHING events or
64 /// state changes and if the entry would be unreffed automatically, the handle
65 /// might become invalid without any notification.
66 ///
67 /// These clock operations do not operate on the running time, so the callbacks
68 /// will also occur when not in PLAYING state as if the clock just keeps on
69 /// running. Some clocks however do not progress when the element that provided
70 /// the clock is not PLAYING.
71 ///
72 /// When a clock has the [`ClockFlags::CAN_SET_MASTER`][crate::ClockFlags::CAN_SET_MASTER] flag set, it can be
73 /// slaved to another [`Clock`][crate::Clock] with [`ClockExt::set_master()`][crate::prelude::ClockExt::set_master()]. The clock will
74 /// then automatically be synchronized to this master clock by repeatedly
75 /// sampling the master clock and the slave clock and recalibrating the slave
76 /// clock with [`ClockExtManual::set_calibration()`][crate::prelude::ClockExtManual::set_calibration()]. This feature is mostly useful for
77 /// plugins that have an internal clock but must operate with another clock
78 /// selected by the [`Pipeline`][crate::Pipeline]. They can track the offset and rate difference
79 /// of their internal clock relative to the master clock by using the
80 /// [`ClockExtManual::calibration()`][crate::prelude::ClockExtManual::calibration()] function.
81 ///
82 /// The master/slave synchronisation can be tuned with the [`timeout`][struct@crate::Clock#timeout],
83 /// [`window-size`][struct@crate::Clock#window-size] and [`window-threshold`][struct@crate::Clock#window-threshold] properties.
84 /// The [`timeout`][struct@crate::Clock#timeout] property defines the interval to sample the master
85 /// clock and run the calibration functions. [`window-size`][struct@crate::Clock#window-size] defines the
86 /// number of samples to use when calibrating and [`window-threshold`][struct@crate::Clock#window-threshold]
87 /// defines the minimum number of samples before the calibration is performed.
88 ///
89 /// This is an Abstract Base Class, you cannot instantiate it.
90 ///
91 /// ## Properties
92 ///
93 ///
94 /// #### `timeout`
95 /// Readable | Writeable
96 ///
97 ///
98 /// #### `window-size`
99 /// Readable | Writeable
100 ///
101 ///
102 /// #### `window-threshold`
103 /// Readable | Writeable
104 /// <details><summary><h4>Object</h4></summary>
105 ///
106 ///
107 /// #### `name`
108 /// Readable | Writeable | Construct
109 ///
110 ///
111 /// #### `parent`
112 /// The parent of the object. Please note, that when changing the 'parent'
113 /// property, we don't emit [`notify`][struct@crate::glib::Object#notify] and [`deep-notify`][struct@crate::Object#deep-notify]
114 /// signals due to locking issues. In some cases one can use
115 /// [`element-added`][struct@crate::Bin#element-added] or [`element-removed`][struct@crate::Bin#element-removed] signals on the parent to
116 /// achieve a similar effect.
117 ///
118 /// Readable | Writeable
119 /// </details>
120 ///
121 /// ## Signals
122 ///
123 ///
124 /// #### `synced`
125 /// Signaled on clocks with [`ClockFlags::NEEDS_STARTUP_SYNC`][crate::ClockFlags::NEEDS_STARTUP_SYNC] set once
126 /// the clock is synchronized, or when it completely lost synchronization.
127 /// This signal will not be emitted on clocks without the flag.
128 ///
129 /// This signal will be emitted from an arbitrary thread, most likely not
130 /// the application's main thread.
131 ///
132 ///
133 /// <details><summary><h4>Object</h4></summary>
134 ///
135 ///
136 /// #### `deep-notify`
137 /// The deep notify signal is used to be notified of property changes. It is
138 /// typically attached to the toplevel bin to receive notifications from all
139 /// the elements contained in that bin.
140 ///
141 /// Detailed
142 /// </details>
143 ///
144 /// # Implements
145 ///
146 /// [`ClockExt`][trait@crate::prelude::ClockExt], [`GstObjectExt`][trait@crate::prelude::GstObjectExt], [`trait@glib::ObjectExt`], [`ClockExtManual`][trait@crate::prelude::ClockExtManual]
147 #[doc(alias = "GstClock")]
148 pub struct Clock(Object<ffi::GstClock, ffi::GstClockClass>) @extends Object;
149
150 match fn {
151 type_ => || ffi::gst_clock_get_type(),
152 }
153}
154
155impl Clock {
156 pub const NONE: Option<&'static Clock> = None;
157
158 //#[doc(alias = "gst_clock_id_compare_func")]
159 //pub fn id_compare_func(id1: /*Unimplemented*/Option<Basic: Pointer>, id2: /*Unimplemented*/Option<Basic: Pointer>) -> i32 {
160 // unsafe { TODO: call ffi:gst_clock_id_compare_func() }
161 //}
162
163 //#[cfg(feature = "v1_16")]
164 //#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
165 //#[doc(alias = "gst_clock_id_get_clock")]
166 //pub fn id_get_clock(id: /*Unimplemented*/ClockID) -> Option<Clock> {
167 // unsafe { TODO: call ffi:gst_clock_id_get_clock() }
168 //}
169
170 //#[doc(alias = "gst_clock_id_get_time")]
171 //pub fn id_get_time(id: /*Unimplemented*/ClockID) -> Option<ClockTime> {
172 // unsafe { TODO: call ffi:gst_clock_id_get_time() }
173 //}
174
175 //#[doc(alias = "gst_clock_id_ref")]
176 //pub fn id_ref(id: /*Unimplemented*/ClockID) -> /*Unimplemented*/ClockID {
177 // unsafe { TODO: call ffi:gst_clock_id_ref() }
178 //}
179
180 //#[doc(alias = "gst_clock_id_unref")]
181 //pub fn id_unref(id: /*Unimplemented*/ClockID) {
182 // unsafe { TODO: call ffi:gst_clock_id_unref() }
183 //}
184
185 //#[doc(alias = "gst_clock_id_unschedule")]
186 //pub fn id_unschedule(id: /*Unimplemented*/ClockID) {
187 // unsafe { TODO: call ffi:gst_clock_id_unschedule() }
188 //}
189
190 //#[cfg(feature = "v1_16")]
191 //#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
192 //#[doc(alias = "gst_clock_id_uses_clock")]
193 //pub fn id_uses_clock(id: /*Unimplemented*/ClockID, clock: &impl IsA<Clock>) -> bool {
194 // unsafe { TODO: call ffi:gst_clock_id_uses_clock() }
195 //}
196
197 //#[doc(alias = "gst_clock_id_wait")]
198 //pub fn id_wait(id: /*Unimplemented*/ClockID) -> (Result<ClockSuccess, ClockError>, ClockTimeDiff) {
199 // unsafe { TODO: call ffi:gst_clock_id_wait() }
200 //}
201
202 //#[doc(alias = "gst_clock_id_wait_async")]
203 //pub fn id_wait_async(id: /*Unimplemented*/ClockID, func: /*Unimplemented*/Fn(&Clock, impl Into<Option<ClockTime>>, /*Unimplemented*/ClockID) -> bool, user_data: /*Unimplemented*/Option<Basic: Pointer>) -> Result<ClockSuccess, ClockError> {
204 // unsafe { TODO: call ffi:gst_clock_id_wait_async() }
205 //}
206}
207
208unsafe impl Send for Clock {}
209unsafe impl Sync for Clock {}
210
211/// Trait containing all [`struct@Clock`] methods.
212///
213/// # Implementors
214///
215/// [`Clock`][struct@crate::Clock], [`SystemClock`][struct@crate::SystemClock]
216pub trait ClockExt: IsA<Clock> + 'static {
217 /// The time `observation_external` of the external or master clock and the time
218 /// `observation_internal` of the internal or slave clock are added to the list of
219 /// observations. If enough observations are available, a linear regression
220 /// algorithm is run on the observations and `self` is recalibrated.
221 ///
222 /// If this functions returns [`true`], `r_squared` will contain the
223 /// correlation coefficient of the interpolation. A value of 1.0
224 /// means a perfect regression was performed. This value can
225 /// be used to control the sampling frequency of the master and slave
226 /// clocks.
227 /// ## `observation_internal`
228 /// a time on the internal clock
229 /// ## `observation_external`
230 /// a time on the external clock
231 ///
232 /// # Returns
233 ///
234 /// [`true`] if enough observations were added to run the
235 /// regression algorithm.
236 ///
237 /// ## `r_squared`
238 /// a pointer to hold the result
239 #[doc(alias = "gst_clock_add_observation")]
240 fn add_observation(
241 &self,
242 observation_internal: ClockTime,
243 observation_external: ClockTime,
244 ) -> Option<f64> {
245 unsafe {
246 let mut r_squared = std::mem::MaybeUninit::uninit();
247 let ret = from_glib(ffi::gst_clock_add_observation(
248 self.as_ref().to_glib_none().0,
249 observation_internal.into_glib(),
250 observation_external.into_glib(),
251 r_squared.as_mut_ptr(),
252 ));
253 if ret {
254 Some(r_squared.assume_init())
255 } else {
256 None
257 }
258 }
259 }
260
261 /// Add a clock observation to the internal slaving algorithm the same as
262 /// [`add_observation()`][Self::add_observation()], and return the result of the external or master
263 /// clock estimation, without updating the internal calibration.
264 ///
265 /// The caller can then take the results and call [`ClockExtManual::set_calibration()`][crate::prelude::ClockExtManual::set_calibration()]
266 /// with the values, or some modified version of them.
267 /// ## `observation_internal`
268 /// a time on the internal clock
269 /// ## `observation_external`
270 /// a time on the external clock
271 ///
272 /// # Returns
273 ///
274 /// [`true`] if enough observations were added to run the
275 /// regression algorithm.
276 ///
277 /// ## `r_squared`
278 /// a pointer to hold the result
279 ///
280 /// ## `internal`
281 /// a location to store the internal time
282 ///
283 /// ## `external`
284 /// a location to store the external time
285 ///
286 /// ## `rate_num`
287 /// a location to store the rate numerator
288 ///
289 /// ## `rate_denom`
290 /// a location to store the rate denominator
291 #[doc(alias = "gst_clock_add_observation_unapplied")]
292 fn add_observation_unapplied(
293 &self,
294 observation_internal: ClockTime,
295 observation_external: ClockTime,
296 ) -> Option<(f64, ClockTime, ClockTime, ClockTime, ClockTime)> {
297 unsafe {
298 let mut r_squared = std::mem::MaybeUninit::uninit();
299 let mut internal = std::mem::MaybeUninit::uninit();
300 let mut external = std::mem::MaybeUninit::uninit();
301 let mut rate_num = std::mem::MaybeUninit::uninit();
302 let mut rate_denom = std::mem::MaybeUninit::uninit();
303 let ret = from_glib(ffi::gst_clock_add_observation_unapplied(
304 self.as_ref().to_glib_none().0,
305 observation_internal.into_glib(),
306 observation_external.into_glib(),
307 r_squared.as_mut_ptr(),
308 internal.as_mut_ptr(),
309 external.as_mut_ptr(),
310 rate_num.as_mut_ptr(),
311 rate_denom.as_mut_ptr(),
312 ));
313 if ret {
314 Some((
315 r_squared.assume_init(),
316 try_from_glib(internal.assume_init()).expect("mandatory glib value is None"),
317 try_from_glib(external.assume_init()).expect("mandatory glib value is None"),
318 try_from_glib(rate_num.assume_init()).expect("mandatory glib value is None"),
319 try_from_glib(rate_denom.assume_init()).expect("mandatory glib value is None"),
320 ))
321 } else {
322 None
323 }
324 }
325 }
326
327 /// Converts the given `internal` clock time to the external time, adjusting for the
328 /// rate and reference time set with [`ClockExtManual::set_calibration()`][crate::prelude::ClockExtManual::set_calibration()] and making sure
329 /// that the returned time is increasing. This function should be called with the
330 /// clock's OBJECT_LOCK held and is mainly used by clock subclasses.
331 ///
332 /// This function is the reverse of [`unadjust_unlocked()`][Self::unadjust_unlocked()].
333 /// ## `internal`
334 /// a clock time
335 ///
336 /// # Returns
337 ///
338 /// the converted time of the clock.
339 #[doc(alias = "gst_clock_adjust_unlocked")]
340 fn adjust_unlocked(&self, internal: ClockTime) -> ClockTime {
341 unsafe {
342 try_from_glib(ffi::gst_clock_adjust_unlocked(
343 self.as_ref().to_glib_none().0,
344 internal.into_glib(),
345 ))
346 .expect("mandatory glib value is None")
347 }
348 }
349
350 /// Gets the current internal time of the given clock. The time is returned
351 /// unadjusted for the offset and the rate.
352 ///
353 /// # Returns
354 ///
355 /// the internal time of the clock. Or `GST_CLOCK_TIME_NONE` when
356 /// given invalid input.
357 #[doc(alias = "gst_clock_get_internal_time")]
358 #[doc(alias = "get_internal_time")]
359 fn internal_time(&self) -> ClockTime {
360 unsafe {
361 try_from_glib(ffi::gst_clock_get_internal_time(
362 self.as_ref().to_glib_none().0,
363 ))
364 .expect("mandatory glib value is None")
365 }
366 }
367
368 /// Gets the master clock that `self` is slaved to or [`None`] when the clock is
369 /// not slaved to any master clock.
370 ///
371 /// # Returns
372 ///
373 /// a master [`Clock`][crate::Clock] or [`None`]
374 /// when this clock is not slaved to a master clock.
375 #[doc(alias = "gst_clock_get_master")]
376 #[doc(alias = "get_master")]
377 #[must_use]
378 fn master(&self) -> Option<Clock> {
379 unsafe { from_glib_full(ffi::gst_clock_get_master(self.as_ref().to_glib_none().0)) }
380 }
381
382 /// Gets the accuracy of the clock. The accuracy of the clock is the granularity
383 /// of the values returned by [`time()`][Self::time()].
384 ///
385 /// # Returns
386 ///
387 /// the resolution of the clock in units of `GstClockTime`.
388 #[doc(alias = "gst_clock_get_resolution")]
389 #[doc(alias = "get_resolution")]
390 fn resolution(&self) -> ClockTime {
391 unsafe {
392 try_from_glib(ffi::gst_clock_get_resolution(
393 self.as_ref().to_glib_none().0,
394 ))
395 .expect("mandatory glib value is None")
396 }
397 }
398
399 /// Gets the current time of the given clock. The time is always
400 /// monotonically increasing and adjusted according to the current
401 /// offset and rate.
402 ///
403 /// # Returns
404 ///
405 /// the time of the clock. Or `GST_CLOCK_TIME_NONE` when
406 /// given invalid input.
407 #[doc(alias = "gst_clock_get_time")]
408 #[doc(alias = "get_time")]
409 fn time(&self) -> ClockTime {
410 unsafe {
411 try_from_glib(ffi::gst_clock_get_time(self.as_ref().to_glib_none().0))
412 .expect("mandatory glib value is None")
413 }
414 }
415
416 /// Gets the amount of time that master and slave clocks are sampled.
417 ///
418 /// # Returns
419 ///
420 /// the interval between samples.
421 #[doc(alias = "gst_clock_get_timeout")]
422 #[doc(alias = "get_timeout")]
423 fn timeout(&self) -> Option<ClockTime> {
424 unsafe { from_glib(ffi::gst_clock_get_timeout(self.as_ref().to_glib_none().0)) }
425 }
426
427 /// Checks if the clock is currently synced, by looking at whether
428 /// [`ClockFlags::NEEDS_STARTUP_SYNC`][crate::ClockFlags::NEEDS_STARTUP_SYNC] is set.
429 ///
430 /// # Returns
431 ///
432 /// [`true`] if the clock is currently synced
433 #[doc(alias = "gst_clock_is_synced")]
434 fn is_synced(&self) -> bool {
435 unsafe { from_glib(ffi::gst_clock_is_synced(self.as_ref().to_glib_none().0)) }
436 }
437
438 /// Checks that `self` is the default system clock, as returned by
439 /// [`SystemClock::obtain()`][crate::SystemClock::obtain()], and is of type [`ClockType::Monotonic`][crate::ClockType::Monotonic].
440 ///
441 /// # Returns
442 ///
443 /// [`true`] if `self` is the default system monotonic clock,
444 /// [`false`] otherwise.
445 #[cfg(feature = "v1_28")]
446 #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
447 #[doc(alias = "gst_clock_is_system_monotonic")]
448 fn is_system_monotonic(&self) -> bool {
449 unsafe {
450 from_glib(ffi::gst_clock_is_system_monotonic(
451 self.as_ref().to_glib_none().0,
452 ))
453 }
454 }
455
456 /// Sets `master` as the master clock for `self`. `self` will be automatically
457 /// calibrated so that [`time()`][Self::time()] reports the same time as the
458 /// master clock.
459 ///
460 /// A clock provider that slaves its clock to a master can get the current
461 /// calibration values with [`ClockExtManual::calibration()`][crate::prelude::ClockExtManual::calibration()].
462 ///
463 /// `master` can be [`None`] in which case `self` will not be slaved anymore. It will
464 /// however keep reporting its time adjusted with the last configured rate
465 /// and time offsets.
466 /// ## `master`
467 /// a master [`Clock`][crate::Clock]
468 ///
469 /// # Returns
470 ///
471 /// [`true`] if the clock is capable of being slaved to a master clock.
472 /// Trying to set a master on a clock without the
473 /// [`ClockFlags::CAN_SET_MASTER`][crate::ClockFlags::CAN_SET_MASTER] flag will make this function return [`false`].
474 #[doc(alias = "gst_clock_set_master")]
475 fn set_master(&self, master: Option<&impl IsA<Clock>>) -> Result<(), glib::error::BoolError> {
476 unsafe {
477 glib::result_from_gboolean!(
478 ffi::gst_clock_set_master(
479 self.as_ref().to_glib_none().0,
480 master.map(|p| p.as_ref()).to_glib_none().0
481 ),
482 "Failed to set master clock"
483 )
484 }
485 }
486
487 /// Sets the accuracy of the clock. Some clocks have the possibility to operate
488 /// with different accuracy at the expense of more resource usage. There is
489 /// normally no need to change the default resolution of a clock. The resolution
490 /// of a clock can only be changed if the clock has the
491 /// [`ClockFlags::CAN_SET_RESOLUTION`][crate::ClockFlags::CAN_SET_RESOLUTION] flag set.
492 /// ## `resolution`
493 /// The resolution to set
494 ///
495 /// # Returns
496 ///
497 /// the new resolution of the clock.
498 #[doc(alias = "gst_clock_set_resolution")]
499 fn set_resolution(&self, resolution: ClockTime) -> ClockTime {
500 unsafe {
501 try_from_glib(ffi::gst_clock_set_resolution(
502 self.as_ref().to_glib_none().0,
503 resolution.into_glib(),
504 ))
505 .expect("mandatory glib value is None")
506 }
507 }
508
509 /// Sets `self` to synced and emits the [`synced`][struct@crate::Clock#synced] signal, and wakes up any
510 /// thread waiting in [`wait_for_sync()`][Self::wait_for_sync()].
511 ///
512 /// This function must only be called if [`ClockFlags::NEEDS_STARTUP_SYNC`][crate::ClockFlags::NEEDS_STARTUP_SYNC]
513 /// is set on the clock, and is intended to be called by subclasses only.
514 /// ## `synced`
515 /// if the clock is synced
516 #[doc(alias = "gst_clock_set_synced")]
517 fn set_synced(&self, synced: bool) {
518 unsafe {
519 ffi::gst_clock_set_synced(self.as_ref().to_glib_none().0, synced.into_glib());
520 }
521 }
522
523 /// Sets the amount of time, in nanoseconds, to sample master and slave
524 /// clocks
525 /// ## `timeout`
526 /// a timeout
527 #[doc(alias = "gst_clock_set_timeout")]
528 #[doc(alias = "timeout")]
529 fn set_timeout(&self, timeout: impl Into<Option<ClockTime>>) {
530 unsafe {
531 ffi::gst_clock_set_timeout(self.as_ref().to_glib_none().0, timeout.into().into_glib());
532 }
533 }
534
535 /// Converts the given `external` clock time to the internal time of `self`,
536 /// using the rate and reference time set with [`ClockExtManual::set_calibration()`][crate::prelude::ClockExtManual::set_calibration()].
537 /// This function should be called with the clock's OBJECT_LOCK held and
538 /// is mainly used by clock subclasses.
539 ///
540 /// This function is the reverse of [`adjust_unlocked()`][Self::adjust_unlocked()].
541 /// ## `external`
542 /// an external clock time
543 ///
544 /// # Returns
545 ///
546 /// the internal time of the clock corresponding to `external`.
547 #[doc(alias = "gst_clock_unadjust_unlocked")]
548 fn unadjust_unlocked(&self, external: ClockTime) -> ClockTime {
549 unsafe {
550 try_from_glib(ffi::gst_clock_unadjust_unlocked(
551 self.as_ref().to_glib_none().0,
552 external.into_glib(),
553 ))
554 .expect("mandatory glib value is None")
555 }
556 }
557
558 /// Waits until `self` is synced for reporting the current time. If `timeout`
559 /// is `GST_CLOCK_TIME_NONE` it will wait forever, otherwise it will time out
560 /// after `timeout` nanoseconds.
561 ///
562 /// For asynchronous waiting, the [`synced`][struct@crate::Clock#synced] signal can be used.
563 ///
564 /// This returns immediately with [`true`] if [`ClockFlags::NEEDS_STARTUP_SYNC`][crate::ClockFlags::NEEDS_STARTUP_SYNC]
565 /// is not set on the clock, or if the clock is already synced.
566 /// ## `timeout`
567 /// timeout for waiting or `GST_CLOCK_TIME_NONE`
568 ///
569 /// # Returns
570 ///
571 /// [`true`] if waiting was successful, or [`false`] on timeout
572 #[doc(alias = "gst_clock_wait_for_sync")]
573 fn wait_for_sync(
574 &self,
575 timeout: impl Into<Option<ClockTime>>,
576 ) -> Result<(), glib::error::BoolError> {
577 unsafe {
578 glib::result_from_gboolean!(
579 ffi::gst_clock_wait_for_sync(
580 self.as_ref().to_glib_none().0,
581 timeout.into().into_glib()
582 ),
583 "Timed out waiting for sync"
584 )
585 }
586 }
587
588 #[doc(alias = "window-size")]
589 fn window_size(&self) -> i32 {
590 ObjectExt::property(self.as_ref(), "window-size")
591 }
592
593 #[doc(alias = "window-size")]
594 fn set_window_size(&self, window_size: i32) {
595 ObjectExt::set_property(self.as_ref(), "window-size", window_size)
596 }
597
598 #[doc(alias = "window-threshold")]
599 fn window_threshold(&self) -> i32 {
600 ObjectExt::property(self.as_ref(), "window-threshold")
601 }
602
603 #[doc(alias = "window-threshold")]
604 fn set_window_threshold(&self, window_threshold: i32) {
605 ObjectExt::set_property(self.as_ref(), "window-threshold", window_threshold)
606 }
607
608 /// Signaled on clocks with [`ClockFlags::NEEDS_STARTUP_SYNC`][crate::ClockFlags::NEEDS_STARTUP_SYNC] set once
609 /// the clock is synchronized, or when it completely lost synchronization.
610 /// This signal will not be emitted on clocks without the flag.
611 ///
612 /// This signal will be emitted from an arbitrary thread, most likely not
613 /// the application's main thread.
614 /// ## `synced`
615 /// if the clock is synced now
616 #[doc(alias = "synced")]
617 fn connect_synced<F: Fn(&Self, bool) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
618 unsafe extern "C" fn synced_trampoline<
619 P: IsA<Clock>,
620 F: Fn(&P, bool) + Send + Sync + 'static,
621 >(
622 this: *mut ffi::GstClock,
623 synced: glib::ffi::gboolean,
624 f: glib::ffi::gpointer,
625 ) {
626 unsafe {
627 let f: &F = &*(f as *const F);
628 f(
629 Clock::from_glib_borrow(this).unsafe_cast_ref(),
630 from_glib(synced),
631 )
632 }
633 }
634 unsafe {
635 let f: Box_<F> = Box_::new(f);
636 connect_raw(
637 self.as_ptr() as *mut _,
638 c"synced".as_ptr(),
639 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
640 synced_trampoline::<Self, F> as *const (),
641 )),
642 Box_::into_raw(f),
643 )
644 }
645 }
646
647 #[doc(alias = "timeout")]
648 fn connect_timeout_notify<F: Fn(&Self) + Send + Sync + 'static>(
649 &self,
650 f: F,
651 ) -> SignalHandlerId {
652 unsafe extern "C" fn notify_timeout_trampoline<
653 P: IsA<Clock>,
654 F: Fn(&P) + Send + Sync + 'static,
655 >(
656 this: *mut ffi::GstClock,
657 _param_spec: glib::ffi::gpointer,
658 f: glib::ffi::gpointer,
659 ) {
660 unsafe {
661 let f: &F = &*(f as *const F);
662 f(Clock::from_glib_borrow(this).unsafe_cast_ref())
663 }
664 }
665 unsafe {
666 let f: Box_<F> = Box_::new(f);
667 connect_raw(
668 self.as_ptr() as *mut _,
669 c"notify::timeout".as_ptr(),
670 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
671 notify_timeout_trampoline::<Self, F> as *const (),
672 )),
673 Box_::into_raw(f),
674 )
675 }
676 }
677
678 #[doc(alias = "window-size")]
679 fn connect_window_size_notify<F: Fn(&Self) + Send + Sync + 'static>(
680 &self,
681 f: F,
682 ) -> SignalHandlerId {
683 unsafe extern "C" fn notify_window_size_trampoline<
684 P: IsA<Clock>,
685 F: Fn(&P) + Send + Sync + 'static,
686 >(
687 this: *mut ffi::GstClock,
688 _param_spec: glib::ffi::gpointer,
689 f: glib::ffi::gpointer,
690 ) {
691 unsafe {
692 let f: &F = &*(f as *const F);
693 f(Clock::from_glib_borrow(this).unsafe_cast_ref())
694 }
695 }
696 unsafe {
697 let f: Box_<F> = Box_::new(f);
698 connect_raw(
699 self.as_ptr() as *mut _,
700 c"notify::window-size".as_ptr(),
701 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
702 notify_window_size_trampoline::<Self, F> as *const (),
703 )),
704 Box_::into_raw(f),
705 )
706 }
707 }
708
709 #[doc(alias = "window-threshold")]
710 fn connect_window_threshold_notify<F: Fn(&Self) + Send + Sync + 'static>(
711 &self,
712 f: F,
713 ) -> SignalHandlerId {
714 unsafe extern "C" fn notify_window_threshold_trampoline<
715 P: IsA<Clock>,
716 F: Fn(&P) + Send + Sync + 'static,
717 >(
718 this: *mut ffi::GstClock,
719 _param_spec: glib::ffi::gpointer,
720 f: glib::ffi::gpointer,
721 ) {
722 unsafe {
723 let f: &F = &*(f as *const F);
724 f(Clock::from_glib_borrow(this).unsafe_cast_ref())
725 }
726 }
727 unsafe {
728 let f: Box_<F> = Box_::new(f);
729 connect_raw(
730 self.as_ptr() as *mut _,
731 c"notify::window-threshold".as_ptr(),
732 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
733 notify_window_threshold_trampoline::<Self, F> as *const (),
734 )),
735 Box_::into_raw(f),
736 )
737 }
738 }
739}
740
741impl<O: IsA<Clock>> ClockExt for O {}