From 33982ccf2c63d6d70a24097e57a58e0e80611b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Fri, 1 Apr 2022 10:52:36 +0300 Subject: [PATCH] audio: Add subclassing bindings for audioaggregator --- .../src/subclass/audio_aggregator.rs | 161 ++++++++++++++++++ .../subclass/audio_aggregator_convert_pad.rs | 10 ++ .../src/subclass/audio_aggregator_pad.rs | 116 +++++++++++++ gstreamer-audio/src/subclass/mod.rs | 18 ++ 4 files changed, 305 insertions(+) create mode 100644 gstreamer-audio/src/subclass/audio_aggregator.rs create mode 100644 gstreamer-audio/src/subclass/audio_aggregator_convert_pad.rs create mode 100644 gstreamer-audio/src/subclass/audio_aggregator_pad.rs diff --git a/gstreamer-audio/src/subclass/audio_aggregator.rs b/gstreamer-audio/src/subclass/audio_aggregator.rs new file mode 100644 index 000000000..4ce58c9a1 --- /dev/null +++ b/gstreamer-audio/src/subclass/audio_aggregator.rs @@ -0,0 +1,161 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::translate::*; + +use gst_base::prelude::*; +use gst_base::subclass::prelude::*; + +use std::ptr; + +use crate::AudioAggregator; +use crate::AudioAggregatorPad; + +pub trait AudioAggregatorImpl: AudioAggregatorImplExt + AggregatorImpl { + fn create_output_buffer(&self, element: &Self::Type, num_frames: u32) -> Option { + self.parent_create_output_buffer(element, num_frames) + } + + #[allow(clippy::too_many_arguments)] + fn aggregate_one_buffer( + &self, + element: &Self::Type, + pad: &AudioAggregatorPad, + inbuf: &gst::BufferRef, + in_offset: u32, + outbuf: &mut gst::BufferRef, + out_offset: u32, + num_frames: u32, + ) -> bool { + self.parent_aggregate_one_buffer( + element, pad, inbuf, in_offset, outbuf, out_offset, num_frames, + ) + } +} + +pub trait AudioAggregatorImplExt: ObjectSubclass { + fn parent_create_output_buffer( + &self, + element: &Self::Type, + num_frames: u32, + ) -> Option; + + #[allow(clippy::too_many_arguments)] + fn parent_aggregate_one_buffer( + &self, + element: &Self::Type, + pad: &AudioAggregatorPad, + inbuf: &gst::BufferRef, + in_offset: u32, + outbuf: &mut gst::BufferRef, + out_offset: u32, + num_frames: u32, + ) -> bool; +} + +impl AudioAggregatorImplExt for T { + fn parent_create_output_buffer( + &self, + element: &Self::Type, + num_frames: u32, + ) -> Option { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorClass; + let f = (*parent_class) + .create_output_buffer + .expect("Missing parent function `create_output_buffer`"); + + from_glib_full(f( + element + .unsafe_cast_ref::() + .to_glib_none() + .0, + num_frames, + )) + } + } + + fn parent_aggregate_one_buffer( + &self, + element: &Self::Type, + pad: &AudioAggregatorPad, + inbuf: &gst::BufferRef, + in_offset: u32, + outbuf: &mut gst::BufferRef, + out_offset: u32, + num_frames: u32, + ) -> bool { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorClass; + let f = (*parent_class) + .aggregate_one_buffer + .expect("Missing parent function `aggregate_one_buffer`"); + + from_glib(f( + element + .unsafe_cast_ref::() + .to_glib_none() + .0, + pad.to_glib_none().0, + inbuf.as_mut_ptr(), + in_offset, + outbuf.as_mut_ptr(), + out_offset, + num_frames, + )) + } + } +} + +unsafe impl IsSubclassable for AudioAggregator { + fn class_init(klass: &mut glib::Class) { + Self::parent_class_init::(klass); + + let klass = klass.as_mut(); + klass.create_output_buffer = Some(audio_aggregator_create_output_buffer::); + klass.aggregate_one_buffer = Some(audio_aggregator_aggregate_one_buffer::); + } +} + +unsafe extern "C" fn audio_aggregator_create_output_buffer( + ptr: *mut ffi::GstAudioAggregator, + num_frames: u32, +) -> *mut gst::ffi::GstBuffer { + 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(), None, { + imp.create_output_buffer(wrap.unsafe_cast_ref(), num_frames) + }) + .map(|buffer| buffer.into_ptr()) + .unwrap_or(ptr::null_mut()) +} + +unsafe extern "C" fn audio_aggregator_aggregate_one_buffer( + ptr: *mut ffi::GstAudioAggregator, + pad: *mut ffi::GstAudioAggregatorPad, + inbuf: *mut gst::ffi::GstBuffer, + in_offset: u32, + outbuf: *mut gst::ffi::GstBuffer, + out_offset: u32, + num_frames: u32, +) -> 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(), true, { + imp.aggregate_one_buffer( + wrap.unsafe_cast_ref(), + &from_glib_borrow(pad), + gst::BufferRef::from_ptr(inbuf), + in_offset, + gst::BufferRef::from_mut_ptr(outbuf), + out_offset, + num_frames, + ) + }) + .into_glib() +} diff --git a/gstreamer-audio/src/subclass/audio_aggregator_convert_pad.rs b/gstreamer-audio/src/subclass/audio_aggregator_convert_pad.rs new file mode 100644 index 000000000..8bff851d6 --- /dev/null +++ b/gstreamer-audio/src/subclass/audio_aggregator_convert_pad.rs @@ -0,0 +1,10 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use gst_base::subclass::prelude::*; + +use super::prelude::AudioAggregatorPadImpl; +use crate::AudioAggregatorConvertPad; + +pub trait AudioAggregatorConvertPadImpl: AudioAggregatorPadImpl {} + +unsafe impl IsSubclassable for AudioAggregatorConvertPad {} diff --git a/gstreamer-audio/src/subclass/audio_aggregator_pad.rs b/gstreamer-audio/src/subclass/audio_aggregator_pad.rs new file mode 100644 index 000000000..3c3831194 --- /dev/null +++ b/gstreamer-audio/src/subclass/audio_aggregator_pad.rs @@ -0,0 +1,116 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use glib::translate::*; + +use gst_base::prelude::*; +use gst_base::subclass::prelude::*; + +use std::ptr; + +use crate::AudioAggregatorPad; + +pub trait AudioAggregatorPadImpl: AudioAggregatorPadImplExt + AggregatorPadImpl { + const HANDLE_CONVERSION: bool = false; + + fn update_conversion_info(&self, pad: &Self::Type) { + self.parent_update_conversion_info(pad) + } + + fn convert_buffer( + &self, + pad: &Self::Type, + in_info: &crate::AudioInfo, + out_info: &crate::AudioInfo, + buffer: &gst::Buffer, + ) -> Option { + self.parent_convert_buffer(pad, in_info, out_info, buffer) + } +} + +pub trait AudioAggregatorPadImplExt: ObjectSubclass { + fn parent_update_conversion_info(&self, pad: &Self::Type); + + fn parent_convert_buffer( + &self, + pad: &Self::Type, + in_info: &crate::AudioInfo, + out_info: &crate::AudioInfo, + buffer: &gst::Buffer, + ) -> Option; +} + +impl AudioAggregatorPadImplExt for T { + fn parent_update_conversion_info(&self, pad: &Self::Type) { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorPadClass; + if let Some(f) = (*parent_class).update_conversion_info { + f(pad.unsafe_cast_ref::().to_glib_none().0); + } + } + } + + fn parent_convert_buffer( + &self, + pad: &Self::Type, + in_info: &crate::AudioInfo, + out_info: &crate::AudioInfo, + buffer: &gst::Buffer, + ) -> Option { + unsafe { + let data = Self::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioAggregatorPadClass; + let f = (*parent_class) + .convert_buffer + .expect("Missing parent function `convert_buffer`"); + from_glib_full(f( + pad.unsafe_cast_ref::().to_glib_none().0, + mut_override(in_info.to_glib_none().0), + mut_override(out_info.to_glib_none().0), + buffer.as_mut_ptr(), + )) + } + } +} + +unsafe impl IsSubclassable for AudioAggregatorPad { + fn class_init(klass: &mut glib::Class) { + Self::parent_class_init::(klass); + + let klass = klass.as_mut(); + if T::HANDLE_CONVERSION { + klass.update_conversion_info = Some(audio_aggregator_pad_update_conversion_info::); + klass.convert_buffer = Some(audio_aggregator_pad_convert_buffer::); + } + } +} + +unsafe extern "C" fn audio_aggregator_pad_update_conversion_info( + ptr: *mut ffi::GstAudioAggregatorPad, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + + imp.update_conversion_info(wrap.unsafe_cast_ref()); +} + +unsafe extern "C" fn audio_aggregator_pad_convert_buffer( + ptr: *mut ffi::GstAudioAggregatorPad, + in_info: *mut ffi::GstAudioInfo, + out_info: *mut ffi::GstAudioInfo, + buffer: *mut gst::ffi::GstBuffer, +) -> *mut gst::ffi::GstBuffer { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + let wrap: Borrowed = from_glib_borrow(ptr); + + imp.convert_buffer( + wrap.unsafe_cast_ref(), + &from_glib_none(in_info), + &from_glib_none(out_info), + &from_glib_borrow(buffer), + ) + .map(|buffer| buffer.into_ptr()) + .unwrap_or(ptr::null_mut()) +} diff --git a/gstreamer-audio/src/subclass/mod.rs b/gstreamer-audio/src/subclass/mod.rs index a5c31ee92..482c11145 100644 --- a/gstreamer-audio/src/subclass/mod.rs +++ b/gstreamer-audio/src/subclass/mod.rs @@ -2,6 +2,15 @@ #![allow(clippy::cast_ptr_alignment)] +#[cfg(any(feature = "v1_14", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] +mod audio_aggregator; +#[cfg(any(feature = "v1_14", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] +mod audio_aggregator_convert_pad; +#[cfg(any(feature = "v1_14", feature = "dox"))] +#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] +mod audio_aggregator_pad; mod audio_base_sink; mod audio_base_src; mod audio_decoder; @@ -13,6 +22,15 @@ pub mod prelude { #[doc(hidden)] pub use gst_base::subclass::prelude::*; + #[cfg(any(feature = "v1_14", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] + pub use super::audio_aggregator::{AudioAggregatorImpl, AudioAggregatorImplExt}; + #[cfg(any(feature = "v1_14", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] + pub use super::audio_aggregator_convert_pad::AudioAggregatorConvertPadImpl; + #[cfg(any(feature = "v1_14", feature = "dox"))] + #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_14")))] + pub use super::audio_aggregator_pad::{AudioAggregatorPadImpl, AudioAggregatorPadImplExt}; pub use super::audio_base_sink::AudioBaseSinkImpl; pub use super::audio_base_src::AudioBaseSrcImpl; pub use super::audio_decoder::{AudioDecoderImpl, AudioDecoderImplExt};