From 6c57d89e9c7f43915916f531e3d309bdae978d97 Mon Sep 17 00:00:00 2001 From: Mathieu Duponchelle Date: Thu, 7 Apr 2022 02:09:44 +0200 Subject: [PATCH] rtp: add bindings for RTPBasePayload Part-of: --- gstreamer-rtp/Gir.toml | 61 +- gstreamer-rtp/src/auto/mod.rs | 4 + gstreamer-rtp/src/auto/rtp_base_payload.rs | 1055 +++++++++++++++++ gstreamer-rtp/src/lib.rs | 9 + gstreamer-rtp/src/rtp_base_payload.rs | 54 + gstreamer-rtp/src/subclass/mod.rs | 8 + .../src/subclass/rtp_base_payload.rs | 311 +++++ 7 files changed, 1501 insertions(+), 1 deletion(-) create mode 100644 gstreamer-rtp/src/auto/rtp_base_payload.rs create mode 100644 gstreamer-rtp/src/rtp_base_payload.rs create mode 100644 gstreamer-rtp/src/subclass/rtp_base_payload.rs diff --git a/gstreamer-rtp/Gir.toml b/gstreamer-rtp/Gir.toml index 467ccd678..52a8562ad 100644 --- a/gstreamer-rtp/Gir.toml +++ b/gstreamer-rtp/Gir.toml @@ -30,7 +30,6 @@ manual = [ "Gst.Caps", "Gst.Element", "Gst.ElementFactory", - "Gst.Structure", ] [[object]] @@ -38,6 +37,30 @@ name = "Gst.Buffer" status = "manual" ref_mode = "ref" +[[object]] +name = "Gst.BufferList" +status = "manual" +ref_mode = "ref" + +[[object]] +name = "Gst.ClockTime" +status = "manual" +conversion_type = "Option" + +[[object]] +name = "Gst.FlowReturn" +status = "manual" +must_use = true + [object.conversion_type] + variant = "Result" + ok_type = "gst::FlowSuccess" + err_type = "gst::FlowError" + +[[object]] +name = "Gst.Structure" +status = "manual" +ref_mode = "ref" + [[object]] name = "GstRtp.*" status = "generate" @@ -56,6 +79,42 @@ status = "generate" name = "rtp_source_meta_api_get_type" ignore = true +[[object]] +name = "GstRtp.RTPBasePayload" +status = "generate" +manual_traits = ["RTPHeaderExtensionExtManual"] + + [[object.function]] + name = "set_outcaps" + # varargs function + ignore = true + + [[object.function]] + name = "push" + # Move buffer + manual = true + + [[object.function]] + name = "push_list" + # Move buffer list + manual = true + + [[object.function]] + name = "set_outcaps_structure" + # StructureRef instead of Structure + manual = true + rename = "set_outcaps" + + [[object.function]] + name = "allocate_output_buffer" + [object.function.return] + nullable_return_is_error = "Failed to allocate output buffer" + + [[object.signal]] + name = "request-extension" + [object.signal.return] + nullable = true + [[object]] name = "GstRtp.RTPBuffer" status = "manual" diff --git a/gstreamer-rtp/src/auto/mod.rs b/gstreamer-rtp/src/auto/mod.rs index 210833bd5..d1cf830d5 100644 --- a/gstreamer-rtp/src/auto/mod.rs +++ b/gstreamer-rtp/src/auto/mod.rs @@ -3,6 +3,9 @@ // from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git) // DO NOT EDIT +mod rtp_base_payload; +pub use self::rtp_base_payload::RTPBasePayload; + #[cfg(any(feature = "v1_20", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] mod rtp_header_extension; @@ -78,6 +81,7 @@ pub use self::constants::RTP_PAYLOAD_TS48_STRING; #[doc(hidden)] pub mod traits { + pub use super::rtp_base_payload::RTPBasePayloadExt; #[cfg(any(feature = "v1_20", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] pub use super::rtp_header_extension::RTPHeaderExtensionExt; diff --git a/gstreamer-rtp/src/auto/rtp_base_payload.rs b/gstreamer-rtp/src/auto/rtp_base_payload.rs new file mode 100644 index 000000000..6577402b6 --- /dev/null +++ b/gstreamer-rtp/src/auto/rtp_base_payload.rs @@ -0,0 +1,1055 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git) +// DO NOT EDIT + +#[cfg(any(feature = "v1_20", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] +use crate::RTPHeaderExtension; +use glib::object::Cast; +use glib::object::IsA; +#[cfg(any(feature = "v1_20", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] +use glib::object::ObjectExt; +use glib::signal::connect_raw; +use glib::signal::SignalHandlerId; +use glib::translate::*; +use glib::StaticType; +use glib::ToValue; +use std::boxed::Box as Box_; +use std::mem::transmute; + +glib::wrapper! { + #[doc(alias = "GstRTPBasePayload")] + pub struct RTPBasePayload(Object) @extends gst::Element; + + match fn { + type_ => || ffi::gst_rtp_base_payload_get_type(), + } +} + +impl RTPBasePayload { + pub const NONE: Option<&'static RTPBasePayload> = None; +} + +unsafe impl Send for RTPBasePayload {} +unsafe impl Sync for RTPBasePayload {} + +pub trait RTPBasePayloadExt: 'static { + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "gst_rtp_base_payload_allocate_output_buffer")] + fn allocate_output_buffer( + &self, + payload_len: u32, + pad_len: u8, + csrc_count: u8, + ) -> Result; + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "gst_rtp_base_payload_get_source_count")] + #[doc(alias = "get_source_count")] + fn source_count(&self, buffer: &gst::Buffer) -> u32; + + #[doc(alias = "gst_rtp_base_payload_is_filled")] + fn is_filled(&self, size: u32, duration: impl Into>) -> bool; + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "gst_rtp_base_payload_is_source_info_enabled")] + fn is_source_info_enabled(&self) -> bool; + + #[doc(alias = "gst_rtp_base_payload_set_options")] + fn set_options(&self, media: &str, dynamic: bool, encoding_name: &str, clock_rate: u32); + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "gst_rtp_base_payload_set_source_info_enabled")] + fn set_source_info_enabled(&self, enable: bool); + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + #[doc(alias = "auto-header-extension")] + fn is_auto_header_extension(&self) -> bool; + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + #[doc(alias = "auto-header-extension")] + fn set_auto_header_extension(&self, auto_header_extension: bool); + + #[doc(alias = "max-ptime")] + fn max_ptime(&self) -> i64; + + #[doc(alias = "max-ptime")] + fn set_max_ptime(&self, max_ptime: i64); + + #[doc(alias = "min-ptime")] + fn min_ptime(&self) -> i64; + + #[doc(alias = "min-ptime")] + fn set_min_ptime(&self, min_ptime: i64); + + fn mtu(&self) -> u32; + + fn set_mtu(&self, mtu: u32); + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "onvif-no-rate-control")] + fn is_onvif_no_rate_control(&self) -> bool; + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "onvif-no-rate-control")] + fn set_onvif_no_rate_control(&self, onvif_no_rate_control: bool); + + #[doc(alias = "perfect-rtptime")] + fn is_perfect_rtptime(&self) -> bool; + + #[doc(alias = "perfect-rtptime")] + fn set_perfect_rtptime(&self, perfect_rtptime: bool); + + fn pt(&self) -> u32; + + fn set_pt(&self, pt: u32); + + #[doc(alias = "ptime-multiple")] + fn ptime_multiple(&self) -> i64; + + #[doc(alias = "ptime-multiple")] + fn set_ptime_multiple(&self, ptime_multiple: i64); + + #[cfg(any(feature = "v1_18", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + #[doc(alias = "scale-rtptime")] + fn is_scale_rtptime(&self) -> bool; + + #[cfg(any(feature = "v1_18", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + #[doc(alias = "scale-rtptime")] + fn set_scale_rtptime(&self, scale_rtptime: bool); + + fn seqnum(&self) -> u32; + + #[doc(alias = "seqnum-offset")] + fn seqnum_offset(&self) -> i32; + + #[doc(alias = "seqnum-offset")] + fn set_seqnum_offset(&self, seqnum_offset: i32); + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "source-info")] + fn is_source_info(&self) -> bool; + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "source-info")] + fn set_source_info(&self, source_info: bool); + + fn ssrc(&self) -> u32; + + fn set_ssrc(&self, ssrc: u32); + + fn stats(&self) -> Option; + + fn timestamp(&self) -> u32; + + #[doc(alias = "timestamp-offset")] + fn timestamp_offset(&self) -> u32; + + #[doc(alias = "timestamp-offset")] + fn set_timestamp_offset(&self, timestamp_offset: u32); + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + #[doc(alias = "add-extension")] + fn connect_add_extension( + &self, + f: F, + ) -> SignalHandlerId; + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn emit_add_extension(&self, ext: &RTPHeaderExtension); + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + #[doc(alias = "clear-extensions")] + fn connect_clear_extensions( + &self, + f: F, + ) -> SignalHandlerId; + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn emit_clear_extensions(&self); + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + #[doc(alias = "request-extension")] + fn connect_request_extension< + F: Fn(&Self, u32, &str) -> Option + Send + Sync + 'static, + >( + &self, + f: F, + ) -> SignalHandlerId; + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + #[doc(alias = "auto-header-extension")] + fn connect_auto_header_extension_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "max-ptime")] + fn connect_max_ptime_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "min-ptime")] + fn connect_min_ptime_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "mtu")] + fn connect_mtu_notify(&self, f: F) -> SignalHandlerId; + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "onvif-no-rate-control")] + fn connect_onvif_no_rate_control_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "perfect-rtptime")] + fn connect_perfect_rtptime_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "pt")] + fn connect_pt_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "ptime-multiple")] + fn connect_ptime_multiple_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[cfg(any(feature = "v1_18", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + #[doc(alias = "scale-rtptime")] + fn connect_scale_rtptime_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "seqnum")] + fn connect_seqnum_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "seqnum-offset")] + fn connect_seqnum_offset_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + #[doc(alias = "source-info")] + fn connect_source_info_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "ssrc")] + fn connect_ssrc_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "stats")] + fn connect_stats_notify(&self, f: F) -> SignalHandlerId; + + #[doc(alias = "timestamp")] + fn connect_timestamp_notify( + &self, + f: F, + ) -> SignalHandlerId; + + #[doc(alias = "timestamp-offset")] + fn connect_timestamp_offset_notify( + &self, + f: F, + ) -> SignalHandlerId; +} + +impl> RTPBasePayloadExt for O { + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn allocate_output_buffer( + &self, + payload_len: u32, + pad_len: u8, + csrc_count: u8, + ) -> Result { + unsafe { + Option::<_>::from_glib_full(ffi::gst_rtp_base_payload_allocate_output_buffer( + self.as_ref().to_glib_none().0, + payload_len, + pad_len, + csrc_count, + )) + .ok_or_else(|| glib::bool_error!("Failed to allocate output buffer")) + } + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn source_count(&self, buffer: &gst::Buffer) -> u32 { + unsafe { + ffi::gst_rtp_base_payload_get_source_count( + self.as_ref().to_glib_none().0, + buffer.to_glib_none().0, + ) + } + } + + fn is_filled(&self, size: u32, duration: impl Into>) -> bool { + unsafe { + from_glib(ffi::gst_rtp_base_payload_is_filled( + self.as_ref().to_glib_none().0, + size, + duration.into().into_glib(), + )) + } + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn is_source_info_enabled(&self) -> bool { + unsafe { + from_glib(ffi::gst_rtp_base_payload_is_source_info_enabled( + self.as_ref().to_glib_none().0, + )) + } + } + + fn set_options(&self, media: &str, dynamic: bool, encoding_name: &str, clock_rate: u32) { + unsafe { + ffi::gst_rtp_base_payload_set_options( + self.as_ref().to_glib_none().0, + media.to_glib_none().0, + dynamic.into_glib(), + encoding_name.to_glib_none().0, + clock_rate, + ); + } + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn set_source_info_enabled(&self, enable: bool) { + unsafe { + ffi::gst_rtp_base_payload_set_source_info_enabled( + self.as_ref().to_glib_none().0, + enable.into_glib(), + ); + } + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn is_auto_header_extension(&self) -> bool { + glib::ObjectExt::property(self.as_ref(), "auto-header-extension") + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn set_auto_header_extension(&self, auto_header_extension: bool) { + glib::ObjectExt::set_property( + self.as_ref(), + "auto-header-extension", + &auto_header_extension, + ) + } + + fn max_ptime(&self) -> i64 { + glib::ObjectExt::property(self.as_ref(), "max-ptime") + } + + fn set_max_ptime(&self, max_ptime: i64) { + glib::ObjectExt::set_property(self.as_ref(), "max-ptime", &max_ptime) + } + + fn min_ptime(&self) -> i64 { + glib::ObjectExt::property(self.as_ref(), "min-ptime") + } + + fn set_min_ptime(&self, min_ptime: i64) { + glib::ObjectExt::set_property(self.as_ref(), "min-ptime", &min_ptime) + } + + fn mtu(&self) -> u32 { + glib::ObjectExt::property(self.as_ref(), "mtu") + } + + fn set_mtu(&self, mtu: u32) { + glib::ObjectExt::set_property(self.as_ref(), "mtu", &mtu) + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn is_onvif_no_rate_control(&self) -> bool { + glib::ObjectExt::property(self.as_ref(), "onvif-no-rate-control") + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn set_onvif_no_rate_control(&self, onvif_no_rate_control: bool) { + glib::ObjectExt::set_property( + self.as_ref(), + "onvif-no-rate-control", + &onvif_no_rate_control, + ) + } + + fn is_perfect_rtptime(&self) -> bool { + glib::ObjectExt::property(self.as_ref(), "perfect-rtptime") + } + + fn set_perfect_rtptime(&self, perfect_rtptime: bool) { + glib::ObjectExt::set_property(self.as_ref(), "perfect-rtptime", &perfect_rtptime) + } + + fn pt(&self) -> u32 { + glib::ObjectExt::property(self.as_ref(), "pt") + } + + fn set_pt(&self, pt: u32) { + glib::ObjectExt::set_property(self.as_ref(), "pt", &pt) + } + + fn ptime_multiple(&self) -> i64 { + glib::ObjectExt::property(self.as_ref(), "ptime-multiple") + } + + fn set_ptime_multiple(&self, ptime_multiple: i64) { + glib::ObjectExt::set_property(self.as_ref(), "ptime-multiple", &ptime_multiple) + } + + #[cfg(any(feature = "v1_18", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + fn is_scale_rtptime(&self) -> bool { + glib::ObjectExt::property(self.as_ref(), "scale-rtptime") + } + + #[cfg(any(feature = "v1_18", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + fn set_scale_rtptime(&self, scale_rtptime: bool) { + glib::ObjectExt::set_property(self.as_ref(), "scale-rtptime", &scale_rtptime) + } + + fn seqnum(&self) -> u32 { + glib::ObjectExt::property(self.as_ref(), "seqnum") + } + + fn seqnum_offset(&self) -> i32 { + glib::ObjectExt::property(self.as_ref(), "seqnum-offset") + } + + fn set_seqnum_offset(&self, seqnum_offset: i32) { + glib::ObjectExt::set_property(self.as_ref(), "seqnum-offset", &seqnum_offset) + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn is_source_info(&self) -> bool { + glib::ObjectExt::property(self.as_ref(), "source-info") + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn set_source_info(&self, source_info: bool) { + glib::ObjectExt::set_property(self.as_ref(), "source-info", &source_info) + } + + fn ssrc(&self) -> u32 { + glib::ObjectExt::property(self.as_ref(), "ssrc") + } + + fn set_ssrc(&self, ssrc: u32) { + glib::ObjectExt::set_property(self.as_ref(), "ssrc", &ssrc) + } + + fn stats(&self) -> Option { + glib::ObjectExt::property(self.as_ref(), "stats") + } + + fn timestamp(&self) -> u32 { + glib::ObjectExt::property(self.as_ref(), "timestamp") + } + + fn timestamp_offset(&self) -> u32 { + glib::ObjectExt::property(self.as_ref(), "timestamp-offset") + } + + fn set_timestamp_offset(&self, timestamp_offset: u32) { + glib::ObjectExt::set_property(self.as_ref(), "timestamp-offset", ×tamp_offset) + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn connect_add_extension( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn add_extension_trampoline< + P: IsA, + F: Fn(&P, &RTPHeaderExtension) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + ext: *mut ffi::GstRTPHeaderExtension, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f( + RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref(), + &from_glib_full(ext), + ) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"add-extension\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + add_extension_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn emit_add_extension(&self, ext: &RTPHeaderExtension) { + self.emit_by_name::<()>("add-extension", &[&ext]); + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn connect_clear_extensions( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn clear_extensions_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"clear-extensions\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + clear_extensions_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn emit_clear_extensions(&self) { + self.emit_by_name::<()>("clear-extensions", &[]); + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn connect_request_extension< + F: Fn(&Self, u32, &str) -> Option + Send + Sync + 'static, + >( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn request_extension_trampoline< + P: IsA, + F: Fn(&P, u32, &str) -> Option + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + ext_id: libc::c_uint, + ext_uri: *mut libc::c_char, + f: glib::ffi::gpointer, + ) -> *mut ffi::GstRTPHeaderExtension { + let f: &F = &*(f as *const F); + f( + RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref(), + ext_id, + &glib::GString::from_glib_borrow(ext_uri), + ) + .to_glib_full() + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"request-extension\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + request_extension_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn connect_auto_header_extension_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_auto_header_extension_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::auto-header-extension\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_auto_header_extension_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_max_ptime_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_max_ptime_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::max-ptime\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_max_ptime_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_min_ptime_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_min_ptime_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::min-ptime\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_min_ptime_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_mtu_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_mtu_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::mtu\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_mtu_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn connect_onvif_no_rate_control_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_onvif_no_rate_control_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::onvif-no-rate-control\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_onvif_no_rate_control_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_perfect_rtptime_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_perfect_rtptime_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::perfect-rtptime\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_perfect_rtptime_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_pt_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_pt_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::pt\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_pt_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_ptime_multiple_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_ptime_multiple_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::ptime-multiple\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_ptime_multiple_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_18", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] + fn connect_scale_rtptime_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_scale_rtptime_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::scale-rtptime\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_scale_rtptime_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_seqnum_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_seqnum_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::seqnum\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_seqnum_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_seqnum_offset_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_seqnum_offset_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::seqnum-offset\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_seqnum_offset_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + #[cfg(any(feature = "v1_16", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))] + fn connect_source_info_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_source_info_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::source-info\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_source_info_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_ssrc_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_ssrc_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::ssrc\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_ssrc_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_stats_notify(&self, f: F) -> SignalHandlerId { + unsafe extern "C" fn notify_stats_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::stats\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_stats_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_timestamp_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_timestamp_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::timestamp\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_timestamp_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } + + fn connect_timestamp_offset_notify( + &self, + f: F, + ) -> SignalHandlerId { + unsafe extern "C" fn notify_timestamp_offset_trampoline< + P: IsA, + F: Fn(&P) + Send + Sync + 'static, + >( + this: *mut ffi::GstRTPBasePayload, + _param_spec: glib::ffi::gpointer, + f: glib::ffi::gpointer, + ) { + let f: &F = &*(f as *const F); + f(RTPBasePayload::from_glib_borrow(this).unsafe_cast_ref()) + } + unsafe { + let f: Box_ = Box_::new(f); + connect_raw( + self.as_ptr() as *mut _, + b"notify::timestamp-offset\0".as_ptr() as *const _, + Some(transmute::<_, unsafe extern "C" fn()>( + notify_timestamp_offset_trampoline:: as *const (), + )), + Box_::into_raw(f), + ) + } + } +} diff --git a/gstreamer-rtp/src/lib.rs b/gstreamer-rtp/src/lib.rs index f268b19a3..20157aa73 100644 --- a/gstreamer-rtp/src/lib.rs +++ b/gstreamer-rtp/src/lib.rs @@ -26,6 +26,7 @@ macro_rules! skip_assert_initialized { #[allow(clippy::match_same_arms)] #[allow(non_snake_case)] #[allow(clippy::use_self)] +#[allow(unused_imports)] mod auto; pub use crate::auto::functions::*; pub use crate::auto::*; @@ -38,6 +39,10 @@ pub use crate::rtp_buffer::{compare_seqnum, RTPBuffer}; #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] pub mod rtp_header_extension; +#[cfg(any(feature = "v1_20", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] +pub mod rtp_base_payload; + // Re-export all the traits in a prelude module, so that applications // can always "use gst_rtp::prelude::*" without getting conflicts pub mod prelude { @@ -50,4 +55,8 @@ pub mod prelude { #[cfg(any(feature = "v1_20", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] pub use crate::rtp_header_extension::RTPHeaderExtensionExtManual; + + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + pub use crate::rtp_base_payload::RTPBasePayloadExtManual; } diff --git a/gstreamer-rtp/src/rtp_base_payload.rs b/gstreamer-rtp/src/rtp_base_payload.rs new file mode 100644 index 000000000..e5e537a78 --- /dev/null +++ b/gstreamer-rtp/src/rtp_base_payload.rs @@ -0,0 +1,54 @@ +use crate::RTPBasePayload; +use glib::object::IsA; +use glib::translate::*; +use std::ptr; + +pub trait RTPBasePayloadExtManual: 'static { + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + #[doc(alias = "gst_rtp_base_payload_set_outcaps_structure")] + #[doc(alias = "gst_rtp_base_payload_set_outcaps")] + fn set_outcaps(&self, s: Option<&gst::StructureRef>) -> Result<(), glib::error::BoolError>; + + #[doc(alias = "gst_rtp_base_payload_push")] + fn push(&self, buffer: gst::Buffer) -> Result; + + #[doc(alias = "gst_rtp_base_payload_push_list")] + fn push_list(&self, list: gst::BufferList) -> Result; +} + +impl> RTPBasePayloadExtManual for O { + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + fn set_outcaps(&self, s: Option<&gst::StructureRef>) -> Result<(), glib::error::BoolError> { + unsafe { + glib::result_from_gboolean!( + ffi::gst_rtp_base_payload_set_outcaps_structure( + self.as_ref().to_glib_none().0, + s.as_ref() + .map(|s| s.as_ptr() as *mut _) + .unwrap_or(ptr::null_mut()), + ), + "Failed to negotiate by setting outcaps structure" + ) + } + } + + fn push(&self, buffer: gst::Buffer) -> Result { + unsafe { + try_from_glib(ffi::gst_rtp_base_payload_push( + self.as_ref().to_glib_none().0, + buffer.into_ptr(), + )) + } + } + + fn push_list(&self, list: gst::BufferList) -> Result { + unsafe { + try_from_glib(ffi::gst_rtp_base_payload_push_list( + self.as_ref().to_glib_none().0, + list.into_ptr(), + )) + } + } +} diff --git a/gstreamer-rtp/src/subclass/mod.rs b/gstreamer-rtp/src/subclass/mod.rs index 23c8d5a0d..0023ae4a1 100644 --- a/gstreamer-rtp/src/subclass/mod.rs +++ b/gstreamer-rtp/src/subclass/mod.rs @@ -2,6 +2,10 @@ #![allow(clippy::cast_ptr_alignment)] +#[cfg(any(feature = "v1_20", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] +mod rtp_base_payload; + #[cfg(any(feature = "v1_20", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] mod rtp_header_extension; @@ -10,6 +14,10 @@ pub mod prelude { #[doc(hidden)] pub use gst::subclass::prelude::*; + #[cfg(any(feature = "v1_20", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] + pub use super::rtp_base_payload::{RTPBasePayloadImpl, RTPBasePayloadImplExt}; + #[cfg(any(feature = "v1_20", feature = "dox"))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_20")))] pub use super::rtp_header_extension::{RTPHeaderExtensionImpl, RTPHeaderExtensionImplExt}; diff --git a/gstreamer-rtp/src/subclass/rtp_base_payload.rs b/gstreamer-rtp/src/subclass/rtp_base_payload.rs new file mode 100644 index 000000000..bf07ecf89 --- /dev/null +++ b/gstreamer-rtp/src/subclass/rtp_base_payload.rs @@ -0,0 +1,311 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::translate::*; + +use gst::subclass::prelude::*; + +use crate::prelude::*; +use crate::RTPBasePayload; + +pub trait RTPBasePayloadImpl: RTPBasePayloadImplExt + ElementImpl { + fn caps(&self, element: &Self::Type, pad: &gst::Pad, filter: Option<&gst::Caps>) -> gst::Caps { + self.parent_caps(element, pad, filter) + } + + fn set_caps(&self, element: &Self::Type, caps: &gst::Caps) -> Result<(), gst::LoggableError> { + self.parent_set_caps(element, caps) + } + + fn handle_buffer( + &self, + element: &Self::Type, + buffer: gst::Buffer, + ) -> Result { + self.parent_handle_buffer(element, buffer) + } + + fn query(&self, element: &Self::Type, pad: &gst::Pad, query: &mut gst::QueryRef) -> bool { + RTPBasePayloadImplExt::parent_query(self, element, pad, query) + } + + fn sink_event(&self, element: &Self::Type, event: gst::Event) -> bool { + self.parent_sink_event(element, event) + } + + fn src_event(&self, element: &Self::Type, event: gst::Event) -> bool { + self.parent_src_event(element, event) + } +} + +pub trait RTPBasePayloadImplExt: ObjectSubclass { + fn parent_caps( + &self, + element: &Self::Type, + pad: &gst::Pad, + filter: Option<&gst::Caps>, + ) -> gst::Caps; + + fn parent_set_caps( + &self, + element: &Self::Type, + caps: &gst::Caps, + ) -> Result<(), gst::LoggableError>; + + fn parent_handle_buffer( + &self, + element: &Self::Type, + buffer: gst::Buffer, + ) -> Result; + + fn parent_query(&self, element: &Self::Type, pad: &gst::Pad, query: &mut gst::QueryRef) + -> bool; + + fn parent_sink_event(&self, element: &Self::Type, event: gst::Event) -> bool; + + fn parent_src_event(&self, element: &Self::Type, event: gst::Event) -> bool; +} + +impl RTPBasePayloadImplExt for T { + fn parent_caps( + &self, + element: &Self::Type, + pad: &gst::Pad, + filter: Option<&gst::Caps>, + ) -> gst::Caps { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass; + let f = (*parent_class) + .get_caps + .expect("Missing parent function `get_caps`"); + from_glib_full(f( + element.unsafe_cast_ref::().to_glib_none().0, + pad.to_glib_none().0, + filter.to_glib_none().0, + )) + } + } + + fn parent_set_caps( + &self, + element: &Self::Type, + caps: &gst::Caps, + ) -> Result<(), gst::LoggableError> { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass; + (*parent_class) + .set_caps + .map(|f| { + gst::result_from_gboolean!( + f( + element.unsafe_cast_ref::().to_glib_none().0, + caps.to_glib_none().0 + ), + gst::CAT_RUST, + "Parent function `set_caps` failed" + ) + }) + .unwrap_or_else(|| { + // Trigger negotiation as the base class does + element + .unsafe_cast_ref::() + .set_outcaps(None) + .map_err(|_| gst::loggable_error!(gst::CAT_RUST, "Failed to negotiate")) + }) + } + } + + fn parent_handle_buffer( + &self, + element: &Self::Type, + buffer: gst::Buffer, + ) -> Result { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass; + (*parent_class) + .handle_buffer + .map(|f| { + try_from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + buffer.into_ptr(), + )) + }) + .unwrap_or(Err(gst::FlowError::Error)) + } + } + + fn parent_query( + &self, + element: &Self::Type, + pad: &gst::Pad, + query: &mut gst::QueryRef, + ) -> bool { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass; + (*parent_class) + .query + .map(|f| { + from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + pad.to_glib_none().0, + query.as_mut_ptr(), + )) + }) + .unwrap_or(false) + } + } + + fn parent_sink_event(&self, element: &Self::Type, event: gst::Event) -> bool { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass; + (*parent_class) + .sink_event + .map(|f| { + from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + event.into_ptr(), + )) + }) + .unwrap_or(false) + } + } + + fn parent_src_event(&self, element: &Self::Type, event: gst::Event) -> bool { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBasePayloadClass; + (*parent_class) + .src_event + .map(|f| { + from_glib(f( + element.unsafe_cast_ref::().to_glib_none().0, + event.into_ptr(), + )) + }) + .unwrap_or(false) + } + } +} + +unsafe impl IsSubclassable for RTPBasePayload { + fn class_init(klass: &mut glib::Class) { + Self::parent_class_init::(klass); + let klass = klass.as_mut(); + klass.get_caps = Some(rtp_base_payload_get_caps::); + klass.set_caps = Some(rtp_base_payload_set_caps::); + klass.handle_buffer = Some(rtp_base_payload_handle_buffer::); + klass.query = Some(rtp_base_payload_query::); + klass.sink_event = Some(rtp_base_payload_sink_event::); + klass.src_event = Some(rtp_base_payload_src_event::); + } +} + +unsafe extern "C" fn rtp_base_payload_get_caps( + ptr: *mut ffi::GstRTPBasePayload, + pad: *mut gst::ffi::GstPad, + filter: *mut gst::ffi::GstCaps, +) -> *mut gst::ffi::GstCaps { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, imp.panicked(), gst::Caps::new_empty(), { + RTPBasePayloadImpl::caps( + imp, + wrap.unsafe_cast_ref(), + &from_glib_borrow(pad), + Option::::from_glib_borrow(filter) + .as_ref() + .as_ref(), + ) + }) + .to_glib_full() +} + +unsafe extern "C" fn rtp_base_payload_set_caps( + ptr: *mut ffi::GstRTPBasePayload, + caps: *mut gst::ffi::GstCaps, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + let caps = from_glib_borrow(caps); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + match imp.set_caps(wrap.unsafe_cast_ref(), &caps) { + Ok(()) => true, + Err(err) => { + err.log_with_object(&*wrap); + false + } + } + }) + .into_glib() +} + +unsafe extern "C" fn rtp_base_payload_handle_buffer( + ptr: *mut ffi::GstRTPBasePayload, + buffer: *mut gst::ffi::GstBuffer, +) -> gst::ffi::GstFlowReturn { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, imp.panicked(), gst::FlowReturn::Error, { + imp.handle_buffer(wrap.unsafe_cast_ref(), from_glib_full(buffer)) + .into() + }) + .into_glib() +} + +unsafe extern "C" fn rtp_base_payload_query( + ptr: *mut ffi::GstRTPBasePayload, + pad: *mut gst::ffi::GstPad, + query: *mut gst::ffi::GstQuery, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + RTPBasePayloadImpl::query( + imp, + wrap.unsafe_cast_ref(), + &from_glib_borrow(pad), + gst::QueryRef::from_mut_ptr(query), + ) + }) + .into_glib() +} + +unsafe extern "C" fn rtp_base_payload_sink_event( + ptr: *mut ffi::GstRTPBasePayload, + event: *mut gst::ffi::GstEvent, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + imp.sink_event(wrap.unsafe_cast_ref(), from_glib_full(event)) + }) + .into_glib() +} + +unsafe extern "C" fn rtp_base_payload_src_event( + ptr: *mut ffi::GstRTPBasePayload, + event: *mut gst::ffi::GstEvent, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + + gst::panic_to_error!(&wrap, imp.panicked(), false, { + imp.src_event(wrap.unsafe_cast_ref(), from_glib_full(event)) + }) + .into_glib() +}