net: Add various static PTP clock API

This allows initializing the PTP clock infrastructure, deinitializing
it, checking the current status and adding statistics callbacks.
This commit is contained in:
Sebastian Dröge 2022-05-11 14:19:50 +03:00
parent ba25d7ea90
commit c651d96c49
2 changed files with 103 additions and 1 deletions

View file

@ -31,11 +31,13 @@ pub use crate::auto::*;
mod net_client_clock;
mod net_time_provider;
mod ntp_clock;
mod ptp_clock;
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 {

View file

@ -1,5 +1,7 @@
// 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::prelude::*;
@ -22,4 +24,102 @@ 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<u64>, 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::<F>),
Box::into_raw(user_data) as glib::ffi::gpointer,
Some(destroy::<F>),
);
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 _);
}
}
}