X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fcodecs%2Fpcm.rs;fp=nihav-commonfmt%2Fsrc%2Fcodecs%2Fpcm.rs;h=7a7105126ec8a2841ef0a1049768b0b4ea57f783;hb=38953fb529efad1b0b609eec77f7839e62ad2719;hp=0000000000000000000000000000000000000000;hpb=ce64639a7a453c797519d5bdb64b5424bde59262;p=nihav.git diff --git a/nihav-commonfmt/src/codecs/pcm.rs b/nihav-commonfmt/src/codecs/pcm.rs new file mode 100644 index 0000000..7a71051 --- /dev/null +++ b/nihav-commonfmt/src/codecs/pcm.rs @@ -0,0 +1,68 @@ +use std::rc::Rc; +use std::cell::RefCell; +use nihav_core::formats::*; +use nihav_core::codecs::*; +use nihav_core::frame::*; + +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) -> u64 { + if duration == None { + let size_bits = (data_size as u64) * 8; + let blk_size = (ainfo.get_channels() as u64) * (ainfo.get_format().get_bits() as u64); + size_bits / blk_size + } else { + duration.unwrap() as u64 + } +} + +impl NADecoder for PCMDecoder { + fn init(&mut self, info: Rc) -> DecoderResult<()> { + if let NACodecTypeInfo::Audio(ainfo) = info.get_properties() { + 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()); + 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_duration(Some(duration)); + frm.set_keyframe(true); + Ok(Rc::new(RefCell::new(frm))) + } else { + Err(DecoderError::InvalidData) + } + } +} + +pub fn get_decoder() -> Box { + Box::new(PCMDecoder::new()) +}