audio/claxon: validate input depth info

This expands the depth input check into proper validation and resulting
enum, which can be reused by the rest of the logic.

Signed-off-by: Luca BRUNO <lucab@lucabruno.net>
This commit is contained in:
Luca BRUNO 2020-04-11 10:25:11 +00:00
parent 02935b7005
commit bd90d1d9a6
No known key found for this signature in database
GPG key ID: A9834A2252078E4E

View file

@ -264,8 +264,9 @@ impl ClaxonDec {
.audio_info
.as_ref()
.ok_or(gst::FlowError::NotNegotiated)?;
let channels = audio_info.channels() as usize;
let depth = AudioDepth::validate(audio_info.depth())?;
let channels = audio_info.channels() as usize;
if channels > 8 {
unreachable!(
"FLAC only supports from 1 to 8 channels (audio contains {} channels)",
@ -273,13 +274,6 @@ impl ClaxonDec {
);
}
if ![8, 16, 24, 32].contains(&audio_info.depth()) {
unreachable!(
"claxondec doesn't supports {}bits audio",
audio_info.depth()
);
}
let buffer = Vec::new();
let mut cursor = Cursor::new(indata);
let mut reader = claxon::frame::FrameReader::new(&mut cursor);
@ -311,20 +305,58 @@ impl ClaxonDec {
result.into_buffer()
};
let outbuf = if audio_info.depth() == 8 {
let v = v.iter().map(|e| *e as i8).collect::<Vec<_>>();
gst::Buffer::from_slice(v.into_byte_vec())
} else if audio_info.depth() == 16 {
let v = v.iter().map(|e| *e as i16).collect::<Vec<_>>();
gst::Buffer::from_slice(v.into_byte_vec())
} else {
gst::Buffer::from_slice(v.into_byte_vec())
};
let depth_adjusted = depth.adjust_samples(v);
let outbuf = gst::Buffer::from_slice(depth_adjusted);
element.finish_frame(Some(outbuf), 1)
}
}
/// Depth of audio samples
enum AudioDepth {
/// 8bits.
I8,
/// 16bits.
I16,
/// 24bits.
I24,
/// 32bits.
I32,
}
impl AudioDepth {
/// Validate input audio depth.
fn validate(input: u32) -> Result<Self, gst::FlowError> {
let depth = match input {
8 => AudioDepth::I8,
16 => AudioDepth::I16,
24 => AudioDepth::I24,
32 => AudioDepth::I32,
_ => return Err(gst::FlowError::NotSupported),
};
Ok(depth)
}
/// Adjust samples depth.
///
/// This takes a vector of 32bits samples, adjusts the depth of each,
/// and returns the adjusted bytes stream.
fn adjust_samples(&self, input: Vec<i32>) -> Vec<u8> {
match *self {
AudioDepth::I8 => input
.into_iter()
.map(|x| x as i8)
.collect::<Vec<_>>()
.into_byte_vec(),
AudioDepth::I16 => input
.into_iter()
.map(|x| x as i16)
.collect::<Vec<_>>()
.into_byte_vec(),
AudioDepth::I24 | AudioDepth::I32 => input.into_byte_vec(),
}
}
}
pub fn register(plugin: &gst::Plugin) -> Result<(), glib::BoolError> {
gst::Element::register(
Some(plugin),