#[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 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 {
+ pub fn new(id: u32) -> Self {
Self {
- id, tb_num, tb_den,
+ id,
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> {
+ pub fn find_pos(&self, time: u64) -> Option<SeekEntry> {
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;
+ let mut cand = None;
+ for entry in self.entries.iter() {
+ if entry.time <= time {
+ cand = Some(*entry);
} else {
break;
}
}
- Some(self.entries[cand].pos)
+ cand
} else {
None
}
impl SeekIndex {
pub fn new() -> Self { Self::default() }
- pub fn add_stream(&mut self, id: u32, tb_num: u32, tb_den: u32) {
+ pub fn add_stream(&mut self, id: u32) {
if self.stream_id_to_index(id).is_none() {
- self.seek_info.push(StreamSeekInfo::new(id, tb_num, tb_den));
+ self.seek_info.push(StreamSeekInfo::new(id));
}
}
pub fn stream_id_to_index(&self, id: u32) -> Option<usize> {
}
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 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();
+ let res = str.find_pos(time);
+ if res.is_none() { continue; }
+ let res = res.unwrap();
if cand.is_none() {
- cand = Some(SeekIndexResult { pts, pos, str_id: str.id });
+ cand = Some(SeekIndexResult { pts: res.pts, pos: res.pos, str_id: str.id });
} else if let Some(entry) = cand {
- if pos < entry.pos {
- cand = Some(SeekIndexResult { pts, pos, str_id: str.id });
+ if res.pos < entry.pos {
+ cand = Some(SeekIndexResult { pts: res.pts, pos: res.pos, str_id: str.id });
}
}
}
}
seek_idx.mode = SeekIndexMode::Present;
- seek_idx.add_stream(0, tb_num, tb_den);
+ seek_idx.add_stream(0);
self.frame_pos = Vec::with_capacity(self.frames + 1);
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 });
+ let time = (fno as u64) * 1000 * (tb_num as u64) / (tb_den as u64);
+ seek_idx.seek_info[0].add_entry(SeekEntry { time, pts: fno as u64, pos: (pos & !1) as u64 });
}
}
validate!((src.tell() as u32) == (self.frame_pos[0] & !1));