use NATimePoint for seeking
[nihav.git] / nihav-commonfmt / src / demuxers / mov.rs
index 95e6d599e6d05866d54fa6ec449a1c16f28a0a4d..47cfbe3ef0eb9af414d11ee8f006ba46bc88cb75 100644 (file)
@@ -428,6 +428,14 @@ const STBL_CHUNK_HANDLERS: &[TrackChunkHandler] = &[
 fn parse_audio_edata(br: &mut ByteReader, start_pos: u64, size: u64) -> DemuxerResult<Option<Vec<u8>>> {
     let read_part = br.tell() - start_pos;
     if read_part + 8 < size {
+        let mut buf = [0; 8];
+                              br.peek_buf(&mut buf)?;
+        if &buf[4..8] != b"wave" {
+            let mut buf = vec![0; (size - read_part) as usize];
+                              br.read_buf(&mut buf)?;
+            return Ok(Some(buf));
+        }
+
         let csize           = br.read_u32be()? as u64;
         let ctag            = br.read_u32be()?;
         validate!(read_part + csize <= size);
@@ -554,7 +562,8 @@ fn read_stsd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult
             let edata = if br.tell() - start_pos + 4 < size {
 //todo skip various common atoms
                     let edata_size  = br.read_u32be()? as usize;
-                    let mut buf = vec![0; edata_size];
+                    validate!(edata_size >= 4);
+                    let mut buf = vec![0; edata_size - 4];
                                   br.read_buf(buf.as_mut_slice())?;
                     Some(buf)
                 } else {
@@ -586,11 +595,12 @@ fn read_stsd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult
             let soniton = NASoniton::new(sample_size as u8, SONITON_FLAG_SIGNED | SONITON_FLAG_BE);
             let block_align = 1;
             if sver == 1 {
-                let _samples_per_packet     = br.read_u32be()?;
+                let samples_per_packet      = br.read_u32be()?;
                 let _bytes_per_packet       = br.read_u32be()?;
                 let bytes_per_frame         = br.read_u32be()?;
                 let _bytes_per_sample       = br.read_u32be()?;
                 track.bsize = bytes_per_frame as usize;
+                track.frame_samples = samples_per_packet as usize;
             } else {
                 track.bsize = sample_size as usize;
             }
@@ -723,6 +733,7 @@ struct Track {
     chunk_offsets:  Vec<u64>,
     sample_map:     Vec<(u32, u32)>,
     sample_size:    u32,
+    frame_samples:  usize,
     stream:         Option<NAStream>,
     cur_chunk:      usize,
     cur_sample:     usize,
@@ -752,6 +763,7 @@ impl Track {
             chunk_offsets:  Vec::new(),
             sample_map:     Vec::new(),
             sample_size:    0,
+            frame_samples:  0,
             stream:         None,
             depth:          0,
             cur_chunk:      0,
@@ -842,6 +854,14 @@ impl Track {
             self.last_offset += size as u64;
             if self.stream_type == StreamType::Video {
                 self.samples_left -= 1;
+            } else if self.frame_samples != 0 && self.bsize != 0 {
+                let nblocks = size / self.bsize;
+                if nblocks > 0 {
+                    let consumed = (nblocks * self.frame_samples).min(self.samples_left);
+                    self.samples_left -= consumed;
+                } else {
+                    self.samples_left = 0;
+                }
             } else {
                 self.samples_left = 0;
             }
@@ -942,7 +962,7 @@ impl<'a> DemuxCore<'a> for MOVDemuxer<'a> {
         Err(DemuxerError::EOF)
     }
 
-    fn seek(&mut self, time: u64, seek_index: &SeekIndex) -> DemuxerResult<()> {
+    fn seek(&mut self, time: NATimePoint, seek_index: &SeekIndex) -> DemuxerResult<()> {
         let ret = seek_index.find_pos(time);
         if ret.is_none() {
             return Err(DemuxerError::SeekError);