switch demuxers to use NAStream::make_ts()
[nihav.git] / nihav-llaudio / src / demuxers / ape.rs
index 2969c786d9e5750a4fb2e5f13dcac8616e4b223f..76717378ff201c2aaa878140b536b67a60b0d6e0 100644 (file)
@@ -15,6 +15,7 @@ struct APEDemuxer<'a> {
     normal_blocks:  u32,
     last_blocks:    u32,
     truncated:      bool,
+    duration:       u64,
 }
 
 impl<'a> APEDemuxer<'a> {
@@ -26,6 +27,7 @@ impl<'a> APEDemuxer<'a> {
             normal_blocks:  0,
             last_blocks:    0,
             truncated:      false,
+            duration:       0,
         }
     }
 }
@@ -37,7 +39,7 @@ impl<'a> DemuxCore<'a> for APEDemuxer<'a> {
         let tag                         = src.read_tag()?;
         validate!(&tag == b"MAC ");
         let version                     = src.read_u16le()?;
-        validate!(version >= 3800 && version <= 3990);
+        validate!((3800..=3990).contains(&version));
 
         let seektab_len;
         let _wavtail_len;
@@ -114,11 +116,12 @@ impl<'a> DemuxCore<'a> for APEDemuxer<'a> {
         validate!(channels > 0 && channels < 256);
         validate!(bits > 0 && bits <= 32);
         validate!(nframes > 0 && nframes < (1 << 28));
-        validate!(seektab_len == nframes * 4);
+        validate!(seektab_len >= nframes * 4);
 
         self.frames = Vec::with_capacity(nframes);
         self.normal_blocks = blocksperframe;
         self.last_blocks   = finalblocks;
+        self.duration = (((nframes - 1) as u64) * u64::from(blocksperframe) + u64::from(finalblocks)) * 1000 / u64::from(srate);
 
         seek_index.mode = SeekIndexMode::Present;
         let first_off                   = src.peek_u32le()?;
@@ -178,7 +181,7 @@ impl<'a> DemuxCore<'a> for APEDemuxer<'a> {
 
         let ahdr = NAAudioInfo::new(srate, channels as u8, SND_S16P_FORMAT, 1);
         let ainfo = NACodecInfo::new("ape", NACodecTypeInfo::Audio(ahdr), Some(hdr));
-        strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, blocksperframe, srate)).unwrap();
+        strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, blocksperframe, srate, nframes as u64)).unwrap();
 
         self.cur_frame = 0;
 
@@ -202,8 +205,7 @@ impl<'a> DemuxCore<'a> for APEDemuxer<'a> {
                                           self.src.read_buf(&mut buf[8..])?;
 
         let stream = strmgr.get_stream(0).unwrap();
-        let (tb_num, tb_den) = stream.get_timebase();
-        let ts = NATimeInfo::new(Some(self.cur_frame as u64), None, None, tb_num, tb_den);
+        let ts = stream.make_ts(Some(self.cur_frame as u64), None, None);
         let pkt = NAPacket::new(stream, ts, true, buf);
 
         self.cur_frame += 1;
@@ -223,6 +225,7 @@ impl<'a> DemuxCore<'a> for APEDemuxer<'a> {
 
         Ok(())
     }
+    fn get_duration(&self) -> u64 { self.duration }
 }
 
 impl<'a> NAOptionHandler for APEDemuxer<'a> {
@@ -247,6 +250,7 @@ mod test {
 
     #[test]
     fn test_ape_demux() {
+        // sample: https://samples.mplayerhq.hu/A-codecs/lossless/luckynight.ape
         let mut file = File::open("assets/LLaudio/ape/luckynight.ape").unwrap();
         let mut fr = FileReader::new_read(&mut file);
         let mut br = ByteReader::new(&mut fr);