forked from mirrors/gstreamer-rs
pbutils: Add bindings for the AudioVisualizer base class
This commit is contained in:
parent
44d899a0eb
commit
6163914605
9 changed files with 545 additions and 0 deletions
|
@ -19,6 +19,8 @@ libc = "0.2"
|
|||
ffi = { package = "gstreamer-pbutils-sys", path = "sys" }
|
||||
glib = { git = "https://github.com/gtk-rs/gtk-rs-core" }
|
||||
gst = { package = "gstreamer", path = "../gstreamer" }
|
||||
gst-video = { package = "gstreamer-video", path = "../gstreamer-video" }
|
||||
gst-audio = { package = "gstreamer-audio", path = "../gstreamer-audio" }
|
||||
thiserror = "1.0"
|
||||
serde = { version = "1.0", optional = true }
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@ external_libraries = [
|
|||
]
|
||||
|
||||
generate = [
|
||||
"GstPbutils.AudioVisualizer",
|
||||
"GstPbutils.AudioVisualizerShader",
|
||||
"GstPbutils.DiscovererResult",
|
||||
"GstPbutils.PbUtilsCapsDescriptionFlags",
|
||||
]
|
||||
|
|
72
gstreamer-pbutils/src/audio_visualizer.rs
Normal file
72
gstreamer-pbutils/src/audio_visualizer.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use crate::auto::AudioVisualizer;
|
||||
use crate::subclass::AudioVisualizerSetupToken;
|
||||
use glib::object::IsA;
|
||||
use gst::prelude::*;
|
||||
|
||||
pub trait AudioVisualizerExtManual: 'static {
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Returns the number of samples per frame required before calling the render method
|
||||
fn req_spf(&self) -> u32;
|
||||
|
||||
// rustdoc-stripper-ignore-next
|
||||
/// Modify the request of samples per frame required to be present in buffer before calling
|
||||
/// the render method
|
||||
fn set_req_spf(&self, spf: u32, token: &AudioVisualizerSetupToken);
|
||||
|
||||
fn audio_info(&self) -> gst_audio::AudioInfo;
|
||||
|
||||
fn video_info(&self) -> gst_video::VideoInfo;
|
||||
}
|
||||
|
||||
impl<O: IsA<AudioVisualizer> + ElementExt> AudioVisualizerExtManual for O {
|
||||
fn req_spf(&self) -> u32 {
|
||||
let sinkpad = self.static_pad("sink").expect("sink pad presence");
|
||||
let _stream_lock = sinkpad.stream_lock();
|
||||
|
||||
let ptr = self.as_ptr() as *mut ffi::GstAudioVisualizer;
|
||||
unsafe { (*ptr).req_spf }
|
||||
}
|
||||
|
||||
fn set_req_spf(&self, spf: u32, token: &AudioVisualizerSetupToken) {
|
||||
assert_eq!(
|
||||
self.as_ptr() as *mut ffi::GstAudioVisualizer,
|
||||
token.0.as_ptr() as *mut ffi::GstAudioVisualizer
|
||||
);
|
||||
|
||||
let sinkpad = self.static_pad("sink").expect("sink pad presence");
|
||||
let _stream_lock = sinkpad.stream_lock();
|
||||
|
||||
let mut ptr = self.as_ptr() as *mut ffi::GstAudioVisualizer;
|
||||
unsafe {
|
||||
(*ptr).req_spf = spf;
|
||||
}
|
||||
}
|
||||
|
||||
fn audio_info(&self) -> gst_audio::AudioInfo {
|
||||
let sinkpad = self.static_pad("sink").expect("sink pad presence");
|
||||
let _stream_lock = sinkpad.stream_lock();
|
||||
|
||||
let ptr = self.as_ptr() as *mut ffi::GstAudioVisualizer;
|
||||
unsafe {
|
||||
let info = &(*ptr).ainfo;
|
||||
glib::translate::from_glib_none(glib::translate::mut_override(
|
||||
info as *const gst_audio::ffi::GstAudioInfo,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn video_info(&self) -> gst_video::VideoInfo {
|
||||
let srcpad = self.static_pad("src").expect("src pad presence");
|
||||
let _stream_lock = srcpad.stream_lock();
|
||||
|
||||
let ptr = self.as_ptr() as *mut ffi::GstAudioVisualizer;
|
||||
unsafe {
|
||||
let info = &(*ptr).vinfo;
|
||||
glib::translate::from_glib_none(glib::translate::mut_override(
|
||||
info as *const gst_video::ffi::GstVideoInfo,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
123
gstreamer-pbutils/src/auto/audio_visualizer.rs
Normal file
123
gstreamer-pbutils/src/auto/audio_visualizer.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
// 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
|
||||
|
||||
use crate::AudioVisualizerShader;
|
||||
use glib::object::Cast;
|
||||
use glib::object::IsA;
|
||||
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 = "GstAudioVisualizer")]
|
||||
pub struct AudioVisualizer(Object<ffi::GstAudioVisualizer, ffi::GstAudioVisualizerClass>) @extends gst::Element, gst::Object;
|
||||
|
||||
match fn {
|
||||
type_ => || ffi::gst_audio_visualizer_get_type(),
|
||||
}
|
||||
}
|
||||
|
||||
impl AudioVisualizer {
|
||||
pub const NONE: Option<&'static AudioVisualizer> = None;
|
||||
}
|
||||
|
||||
unsafe impl Send for AudioVisualizer {}
|
||||
unsafe impl Sync for AudioVisualizer {}
|
||||
|
||||
pub trait AudioVisualizerExt: 'static {
|
||||
#[doc(alias = "shade-amount")]
|
||||
fn shade_amount(&self) -> u32;
|
||||
|
||||
#[doc(alias = "shade-amount")]
|
||||
fn set_shade_amount(&self, shade_amount: u32);
|
||||
|
||||
fn shader(&self) -> AudioVisualizerShader;
|
||||
|
||||
fn set_shader(&self, shader: AudioVisualizerShader);
|
||||
|
||||
#[doc(alias = "shade-amount")]
|
||||
fn connect_shade_amount_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId;
|
||||
|
||||
#[doc(alias = "shader")]
|
||||
fn connect_shader_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
|
||||
}
|
||||
|
||||
impl<O: IsA<AudioVisualizer>> AudioVisualizerExt for O {
|
||||
fn shade_amount(&self) -> u32 {
|
||||
glib::ObjectExt::property(self.as_ref(), "shade-amount")
|
||||
}
|
||||
|
||||
fn set_shade_amount(&self, shade_amount: u32) {
|
||||
glib::ObjectExt::set_property(self.as_ref(), "shade-amount", &shade_amount)
|
||||
}
|
||||
|
||||
fn shader(&self) -> AudioVisualizerShader {
|
||||
glib::ObjectExt::property(self.as_ref(), "shader")
|
||||
}
|
||||
|
||||
fn set_shader(&self, shader: AudioVisualizerShader) {
|
||||
glib::ObjectExt::set_property(self.as_ref(), "shader", &shader)
|
||||
}
|
||||
|
||||
fn connect_shade_amount_notify<F: Fn(&Self) + Send + Sync + 'static>(
|
||||
&self,
|
||||
f: F,
|
||||
) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_shade_amount_trampoline<
|
||||
P: IsA<AudioVisualizer>,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GstAudioVisualizer,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
) {
|
||||
let f: &F = &*(f as *const F);
|
||||
f(AudioVisualizer::from_glib_borrow(this).unsafe_cast_ref())
|
||||
}
|
||||
unsafe {
|
||||
let f: Box_<F> = Box_::new(f);
|
||||
connect_raw(
|
||||
self.as_ptr() as *mut _,
|
||||
b"notify::shade-amount\0".as_ptr() as *const _,
|
||||
Some(transmute::<_, unsafe extern "C" fn()>(
|
||||
notify_shade_amount_trampoline::<Self, F> as *const (),
|
||||
)),
|
||||
Box_::into_raw(f),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn connect_shader_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
|
||||
unsafe extern "C" fn notify_shader_trampoline<
|
||||
P: IsA<AudioVisualizer>,
|
||||
F: Fn(&P) + Send + Sync + 'static,
|
||||
>(
|
||||
this: *mut ffi::GstAudioVisualizer,
|
||||
_param_spec: glib::ffi::gpointer,
|
||||
f: glib::ffi::gpointer,
|
||||
) {
|
||||
let f: &F = &*(f as *const F);
|
||||
f(AudioVisualizer::from_glib_borrow(this).unsafe_cast_ref())
|
||||
}
|
||||
unsafe {
|
||||
let f: Box_<F> = Box_::new(f);
|
||||
connect_raw(
|
||||
self.as_ptr() as *mut _,
|
||||
b"notify::shader\0".as_ptr() as *const _,
|
||||
Some(transmute::<_, unsafe extern "C" fn()>(
|
||||
notify_shader_trampoline::<Self, F> as *const (),
|
||||
)),
|
||||
Box_::into_raw(f),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,6 +9,108 @@ use glib::value::ToValue;
|
|||
use glib::StaticType;
|
||||
use glib::Type;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
|
||||
#[non_exhaustive]
|
||||
#[doc(alias = "GstAudioVisualizerShader")]
|
||||
pub enum AudioVisualizerShader {
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_NONE")]
|
||||
None,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE")]
|
||||
Fade,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP")]
|
||||
FadeAndMoveUp,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN")]
|
||||
FadeAndMoveDown,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT")]
|
||||
FadeAndMoveLeft,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT")]
|
||||
FadeAndMoveRight,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT")]
|
||||
FadeAndMoveHorizOut,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN")]
|
||||
FadeAndMoveHorizIn,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT")]
|
||||
FadeAndMoveVertOut,
|
||||
#[doc(alias = "GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN")]
|
||||
FadeAndMoveVertIn,
|
||||
#[doc(hidden)]
|
||||
__Unknown(i32),
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl IntoGlib for AudioVisualizerShader {
|
||||
type GlibType = ffi::GstAudioVisualizerShader;
|
||||
|
||||
fn into_glib(self) -> ffi::GstAudioVisualizerShader {
|
||||
match self {
|
||||
Self::None => ffi::GST_AUDIO_VISUALIZER_SHADER_NONE,
|
||||
Self::Fade => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE,
|
||||
Self::FadeAndMoveUp => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP,
|
||||
Self::FadeAndMoveDown => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN,
|
||||
Self::FadeAndMoveLeft => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT,
|
||||
Self::FadeAndMoveRight => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT,
|
||||
Self::FadeAndMoveHorizOut => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT,
|
||||
Self::FadeAndMoveHorizIn => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN,
|
||||
Self::FadeAndMoveVertOut => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT,
|
||||
Self::FadeAndMoveVertIn => ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN,
|
||||
Self::__Unknown(value) => value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl FromGlib<ffi::GstAudioVisualizerShader> for AudioVisualizerShader {
|
||||
unsafe fn from_glib(value: ffi::GstAudioVisualizerShader) -> Self {
|
||||
skip_assert_initialized!();
|
||||
match value {
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_NONE => Self::None,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE => Self::Fade,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_UP => Self::FadeAndMoveUp,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_DOWN => Self::FadeAndMoveDown,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_LEFT => Self::FadeAndMoveLeft,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_RIGHT => Self::FadeAndMoveRight,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_OUT => Self::FadeAndMoveHorizOut,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_HORIZ_IN => Self::FadeAndMoveHorizIn,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_OUT => Self::FadeAndMoveVertOut,
|
||||
ffi::GST_AUDIO_VISUALIZER_SHADER_FADE_AND_MOVE_VERT_IN => Self::FadeAndMoveVertIn,
|
||||
value => Self::__Unknown(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StaticType for AudioVisualizerShader {
|
||||
fn static_type() -> Type {
|
||||
unsafe { from_glib(ffi::gst_audio_visualizer_shader_get_type()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl glib::value::ValueType for AudioVisualizerShader {
|
||||
type Type = Self;
|
||||
}
|
||||
|
||||
unsafe impl<'a> FromValue<'a> for AudioVisualizerShader {
|
||||
type Checker = glib::value::GenericValueTypeChecker<Self>;
|
||||
|
||||
unsafe fn from_value(value: &'a glib::Value) -> Self {
|
||||
skip_assert_initialized!();
|
||||
from_glib(glib::gobject_ffi::g_value_get_enum(value.to_glib_none().0))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToValue for AudioVisualizerShader {
|
||||
fn to_value(&self) -> glib::Value {
|
||||
let mut value = glib::Value::for_value_type::<Self>();
|
||||
unsafe {
|
||||
glib::gobject_ffi::g_value_set_enum(value.to_glib_none_mut().0, self.into_glib());
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
fn value_type(&self) -> glib::Type {
|
||||
Self::static_type()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Copy)]
|
||||
#[non_exhaustive]
|
||||
#[doc(alias = "GstDiscovererResult")]
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
|
||||
// DO NOT EDIT
|
||||
|
||||
mod audio_visualizer;
|
||||
pub use self::audio_visualizer::AudioVisualizer;
|
||||
|
||||
mod discoverer;
|
||||
pub use self::discoverer::Discoverer;
|
||||
|
||||
|
@ -40,6 +43,7 @@ mod encoding_video_profile;
|
|||
pub use self::encoding_video_profile::EncodingVideoProfile;
|
||||
|
||||
mod enums;
|
||||
pub use self::enums::AudioVisualizerShader;
|
||||
pub use self::enums::DiscovererResult;
|
||||
|
||||
mod flags;
|
||||
|
@ -52,6 +56,7 @@ pub mod functions;
|
|||
|
||||
#[doc(hidden)]
|
||||
pub mod traits {
|
||||
pub use super::audio_visualizer::AudioVisualizerExt;
|
||||
pub use super::discoverer_stream_info::DiscovererStreamInfoExt;
|
||||
pub use super::encoding_profile::EncodingProfileExt;
|
||||
}
|
||||
|
|
|
@ -57,12 +57,17 @@ pub mod encoding_profile;
|
|||
pub mod functions;
|
||||
pub use crate::functions::*;
|
||||
|
||||
pub mod subclass;
|
||||
|
||||
pub mod audio_visualizer;
|
||||
|
||||
// Re-export all the traits in a prelude module, so that applications
|
||||
// can always "use gst_pbutils::prelude::*" without getting conflicts
|
||||
pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use gst::prelude::*;
|
||||
|
||||
pub use crate::audio_visualizer::*;
|
||||
pub use crate::auto::traits::*;
|
||||
pub use crate::encoding_profile::{
|
||||
EncodingProfileBuilder, EncodingProfileHasRestrictionGetter,
|
||||
|
|
226
gstreamer-pbutils/src/subclass/audio_visualizer.rs
Normal file
226
gstreamer-pbutils/src/subclass/audio_visualizer.rs
Normal file
|
@ -0,0 +1,226 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use glib::prelude::*;
|
||||
use glib::translate::*;
|
||||
use gst::subclass::prelude::*;
|
||||
use gst::{result_from_gboolean, LoggableError, CAT_RUST};
|
||||
|
||||
use crate::AudioVisualizer;
|
||||
|
||||
pub struct AudioVisualizerSetupToken<'a>(pub(crate) &'a AudioVisualizer);
|
||||
|
||||
pub trait AudioVisualizerImpl: AudioVisualizerImplExt + ElementImpl {
|
||||
fn setup(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
token: &AudioVisualizerSetupToken,
|
||||
) -> Result<(), LoggableError> {
|
||||
self.parent_setup(element, token)
|
||||
}
|
||||
|
||||
fn render(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
audio_buffer: &gst::BufferRef,
|
||||
video_frame: &mut gst_video::VideoFrameRef<&mut gst::BufferRef>,
|
||||
) -> Result<(), LoggableError> {
|
||||
self.parent_render(element, audio_buffer, video_frame)
|
||||
}
|
||||
|
||||
fn decide_allocation(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
query: &mut gst::query::Allocation,
|
||||
) -> Result<(), gst::LoggableError> {
|
||||
self.parent_decide_allocation(element, query)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AudioVisualizerImplExt: ObjectSubclass {
|
||||
fn parent_setup(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
token: &AudioVisualizerSetupToken,
|
||||
) -> Result<(), LoggableError>;
|
||||
|
||||
fn parent_render(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
audio_buffer: &gst::BufferRef,
|
||||
video_frame: &mut gst_video::VideoFrameRef<&mut gst::BufferRef>,
|
||||
) -> Result<(), LoggableError>;
|
||||
|
||||
fn parent_decide_allocation(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
query: &mut gst::query::Allocation,
|
||||
) -> Result<(), gst::LoggableError>;
|
||||
}
|
||||
|
||||
impl<T: AudioVisualizerImpl> AudioVisualizerImplExt for T {
|
||||
fn parent_setup(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
token: &AudioVisualizerSetupToken,
|
||||
) -> Result<(), LoggableError> {
|
||||
assert_eq!(
|
||||
element.as_ptr() as *mut ffi::GstAudioVisualizer,
|
||||
token.0.as_ptr() as *mut ffi::GstAudioVisualizer
|
||||
);
|
||||
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioVisualizerClass;
|
||||
(*parent_class)
|
||||
.setup
|
||||
.map(|f| {
|
||||
result_from_gboolean!(
|
||||
f(element
|
||||
.unsafe_cast_ref::<AudioVisualizer>()
|
||||
.to_glib_none()
|
||||
.0,),
|
||||
CAT_RUST,
|
||||
"Parent function `setup` failed",
|
||||
)
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_render(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
audio_buffer: &gst::BufferRef,
|
||||
video_frame: &mut gst_video::VideoFrameRef<&mut gst::BufferRef>,
|
||||
) -> Result<(), LoggableError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioVisualizerClass;
|
||||
(*parent_class)
|
||||
.render
|
||||
.map(|f| {
|
||||
result_from_gboolean!(
|
||||
f(
|
||||
element
|
||||
.unsafe_cast_ref::<AudioVisualizer>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
audio_buffer.as_mut_ptr(),
|
||||
video_frame.as_mut_ptr(),
|
||||
),
|
||||
CAT_RUST,
|
||||
"Parent function `render` failed",
|
||||
)
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_decide_allocation(
|
||||
&self,
|
||||
element: &Self::Type,
|
||||
query: &mut gst::query::Allocation,
|
||||
) -> Result<(), gst::LoggableError> {
|
||||
unsafe {
|
||||
let data = Self::type_data();
|
||||
let parent_class = data.as_ref().parent_class() as *mut ffi::GstAudioVisualizerClass;
|
||||
(*parent_class)
|
||||
.decide_allocation
|
||||
.map(|f| {
|
||||
gst::result_from_gboolean!(
|
||||
f(
|
||||
element
|
||||
.unsafe_cast_ref::<AudioVisualizer>()
|
||||
.to_glib_none()
|
||||
.0,
|
||||
query.as_mut_ptr(),
|
||||
),
|
||||
gst::CAT_RUST,
|
||||
"Parent function `decide_allocation` failed",
|
||||
)
|
||||
})
|
||||
.unwrap_or(Ok(()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T: AudioVisualizerImpl> IsSubclassable<T> for AudioVisualizer {
|
||||
fn class_init(klass: &mut glib::Class<Self>) {
|
||||
Self::parent_class_init::<T>(klass);
|
||||
let klass = klass.as_mut();
|
||||
klass.setup = Some(audio_visualizer_setup::<T>);
|
||||
klass.render = Some(audio_visualizer_render::<T>);
|
||||
klass.decide_allocation = Some(audio_visualizer_decide_allocation::<T>);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn audio_visualizer_setup<T: AudioVisualizerImpl>(
|
||||
ptr: *mut ffi::GstAudioVisualizer,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.imp();
|
||||
let wrap: Borrowed<AudioVisualizer> = from_glib_borrow(ptr);
|
||||
|
||||
gst::panic_to_error!(&wrap, imp.panicked(), false, {
|
||||
let token = AudioVisualizerSetupToken(&*wrap);
|
||||
|
||||
match imp.setup(wrap.unsafe_cast_ref(), &token) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
err.log_with_object(&*wrap);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn audio_visualizer_render<T: AudioVisualizerImpl>(
|
||||
ptr: *mut ffi::GstAudioVisualizer,
|
||||
audio_buffer: *mut gst::ffi::GstBuffer,
|
||||
video_frame: *mut gst_video::ffi::GstVideoFrame,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.imp();
|
||||
let wrap: Borrowed<AudioVisualizer> = from_glib_borrow(ptr);
|
||||
let buffer = gst::BufferRef::from_ptr(audio_buffer);
|
||||
|
||||
gst::panic_to_error!(&wrap, imp.panicked(), false, {
|
||||
match imp.render(
|
||||
wrap.unsafe_cast_ref(),
|
||||
buffer,
|
||||
&mut gst_video::VideoFrameRef::from_glib_borrow_mut(video_frame),
|
||||
) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
err.log_with_object(&*wrap);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn audio_visualizer_decide_allocation<T: AudioVisualizerImpl>(
|
||||
ptr: *mut ffi::GstAudioVisualizer,
|
||||
query: *mut gst::ffi::GstQuery,
|
||||
) -> gst::ffi::GstFlowReturn {
|
||||
let instance = &*(ptr as *mut T::Instance);
|
||||
let imp = instance.imp();
|
||||
let wrap: Borrowed<AudioVisualizer> = from_glib_borrow(ptr);
|
||||
let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
|
||||
gst::QueryViewMut::Allocation(allocation) => allocation,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
gst::panic_to_error!(&wrap, imp.panicked(), false, {
|
||||
match imp.decide_allocation(wrap.unsafe_cast_ref(), query) {
|
||||
Ok(()) => true,
|
||||
Err(err) => {
|
||||
err.log_with_object(&*wrap);
|
||||
false
|
||||
}
|
||||
}
|
||||
})
|
||||
.into_glib()
|
||||
}
|
8
gstreamer-pbutils/src/subclass/mod.rs
Normal file
8
gstreamer-pbutils/src/subclass/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
mod audio_visualizer;
|
||||
pub use audio_visualizer::AudioVisualizerSetupToken;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::audio_visualizer::{AudioVisualizerImpl, AudioVisualizerImplExt};
|
||||
}
|
Loading…
Reference in a new issue