2020-12-15 10:53:31 +00:00
|
|
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
2017-08-10 11:39:57 +00:00
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
use crate::AudioChannelPosition;
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
use std::mem;
|
|
|
|
|
2021-04-27 15:15:46 +00:00
|
|
|
use glib::translate::{from_glib, IntoGlib};
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
impl AudioChannelPosition {
|
2018-07-20 07:21:06 +00:00
|
|
|
pub fn to_mask(self) -> u64 {
|
2021-04-27 15:15:46 +00:00
|
|
|
let pos = self.into_glib();
|
2019-02-07 15:02:00 +00:00
|
|
|
if pos < 0 {
|
|
|
|
return 0;
|
|
|
|
}
|
2020-04-12 16:10:47 +00:00
|
|
|
|
|
|
|
1 << (pos as u32)
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_channel_positions_to_mask")]
|
2019-11-25 16:48:27 +00:00
|
|
|
pub fn positions_to_mask(
|
2021-04-29 20:49:26 +00:00
|
|
|
positions: &[Self],
|
2019-11-25 16:48:27 +00:00
|
|
|
force_order: bool,
|
|
|
|
) -> Result<u64, glib::error::BoolError> {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2017-08-10 11:39:57 +00:00
|
|
|
let len = positions.len();
|
|
|
|
if len > 64 {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!("Invalid number of channels"));
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
let positions_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
|
|
|
if i >= len as usize {
|
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
positions[i].into_glib()
|
2020-11-21 18:17:20 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut mask = mem::MaybeUninit::uninit();
|
2020-11-21 18:17:20 +00:00
|
|
|
let valid: bool = from_glib(ffi::gst_audio_channel_positions_to_mask(
|
2017-08-10 11:39:57 +00:00
|
|
|
positions_raw.as_ptr() as *mut _,
|
|
|
|
len as i32,
|
2021-04-27 15:15:46 +00:00
|
|
|
force_order.into_glib(),
|
2019-07-11 12:34:28 +00:00
|
|
|
mask.as_mut_ptr(),
|
2017-08-10 11:39:57 +00:00
|
|
|
));
|
|
|
|
if valid {
|
2019-11-25 16:48:27 +00:00
|
|
|
Ok(mask.assume_init())
|
2017-08-10 11:39:57 +00:00
|
|
|
} else {
|
2020-12-17 22:38:06 +00:00
|
|
|
Err(glib::bool_error!(
|
2019-11-25 16:48:27 +00:00
|
|
|
"Couldn't convert channel positions to mask"
|
|
|
|
))
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_channel_positions_from_mask")]
|
2021-04-29 20:49:26 +00:00
|
|
|
pub fn positions_from_mask(mask: u64, positions: &mut [Self]) -> Result<(), glib::BoolError> {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2017-08-10 11:39:57 +00:00
|
|
|
if positions.len() > 64 {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!("Invalid number of channels"));
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let len = positions.len();
|
2020-11-21 18:17:20 +00:00
|
|
|
let mut positions_raw: [ffi::GstAudioChannelPosition; 64] =
|
|
|
|
[ffi::GST_AUDIO_CHANNEL_POSITION_INVALID; 64];
|
2017-08-10 11:39:57 +00:00
|
|
|
let valid: bool = unsafe {
|
2020-11-21 18:17:20 +00:00
|
|
|
from_glib(ffi::gst_audio_channel_positions_from_mask(
|
2017-08-10 11:39:57 +00:00
|
|
|
len as i32,
|
|
|
|
mask,
|
|
|
|
positions_raw.as_mut_ptr(),
|
|
|
|
))
|
|
|
|
};
|
|
|
|
|
|
|
|
if valid {
|
|
|
|
for (d, s) in positions.iter_mut().zip(positions_raw.iter()) {
|
2020-12-08 14:07:12 +00:00
|
|
|
*d = unsafe { from_glib(*s) };
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2020-12-17 22:38:06 +00:00
|
|
|
Err(glib::bool_error!(
|
2017-08-10 11:39:57 +00:00
|
|
|
"Couldn't convert channel positions to mask",
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_channel_positions_to_valid_order")]
|
2021-04-29 20:49:26 +00:00
|
|
|
pub fn positions_to_valid_order(positions: &mut [Self]) -> Result<(), glib::BoolError> {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2017-08-10 11:39:57 +00:00
|
|
|
if positions.len() > 64 {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!("Invalid number of channels"));
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let len = positions.len();
|
2020-11-21 18:17:20 +00:00
|
|
|
let mut positions_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
|
|
|
if i >= len as usize {
|
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
positions[i].into_glib()
|
2020-11-21 18:17:20 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
let valid: bool = unsafe {
|
2020-11-21 18:17:20 +00:00
|
|
|
from_glib(ffi::gst_audio_channel_positions_to_valid_order(
|
2017-08-10 11:39:57 +00:00
|
|
|
positions_raw.as_mut_ptr(),
|
|
|
|
len as i32,
|
|
|
|
))
|
|
|
|
};
|
|
|
|
|
|
|
|
if valid {
|
|
|
|
for (d, s) in positions.iter_mut().zip(positions_raw.iter()) {
|
2020-12-08 14:07:12 +00:00
|
|
|
*d = unsafe { from_glib(*s) };
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2020-12-17 22:38:06 +00:00
|
|
|
Err(glib::bool_error!(
|
2017-08-10 11:39:57 +00:00
|
|
|
"Couldn't convert channel positions to mask",
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_fallback_mask")]
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_channel_get_fallback_mask")]
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn fallback_mask(channels: u32) -> u64 {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
unsafe { ffi::gst_audio_channel_get_fallback_mask(channels as i32) }
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_check_valid_channel_positions")]
|
2021-04-29 20:49:26 +00:00
|
|
|
pub fn check_valid_channel_positions(positions: &[Self], force_order: bool) -> bool {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2017-08-10 11:39:57 +00:00
|
|
|
if positions.len() > 64 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
let len = positions.len();
|
2020-11-21 18:17:20 +00:00
|
|
|
let positions_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
|
|
|
if i >= len as usize {
|
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
positions[i].into_glib()
|
2020-11-21 18:17:20 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
unsafe {
|
2020-11-21 18:17:20 +00:00
|
|
|
from_glib(ffi::gst_audio_check_valid_channel_positions(
|
2017-08-10 11:39:57 +00:00
|
|
|
positions_raw.as_ptr() as *mut _,
|
|
|
|
len as i32,
|
2021-04-27 15:15:46 +00:00
|
|
|
force_order.into_glib(),
|
2017-08-10 11:39:57 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_buffer_reorder_channels")]
|
2017-08-10 11:39:57 +00:00
|
|
|
pub fn buffer_reorder_channels(
|
|
|
|
buffer: &mut gst::BufferRef,
|
2020-11-21 18:17:20 +00:00
|
|
|
format: crate::AudioFormat,
|
2017-08-10 11:39:57 +00:00
|
|
|
channels: u32,
|
|
|
|
from: &[AudioChannelPosition],
|
|
|
|
to: &[AudioChannelPosition],
|
|
|
|
) -> Result<(), glib::BoolError> {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2017-08-10 11:39:57 +00:00
|
|
|
if from.len() != to.len() || from.len() > 64 {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!("Invalid number of channels"));
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let from_len = from.len();
|
|
|
|
let to_len = to.len();
|
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
let from_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
2017-11-11 12:31:01 +00:00
|
|
|
if i >= from_len as usize {
|
2020-11-21 18:17:20 +00:00
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
2017-08-10 11:39:57 +00:00
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
from[i].into_glib()
|
2017-11-11 12:31:01 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
let to_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
2017-11-11 12:31:01 +00:00
|
|
|
if i >= to_len as usize {
|
2020-11-21 18:17:20 +00:00
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
2017-08-10 11:39:57 +00:00
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
to[i].into_glib()
|
2017-11-11 12:31:01 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
let valid: bool = unsafe {
|
2020-11-21 18:17:20 +00:00
|
|
|
from_glib(ffi::gst_audio_buffer_reorder_channels(
|
2017-08-10 11:39:57 +00:00
|
|
|
buffer.as_mut_ptr(),
|
2021-04-27 15:15:46 +00:00
|
|
|
format.into_glib(),
|
2017-08-10 11:39:57 +00:00
|
|
|
channels as i32,
|
|
|
|
from_raw.as_ptr() as *mut _,
|
|
|
|
to_raw.as_ptr() as *mut _,
|
|
|
|
))
|
|
|
|
};
|
|
|
|
|
|
|
|
if valid {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2020-12-17 22:38:06 +00:00
|
|
|
Err(glib::bool_error!("Failed to reorder channels"))
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_reorder_channels")]
|
2017-08-10 11:39:57 +00:00
|
|
|
pub fn reorder_channels(
|
|
|
|
data: &mut [u8],
|
2020-11-21 18:17:20 +00:00
|
|
|
format: crate::AudioFormat,
|
2017-08-10 11:39:57 +00:00
|
|
|
channels: u32,
|
|
|
|
from: &[AudioChannelPosition],
|
|
|
|
to: &[AudioChannelPosition],
|
|
|
|
) -> Result<(), glib::BoolError> {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2017-08-10 11:39:57 +00:00
|
|
|
if from.len() != to.len() || from.len() > 64 {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!("Invalid number of channels"));
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let from_len = from.len();
|
|
|
|
let to_len = to.len();
|
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
let from_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
2017-11-11 12:31:01 +00:00
|
|
|
if i >= from_len as usize {
|
2020-11-21 18:17:20 +00:00
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
2017-08-10 11:39:57 +00:00
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
from[i].into_glib()
|
2017-11-11 12:31:01 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
let to_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
2017-11-11 12:31:01 +00:00
|
|
|
if i >= to_len as usize {
|
2020-11-21 18:17:20 +00:00
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
2017-08-10 11:39:57 +00:00
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
to[i].into_glib()
|
2017-11-11 12:31:01 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
let valid: bool = unsafe {
|
2020-11-21 18:17:20 +00:00
|
|
|
from_glib(ffi::gst_audio_reorder_channels(
|
2017-08-10 11:39:57 +00:00
|
|
|
data.as_mut_ptr() as *mut _,
|
|
|
|
data.len(),
|
2021-04-27 15:15:46 +00:00
|
|
|
format.into_glib(),
|
2017-08-10 11:39:57 +00:00
|
|
|
channels as i32,
|
|
|
|
from_raw.as_ptr() as *mut _,
|
|
|
|
to_raw.as_ptr() as *mut _,
|
|
|
|
))
|
|
|
|
};
|
|
|
|
|
|
|
|
if valid {
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2020-12-17 22:38:06 +00:00
|
|
|
Err(glib::bool_error!("Failed to reorder channels"))
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-02 09:41:18 +00:00
|
|
|
#[doc(alias = "get_channel_reorder_map")]
|
2021-05-19 20:35:47 +00:00
|
|
|
#[doc(alias = "gst_audio_get_channel_reorder_map")]
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn channel_reorder_map(
|
2017-08-10 11:39:57 +00:00
|
|
|
from: &[AudioChannelPosition],
|
|
|
|
to: &[AudioChannelPosition],
|
|
|
|
reorder_map: &mut [usize],
|
|
|
|
) -> Result<(), glib::BoolError> {
|
2017-08-30 11:39:09 +00:00
|
|
|
assert_initialized_main_thread!();
|
|
|
|
|
2017-08-10 11:39:57 +00:00
|
|
|
if from.len() != to.len() || from.len() != reorder_map.len() || from.len() > 64 {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!("Invalid number of channels"));
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let from_len = from.len();
|
|
|
|
let to_len = to.len();
|
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
let from_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
2017-11-11 12:31:01 +00:00
|
|
|
if i >= from_len as usize {
|
2020-11-21 18:17:20 +00:00
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
2017-08-10 11:39:57 +00:00
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
from[i].into_glib()
|
2017-11-11 12:31:01 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
2020-11-21 18:17:20 +00:00
|
|
|
let to_raw: [ffi::GstAudioChannelPosition; 64] = array_init::array_init(|i| {
|
2017-11-11 12:31:01 +00:00
|
|
|
if i >= to_len as usize {
|
2020-11-21 18:17:20 +00:00
|
|
|
ffi::GST_AUDIO_CHANNEL_POSITION_INVALID
|
2017-08-10 11:39:57 +00:00
|
|
|
} else {
|
2021-04-27 15:15:46 +00:00
|
|
|
to[i].into_glib()
|
2017-11-11 12:31:01 +00:00
|
|
|
}
|
|
|
|
});
|
2017-08-10 11:39:57 +00:00
|
|
|
|
|
|
|
let mut reorder_map_raw = [0i32, 64];
|
|
|
|
let valid: bool = unsafe {
|
2020-11-21 18:17:20 +00:00
|
|
|
from_glib(ffi::gst_audio_get_channel_reorder_map(
|
2017-08-10 11:39:57 +00:00
|
|
|
from_len as i32,
|
|
|
|
from_raw.as_ptr() as *mut _,
|
|
|
|
to_raw.as_ptr() as *mut _,
|
|
|
|
reorder_map_raw.as_mut_ptr(),
|
|
|
|
))
|
|
|
|
};
|
|
|
|
|
|
|
|
if valid {
|
|
|
|
for (d, s) in reorder_map.iter_mut().zip(reorder_map_raw.iter()) {
|
|
|
|
*d = *s as usize;
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
} else {
|
2020-12-17 22:38:06 +00:00
|
|
|
Err(glib::bool_error!("Failed to reorder channels"))
|
2017-08-10 11:39:57 +00:00
|
|
|
}
|
|
|
|
}
|