X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fdemuxers%2Fwav.rs;h=2164619d74085ecde706b107a10482535b286920;hp=f9c955154e36d0c69d3700685f5ea6fb58040a43;hb=a480a0de101483d802a11e72d758dae00fa4860a;hpb=61cab15b810434b8e62234ab5cdfcb17ec2d566d diff --git a/nihav-commonfmt/src/demuxers/wav.rs b/nihav-commonfmt/src/demuxers/wav.rs index f9c9551..2164619 100644 --- a/nihav-commonfmt/src/demuxers/wav.rs +++ b/nihav-commonfmt/src/demuxers/wav.rs @@ -19,13 +19,14 @@ struct WAVDemuxer<'a> { block_size: usize, is_pcm: bool, avg_bytes: u32, + duration: u64, } impl<'a> DemuxCore<'a> for WAVDemuxer<'a> { fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> { let riff = self.src.read_u32be()?; let riff_size = self.src.read_u32le()? as usize; - let riff_end = self.src.tell() + if riff_size > 0 { (riff_size as u64) } else { u64::from(std::u32::MAX) }; + let riff_end = self.src.tell() + if riff_size > 0 { riff_size as u64 } else { u64::from(std::u32::MAX) }; let wave = self.src.read_u32be()?; validate!(riff == mktag!(b"RIFF")); validate!(wave == mktag!(b"WAVE")); @@ -33,7 +34,7 @@ impl<'a> DemuxCore<'a> for WAVDemuxer<'a> { seek_index.mode = SeekIndexMode::Automatic; let mut fmt_parsed = false; - let mut _duration = 0; + let mut duration = 0; while self.src.tell() < riff_end { let ctype = self.src.read_tag()?; let csize = self.src.read_u32le()? as usize; @@ -45,12 +46,21 @@ impl<'a> DemuxCore<'a> for WAVDemuxer<'a> { }, b"fact" => { validate!(csize == 4); - _duration = self.src.read_u32le()? as usize; + duration = self.src.read_u32le()? as usize; }, b"data" => { validate!(fmt_parsed); self.data_pos = self.src.tell(); self.data_end = self.data_pos + (csize as u64); + + if duration != 0 { + self.duration = (duration as u64) * 1000 / u64::from(self.srate); + } else if self.avg_bytes > 0 { + self.duration = (self.data_end - self.data_pos) * 1000 / u64::from(self.avg_bytes); + } else { + self.duration = 0; + } + return Ok(()); }, _ => { @@ -68,7 +78,13 @@ impl<'a> DemuxCore<'a> for WAVDemuxer<'a> { let str = strmgr.get_stream(0); if str.is_none() { return Err(InvalidData); } let stream = str.unwrap(); - let ts = NATimeInfo::new(None, None, None, 1, self.srate); + let pts = if self.avg_bytes != 0 { + let pos = self.src.tell() - self.data_pos; + Some(pos * u64::from(self.srate) / u64::from(self.avg_bytes)) + } else { + None + }; + let ts = NATimeInfo::new(pts, None, None, 1, self.srate); if self.is_pcm { let mut bsize = self.block_size; while bsize < 256 { @@ -83,16 +99,24 @@ impl<'a> DemuxCore<'a> for WAVDemuxer<'a> { } } - fn seek(&mut self, time: u64, _seek_index: &SeekIndex) -> DemuxerResult<()> { + fn seek(&mut self, time: NATimePoint, _seek_index: &SeekIndex) -> DemuxerResult<()> { if self.block_size != 0 && self.avg_bytes != 0 { - let seek_dst = u64::from(self.avg_bytes) * time / 1000; - let seek_off = seek_dst / (self.block_size as u64) * (self.block_size as u64); + let seek_off = match time { + NATimePoint::Milliseconds(ms) => { + let seek_dst = u64::from(self.avg_bytes) * ms / 1000; + seek_dst / (self.block_size as u64) * (self.block_size as u64) + }, + NATimePoint::PTS(pts) => (self.block_size as u64) * pts, + NATimePoint::None => return Ok(()), + }; self.src.seek(SeekFrom::Start(self.data_pos + seek_off))?; Ok(()) } else { Err(DemuxerError::NotImplemented) } } + + fn get_duration(&self) -> u64 { self.duration } } impl<'a> NAOptionHandler for WAVDemuxer<'a> { @@ -111,6 +135,7 @@ impl<'a> WAVDemuxer<'a> { block_size: 0, is_pcm: false, avg_bytes: 0, + duration: 0, } } fn parse_fmt(&mut self, strmgr: &mut StreamManager, csize: usize) -> DemuxerResult<()> { @@ -153,13 +178,16 @@ impl<'a> WAVDemuxer<'a> { }; let ahdr = NAAudioInfo::new(samples_per_sec, channels as u8, soniton, block_align); let ainfo = NACodecInfo::new(cname, NACodecTypeInfo::Audio(ahdr), edata); - let res = strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, 1, samples_per_sec)); + let res = strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, 1, samples_per_sec, 0)); if res.is_none() { return Err(MemoryError); } self.srate = samples_per_sec; self.block_size = block_align; self.avg_bytes = avg_bytes_per_sec; self.is_pcm = cname == "pcm"; + if self.is_pcm && self.avg_bytes == 0 { + self.avg_bytes = self.block_size as u32 * self.srate; + } Ok(()) }