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
9unsafeextern "C" {
10 unsafefn _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);
192