diff --git a/gstreamer/src/clock.rs b/gstreamer/src/clock.rs index 9a75a211f..54d6a29b8 100644 --- a/gstreamer/src/clock.rs +++ b/gstreamer/src/clock.rs @@ -17,6 +17,7 @@ use libc::c_void; use std::cmp; use std::ptr; use Clock; +use ClockEntryType; use ClockError; use ClockFlags; use ClockReturn; @@ -24,6 +25,9 @@ use ClockSuccess; use ClockTime; use ClockTimeDiff; +use std::sync::atomic; +use std::sync::atomic::AtomicI32; + glib_wrapper! { #[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Hash)] pub struct ClockId(Shared); @@ -118,7 +122,7 @@ impl ClockId { } #[cfg(any(feature = "v1_16", feature = "dox"))] - pub fn id_uses_clock>(&self, clock: &P) -> bool { + pub fn uses_clock>(&self, clock: &P) -> bool { unsafe { from_glib(gst_sys::gst_clock_id_uses_clock( self.to_glib_none().0, @@ -126,6 +130,86 @@ impl ClockId { )) } } + + pub fn get_type(&self) -> ClockEntryType { + unsafe { + let ptr: *mut gst_sys::GstClockEntry = self.to_glib_none().0 as *mut _; + from_glib((*ptr).type_) + } + } + + pub fn get_interval(&self) -> Option { + if self.get_type() != ClockEntryType::Periodic { + return None; + } + + unsafe { + let ptr: *mut gst_sys::GstClockEntry = self.to_glib_none().0 as *mut _; + Some(from_glib((*ptr).interval)) + } + } + + pub fn get_status(&self) -> &AtomicClockReturn { + unsafe { + let ptr: *mut gst_sys::GstClockEntry = self.to_glib_none().0 as *mut _; + &*((&(*ptr).status) as *const i32 as *const AtomicClockReturn) + } + } + + pub fn wake_up(&self, clock: &Clock) { + #[cfg(feature = "v1_16")] + { + assert!(self.uses_clock(clock)); + } + #[cfg(not(feature = "v1_16"))] + { + unsafe { + let ptr: *mut gst_sys::GstClockEntry = self.to_glib_none().0 as *mut _; + assert_eq!((*ptr).clock, clock.to_glib_none().0); + } + } + + unsafe { + let ptr: *mut gst_sys::GstClockEntry = self.to_glib_none().0 as *mut _; + if let Some(func) = (*ptr).func { + func( + clock.to_glib_none().0, + (*ptr).time, + ptr as gst_sys::GstClockID, + (*ptr).user_data, + ); + } + if (*ptr).type_ == gst_sys::GST_CLOCK_ENTRY_PERIODIC { + (*ptr).time += (*ptr).interval; + } + } + } +} + +#[repr(C)] +#[derive(Debug)] +pub struct AtomicClockReturn(AtomicI32); + +impl AtomicClockReturn { + pub fn load(&self) -> ClockReturn { + from_glib(self.0.load(atomic::Ordering::SeqCst)) + } + + pub fn store(&self, val: ClockReturn) { + self.0.store(val.to_glib(), atomic::Ordering::SeqCst) + } + + pub fn swap(&self, val: ClockReturn) -> ClockReturn { + from_glib(self.0.swap(val.to_glib(), atomic::Ordering::SeqCst)) + } + + pub fn compare_and_swap(&self, current: ClockReturn, new: ClockReturn) -> ClockReturn { + from_glib(self.0.compare_and_swap( + current.to_glib(), + new.to_glib(), + atomic::Ordering::SeqCst, + )) + } } unsafe impl Send for ClockId {} diff --git a/gstreamer/src/lib.rs b/gstreamer/src/lib.rs index ac0411fdd..086e6ec77 100644 --- a/gstreamer/src/lib.rs +++ b/gstreamer/src/lib.rs @@ -263,7 +263,7 @@ pub use toc::{Toc, TocEntry, TocEntryRef, TocRef}; mod toc_serde; mod clock; -pub use clock::{ClockExtManual, ClockId}; +pub use clock::{AtomicClockReturn, ClockExtManual, ClockId}; mod buffer_pool; pub use buffer_pool::*;