X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-core%2Fsrc%2Fdemuxers%2Fmod.rs;h=dfcd11836e0e7d6dcba1c396ec254ab5a150a5f9;hp=9a69abb18c6d3d11c7b6a3241069be90e8706957;hb=a480a0de101483d802a11e72d758dae00fa4860a;hpb=cec53b883696692aab5db70045be143ff0be01ea diff --git a/nihav-core/src/demuxers/mod.rs b/nihav-core/src/demuxers/mod.rs index 9a69abb..dfcd118 100644 --- a/nihav-core/src/demuxers/mod.rs +++ b/nihav-core/src/demuxers/mod.rs @@ -37,7 +37,9 @@ pub trait DemuxCore<'a>: NAOptionHandler { /// Demuxes a packet. fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult; /// Seeks to the requested time. - fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()>; + fn seek(&mut self, time: NATimePoint, seek_idx: &SeekIndex) -> DemuxerResult<()>; + /// Returns container duration in milliseconds (zero if not available). + fn get_duration(&self) -> u64; } /// An auxiliary trait to make bytestream reader read packet data. @@ -88,7 +90,7 @@ impl StreamManager { /// Adds a new stream. pub fn add_stream(&mut self, stream: NAStream) -> Option { let stream_num = self.streams.len(); - let mut str = stream.clone(); + let mut str = stream; str.set_num(stream_num); self.streams.push(str.into_ref()); self.ignored.push(false); @@ -229,16 +231,31 @@ impl StreamSeekInfo { self.entries.push(entry); } /// Searches for an appropriate seek position before requested time. - pub fn find_pos(&self, time: u64) -> Option { + pub fn find_pos(&self, time: NATimePoint) -> Option { + if time == NATimePoint::None { + return None; + } if !self.entries.is_empty() { // todo something faster like binary search let mut cand = None; for entry in self.entries.iter() { - if entry.time <= time { - cand = Some(*entry); - } else { - break; - } + match time { + NATimePoint::Milliseconds(ms) => { + if entry.time <= ms { + cand = Some(*entry); + } else { + break; + } + }, + NATimePoint::PTS(pts) => { + if entry.pts <= pts { + cand = Some(*entry); + } else { + break; + } + }, + NATimePoint::None => unreachable!(), + }; } cand } else { @@ -309,7 +326,7 @@ impl SeekIndex { self.seek_info[idx.unwrap()].filled = true; } /// Searches for a seek position before requested time. - pub fn find_pos(&self, time: u64) -> Option { + pub fn find_pos(&self, time: NATimePoint) -> Option { let mut cand = None; for str in self.seek_info.iter() { if !str.filled { continue; } @@ -389,8 +406,8 @@ impl<'a> Demuxer<'a> { } } } - /// Seeks to the requested time (in milliseconds) if possible. - pub fn seek(&mut self, time: u64) -> DemuxerResult<()> { + /// Seeks to the requested time if possible. + pub fn seek(&mut self, time: NATimePoint) -> DemuxerResult<()> { if self.seek_idx.skip_index { return Err(DemuxerError::NotPossible); } @@ -400,6 +417,25 @@ impl<'a> Demuxer<'a> { pub fn get_seek_index(&self) -> &SeekIndex { &self.seek_idx } + /// Returns media duration reported by container or its streams. + /// + /// Duration is in milliseconds and set to zero when it is not available. + pub fn get_duration(&self) -> u64 { + let duration = self.dmx.get_duration(); + if duration != 0 { + return duration; + } + let mut duration = 0; + for stream in self.streams.iter() { + if stream.duration > 0 { + let dur = NATimeInfo::ts_to_time(stream.duration, 1000, stream.tb_num, stream.tb_den); + if duration < dur { + duration = dur; + } + } + } + duration + } } impl<'a> NAOptionHandler for Demuxer<'a> { @@ -427,7 +463,7 @@ pub trait DemuxerCreator { } /// Creates demuxer for a provided bytestream. -pub fn create_demuxer<'a>(dmxcr: &DemuxerCreator, br: &'a mut ByteReader<'a>) -> DemuxerResult> { +pub fn create_demuxer<'a>(dmxcr: &dyn DemuxerCreator, br: &'a mut ByteReader<'a>) -> DemuxerResult> { let mut dmx = dmxcr.new_demuxer(br); let mut str = StreamManager::new(); let mut seek_idx = SeekIndex::new(); @@ -438,7 +474,7 @@ pub fn create_demuxer<'a>(dmxcr: &DemuxerCreator, br: &'a mut ByteReader<'a>) -> /// List of registered demuxers. #[derive(Default)] pub struct RegisteredDemuxers { - dmxs: Vec<&'static DemuxerCreator>, + dmxs: Vec<&'static dyn DemuxerCreator>, } impl RegisteredDemuxers { @@ -447,11 +483,11 @@ impl RegisteredDemuxers { Self { dmxs: Vec::new() } } /// Registers a new demuxer. - pub fn add_demuxer(&mut self, dmx: &'static DemuxerCreator) { + pub fn add_demuxer(&mut self, dmx: &'static dyn DemuxerCreator) { self.dmxs.push(dmx); } /// Searches for a demuxer that supports requested container format. - pub fn find_demuxer(&self, name: &str) -> Option<&DemuxerCreator> { + pub fn find_demuxer(&self, name: &str) -> Option<&dyn DemuxerCreator> { for &dmx in self.dmxs.iter() { if dmx.get_name() == name { return Some(dmx); @@ -460,7 +496,7 @@ impl RegisteredDemuxers { None } /// Provides an iterator over currently registered demuxers. - pub fn iter(&self) -> std::slice::Iter<&DemuxerCreator> { + pub fn iter(&self) -> std::slice::Iter<&dyn DemuxerCreator> { self.dmxs.iter() } }