forked from mirrors/gstreamer-rs
Add bindings for various audio channel position functions
This commit is contained in:
parent
8215770076
commit
e1538b6ca5
6 changed files with 364 additions and 37 deletions
25
Cargo.lock
generated
25
Cargo.lock
generated
|
@ -2,6 +2,7 @@
|
||||||
name = "gstreamer-audio"
|
name = "gstreamer-audio"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"array-init 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glib 0.1.3 (git+https://github.com/gtk-rs/glib)",
|
"glib 0.1.3 (git+https://github.com/gtk-rs/glib)",
|
||||||
"glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)",
|
"glib-sys 0.3.4 (git+https://github.com/gtk-rs/sys)",
|
||||||
|
@ -13,6 +14,14 @@ dependencies = [
|
||||||
"rustdoc-stripper 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustdoc-stripper 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "array-init"
|
||||||
|
version = "0.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atk-sys"
|
name = "atk-sys"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
|
@ -465,6 +474,14 @@ dependencies = [
|
||||||
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nodrop"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-integer"
|
name = "num-integer"
|
||||||
version = "0.1.35"
|
version = "0.1.35"
|
||||||
|
@ -487,6 +504,11 @@ name = "num-traits"
|
||||||
version = "0.1.40"
|
version = "0.1.40"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "odds"
|
||||||
|
version = "0.2.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pango"
|
name = "pango"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -582,6 +604,7 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
|
"checksum array-init 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4d3b508d35216892b50a135fb52c9bb90f04a97b7782230805dff1a156ad5469"
|
||||||
"checksum atk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "<none>"
|
"checksum atk-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "<none>"
|
||||||
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||||
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
|
||||||
|
@ -621,9 +644,11 @@ dependencies = [
|
||||||
"checksum mio 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dbd91d3bfbceb13897065e97b2ef177a09a438cb33612b2d371bf568819a9313"
|
"checksum mio 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "dbd91d3bfbceb13897065e97b2ef177a09a438cb33612b2d371bf568819a9313"
|
||||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||||
"checksum net2 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "94101fd932816f97eb9a5116f6c1a11511a1fed7db21c5ccd823b2dc11abf566"
|
"checksum net2 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "94101fd932816f97eb9a5116f6c1a11511a1fed7db21c5ccd823b2dc11abf566"
|
||||||
|
"checksum nodrop 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "52cd74cd09beba596430cc6e3091b74007169a56246e1262f0ba451ea95117b2"
|
||||||
"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
|
"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba"
|
||||||
"checksum num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "288629c76fac4b33556f4b7ab57ba21ae202da65ba8b77466e6d598e31990790"
|
"checksum num-rational 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "288629c76fac4b33556f4b7ab57ba21ae202da65ba8b77466e6d598e31990790"
|
||||||
"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
|
"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
|
||||||
|
"checksum odds 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "c3df9b730298cea3a1c3faa90b7e2f9df3a9c400d0936d6015e6165734eefcba"
|
||||||
"checksum pango 0.1.3 (git+https://github.com/gtk-rs/pango)" = "<none>"
|
"checksum pango 0.1.3 (git+https://github.com/gtk-rs/pango)" = "<none>"
|
||||||
"checksum pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "<none>"
|
"checksum pango-sys 0.3.4 (git+https://github.com/gtk-rs/sys)" = "<none>"
|
||||||
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
|
||||||
|
|
|
@ -19,6 +19,7 @@ gstreamer-sys = { version = "0.1.1", git = "https://github.com/sdroege/gstreamer
|
||||||
gstreamer-audio-sys = { version = "0.1.1", git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
|
gstreamer-audio-sys = { version = "0.1.1", git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
|
||||||
glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" }
|
glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" }
|
||||||
gstreamer = { version = "0.1.0", path = "../gstreamer" }
|
gstreamer = { version = "0.1.0", path = "../gstreamer" }
|
||||||
|
array-init = "0.0"
|
||||||
|
|
||||||
[build-dependencies.rustdoc-stripper]
|
[build-dependencies.rustdoc-stripper]
|
||||||
version = "0.1"
|
version = "0.1"
|
||||||
|
|
288
gstreamer-audio/src/audio_channel_position.rs
Normal file
288
gstreamer-audio/src/audio_channel_position.rs
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use ffi;
|
||||||
|
use AudioChannelPosition;
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
use gst;
|
||||||
|
use gst::MiniObject;
|
||||||
|
use glib;
|
||||||
|
use glib::translate::{from_glib, ToGlib};
|
||||||
|
|
||||||
|
use array_init;
|
||||||
|
|
||||||
|
impl AudioChannelPosition {
|
||||||
|
pub fn to_mask(&self) -> u64 {
|
||||||
|
unsafe {
|
||||||
|
let val = mem::transmute::<ffi::GstAudioChannelPosition, u32>(self.to_glib());
|
||||||
|
1 << val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn positions_to_mask(positions: &[AudioChannelPosition], force_order: bool) -> Option<u64> {
|
||||||
|
let len = positions.len();
|
||||||
|
if len > 64 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let positions_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
positions[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let mut mask = mem::uninitialized();
|
||||||
|
let valid: bool = from_glib(ffi::gst_audio_channel_positions_to_mask(
|
||||||
|
positions_raw.as_ptr() as *mut _,
|
||||||
|
len as i32,
|
||||||
|
force_order.to_glib(),
|
||||||
|
&mut mask,
|
||||||
|
));
|
||||||
|
if valid {
|
||||||
|
Some(mask)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn positions_from_mask(
|
||||||
|
mask: u64,
|
||||||
|
positions: &mut [AudioChannelPosition],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
if positions.len() > 64 {
|
||||||
|
return Err(glib::BoolError("Invalid number of channels"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = positions.len();
|
||||||
|
let mut positions_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
[ffi::GstAudioChannelPosition::Invalid; 64];
|
||||||
|
let valid: bool = unsafe {
|
||||||
|
from_glib(ffi::gst_audio_channel_positions_from_mask(
|
||||||
|
len as i32,
|
||||||
|
mask,
|
||||||
|
positions_raw.as_mut_ptr(),
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
if valid {
|
||||||
|
for (d, s) in positions.iter_mut().zip(positions_raw.iter()) {
|
||||||
|
*d = from_glib(*s);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::BoolError(
|
||||||
|
"Couldn't convert channel positions to mask",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn positions_to_valid_order(
|
||||||
|
positions: &mut [AudioChannelPosition],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
if positions.len() > 64 {
|
||||||
|
return Err(glib::BoolError("Invalid number of channels"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = positions.len();
|
||||||
|
let mut positions_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
positions[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let valid: bool = unsafe {
|
||||||
|
from_glib(ffi::gst_audio_channel_positions_to_valid_order(
|
||||||
|
positions_raw.as_mut_ptr(),
|
||||||
|
len as i32,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
if valid {
|
||||||
|
for (d, s) in positions.iter_mut().zip(positions_raw.iter()) {
|
||||||
|
*d = from_glib(*s);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::BoolError(
|
||||||
|
"Couldn't convert channel positions to mask",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_fallback_mask(channels: u32) -> u64 {
|
||||||
|
unsafe { ffi::gst_audio_channel_get_fallback_mask(channels as i32) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_valid_channel_positions(
|
||||||
|
positions: &[::AudioChannelPosition],
|
||||||
|
force_order: bool,
|
||||||
|
) -> bool {
|
||||||
|
if positions.len() > 64 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = positions.len();
|
||||||
|
let positions_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
positions[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
from_glib(ffi::gst_audio_check_valid_channel_positions(
|
||||||
|
positions_raw.as_ptr() as *mut _,
|
||||||
|
len as i32,
|
||||||
|
force_order.to_glib(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn buffer_reorder_channels(
|
||||||
|
buffer: &mut gst::BufferRef,
|
||||||
|
format: ::AudioFormat,
|
||||||
|
channels: u32,
|
||||||
|
from: &[AudioChannelPosition],
|
||||||
|
to: &[AudioChannelPosition],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
if from.len() != to.len() || from.len() > 64 {
|
||||||
|
return Err(glib::BoolError("Invalid number of channels"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let from_len = from.len();
|
||||||
|
let to_len = to.len();
|
||||||
|
|
||||||
|
let from_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= from_len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
from[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let to_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= to_len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
to[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let valid: bool = unsafe {
|
||||||
|
from_glib(ffi::gst_audio_buffer_reorder_channels(
|
||||||
|
buffer.as_mut_ptr(),
|
||||||
|
format.to_glib(),
|
||||||
|
channels as i32,
|
||||||
|
from_raw.as_ptr() as *mut _,
|
||||||
|
to_raw.as_ptr() as *mut _,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
if valid {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::BoolError("Failed to reorder channels"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reorder_channels(
|
||||||
|
data: &mut [u8],
|
||||||
|
format: ::AudioFormat,
|
||||||
|
channels: u32,
|
||||||
|
from: &[AudioChannelPosition],
|
||||||
|
to: &[AudioChannelPosition],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
if from.len() != to.len() || from.len() > 64 {
|
||||||
|
return Err(glib::BoolError("Invalid number of channels"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let from_len = from.len();
|
||||||
|
let to_len = to.len();
|
||||||
|
|
||||||
|
let from_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= from_len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
from[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let to_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= to_len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
to[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let valid: bool = unsafe {
|
||||||
|
from_glib(ffi::gst_audio_reorder_channels(
|
||||||
|
data.as_mut_ptr() as *mut _,
|
||||||
|
data.len(),
|
||||||
|
format.to_glib(),
|
||||||
|
channels as i32,
|
||||||
|
from_raw.as_ptr() as *mut _,
|
||||||
|
to_raw.as_ptr() as *mut _,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
|
||||||
|
if valid {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(glib::BoolError("Failed to reorder channels"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_channel_reorder_map(
|
||||||
|
from: &[AudioChannelPosition],
|
||||||
|
to: &[AudioChannelPosition],
|
||||||
|
reorder_map: &mut [usize],
|
||||||
|
) -> Result<(), glib::BoolError> {
|
||||||
|
if from.len() != to.len() || from.len() != reorder_map.len() || from.len() > 64 {
|
||||||
|
return Err(glib::BoolError("Invalid number of channels"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let from_len = from.len();
|
||||||
|
let to_len = to.len();
|
||||||
|
|
||||||
|
let from_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= from_len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
from[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let to_raw: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= to_len as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
to[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut reorder_map_raw = [0i32, 64];
|
||||||
|
let valid: bool = unsafe {
|
||||||
|
from_glib(ffi::gst_audio_get_channel_reorder_map(
|
||||||
|
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 {
|
||||||
|
Err(glib::BoolError("Failed to reorder channels"))
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,9 @@ use glib::translate::{from_glib, from_glib_full, from_glib_none, FromGlibPtrNone
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
pub struct AudioInfo(ffi::GstAudioInfo);
|
use array_init;
|
||||||
|
|
||||||
|
pub struct AudioInfo(ffi::GstAudioInfo, [::AudioChannelPosition; 64]);
|
||||||
|
|
||||||
pub struct AudioInfoBuilder<'a> {
|
pub struct AudioInfoBuilder<'a> {
|
||||||
format: ::AudioFormat,
|
format: ::AudioFormat,
|
||||||
|
@ -34,33 +36,37 @@ impl<'a> AudioInfoBuilder<'a> {
|
||||||
pub fn build(self) -> Option<AudioInfo> {
|
pub fn build(self) -> Option<AudioInfo> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut info = mem::uninitialized();
|
let mut info = mem::uninitialized();
|
||||||
let mut positions_raw = Vec::new();
|
|
||||||
|
|
||||||
let positions_ptr = match self.positions {
|
let positions = if let Some(p) = self.positions {
|
||||||
Some(p) => {
|
if p.len() != self.channels as usize || p.len() > 64 {
|
||||||
if p.len() != self.channels as usize {
|
return None;
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
positions_raw.reserve(self.channels as usize);
|
|
||||||
for i in p {
|
|
||||||
positions_raw.push(i.to_glib());
|
|
||||||
}
|
|
||||||
|
|
||||||
let valid: bool = from_glib(ffi::gst_audio_check_valid_channel_positions(
|
|
||||||
positions_raw.as_mut_ptr(),
|
|
||||||
self.channels as i32,
|
|
||||||
true.to_glib(),
|
|
||||||
));
|
|
||||||
if !valid {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
positions_raw.as_ptr()
|
|
||||||
}
|
}
|
||||||
None => ptr::null(),
|
|
||||||
|
let positions: [ffi::GstAudioChannelPosition; 64] =
|
||||||
|
array_init::array_init_copy(|i| if i >= self.channels as usize {
|
||||||
|
ffi::GstAudioChannelPosition::Invalid
|
||||||
|
} else {
|
||||||
|
p[i].to_glib()
|
||||||
|
});
|
||||||
|
|
||||||
|
let valid: bool = from_glib(ffi::gst_audio_check_valid_channel_positions(
|
||||||
|
positions.as_ptr() as *mut _,
|
||||||
|
self.channels as i32,
|
||||||
|
true.to_glib(),
|
||||||
|
));
|
||||||
|
if !valid {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(positions)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let positions_ptr = positions
|
||||||
|
.as_ref()
|
||||||
|
.map(|p| p.as_ptr())
|
||||||
|
.unwrap_or(ptr::null());
|
||||||
|
|
||||||
ffi::gst_audio_info_set_format(
|
ffi::gst_audio_info_set_format(
|
||||||
&mut info,
|
&mut info,
|
||||||
|
@ -82,7 +88,8 @@ impl<'a> AudioInfoBuilder<'a> {
|
||||||
info.layout = layout.to_glib();
|
info.layout = layout.to_glib();
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(AudioInfo(info))
|
let positions = array_init::array_init_copy(|i| from_glib(info.position[i]));
|
||||||
|
Some(AudioInfo(info, positions))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +131,8 @@ impl AudioInfo {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut info = mem::uninitialized();
|
let mut info = mem::uninitialized();
|
||||||
if from_glib(ffi::gst_audio_info_from_caps(&mut info, caps.as_ptr())) {
|
if from_glib(ffi::gst_audio_info_from_caps(&mut info, caps.as_ptr())) {
|
||||||
Some(AudioInfo(info))
|
let positions = array_init::array_init_copy(|i| from_glib(info.position[i]));
|
||||||
|
Some(AudioInfo(info, positions))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -228,13 +236,12 @@ impl AudioInfo {
|
||||||
self.format_info().is_signed()
|
self.format_info().is_signed()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn positions(&self) -> Vec<::AudioChannelPosition> {
|
pub fn positions(&self) -> Option<&[::AudioChannelPosition]> {
|
||||||
let mut v = Vec::with_capacity(self.0.channels as usize);
|
if self.0.channels > 64 || self.is_unpositioned() {
|
||||||
for i in 0..(self.0.channels as usize) {
|
return None;
|
||||||
v.push(from_glib(self.0.position[i]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v
|
Some(&self.1[0..(self.0.channels as usize)])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_unpositioned(&self) -> bool {
|
pub fn is_unpositioned(&self) -> bool {
|
||||||
|
@ -244,7 +251,7 @@ impl AudioInfo {
|
||||||
|
|
||||||
impl Clone for AudioInfo {
|
impl Clone for AudioInfo {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
unsafe { AudioInfo(ptr::read(&self.0)) }
|
unsafe { AudioInfo(ptr::read(&self.0), self.1) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,7 +329,10 @@ impl<'a> glib::translate::ToGlibPtr<'a, *const ffi::GstAudioInfo> for AudioInfo
|
||||||
impl glib::translate::FromGlibPtrNone<*mut ffi::GstAudioInfo> for AudioInfo {
|
impl glib::translate::FromGlibPtrNone<*mut ffi::GstAudioInfo> for AudioInfo {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn from_glib_none(ptr: *mut ffi::GstAudioInfo) -> Self {
|
unsafe fn from_glib_none(ptr: *mut ffi::GstAudioInfo) -> Self {
|
||||||
AudioInfo(ptr::read(ptr))
|
AudioInfo(
|
||||||
|
ptr::read(ptr),
|
||||||
|
array_init::array_init_copy(|i| from_glib((*ptr).position[i])),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,7 +362,7 @@ mod tests {
|
||||||
assert_eq!(info.rate(), 48000);
|
assert_eq!(info.rate(), 48000);
|
||||||
assert_eq!(info.channels(), 2);
|
assert_eq!(info.channels(), 2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&info.positions(),
|
&info.positions().unwrap(),
|
||||||
&[
|
&[
|
||||||
::AudioChannelPosition::FrontLeft,
|
::AudioChannelPosition::FrontLeft,
|
||||||
::AudioChannelPosition::FrontRight
|
::AudioChannelPosition::FrontRight
|
||||||
|
@ -371,7 +381,7 @@ mod tests {
|
||||||
assert_eq!(info.rate(), 48000);
|
assert_eq!(info.rate(), 48000);
|
||||||
assert_eq!(info.channels(), 2);
|
assert_eq!(info.channels(), 2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&info.positions(),
|
&info.positions().unwrap(),
|
||||||
&[
|
&[
|
||||||
::AudioChannelPosition::RearLeft,
|
::AudioChannelPosition::RearLeft,
|
||||||
::AudioChannelPosition::RearRight
|
::AudioChannelPosition::RearRight
|
||||||
|
@ -398,7 +408,7 @@ mod tests {
|
||||||
assert_eq!(info.rate(), 48000);
|
assert_eq!(info.rate(), 48000);
|
||||||
assert_eq!(info.channels(), 2);
|
assert_eq!(info.channels(), 2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&info.positions(),
|
&info.positions().unwrap(),
|
||||||
&[
|
&[
|
||||||
::AudioChannelPosition::FrontLeft,
|
::AudioChannelPosition::FrontLeft,
|
||||||
::AudioChannelPosition::FrontRight
|
::AudioChannelPosition::FrontRight
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
extern crate array_init;
|
||||||
|
|
||||||
extern crate glib_sys as glib_ffi;
|
extern crate glib_sys as glib_ffi;
|
||||||
extern crate gobject_sys as gobject_ffi;
|
extern crate gobject_sys as gobject_ffi;
|
||||||
|
@ -46,3 +47,5 @@ mod audio_format_info;
|
||||||
pub use audio_format_info::*;
|
pub use audio_format_info::*;
|
||||||
mod audio_info;
|
mod audio_info;
|
||||||
pub use audio_info::*;
|
pub use audio_info::*;
|
||||||
|
mod audio_channel_position;
|
||||||
|
pub use audio_channel_position::*;
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub use auto::traits::*;
|
||||||
pub use auto::functions::{parse_bin_from_description, parse_launch};
|
pub use auto::functions::{parse_bin_from_description, parse_launch};
|
||||||
|
|
||||||
pub mod miniobject;
|
pub mod miniobject;
|
||||||
pub use miniobject::GstRc;
|
pub use miniobject::{GstRc, MiniObject};
|
||||||
pub mod message;
|
pub mod message;
|
||||||
pub use message::{Message, MessageRef, MessageView};
|
pub use message::{Message, MessageRef, MessageView};
|
||||||
pub mod structure;
|
pub mod structure;
|
||||||
|
|
Loading…
Reference in a new issue