X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-mpeg%2Fsrc%2Fcodecs%2Fmpegaudio%2Fmod.rs;h=99b57720127296ca210430b86146581b3952e538;hp=0f44e89aea39304f19e0844a14c4c5921aa7d98d;hb=7f7356a02d44ed553643502806d4342394419637;hpb=418df65e14707270566bb2a499d3633dacef249a diff --git a/nihav-mpeg/src/codecs/mpegaudio/mod.rs b/nihav-mpeg/src/codecs/mpegaudio/mod.rs index 0f44e89..99b5772 100644 --- a/nihav-mpeg/src/codecs/mpegaudio/mod.rs +++ b/nihav-mpeg/src/codecs/mpegaudio/mod.rs @@ -3,6 +3,9 @@ use nihav_core::io::byteio::read_u32be; use nihav_core::io::bitreader::*; use nihav_codec_support::dsp::qmf::QMF; +mod mp2data; +mod mp2code; +use mp2code::*; mod mp3data; mod mp3code; use mp3code::*; @@ -13,7 +16,7 @@ const BYTEBUF_SIZE: usize = 2048; #[allow(clippy::large_enum_variant)] enum LayerData { MP1, - MP2, + MP2(MP2Data), MP3(MP3Data), } @@ -21,14 +24,14 @@ impl LayerData { fn layer_id(&self) -> u8 { match *self { LayerData::MP1 => 0, - LayerData::MP2 => 1, + LayerData::MP2(_) => 1, LayerData::MP3(_) => 2, } } fn reset(&mut self) { match self { LayerData::MP1 => {}, - LayerData::MP2 => {}, + LayerData::MP2(ref mut data) => data.reset(), LayerData::MP3(ref mut data) => data.reset(), }; } @@ -53,7 +56,7 @@ impl MPADecoder { fn new(layer: u8) -> Self { let ctx = match layer { 0 => LayerData::MP1, - 1 => LayerData::MP2, + 1 => LayerData::MP2(MP2Data::new()), 2 => LayerData::MP3(MP3Data::new()), _ => unreachable!(), }; @@ -216,7 +219,24 @@ impl NADecoder for MPADecoder { match layer { 0 => unimplemented!(), - 1 => unimplemented!(), + 1 => { + if let LayerData::MP2(ref mut ctx) = self.ctx { + ctx.mpeg1 = self.sf_idx < 3; + ctx.sf_idx = self.sf_idx; + ctx.br_idx = bitrate_index; + ctx.read_layer2(&mut br, channels as usize, &mut self.out, mode, mode_extension)?; + } else { + return Err(DecoderError::Bug); + } + for (dst, src) in ch0.chunks_exact_mut(32).zip(self.out[0].iter_mut()) { + self.qmf[0].synth(src, dst); + } + if channels == 2 { + for (dst, src) in ch1.chunks_mut(32).zip(self.out[1].iter_mut()) { + self.qmf[1].synth(src, dst); + } + } + }, _ => { let ret = self.read_mp3_side_data(&mut br, &src[..frame_size], channels == 1); match ret { @@ -269,6 +289,10 @@ impl NAOptionHandler for MPADecoder { fn query_option_value(&self, _name: &str) -> Option { None } } +pub fn get_decoder_mp2() -> Box { + Box::new(MPADecoder::new(1)) +} + pub fn get_decoder_mp3() -> Box { Box::new(MPADecoder::new(2)) } @@ -304,20 +328,20 @@ impl MPAPacketiser { let mut br = BitReader::new(&self.buf[off..], BitReaderMode::BE); let syncword = br.read(11)?; - validate!(syncword == 0x7FF); + if syncword != 0x7FF { return Err(DecoderError::InvalidData); } let id = br.read(2)?; - validate!(id != 1); + if id == 1 { return Err(DecoderError::InvalidData); } let layer = (br.read(2)? ^ 3) as u8; - validate!(layer != 3); + if layer == 3 { return Err(DecoderError::InvalidData); } let _protection = br.read_bool()?; let bitrate_index = br.read(4)? as usize; - validate!(bitrate_index < 15); + if bitrate_index == 15 { return Err(DecoderError::InvalidData); } if bitrate_index == 0 { //todo freeform eventually unimplemented!(); } let mut sf_idx = br.read(2)? as usize; - validate!(sf_idx != 3); + if sf_idx == 3 { return Err(DecoderError::InvalidData); } let padding = br.read_bool()?; let _private = br.read_bool()?; let mode = br.read(2)? as u8; @@ -381,7 +405,12 @@ impl NAPacketiser for MPAPacketiser { } } let ainfo = NAAudioInfo::new(hdr.srate, hdr.channels, SND_F32P_FORMAT, hdr.nsamples); - let info = NACodecInfo::new("mp3", NACodecTypeInfo::Audio(ainfo), None); + let cname = match hdr.layer { + 0 => "mp1", + 1 => "mp2", + _ => "mp3", + }; + let info = NACodecInfo::new(cname, NACodecTypeInfo::Audio(ainfo), None); Ok(NAStream::new(StreamType::Audio, id, info, hdr.nsamples as u32, hdr.srate, duration).into_ref()) } fn skip_junk(&mut self) -> DecoderResult {