gstreamer_audio/
audio_decoder.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{mem, ptr};
4
5use glib::{prelude::*, translate::*};
6
7use crate::{ffi, AudioDecoder, AudioInfo};
8
9extern "C" {
10    fn _gst_audio_decoder_error(
11        dec: *mut ffi::GstAudioDecoder,
12        weight: i32,
13        domain: glib::ffi::GQuark,
14        code: i32,
15        txt: *mut libc::c_char,
16        debug: *mut libc::c_char,
17        file: *const libc::c_char,
18        function: *const libc::c_char,
19        line: i32,
20    ) -> gst::ffi::GstFlowReturn;
21}
22
23mod sealed {
24    pub trait Sealed {}
25    impl<T: super::IsA<super::AudioDecoder>> Sealed for T {}
26}
27
28pub trait AudioDecoderExtManual: sealed::Sealed + IsA<AudioDecoder> + 'static {
29    #[doc(alias = "gst_audio_decoder_negotiate")]
30    fn negotiate(&self) -> Result<(), gst::FlowError> {
31        unsafe {
32            let ret = from_glib(ffi::gst_audio_decoder_negotiate(
33                self.as_ref().to_glib_none().0,
34            ));
35            if ret {
36                Ok(())
37            } else {
38                Err(gst::FlowError::NotNegotiated)
39            }
40        }
41    }
42
43    #[cfg(feature = "v1_16")]
44    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
45    #[doc(alias = "gst_audio_decoder_set_output_caps")]
46    fn set_output_caps(&self, caps: &gst::Caps) -> Result<(), gst::FlowError> {
47        unsafe {
48            let ret = from_glib(ffi::gst_audio_decoder_set_output_caps(
49                self.as_ref().to_glib_none().0,
50                caps.to_glib_none().0,
51            ));
52            if ret {
53                Ok(())
54            } else {
55                Err(gst::FlowError::NotNegotiated)
56            }
57        }
58    }
59
60    #[doc(alias = "gst_audio_decoder_set_output_format")]
61    fn set_output_format(&self, info: &AudioInfo) -> Result<(), gst::FlowError> {
62        unsafe {
63            let ret = from_glib(ffi::gst_audio_decoder_set_output_format(
64                self.as_ref().to_glib_none().0,
65                info.to_glib_none().0,
66            ));
67            if ret {
68                Ok(())
69            } else {
70                Err(gst::FlowError::NotNegotiated)
71            }
72        }
73    }
74
75    #[doc(alias = "get_allocator")]
76    #[doc(alias = "gst_audio_decoder_get_allocator")]
77    fn allocator(&self) -> (Option<gst::Allocator>, gst::AllocationParams) {
78        unsafe {
79            let mut allocator = ptr::null_mut();
80            let mut params = mem::MaybeUninit::uninit();
81            ffi::gst_audio_decoder_get_allocator(
82                self.as_ref().to_glib_none().0,
83                &mut allocator,
84                params.as_mut_ptr(),
85            );
86            (from_glib_full(allocator), params.assume_init().into())
87        }
88    }
89
90    #[allow(clippy::too_many_arguments)]
91    fn error<T: gst::MessageErrorDomain>(
92        &self,
93        weight: i32,
94        code: T,
95        message: Option<&str>,
96        debug: Option<&str>,
97        file: &str,
98        function: &str,
99        line: u32,
100    ) -> Result<gst::FlowSuccess, gst::FlowError> {
101        unsafe {
102            try_from_glib(_gst_audio_decoder_error(
103                self.as_ref().to_glib_none().0,
104                weight,
105                T::domain().into_glib(),
106                code.code(),
107                message.to_glib_full(),
108                debug.to_glib_full(),
109                file.to_glib_none().0,
110                function.to_glib_none().0,
111                line as i32,
112            ))
113        }
114    }
115
116    fn sink_pad(&self) -> &gst::Pad {
117        unsafe {
118            let elt = &*(self.as_ptr() as *const ffi::GstAudioDecoder);
119            &*(&elt.sinkpad as *const *mut gst::ffi::GstPad as *const gst::Pad)
120        }
121    }
122
123    fn src_pad(&self) -> &gst::Pad {
124        unsafe {
125            let elt = &*(self.as_ptr() as *const ffi::GstAudioDecoder);
126            &*(&elt.srcpad as *const *mut gst::ffi::GstPad as *const gst::Pad)
127        }
128    }
129
130    fn input_segment(&self) -> gst::Segment {
131        unsafe {
132            let ptr: &ffi::GstAudioDecoder = &*(self.as_ptr() as *const _);
133            glib::ffi::g_rec_mutex_lock(mut_override(&ptr.stream_lock));
134            let segment = ptr.input_segment;
135            glib::ffi::g_rec_mutex_unlock(mut_override(&ptr.stream_lock));
136            from_glib_none(&segment as *const gst::ffi::GstSegment)
137        }
138    }
139
140    fn output_segment(&self) -> gst::Segment {
141        unsafe {
142            let ptr: &ffi::GstAudioDecoder = &*(self.as_ptr() as *const _);
143            glib::ffi::g_rec_mutex_lock(mut_override(&ptr.stream_lock));
144            let segment = ptr.output_segment;
145            glib::ffi::g_rec_mutex_unlock(mut_override(&ptr.stream_lock));
146            from_glib_none(&segment as *const gst::ffi::GstSegment)
147        }
148    }
149}
150
151impl<O: IsA<AudioDecoder>> AudioDecoderExtManual for O {}
152
153#[macro_export]
154macro_rules! audio_decoder_error(
155    ($obj:expr, $weight:expr, $err:expr, ($($msg:tt)*), [$($debug:tt)*]) => { {
156        use $crate::prelude::AudioDecoderExtManual;
157        $obj.error(
158            $weight,
159            $err,
160            Some(&format!($($msg)*)),
161            Some(&format!($($debug)*)),
162            file!(),
163            $crate::glib::function_name!(),
164            line!(),
165        )
166    }};
167    ($obj:expr, $weight:expr, $err:expr, ($($msg:tt)*)) => { {
168        use $crate::prelude::AudioDecoderExtManual;
169        $obj.error(
170            $weight,
171            $err,
172            Some(&format!($($msg)*)),
173            None,
174            file!(),
175            $crate::glib::function_name!(),
176            line!(),
177        )
178    }};
179    ($obj:expr, $weight:expr, $err:expr, [$($debug:tt)*]) => { {
180        use $crate::prelude::AudioDecoderExtManual;
181        $obj.error(
182            $weight,
183            $err,
184            None,
185            Some(&format!($($debug)*)),
186            file!(),
187            $crate::glib::function_name!(),
188            line!(),
189        )
190    }};
191);