From 3234da61c291704c7e9d928c4c50dd41f537e0c5 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Tue, 23 May 2017 19:10:37 +0200 Subject: [PATCH] add PCM decoder(rewrapper) --- Cargo.toml | 3 ++- src/codecs/mod.rs | 4 +++ src/codecs/pcm.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/codecs/pcm.rs diff --git a/Cargo.toml b/Cargo.toml index febb4c6..5056799 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,6 @@ demuxer_avi = ["demuxers"] demuxer_gdv = ["demuxers"] decoders = [] -all_decoders = ["decoder_indeo2"] +all_decoders = ["decoder_indeo2", "decoder_pcm"] decoder_indeo2 = ["decoders"] +decoder_pcm = ["decoders"] diff --git a/src/codecs/mod.rs b/src/codecs/mod.rs index a2c10fe..206032e 100644 --- a/src/codecs/mod.rs +++ b/src/codecs/mod.rs @@ -1,5 +1,7 @@ #[cfg(feature="decoder_indeo2")] pub mod indeo2; +#[cfg(feature="decoder_pcm")] +pub mod pcm; use frame::*; use std::rc::Rc; @@ -84,6 +86,8 @@ pub struct DecoderInfo { const DECODERS: &[DecoderInfo] = &[ #[cfg(feature="decoder_indeo2")] DecoderInfo { name: "indeo2", get_decoder: indeo2::get_decoder }, +#[cfg(feature="decoder_pcm")] + DecoderInfo { name: "pcm", get_decoder: pcm::get_decoder }, ]; pub fn find_decoder(name: &str) -> Option Box> { diff --git a/src/codecs/pcm.rs b/src/codecs/pcm.rs new file mode 100644 index 0000000..c5c3b5b --- /dev/null +++ b/src/codecs/pcm.rs @@ -0,0 +1,67 @@ +use formats::*; +use super::*; + +struct PCMDecoder { chmap: NAChannelMap } + +impl PCMDecoder { + fn new() -> Self { + PCMDecoder { chmap: NAChannelMap::new() } + } +} + +const CHMAP_MONO: [NAChannelType; 1] = [NAChannelType::C]; +const CHMAP_STEREO: [NAChannelType; 2] = [NAChannelType::L, NAChannelType::R]; + +fn get_default_chmap(nch: u8) -> NAChannelMap { + let mut chmap = NAChannelMap::new(); + match nch { + 1 => chmap.add_channels(&CHMAP_MONO), + 2 => chmap.add_channels(&CHMAP_STEREO), + _ => (), + } + chmap +} + +fn get_duration(ainfo: &NAAudioInfo, duration: Option, data_size: usize) -> usize { +println!("pcm in {:?}, {}", duration, data_size); + if duration == None { + let size_bits = data_size * 8; + let blk_size = (ainfo.get_channels() as usize) * (ainfo.get_format().get_bits() as usize); + size_bits / blk_size + } else { + duration.unwrap() as usize + } +} + +impl NADecoder for PCMDecoder { + fn init(&mut self, info: Rc) -> DecoderResult<()> { + if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { +println!("got info {}", ainfo); + self.chmap = get_default_chmap(ainfo.get_channels()); + if self.chmap.num_channels() == 0 { return Err(DecoderError::InvalidData); } + Ok(()) + } else { + Err(DecoderError::InvalidData) + } + } + fn decode(&mut self, pkt: &NAPacket) -> DecoderResult { + let info = pkt.get_stream().get_info(); + if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { + let duration = get_duration(&ainfo, pkt.get_duration(), pkt.get_buffer().len()); +println!("duration = {}", duration); + let pktbuf = pkt.get_buffer(); + let mut buf: Vec = Vec::with_capacity(pktbuf.len()); + buf.clone_from(&pktbuf); + let abuf = NAAudioBuffer::new_from_buf(ainfo, Rc::new(RefCell::new(buf)), self.chmap.clone()); + let mut frm = NAFrame::new_from_pkt(pkt, info, NABufferType::AudioPacked(abuf)); + frm.set_keyframe(true); + Ok(Rc::new(RefCell::new(frm))) + } else { + Err(DecoderError::InvalidData) + } + } +} + +pub fn get_decoder() -> Box { + Box::new(PCMDecoder::new()) +} -- 2.30.2