use nihav_core::io::bitreader::*;
use nihav_codec_support::dsp::qmf::QMF;
+mod mp2data;
+mod mp2code;
+use mp2code::*;
mod mp3data;
mod mp3code;
use mp3code::*;
#[allow(clippy::large_enum_variant)]
enum LayerData {
MP1,
- MP2,
+ MP2(MP2Data),
MP3(MP3Data),
}
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(),
};
}
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!(),
};
ctx.mpeg1 = self.sf_idx < 3;
ctx.sf_idx = self.sf_idx;
ctx.read_mp3_side_data(br, channels)?;
- let hdr_size = (br.tell() / 8) as usize;
+ let hdr_size = br.tell() / 8;
let add_len = src.len() - hdr_size;
if self.bytebuf.len() + add_len > BYTEBUF_SIZE {
self.bytebuf.drain(..self.bytebuf.len() + add_len - BYTEBUF_SIZE);
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 {
fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
}
+pub fn get_decoder_mp2() -> Box<dyn NADecoder + Send> {
+ Box::new(MPADecoder::new(1))
+}
+
pub fn get_decoder_mp3() -> Box<dyn NADecoder + Send> {
Box::new(MPADecoder::new(2))
}
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;
}
impl NAPacketiser for MPAPacketiser {
+ fn attach_stream(&mut self, _stream: NAStreamRef) {}
fn add_data(&mut self, src: &[u8]) -> bool {
self.buf.extend_from_slice(src);
self.buf.len() < 4096
if (flags & 1) != 0 {
duration = u64::from(read_u32be(&self.buf[offset + 8..]).unwrap_or(0));
}
+ } else if self.buf.len() >= offset + 18 && &self.buf[offset..][..6] == b"VBRI\x00\x01" {
+ duration = u64::from(read_u32be(&self.buf[offset + 14..]).unwrap_or(0));
}
}
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<usize> {