mov: take audio frame size/length into account while demuxing
[nihav.git] / nihav-commonfmt / src / demuxers / mov.rs
index 95e6d599e6d05866d54fa6ec449a1c16f28a0a4d..4904697e193a901b9b974f518ff90f559b75824f 100644 (file)
@@ -554,7 +554,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 +587,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 +725,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 +755,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 +846,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;
             }