allow to skip index building
[nihav.git] / nihav-core / src / demuxers / mod.rs
index 405d88d6f4e528a446e13389d64adbdda0aa0f7d..ee2fe58ae871aa604a05ee13b0092acf0153ad4b 100644 (file)
@@ -151,6 +151,7 @@ impl Default for SeekIndexMode {
 
 #[derive(Clone,Copy,Default)]
 pub struct SeekEntry {
+    pub time:   u64, // in milliseconds
     pub pts:    u64,
     pub pos:    u64,
 }
@@ -158,16 +159,14 @@ pub struct SeekEntry {
 #[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(),
         }
@@ -175,18 +174,18 @@ impl StreamSeekInfo {
     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
         }
@@ -204,13 +203,18 @@ pub struct SeekIndexResult {
 pub struct SeekIndex {
     pub seek_info:  Vec<StreamSeekInfo>,
     pub mode:       SeekIndexMode,
+    pub skip_index: bool,
 }
 
 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 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<usize> {
@@ -221,19 +225,34 @@ impl SeekIndex {
         }
         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<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 { ptspos, 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 { ptspos, str_id: str.id });
+                if res.pos < entry.pos {
+                    cand = Some(SeekIndexResult { pts: res.pts, pos: res.pos, str_id: str.id });
                 }
             }
         }
@@ -289,6 +308,9 @@ impl<'a> Demuxer<'a> {
         }
     }
     pub fn seek(&mut self, time: u64) -> DemuxerResult<()> {
+        if self.seek_idx.skip_index {
+            return Err(DemuxerError::NotPossible);
+        }
         self.dmx.seek(time, &self.seek_idx)
     }
     pub fn get_seek_index(&self) -> &SeekIndex {