1 // Take a look at the license at the top of the repository in the LICENSE file.
2
3 use crate::AudioChannelPosition;
4
5 use std::mem;
6
7 use glib::translate::{from_glib, IntoGlib};
8
9 impl AudioChannelPosition {
to_mask(self) -> u6410 pub fn to_mask(self) -> u64 {
11 let pos = self.into_glib();
12 if pos < 0 {
13 return 0;
14 }
15
16 1 << (pos as u32)
17 }
18
19 #[doc(alias = "gst_audio_channel_positions_to_mask")]
positions_to_mask( positions: &[Self], force_order: bool, ) -> Result<u64, glib::error::BoolError>20 pub fn positions_to_mask(
21 positions: &[Self],
22 force_order: bool,
23 ) -> Result<u64, glib::error::BoolError> {
24 assert_initialized_main_thread!();
25
26 let len = positions.len();
27 if len > 64 {
28 return Err(glib::bool_error!("Invalid number of channels"));
29 }
30
31 let positions_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
32 if i >= len as usize {
33 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
34 } else {
35 positions[i].into_glib()
36 }
37 });
38
39 unsafe {
40 let mut mask = mem::MaybeUninit::uninit();
41 let valid: bool = from_glib(ffi::gst_audio_channel_positions_to_mask(
42 positions_raw.as_ptr() as *mut _,
43 len as i32,
44 force_order.into_glib(),
45 mask.as_mut_ptr(),
46 ));
47 if valid {
48 Ok(mask.assume_init())
49 } else {
50 Err(glib::bool_error!(
51 "Couldn't convert channel positions to mask"
52 ))
53 }
54 }
55 }
56
57 #[doc(alias = "gst_audio_channel_positions_from_mask")]
positions_from_mask(mask: u64, positions: &mut [Self]) -> Result<(), glib::BoolError>58 pub fn positions_from_mask(mask: u64, positions: &mut [Self]) -> Result<(), glib::BoolError> {
59 assert_initialized_main_thread!();
60
61 if positions.len() > 64 {
62 return Err(glib::bool_error!("Invalid number of channels"));
63 }
64
65 let len = positions.len();
66 let mut positions_raw: [ffi::GstAudioChannelPosition; 64] =
67 [ffi::GST_AUDIO_CHANNEL_POSITION_INVALID; 64];
68 let valid: bool = unsafe {
69 from_glib(ffi::gst_audio_channel_positions_from_mask(
70 len as i32,
71 mask,
72 positions_raw.as_mut_ptr(),
73 ))
74 };
75
76 if valid {
77 for (d, s) in positions.iter_mut().zip(positions_raw.iter()) {
78 *d = unsafe { from_glib(*s) };
79 }
80 Ok(())
81 } else {
82 Err(glib::bool_error!(
83 "Couldn't convert channel positions to mask",
84 ))
85 }
86 }
87
88 #[doc(alias = "gst_audio_channel_positions_to_valid_order")]
positions_to_valid_order(positions: &mut [Self]) -> Result<(), glib::BoolError>89 pub fn positions_to_valid_order(positions: &mut [Self]) -> Result<(), glib::BoolError> {
90 assert_initialized_main_thread!();
91
92 if positions.len() > 64 {
93 return Err(glib::bool_error!("Invalid number of channels"));
94 }
95
96 let len = positions.len();
97 let mut positions_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
98 if i >= len as usize {
99 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
100 } else {
101 positions[i].into_glib()
102 }
103 });
104
105 let valid: bool = unsafe {
106 from_glib(ffi::gst_audio_channel_positions_to_valid_order(
107 positions_raw.as_mut_ptr(),
108 len as i32,
109 ))
110 };
111
112 if valid {
113 for (d, s) in positions.iter_mut().zip(positions_raw.iter()) {
114 *d = unsafe { from_glib(*s) };
115 }
116 Ok(())
117 } else {
118 Err(glib::bool_error!(
119 "Couldn't convert channel positions to mask",
120 ))
121 }
122 }
123
124 #[doc(alias = "get_fallback_mask")]
125 #[doc(alias = "gst_audio_channel_get_fallback_mask")]
fallback_mask(channels: u32) -> u64126 pub fn fallback_mask(channels: u32) -> u64 {
127 assert_initialized_main_thread!();
128
129 unsafe { ffi::gst_audio_channel_get_fallback_mask(channels as i32) }
130 }
131
132 #[doc(alias = "gst_audio_check_valid_channel_positions")]
check_valid_channel_positions(positions: &[Self], force_order: bool) -> bool133 pub fn check_valid_channel_positions(positions: &[Self], force_order: bool) -> bool {
134 assert_initialized_main_thread!();
135
136 if positions.len() > 64 {
137 return false;
138 }
139
140 let len = positions.len();
141 let positions_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
142 if i >= len as usize {
143 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
144 } else {
145 positions[i].into_glib()
146 }
147 });
148
149 unsafe {
150 from_glib(ffi::gst_audio_check_valid_channel_positions(
151 positions_raw.as_ptr() as *mut _,
152 len as i32,
153 force_order.into_glib(),
154 ))
155 }
156 }
157 }
158
159 #[doc(alias = "gst_audio_buffer_reorder_channels")]
buffer_reorder_channels( buffer: &mut gst::BufferRef, format: crate::AudioFormat, channels: u32, from: &[AudioChannelPosition], to: &[AudioChannelPosition], ) -> Result<(), glib::BoolError>160 pub fn buffer_reorder_channels(
161 buffer: &mut gst::BufferRef,
162 format: crate::AudioFormat,
163 channels: u32,
164 from: &[AudioChannelPosition],
165 to: &[AudioChannelPosition],
166 ) -> Result<(), glib::BoolError> {
167 assert_initialized_main_thread!();
168
169 if from.len() != to.len() || from.len() > 64 {
170 return Err(glib::bool_error!("Invalid number of channels"));
171 }
172
173 let from_len = from.len();
174 let to_len = to.len();
175
176 let from_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
177 if i >= from_len as usize {
178 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
179 } else {
180 from[i].into_glib()
181 }
182 });
183
184 let to_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
185 if i >= to_len as usize {
186 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
187 } else {
188 to[i].into_glib()
189 }
190 });
191
192 let valid: bool = unsafe {
193 from_glib(ffi::gst_audio_buffer_reorder_channels(
194 buffer.as_mut_ptr(),
195 format.into_glib(),
196 channels as i32,
197 from_raw.as_ptr() as *mut _,
198 to_raw.as_ptr() as *mut _,
199 ))
200 };
201
202 if valid {
203 Ok(())
204 } else {
205 Err(glib::bool_error!("Failed to reorder channels"))
206 }
207 }
208
209 #[doc(alias = "gst_audio_reorder_channels")]
reorder_channels( data: &mut [u8], format: crate::AudioFormat, channels: u32, from: &[AudioChannelPosition], to: &[AudioChannelPosition], ) -> Result<(), glib::BoolError>210 pub fn reorder_channels(
211 data: &mut [u8],
212 format: crate::AudioFormat,
213 channels: u32,
214 from: &[AudioChannelPosition],
215 to: &[AudioChannelPosition],
216 ) -> Result<(), glib::BoolError> {
217 assert_initialized_main_thread!();
218
219 if from.len() != to.len() || from.len() > 64 {
220 return Err(glib::bool_error!("Invalid number of channels"));
221 }
222
223 let from_len = from.len();
224 let to_len = to.len();
225
226 let from_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
227 if i >= from_len as usize {
228 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
229 } else {
230 from[i].into_glib()
231 }
232 });
233
234 let to_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
235 if i >= to_len as usize {
236 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
237 } else {
238 to[i].into_glib()
239 }
240 });
241
242 let valid: bool = unsafe {
243 from_glib(ffi::gst_audio_reorder_channels(
244 data.as_mut_ptr() as *mut _,
245 data.len(),
246 format.into_glib(),
247 channels as i32,
248 from_raw.as_ptr() as *mut _,
249 to_raw.as_ptr() as *mut _,
250 ))
251 };
252
253 if valid {
254 Ok(())
255 } else {
256 Err(glib::bool_error!("Failed to reorder channels"))
257 }
258 }
259
260 #[doc(alias = "get_channel_reorder_map")]
261 #[doc(alias = "gst_audio_get_channel_reorder_map")]
channel_reorder_map( from: &[AudioChannelPosition], to: &[AudioChannelPosition], reorder_map: &mut [usize], ) -> Result<(), glib::BoolError>262 pub fn channel_reorder_map(
263 from: &[AudioChannelPosition],
264 to: &[AudioChannelPosition],
265 reorder_map: &mut [usize],
266 ) -> Result<(), glib::BoolError> {
267 assert_initialized_main_thread!();
268
269 if from.len() != to.len() || from.len() != reorder_map.len() || from.len() > 64 {
270 return Err(glib::bool_error!("Invalid number of channels"));
271 }
272
273 let from_len = from.len();
274 let to_len = to.len();
275
276 let from_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
277 if i >= from_len as usize {
278 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
279 } else {
280 from[i].into_glib()
281 }
282 });
283
284 let to_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
285 if i >= to_len as usize {
286 ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
287 } else {
288 to[i].into_glib()
289 }
290 });
291
292 let mut reorder_map_raw = [0i32, 64];
293 let valid: bool = unsafe {
294 from_glib(ffi::gst_audio_get_channel_reorder_map(
295 from_len as i32,
296 from_raw.as_ptr() as *mut _,
297 to_raw.as_ptr() as *mut _,
298 reorder_map_raw.as_mut_ptr(),
299 ))
300 };
301
302 if valid {
303 for (d, s) in reorder_map.iter_mut().zip(reorder_map_raw.iter()) {
304 *d = *s as usize;
305 }
306 Ok(())
307 } else {
308 Err(glib::bool_error!("Failed to reorder channels"))
309 }
310 }
311