aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2021-11-22 18:44:32 +0100
committerKostya Shishkov <kostya.shishkov@gmail.com>2021-11-22 18:44:32 +0100
commita091b9684d877827287a51259edce3140112667a (patch)
tree2053cc97fb83238119f11733589d56eeaaeb1534
parenta4def632d32d037e7cf4740290ba99fc14e998c8 (diff)
downloadnihav-a091b9684d877827287a51259edce3140112667a.tar.gz
mpegaudio: get duration from Xing/LAME information if available
-rw-r--r--nihav-mpeg/src/codecs/mpegaudio/mod.rs19
1 files changed, 18 insertions, 1 deletions
diff --git a/nihav-mpeg/src/codecs/mpegaudio/mod.rs b/nihav-mpeg/src/codecs/mpegaudio/mod.rs
index 0ca85f5..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<usize> {
if self.buf.len() <= 2 {