X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Fdemuxers%2Fmod.rs;h=ee2fe58ae871aa604a05ee13b0092acf0153ad4b;hb=9da33f04bbd89f18942bbafc6d135b5d3f102953;hp=201e163b484116d13f0decbfac756c7532399ce0;hpb=4e8b4f31bc2ef2b22b4c725aa07dfc776664a97b;p=nihav.git diff --git a/nihav-core/src/demuxers/mod.rs b/nihav-core/src/demuxers/mod.rs index 201e163..ee2fe58 100644 --- a/nihav-core/src/demuxers/mod.rs +++ b/nihav-core/src/demuxers/mod.rs @@ -1,4 +1,3 @@ -use std::rc::Rc; pub use crate::frame::*; pub use crate::io::byteio::*; @@ -12,42 +11,43 @@ pub enum DemuxerError { NotImplemented, MemoryError, TryAgain, + SeekError, + NotPossible, } pub type DemuxerResult = Result; pub trait DemuxCore<'a> { - fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()>; + fn open(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<()>; fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult; - fn seek(&mut self, time: u64) -> DemuxerResult<()>; + fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()>; } pub trait NAPacketReader { - fn read_packet(&mut self, str: Rc, ts: NATimeInfo, keyframe: bool, size: usize) -> DemuxerResult; + fn read_packet(&mut self, str: NAStreamRef, ts: NATimeInfo, keyframe: bool, size: usize) -> DemuxerResult; fn fill_packet(&mut self, pkt: &mut NAPacket) -> DemuxerResult<()>; } impl<'a> NAPacketReader for ByteReader<'a> { - fn read_packet(&mut self, str: Rc, ts: NATimeInfo, kf: bool, size: usize) -> DemuxerResult { + fn read_packet(&mut self, str: NAStreamRef, ts: NATimeInfo, kf: bool, size: usize) -> DemuxerResult { let mut buf: Vec = Vec::with_capacity(size); if buf.capacity() < size { return Err(DemuxerError::MemoryError); } buf.resize(size, 0); - let res = self.read_buf(buf.as_mut_slice()); - if let Err(_) = res { return Err(DemuxerError::IOError); } + self.read_buf(buf.as_mut_slice())?; let pkt = NAPacket::new(str, ts, kf, buf); Ok(pkt) } fn fill_packet(&mut self, pkt: &mut NAPacket) -> DemuxerResult<()> { let mut refbuf = pkt.get_buffer(); - let buf = Rc::make_mut(&mut refbuf); - let res = self.read_buf(buf.as_mut_slice()); - if let Err(_) = res { return Err(DemuxerError::IOError); } + let buf = refbuf.as_mut().unwrap(); + self.read_buf(buf.as_mut_slice())?; Ok(()) } } +#[derive(Default)] pub struct StreamManager { - streams: Vec>, + streams: Vec, ignored: Vec, no_ign: bool, } @@ -66,18 +66,18 @@ impl StreamManager { let stream_num = self.streams.len(); let mut str = stream.clone(); str.set_num(stream_num); - self.streams.push(Rc::new(str)); + self.streams.push(str.into_ref()); self.ignored.push(false); Some(stream_num) } - pub fn get_stream(&self, idx: usize) -> Option> { + pub fn get_stream(&self, idx: usize) -> Option { if idx < self.streams.len() { Some(self.streams[idx].clone()) } else { None } } - pub fn get_stream_by_id(&self, id: u32) -> Option> { + pub fn get_stream_by_id(&self, id: u32) -> Option { for i in 0..self.streams.len() { if self.streams[i].get_id() == id { return Some(self.streams[i].clone()); @@ -117,18 +117,18 @@ impl StreamManager { } pub struct StreamIter<'a> { - streams: &'a Vec>, + streams: &'a [NAStreamRef], pos: usize, } impl<'a> StreamIter<'a> { - pub fn new(streams: &'a Vec>) -> Self { - StreamIter { streams: streams, pos: 0 } + pub fn new(streams: &'a [NAStreamRef]) -> Self { + StreamIter { streams, pos: 0 } } } impl<'a> Iterator for StreamIter<'a> { - type Item = Rc; + type Item = NAStreamRef; fn next(&mut self) -> Option { if self.pos >= self.streams.len() { return None; } @@ -138,22 +138,146 @@ impl<'a> Iterator for StreamIter<'a> { } } +#[derive(Clone,Copy,PartialEq)] +pub enum SeekIndexMode { + None, + Present, + Automatic, +} + +impl Default for SeekIndexMode { + fn default() -> Self { SeekIndexMode::None } +} + +#[derive(Clone,Copy,Default)] +pub struct SeekEntry { + pub time: u64, // in milliseconds + pub pts: u64, + pub pos: u64, +} + +#[derive(Clone)] +pub struct StreamSeekInfo { + pub id: u32, + pub filled: bool, + pub entries: Vec, +} + +impl StreamSeekInfo { + pub fn new(id: u32) -> Self { + Self { + id, + filled: false, + entries: Vec::new(), + } + } + pub fn add_entry(&mut self, entry: SeekEntry) { + self.entries.push(entry); + } + pub fn find_pos(&self, time: u64) -> Option { + 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; + } + } + cand + } else { + None + } + } +} + +#[derive(Clone,Copy,Default)] +pub struct SeekIndexResult { + pub pts: u64, + pub pos: u64, + pub str_id: u32, +} + +#[derive(Default)] +pub struct SeekIndex { + pub seek_info: Vec, + pub mode: SeekIndexMode, + pub skip_index: bool, +} + +impl SeekIndex { + pub fn new() -> Self { Self::default() } + pub fn add_stream(&mut self, id: u32) -> usize { + let ret = self.stream_id_to_index(id); + if ret.is_none() { + self.seek_info.push(StreamSeekInfo::new(id)); + self.seek_info.len() - 1 + } else { + ret.unwrap() + } + } + pub fn stream_id_to_index(&self, id: u32) -> Option { + for (idx, str) in self.seek_info.iter().enumerate() { + if str.id == id { + return Some(idx); + } + } + None + } + pub fn get_stream_index(&mut self, id: u32) -> Option<&mut StreamSeekInfo> { + for str in self.seek_info.iter_mut() { + if str.id == id { + return Some(str); + } + } + None + } + pub fn add_entry(&mut self, id: u32, entry: SeekEntry) { + let mut idx = self.stream_id_to_index(id); + if idx.is_none() { + idx = Some(self.add_stream(id)); + } + self.seek_info[idx.unwrap()].add_entry(entry); + self.seek_info[idx.unwrap()].filled = true; + } + pub fn find_pos(&self, time: u64) -> Option { + let mut cand = None; + for str in self.seek_info.iter() { + if !str.filled { continue; } + let res = str.find_pos(time); + if res.is_none() { continue; } + let res = res.unwrap(); + if cand.is_none() { + cand = Some(SeekIndexResult { pts: res.pts, pos: res.pos, str_id: str.id }); + } else if let Some(entry) = cand { + if res.pos < entry.pos { + cand = Some(SeekIndexResult { pts: res.pts, pos: res.pos, str_id: str.id }); + } + } + } + cand + } +} + pub struct Demuxer<'a> { - dmx: Box + 'a>, + dmx: Box + 'a>, streams: StreamManager, + seek_idx: SeekIndex, } impl<'a> Demuxer<'a> { - fn new(dmx: Box + 'a>, str: StreamManager) -> Self { + fn new(dmx: Box + 'a>, str: StreamManager, seek_idx: SeekIndex) -> Self { Demuxer { - dmx: dmx, + dmx, streams: str, + seek_idx, } } - pub fn get_stream(&self, idx: usize) -> Option> { + pub fn get_stream(&self, idx: usize) -> Option { self.streams.get_stream(idx) } - pub fn get_stream_by_id(&self, id: u32) -> Option> { + pub fn get_stream_by_id(&self, id: u32) -> Option { self.streams.get_stream_by_id(id) } pub fn get_num_streams(&self) -> usize { @@ -184,7 +308,13 @@ impl<'a> Demuxer<'a> { } } pub fn seek(&mut self, time: u64) -> DemuxerResult<()> { - self.dmx.seek(time) + if self.seek_idx.skip_index { + return Err(DemuxerError::NotPossible); + } + self.dmx.seek(time, &self.seek_idx) + } + pub fn get_seek_index(&self) -> &SeekIndex { + &self.seek_idx } } @@ -195,7 +325,7 @@ impl From for DemuxerError { ///The structure used to create demuxers. pub trait DemuxerCreator { /// Create new demuxer instance that will use `ByteReader` source as an input. - fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box + 'a>; + fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box + 'a>; /// Get the name of current demuxer creator. fn get_name(&self) -> &'static str; } @@ -203,10 +333,12 @@ pub trait DemuxerCreator { pub fn create_demuxer<'a>(dmxcr: &DemuxerCreator, br: &'a mut ByteReader<'a>) -> DemuxerResult> { let mut dmx = dmxcr.new_demuxer(br); let mut str = StreamManager::new(); - dmx.open(&mut str)?; - Ok(Demuxer::new(dmx, str)) + let mut seek_idx = SeekIndex::new(); + dmx.open(&mut str, &mut seek_idx)?; + Ok(Demuxer::new(dmx, str, seek_idx)) } +#[derive(Default)] pub struct RegisteredDemuxers { dmxs: Vec<&'static DemuxerCreator>, } @@ -226,4 +358,4 @@ impl RegisteredDemuxers { } None } -} \ No newline at end of file +}