// Take a look at the license at the top of the repository in the LICENSE file. use std::ptr; use glib::translate::*; use gst::subclass::prelude::*; use crate::{prelude::*, RTPBaseDepayload}; pub trait RTPBaseDepayloadImpl: RTPBaseDepayloadImplExt + ElementImpl { fn set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> { self.parent_set_caps(caps) } fn handle_event(&self, event: gst::Event) -> bool { self.parent_handle_event(event) } fn packet_lost(&self, event: &gst::EventRef) -> bool { self.parent_packet_lost(event) } fn process_rtp_packet( &self, rtp_buffer: &crate::RTPBuffer, ) -> Option { self.parent_process_rtp_packet(rtp_buffer) } } mod sealed { pub trait Sealed {} impl Sealed for T {} } pub trait RTPBaseDepayloadImplExt: sealed::Sealed + ObjectSubclass { fn parent_set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBaseDepayloadClass; (*parent_class) .set_caps .map(|f| { gst::result_from_gboolean!( f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, caps.to_glib_none().0 ), gst::CAT_RUST, "Parent function `set_caps` failed" ) }) .unwrap_or(Ok(())) } } fn parent_handle_event(&self, event: gst::Event) -> bool { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBaseDepayloadClass; (*parent_class) .handle_event .map(|f| { from_glib(f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, event.into_glib_ptr(), )) }) .unwrap_or(false) } } fn parent_packet_lost(&self, event: &gst::EventRef) -> bool { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBaseDepayloadClass; (*parent_class) .packet_lost .map(|f| { from_glib(f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, event.as_mut_ptr(), )) }) .unwrap_or(true) } } fn parent_process_rtp_packet( &self, rtp_buffer: &crate::RTPBuffer, ) -> Option { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPBaseDepayloadClass; let f = (*parent_class) .process_rtp_packet .expect("no parent \"process\" implementation"); from_glib_full(f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, mut_override(rtp_buffer.as_ptr()), )) } } } impl RTPBaseDepayloadImplExt for T {} unsafe impl IsSubclassable for RTPBaseDepayload { fn class_init(klass: &mut glib::Class) { Self::parent_class_init::(klass); let klass = klass.as_mut(); klass.process = None; klass.process_rtp_packet = Some(rtp_base_depayload_process_rtp_packet::); klass.set_caps = Some(rtp_base_depayload_set_caps::); klass.handle_event = Some(rtp_base_depayload_handle_event::); klass.packet_lost = Some(rtp_base_depayload_packet_lost::); } } unsafe extern "C" fn rtp_base_depayload_set_caps( ptr: *mut ffi::GstRTPBaseDepayload, caps: *mut gst::ffi::GstCaps, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); let caps = from_glib_borrow(caps); gst::panic_to_error!(imp, false, { match imp.set_caps(&caps) { Ok(()) => true, Err(err) => { err.log_with_imp(imp); false } } }) .into_glib() } unsafe extern "C" fn rtp_base_depayload_handle_event( ptr: *mut ffi::GstRTPBaseDepayload, event: *mut gst::ffi::GstEvent, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, false, { imp.handle_event(from_glib_full(event)) }).into_glib() } unsafe extern "C" fn rtp_base_depayload_packet_lost( ptr: *mut ffi::GstRTPBaseDepayload, event: *mut gst::ffi::GstEvent, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, false, { imp.packet_lost(gst::EventRef::from_ptr(event)) }) .into_glib() } unsafe extern "C" fn rtp_base_depayload_process_rtp_packet( ptr: *mut ffi::GstRTPBaseDepayload, rtp_packet: *mut ffi::GstRTPBuffer, ) -> *mut gst::ffi::GstBuffer { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, ptr::null_mut(), { let bufwrap = crate::RTPBuffer::::from_glib_borrow(rtp_packet); imp.process_rtp_packet(&bufwrap) .map(|buffer| buffer.into_glib_ptr()) .unwrap_or(ptr::null_mut()) }) }