From 081d42ac86052351c1dc1dedfc9cc8138a9f8c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 11 May 2022 14:19:50 +0300 Subject: [PATCH] net: Add various static PTP clock API This allows initializing the PTP clock infrastructure, deinitializing it, checking the current status and adding statistics callbacks. --- gstreamer-net/src/lib.rs | 3 + gstreamer-net/src/ptp_clock.rs | 106 +++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 gstreamer-net/src/ptp_clock.rs diff --git a/gstreamer-net/src/lib.rs b/gstreamer-net/src/lib.rs index f4bfd77ef..bdc643a0d 100644 --- a/gstreamer-net/src/lib.rs +++ b/gstreamer-net/src/lib.rs @@ -32,6 +32,9 @@ pub use crate::auto::*; pub use crate::net_address_meta::*; mod net_address_meta; +mod ptp_clock; +pub use ptp_clock::PtpStatisticsCallback; + // Re-export all the traits in a prelude module, so that applications // can always "use gst_net::prelude::*" without getting conflicts pub mod prelude { diff --git a/gstreamer-net/src/ptp_clock.rs b/gstreamer-net/src/ptp_clock.rs new file mode 100644 index 000000000..18f1a7823 --- /dev/null +++ b/gstreamer-net/src/ptp_clock.rs @@ -0,0 +1,106 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use std::num::NonZeroU64; + +use crate::PtpClock; +use glib::translate::*; + +impl PtpClock { + // rustdoc-stripper-ignore-next + /// Initialize GStreamer PTP clock support + /// + /// This is automatically called once the first PTP clock instance is created. + #[doc(alias = "gst_ptp_init")] + pub fn init(clock_id: Option, interfaces: &[&str]) -> Result<(), glib::BoolError> { + skip_assert_initialized!(); + unsafe { + let res: bool = from_glib(ffi::gst_ptp_init( + clock_id.unwrap_or(u64::MAX), + interfaces.to_glib_none().0, + )); + + if res { + Ok(()) + } else { + Err(glib::bool_error!("Failed to initialize PTP subsystem")) + } + } + } + + // rustdoc-stripper-ignore-next + /// Deinitialize GStreamer PTP clock support + /// + /// Any PTP clocks that are still running will not receive any updates anymore. + #[doc(alias = "gst_ptp_deinit")] + pub fn deinit() { + unsafe { + ffi::gst_ptp_deinit(); + } + } + + // rustdoc-stripper-ignore-next + /// Check if the GStreamer PTP clock support is initialized + #[doc(alias = "gst_ptp_is_initialized")] + pub fn is_initialized() -> bool { + unsafe { from_glib(ffi::gst_ptp_is_initialized()) } + } + + // rustdoc-stripper-ignore-next + /// Check if GStreamer PTP clocks are supported + #[doc(alias = "gst_ptp_is_supported")] + pub fn is_supported() -> bool { + unsafe { from_glib(ffi::gst_ptp_is_supported()) } + } + + // rustdoc-stripper-ignore-next + /// Add a PTP clock statistics callback + #[doc(alias = "gst_ptp_statistics_callback_add")] + pub fn add_statistics_callback< + F: Fn(u8, &gst::StructureRef) -> glib::Continue + 'static + Send + Sync, + >( + func: F, + ) -> PtpStatisticsCallback { + unsafe { + unsafe extern "C" fn trampoline< + F: Fn(u8, &gst::StructureRef) -> glib::Continue + 'static + Send + Sync, + >( + domain: u8, + stats: *const gst::ffi::GstStructure, + user_data: glib::ffi::gpointer, + ) -> glib::ffi::gboolean { + let callback = &*(user_data as *const F); + callback(domain, gst::StructureRef::from_glib_borrow(stats)).into_glib() + } + + unsafe extern "C" fn destroy< + F: Fn(u8, &gst::StructureRef) -> glib::Continue + 'static + Send + Sync, + >( + user_data: glib::ffi::gpointer, + ) { + let _ = Box::from_raw(user_data as *mut F); + } + + let user_data = Box::new(func); + let id = ffi::gst_ptp_statistics_callback_add( + Some(trampoline::), + Box::into_raw(user_data) as glib::ffi::gpointer, + Some(destroy::), + ); + assert_ne!(id, 0); + + PtpStatisticsCallback(NonZeroU64::new_unchecked(id)) + } + } +} + +#[derive(Debug)] +pub struct PtpStatisticsCallback(NonZeroU64); + +impl PtpStatisticsCallback { + #[doc(alias = "gst_ptp_statistics_callback_remove")] + pub fn remove(self) { + unsafe { + ffi::gst_ptp_statistics_callback_remove(self.0.get() as _); + } + } +}