// Take a look at the license at the top of the repository in the LICENSE file. use glib::{prelude::*, subclass::prelude::*, translate::*}; use super::prelude::*; pub trait RTPHeaderExtensionImpl: RTPHeaderExtensionImplExt + ElementImpl { const URI: &'static str; fn supported_flags(&self) -> crate::RTPHeaderExtensionFlags { self.parent_supported_flags() } fn max_size(&self, input: &gst::BufferRef) -> usize { self.parent_max_size(input) } fn write( &self, input: &gst::BufferRef, write_flags: crate::RTPHeaderExtensionFlags, output: &gst::BufferRef, output_data: &mut [u8], ) -> Result { self.parent_write(input, write_flags, output, output_data) } fn read( &self, read_flags: crate::RTPHeaderExtensionFlags, input_data: &[u8], output: &mut gst::BufferRef, ) -> Result<(), gst::LoggableError> { self.parent_read(read_flags, input_data, output) } fn set_non_rtp_sink_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> { self.parent_set_non_rtp_sink_caps(caps) } fn update_non_rtp_src_caps(&self, caps: &mut gst::CapsRef) -> Result<(), gst::LoggableError> { self.parent_update_non_rtp_src_caps(caps) } fn set_attributes( &self, direction: crate::RTPHeaderExtensionDirection, attributes: &str, ) -> Result<(), gst::LoggableError> { self.parent_set_attributes(direction, attributes) } fn set_caps_from_attributes(&self, caps: &mut gst::CapsRef) -> Result<(), gst::LoggableError> { self.parent_set_caps_from_attributes(caps) } } mod sealed { pub trait Sealed {} impl Sealed for T {} } pub trait RTPHeaderExtensionImplExt: sealed::Sealed + ObjectSubclass { fn parent_supported_flags(&self) -> crate::RTPHeaderExtensionFlags { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass; let f = (*parent_class) .get_supported_flags .expect("no parent \"get_supported_flags\" implementation"); from_glib(f(self .obj() .unsafe_cast_ref::() .to_glib_none() .0)) } } fn parent_max_size(&self, input: &gst::BufferRef) -> usize { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass; let f = (*parent_class) .get_max_size .expect("no parent \"get_max_size\" implementation"); f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, input.as_ptr(), ) } } fn parent_write( &self, input: &gst::BufferRef, write_flags: crate::RTPHeaderExtensionFlags, output: &gst::BufferRef, output_data: &mut [u8], ) -> Result { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass; let f = (*parent_class) .write .expect("no parent \"write\" implementation"); let res = f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, input.as_ptr(), write_flags.into_glib(), mut_override(output.as_ptr()), output_data.as_mut_ptr(), output_data.len(), ); if res < 0 { Err(gst::loggable_error!( gst::CAT_RUST, "Failed to write extension data" )) } else { Ok(res as usize) } } } fn parent_read( &self, read_flags: crate::RTPHeaderExtensionFlags, input_data: &[u8], output: &mut gst::BufferRef, ) -> Result<(), gst::LoggableError> { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass; let f = (*parent_class) .read .expect("no parent \"read\" implementation"); gst::result_from_gboolean!( f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, read_flags.into_glib(), input_data.as_ptr(), input_data.len(), output.as_mut_ptr(), ), gst::CAT_RUST, "Failed to read extension data", ) } } fn parent_set_non_rtp_sink_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::GstRTPHeaderExtensionClass; if let Some(f) = (*parent_class).set_non_rtp_sink_caps { gst::result_from_gboolean!( f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, caps.as_mut_ptr(), ), gst::CAT_RUST, "Failed to set non-RTP sink caps", ) } else { Ok(()) } } } fn parent_update_non_rtp_src_caps( &self, caps: &mut gst::CapsRef, ) -> Result<(), gst::LoggableError> { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass; if let Some(f) = (*parent_class).update_non_rtp_src_caps { gst::result_from_gboolean!( f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, caps.as_mut_ptr(), ), gst::CAT_RUST, "Failed to update non-RTP source caps", ) } else { Ok(()) } } } fn parent_set_attributes( &self, direction: crate::RTPHeaderExtensionDirection, attributes: &str, ) -> Result<(), gst::LoggableError> { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass; if let Some(f) = (*parent_class).set_attributes { gst::result_from_gboolean!( f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, direction.into_glib(), attributes.to_glib_none().0, ), gst::CAT_RUST, "Failed to set attributes", ) } else { Ok(()) } } } fn parent_set_caps_from_attributes( &self, caps: &mut gst::CapsRef, ) -> Result<(), gst::LoggableError> { unsafe { let data = Self::type_data(); let parent_class = data.as_ref().parent_class() as *mut ffi::GstRTPHeaderExtensionClass; let f = (*parent_class) .set_caps_from_attributes .expect("no parent \"set_caps_from_attributes\" implementation"); gst::result_from_gboolean!( f( self.obj() .unsafe_cast_ref::() .to_glib_none() .0, caps.as_mut_ptr(), ), gst::CAT_RUST, "Failed to set caps from attributes", ) } } } impl RTPHeaderExtensionImplExt for T {} unsafe impl IsSubclassable for crate::RTPHeaderExtension { fn class_init(klass: &mut glib::Class) { Self::parent_class_init::(klass); let klass = klass.as_mut(); klass.get_supported_flags = Some(get_supported_flags::); klass.get_max_size = Some(get_max_size::); klass.write = Some(write::); klass.read = Some(read::); klass.set_non_rtp_sink_caps = Some(set_non_rtp_sink_caps::); klass.update_non_rtp_src_caps = Some(update_non_rtp_src_caps::); klass.set_attributes = Some(set_attributes::); klass.set_caps_from_attributes = Some(set_caps_from_attributes::); unsafe { ffi::gst_rtp_header_extension_class_set_uri(&mut *klass, T::URI.to_glib_none().0); } } } unsafe extern "C" fn get_supported_flags( ptr: *mut ffi::GstRTPHeaderExtension, ) -> ffi::GstRTPHeaderExtensionFlags { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, crate::RTPHeaderExtensionFlags::empty(), { imp.supported_flags() }) .into_glib() } unsafe extern "C" fn get_max_size( ptr: *mut ffi::GstRTPHeaderExtension, input: *const gst::ffi::GstBuffer, ) -> usize { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, 0, { imp.max_size(gst::BufferRef::from_ptr(input)) }) } unsafe extern "C" fn write( ptr: *mut ffi::GstRTPHeaderExtension, input: *const gst::ffi::GstBuffer, write_flags: ffi::GstRTPHeaderExtensionFlags, output: *mut gst::ffi::GstBuffer, output_data: *mut u8, output_data_len: usize, ) -> isize { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, -1, { match imp.write( gst::BufferRef::from_ptr(input), from_glib(write_flags), gst::BufferRef::from_ptr(output), if output_data_len == 0 { &mut [] } else { std::slice::from_raw_parts_mut(output_data, output_data_len) }, ) { Ok(len) => len as isize, Err(err) => { err.log_with_imp(imp); -1 } } }) } unsafe extern "C" fn read( ptr: *mut ffi::GstRTPHeaderExtension, read_flags: ffi::GstRTPHeaderExtensionFlags, input_data: *const u8, input_data_len: usize, output: *mut gst::ffi::GstBuffer, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, false, { match imp.read( from_glib(read_flags), if input_data_len == 0 { &[] } else { std::slice::from_raw_parts(input_data, input_data_len) }, gst::BufferRef::from_mut_ptr(output), ) { Ok(_) => true, Err(err) => { err.log_with_imp(imp); false } } }) .into_glib() } unsafe extern "C" fn set_non_rtp_sink_caps( ptr: *mut ffi::GstRTPHeaderExtension, caps: *mut gst::ffi::GstCaps, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, false, { match imp.set_non_rtp_sink_caps(&from_glib_borrow(caps)) { Ok(_) => true, Err(err) => { err.log_with_imp(imp); false } } }) .into_glib() } unsafe extern "C" fn update_non_rtp_src_caps( ptr: *mut ffi::GstRTPHeaderExtension, caps: *mut gst::ffi::GstCaps, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, false, { match imp.update_non_rtp_src_caps(gst::CapsRef::from_mut_ptr(caps)) { Ok(_) => true, Err(err) => { err.log_with_imp(imp); false } } }) .into_glib() } unsafe extern "C" fn set_attributes( ptr: *mut ffi::GstRTPHeaderExtension, direction: ffi::GstRTPHeaderExtensionDirection, attributes: *const libc::c_char, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, false, { match imp.set_attributes( from_glib(direction), &glib::GString::from_glib_borrow(attributes), ) { Ok(_) => true, Err(err) => { err.log_with_imp(imp); false } } }) .into_glib() } unsafe extern "C" fn set_caps_from_attributes( ptr: *mut ffi::GstRTPHeaderExtension, caps: *mut gst::ffi::GstCaps, ) -> glib::ffi::gboolean { let instance = &*(ptr as *mut T::Instance); let imp = instance.imp(); gst::panic_to_error!(imp, false, { match imp.set_caps_from_attributes(gst::CapsRef::from_mut_ptr(caps)) { Ok(_) => true, Err(err) => { err.log_with_imp(imp); false } } }) .into_glib() }