X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-mpeg%2Fsrc%2Fcodecs%2Fmpegaudio%2Fmod.rs;h=187a695938de6f62d01485c446f1496820ca96d7;hb=556509ab9495f191dac5531be40930daeb7562d0;hp=6c908d825e35609cc262c9ec621421a47428a72a;hpb=f27c73df2e609d8d96790333d8aad65ddd6f0df4;p=nihav.git diff --git a/nihav-mpeg/src/codecs/mpegaudio/mod.rs b/nihav-mpeg/src/codecs/mpegaudio/mod.rs index 6c908d8..187a695 100644 --- a/nihav-mpeg/src/codecs/mpegaudio/mod.rs +++ b/nihav-mpeg/src/codecs/mpegaudio/mod.rs @@ -1,4 +1,5 @@ use nihav_core::codecs::*; +use nihav_core::io::byteio::read_u32be; use nihav_core::io::bitreader::*; use nihav_codec_support::dsp::qmf::QMF; @@ -361,9 +362,25 @@ impl NAPacketiser for MPAPacketiser { self.hdr = Some(hdr); } let hdr = self.hdr.unwrap(); + let mut duration = 0; + if hdr.layer == 2 { // check for Xing/LAME info + let mpeg1 = hdr.srate >= 32000; + let offset = match (mpeg1, hdr.channels) { + (true, 1) => 24, + (true, _) => 36, + (false, 1) => 13, + (false, _) => 21, + }; + if self.buf.len() >= offset + 12 && (&self.buf[offset..][..4] == b"Xing" || &self.buf[offset..][..4] == b"Info") { + let flags = read_u32be(&self.buf[offset + 4..]).unwrap_or(0); + if (flags & 1) != 0 { + duration = u64::from(read_u32be(&self.buf[offset + 8..]).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); - Ok(NAStream::new(StreamType::Audio, id, info, hdr.nsamples as u32, hdr.srate, 0).into_ref()) + Ok(NAStream::new(StreamType::Audio, id, info, hdr.nsamples as u32, hdr.srate, duration).into_ref()) } fn skip_junk(&mut self) -> DecoderResult { if self.buf.len() <= 2 { @@ -426,6 +443,7 @@ impl NAPacketiser for MPAPacketiser { fn reset(&mut self) { self.buf.clear(); } + fn bytes_left(&self) -> usize { self.buf.len() } } pub fn get_packetiser() -> Box { @@ -449,6 +467,7 @@ mod test { let mut dec_reg = RegisteredDecoders::new(); mpeg_register_all_decoders(&mut dec_reg); + // sample: https://samples.mplayerhq.hu/FLV/flash_video_5/i_004.flv let file = "assets/Flash/i_004.flv"; test_decode_audio("flv", file, Some(6000), None/*Some("mp3_1")*/, &dmx_reg, &dec_reg); } @@ -459,6 +478,7 @@ mod test { let mut dec_reg = RegisteredDecoders::new(); mpeg_register_all_decoders(&mut dec_reg); + // sample: https://samples.mplayerhq.hu/FLV/venture_030_ivcp_001_8bit.flv let file = "assets/Flash/venture_030_ivcp_001_8bit.flv"; test_decode_audio("flv", file, Some(7200), None/*Some("mp3_2")*/, &dmx_reg, &dec_reg); } @@ -469,12 +489,14 @@ mod test { let mut dec_reg = RegisteredDecoders::new(); mpeg_register_all_decoders(&mut dec_reg); + // sample: https://samples.mplayerhq.hu/FLV/flash_with_alpha/lection2-2.flv let file = "assets/Flash/lection2-2.flv"; test_decode_audio("flv", file, Some(6000), None/*Some("mp3_3")*/, &dmx_reg, &dec_reg); } #[test] fn test_mpa_packetiser() { let mut buf = [0; 16384]; + // sample from a private collection let mut file = std::fs::File::open("assets/MPEG/1.mp3").unwrap(); let mut pkts = super::MPAPacketiser::new();