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
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 #[doc(alias = "gst_clock_set_master")]
200 fn set_master(&self, master: Option<&impl IsA<Clock>>) -> Result<(), glib::error::BoolError> {
201 unsafe {
202 glib::result_from_gboolean!(
203 ffi::gst_clock_set_master(
204 self.as_ref().to_glib_none().0,
205 master.map(|p| p.as_ref()).to_glib_none().0
206 ),
207 "Failed to set master clock"
208 )
209 }
210 }
211
212 #[doc(alias = "gst_clock_set_resolution")]
213 fn set_resolution(&self, resolution: ClockTime) -> ClockTime {
214 unsafe {
215 try_from_glib(ffi::gst_clock_set_resolution(
216 self.as_ref().to_glib_none().0,
217 resolution.into_glib(),
218 ))
219 .expect("mandatory glib value is None")
220 }
221 }
222
223 #[doc(alias = "gst_clock_set_synced")]
224 fn set_synced(&self, synced: bool) {
225 unsafe {
226 ffi::gst_clock_set_synced(self.as_ref().to_glib_none().0, synced.into_glib());
227 }
228 }
229
230 #[doc(alias = "gst_clock_set_timeout")]
231 #[doc(alias = "timeout")]
232 fn set_timeout(&self, timeout: impl Into<Option<ClockTime>>) {
233 unsafe {
234 ffi::gst_clock_set_timeout(self.as_ref().to_glib_none().0, timeout.into().into_glib());
235 }
236 }
237
238 #[doc(alias = "gst_clock_unadjust_unlocked")]
239 fn unadjust_unlocked(&self, external: ClockTime) -> ClockTime {
240 unsafe {
241 try_from_glib(ffi::gst_clock_unadjust_unlocked(
242 self.as_ref().to_glib_none().0,
243 external.into_glib(),
244 ))
245 .expect("mandatory glib value is None")
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 c"synced".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 c"notify::timeout".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 c"notify::window-size".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 c"notify::window-threshold".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 {}