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