num_streams: u8,
size: usize,
movi_size: usize,
+ movi_pos: u64,
+ movi_orig: usize,
sstate: StreamState,
tb_num: u32,
tb_den: u32,
impl<'a> DemuxCore<'a> for AVIDemuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> {
self.read_header(strmgr)?;
Ok(())
}
}
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- Err(NotImplemented)
+ fn seek(&mut self, time: u64, seek_index: &SeekIndex) -> DemuxerResult<()> {
+ let ret = seek_index.find_pos(time);
+ if ret.is_none() {
+ return Err(DemuxerError::SeekError);
+ }
+ let pos = ret.unwrap().pos;
+ self.src.seek(SeekFrom::Start(pos))?;
+
+ let cur_pos = self.src.tell();
+ if cur_pos < self.movi_pos { return Err(DemuxerError::SeekError); }
+ let skip_size = (cur_pos - self.movi_pos) as usize;
+ if skip_size > self.movi_size { return Err(DemuxerError::SeekError); }
+ self.movi_size = self.movi_orig - skip_size;
+
+ Ok(())
}
}
src: io,
size: 0,
movi_size: 0,
+ movi_pos: 0,
+ movi_orig: 0,
sstate: StreamState::new(),
tb_num: 0,
tb_den: 0,
let mut rest_size = size;
loop {
let (csz, end) = self.parse_chunk(strmgr, RIFFTag::List(mktag!(b"LIST"), mktag!(b"movi")), rest_size,0)?;
- if end { self.movi_size = csz - 4; break; }
+ if end {
+ self.movi_size = csz - 4;
+ self.movi_orig = self.movi_size;
+ self.movi_pos = self.src.tell();
+ break;
+ }
rest_size -= csz;
}
+//todo read index
if !self.sstate.valid_state() || self.sstate.strm_no != self.num_streams {
return Err(InvalidData);
}
NotImplemented,
MemoryError,
TryAgain,
+ SeekError,
+ NotPossible,
}
pub type DemuxerResult<T> = Result<T, DemuxerError>;
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<NAPacket>;
- fn seek(&mut self, time: u64) -> DemuxerResult<()>;
+ fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()>;
}
pub trait NAPacketReader {
}
}
+#[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 pts: u64,
+ pub pos: u64,
+}
+
+#[derive(Clone)]
+pub struct StreamSeekInfo {
+ pub id: u32,
+ pub tb_num: u32,
+ pub tb_den: u32,
+ pub filled: bool,
+ pub entries: Vec<SeekEntry>,
+}
+
+impl StreamSeekInfo {
+ pub fn new(id: u32, tb_num: u32, tb_den: u32) -> Self {
+ Self {
+ id, tb_num, tb_den,
+ filled: false,
+ entries: Vec::new(),
+ }
+ }
+ pub fn add_entry(&mut self, entry: SeekEntry) {
+ self.entries.push(entry);
+ }
+ pub fn find_pos(&self, pts: u64) -> Option<u64> {
+ if !self.entries.is_empty() {
+// todo something faster like binary search
+ let mut cand = 0;
+ for (idx, entry) in self.entries.iter().enumerate() {
+ if entry.pts <= pts {
+ cand = idx;
+ } else {
+ break;
+ }
+ }
+ Some(self.entries[cand].pos)
+ } 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<StreamSeekInfo>,
+ pub mode: SeekIndexMode,
+}
+
+impl SeekIndex {
+ pub fn new() -> Self { Self::default() }
+ pub fn add_stream(&mut self, id: u32, tb_num: u32, tb_den: u32) {
+ if self.stream_id_to_index(id).is_none() {
+ self.seek_info.push(StreamSeekInfo::new(id, tb_num, tb_den));
+ }
+ }
+ pub fn stream_id_to_index(&self, id: u32) -> Option<usize> {
+ for (idx, str) in self.seek_info.iter().enumerate() {
+ if str.id == id {
+ return Some(idx);
+ }
+ }
+ None
+ }
+ pub fn find_pos(&self, time: u64) -> Option<SeekIndexResult> {
+ let mut cand = None;
+ for str in self.seek_info.iter() {
+ if !str.filled { continue; }
+ let pts = NATimeInfo::time_to_ts(time, 1000, str.tb_num, str.tb_den);
+ let pos = str.find_pos(pts);
+ if pos.is_none() { continue; }
+ let pos = pos.unwrap();
+ if cand.is_none() {
+ cand = Some(SeekIndexResult { pts, pos, str_id: str.id });
+ } else if let Some(entry) = cand {
+ if pos < entry.pos {
+ cand = Some(SeekIndexResult { pts, pos, str_id: str.id });
+ }
+ }
+ }
+ cand
+ }
+}
+
pub struct Demuxer<'a> {
dmx: Box<dyn DemuxCore<'a> + 'a>,
streams: StreamManager,
+ seek_idx: SeekIndex,
}
impl<'a> Demuxer<'a> {
- fn new(dmx: Box<dyn DemuxCore<'a> + 'a>, str: StreamManager) -> Self {
+ fn new(dmx: Box<dyn DemuxCore<'a> + 'a>, str: StreamManager, seek_idx: SeekIndex) -> Self {
Demuxer {
dmx,
streams: str,
+ seek_idx,
}
}
pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
}
}
pub fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- self.dmx.seek(time)
+ self.dmx.seek(time, &self.seek_idx)
+ }
+ pub fn get_seek_index(&self) -> &SeekIndex {
+ &self.seek_idx
}
}
pub fn create_demuxer<'a>(dmxcr: &DemuxerCreator, br: &'a mut ByteReader<'a>) -> DemuxerResult<Demuxer<'a>> {
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)]
impl<'a> DemuxCore<'a> for BMVDemuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
let src = &mut self.src;
let vhdr = NAVideoInfo::new(640, 429, false, PAL8_FORMAT);
}
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- Err(DemuxerError::NotImplemented)
+ fn seek(&mut self, _time: u64, _seek_index: &SeekIndex) -> DemuxerResult<()> {
+ Err(DemuxerError::NotPossible)
}
}
impl<'a> DemuxCore<'a> for BMV3Demuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
let src = &mut self.src;
let mut magic = [0u8; 4];
}
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- Err(DemuxerError::NotImplemented)
+ fn seek(&mut self, _time: u64, _seek_index: &SeekIndex) -> DemuxerResult<()> {
+ Err(DemuxerError::NotPossible)
}
}
impl<'a> DemuxCore<'a> for GremlinVideoDemuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
let src = &mut self.src;
let magic = src.read_u32le()?;
if magic != 0x29111994 { return Err(DemuxerError::InvalidData); }
}
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- Err(DemuxerError::NotImplemented)
+ fn seek(&mut self, _time: u64, _seek_index: &SeekIndex) -> DemuxerResult<()> {
+ Err(DemuxerError::NotPossible)
}
}
/*impl<'a> Drop for GremlinVideoDemuxer<'a> {
impl<'a> DemuxCore<'a> for VMDDemuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
let src = &mut self.src;
let mut header: [u8; HEADER_SIZE] = [0; HEADER_SIZE];
Ok(pkt)
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- Err(DemuxerError::NotImplemented)
+ fn seek(&mut self, _time: u64, _seek_index: &SeekIndex) -> DemuxerResult<()> {
+ Err(DemuxerError::NotPossible)
}
}
}
impl<'a> DemuxCore<'a> for BinkDemuxer<'a> {
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
let src = &mut self.src;
let mut magic: [u8; 4] = [0; 4];
src.read_buf(&mut magic)?;
let _trk_id = src.read_u32le()?;
}
+ seek_idx.mode = SeekIndexMode::Present;
+ seek_idx.add_stream(0, tb_num, tb_den);
self.frame_pos = Vec::with_capacity(self.frames + 1);
- for _ in 0..=self.frames {
+ for fno in 0..=self.frames {
let pos = src.read_u32le()?;
self.frame_pos.push(pos);
+ if (pos & 1) != 0 {
+ seek_idx.seek_info[0].add_entry(SeekEntry { pts: fno as u64, pos: (pos & !1) as u64 });
+ }
}
validate!((src.tell() as u32) == (self.frame_pos[0] & !1));
+ seek_idx.seek_info[0].filled = true;
self.cur_frame = 0;
Ok(pkt)
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- Err(DemuxerError::NotImplemented)
+ fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> {
+ let ret = seek_idx.find_pos(time);
+ if ret.is_none() {
+ return Err(DemuxerError::SeekError);
+ }
+ let seek_info = ret.unwrap();
+ self.src.seek(SeekFrom::Start(seek_info.pos))?;
+ self.queued_packets.clear();
+ self.cur_frame = seek_info.pts as usize;
+ Ok(())
}
}
}
impl<'a> DemuxCore<'a> for SmackerVideoDemuxer<'a> {
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
let src = &mut self.src;
let mut magic: [u8; 4] = [0; 4];
src.read_buf(&mut magic)?;
Ok(pkt)
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
+ fn seek(&mut self, time: u64, _seek_idx: &SeekIndex) -> DemuxerResult<()> {
if time == 0 {
let start = self.start;
self.src.seek(SeekFrom::Start(start))?;
impl<'a> DemuxCore<'a> for RealMediaDemuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
self.read_header(strmgr)?;
Ok(())
}
}
#[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
+ fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> {
Err(NotImplemented)
}
}
impl<'a> DemuxCore<'a> for RealAudioDemuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
let magic = self.src.read_u32be()?;
validate!(magic == mktag!(b".ra\xFD"));
let ver = self.src.read_u16be()?;
}
#[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
+ fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> {
Err(NotImplemented)
}
}
impl<'a> DemuxCore<'a> for RealIVRDemuxer<'a> {
#[allow(unused_variables)]
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ fn open(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
let magic = self.src.peek_u32be()?;
if magic == mktag!(b".REC") {
let mut rec = RecordDemuxer::new(0, 0);
}
#[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
+ fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> {
Err(NotImplemented)
}
}