X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fdemuxers%2Fmov.rs;h=9236baa1b0667d0132745e31e3465d959dafe193;hp=d90ff8377214c597557e5ccba74cea39390a7ecd;hb=a480a0de101483d802a11e72d758dae00fa4860a;hpb=89b16ac8f770b22585d0f70def9c952ffb48f33c diff --git a/nihav-commonfmt/src/demuxers/mov.rs b/nihav-commonfmt/src/demuxers/mov.rs index d90ff83..9236baa 100644 --- a/nihav-commonfmt/src/demuxers/mov.rs +++ b/nihav-commonfmt/src/demuxers/mov.rs @@ -239,7 +239,7 @@ fn read_cmov(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> Dem dmx.duration = ddmx.duration; dmx.tb_den = ddmx.tb_den; std::mem::swap(&mut dmx.pal, &mut ddmx.pal); - + Ok(size) } @@ -292,7 +292,7 @@ fn read_tkhd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult let _mtime = br.read_u32be()?; let track_id = br.read_u32be()?; br.read_skip(4)?; - let _duration = br.read_u32be()?; + let duration = br.read_u32be()?; br.read_skip(8)?; let _layer = br.read_u16be()?; let _alt_group = br.read_u16be()?; @@ -304,6 +304,7 @@ fn read_tkhd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult track.width = width >> 16; track.height = height >> 16; track.track_id = track_id; + track.duration = duration; track.tkhd_found = true; Ok(KNOWN_TKHD_SIZE) @@ -428,6 +429,14 @@ const STBL_CHUNK_HANDLERS: &[TrackChunkHandler] = &[ fn parse_audio_edata(br: &mut ByteReader, start_pos: u64, size: u64) -> DemuxerResult>> { 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 +563,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,10 +596,14 @@ 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_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; } let ahdr = NAAudioInfo::new(sample_rate >> 16, nchannels as u8, soniton, block_align); let edata = parse_audio_edata(br, start_pos, size)?; @@ -608,7 +622,7 @@ fn read_stsd(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult }; let read_size = br.tell() - start_pos; validate!(read_size <= size); - track.stream = Some(NAStream::new(track.stream_type, track.track_no, codec_info, 1, track.tb_den)); + track.stream = Some(NAStream::new(track.stream_type, track.track_no, codec_info, 1, track.tb_den, u64::from(track.duration))); track.stsd_found = true; Ok(read_size) } @@ -658,6 +672,9 @@ fn read_stsz(track: &mut Track, br: &mut ByteReader, size: u64) -> DemuxerResult let sample_size = br.read_u32be()?; if sample_size != 0 { track.sample_size = sample_size; + if track.sample_size != 1 || track.bsize == 0 { + track.bsize = sample_size as usize; + } Ok(8) } else { let entries = br.read_u32be()? as usize; @@ -702,6 +719,7 @@ struct Track { track_str_id: usize, track_no: u32, tb_den: u32, + duration: u32, depth: u8, tkhd_found: bool, stsd_found: bool, @@ -710,12 +728,14 @@ struct Track { height: usize, channels: usize, bits: usize, + bsize: usize, fcc: [u8; 4], keyframes: Vec, chunk_sizes: Vec, chunk_offsets: Vec, sample_map: Vec<(u32, u32)>, sample_size: u32, + frame_samples: usize, stream: Option, cur_chunk: usize, cur_sample: usize, @@ -733,17 +753,20 @@ impl Track { track_str_id: 0, track_no, tb_den, + duration: 0, stream_type: StreamType::None, width: 0, height: 0, channels: 0, bits: 0, + bsize: 0, fcc: [0; 4], keyframes: Vec::new(), chunk_sizes: Vec::new(), chunk_offsets: Vec::new(), sample_map: Vec::new(), sample_size: 0, + frame_samples: 0, stream: None, depth: 0, cur_chunk: 0, @@ -773,7 +796,7 @@ impl Track { } fn calculate_chunk_size(&self, nsamp: usize) -> usize { if nsamp == 0 { - self.sample_size as usize + self.bsize } else { match &self.fcc { b"NONE" | b"raw " | b"twos" | b"sowt" => { @@ -799,7 +822,7 @@ impl Track { b"ms\x00\x21" => { //IMA ADPCM (nsamp / 2 + 4) * self.channels }, - _ => self.sample_size as usize, + _ => self.bsize, } } } @@ -834,6 +857,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; } @@ -855,7 +886,7 @@ impl Track { } self.calculate_chunk_size(nsamp as usize) } else { - self.sample_size as usize + self.bsize } } fn seek(&mut self, pts: u64) { @@ -934,7 +965,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); @@ -945,6 +976,13 @@ impl<'a> DemuxCore<'a> for MOVDemuxer<'a> { } Ok(()) } + fn get_duration(&self) -> u64 { + if self.tb_den != 0 { + u64::from(self.duration) * 1000 / u64::from(self.tb_den) + } else { + 0 + } + } } impl<'a> NAOptionHandler for MOVDemuxer<'a> {