use NATimePoint for seeking
[nihav.git] / nihav-core / src / demuxers / mod.rs
index 8857cee560b23d452b5ef1fcb85d4720fcdef558..352c1605f20050b8f33cb5e9700a4c8d2b1fb97f 100644 (file)
@@ -1,6 +1,7 @@
 //! Demuxer definitions.
 pub use crate::frame::*;
 pub use crate::io::byteio::*;
+pub use crate::options::*;
 
 /// A list specifying general demuxing errors.
 #[derive(Debug,Clone,Copy,PartialEq)]
@@ -30,13 +31,13 @@ pub enum DemuxerError {
 pub type DemuxerResult<T> = Result<T, DemuxerError>;
 
 /// A trait for demuxing operations.
-pub trait DemuxCore<'a> {
+pub trait DemuxCore<'a>: NAOptionHandler {
     /// Opens the input stream, reads required headers and prepares everything for packet demuxing.
     fn open(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<()>;
     /// Demuxes a packet.
     fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket>;
     /// 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<()>;
 }
 
 /// An auxiliary trait to make bytestream reader read packet data.
@@ -93,6 +94,13 @@ impl StreamManager {
         self.ignored.push(false);
         Some(stream_num)
     }
+    /// Adds a new stream from reference-counted object.
+    pub fn add_stream_ref(&mut self, stream: NAStreamRef) -> Option<usize> {
+        let stream_num = self.streams.len();
+        self.streams.push(stream);
+        self.ignored.push(false);
+        Some(stream_num)
+    }
     /// Returns stream with the requested index.
     pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
         if idx < self.streams.len() {
@@ -221,16 +229,31 @@ impl StreamSeekInfo {
         self.entries.push(entry);
     }
     /// Searches for an appropriate seek position before requested time.
-    pub fn find_pos(&self, time: u64) -> Option<SeekEntry> {
+    pub fn find_pos(&self, time: NATimePoint) -> Option<SeekEntry> {
+        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 {
@@ -301,7 +324,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<SeekIndexResult> {
+    pub fn find_pos(&self, time: NATimePoint) -> Option<SeekIndexResult> {
         let mut cand = None;
         for str in self.seek_info.iter() {
             if !str.filled { continue; }
@@ -348,6 +371,10 @@ impl<'a> Demuxer<'a> {
     pub fn get_num_streams(&self) -> usize {
         self.streams.get_num_streams()
     }
+    /// Returns a reference to the internal stream manager.
+    pub fn get_stream_manager(&self) -> &StreamManager {
+        &self.streams
+    }
     /// Returns an iterator over streams.
     pub fn get_streams(&self) -> StreamIter {
         self.streams.iter()
@@ -377,8 +404,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);
         }
@@ -390,6 +417,18 @@ impl<'a> Demuxer<'a> {
     }
 }
 
+impl<'a> NAOptionHandler for Demuxer<'a> {
+    fn get_supported_options(&self) -> &[NAOptionDefinition] {
+        self.dmx.get_supported_options()
+    }
+    fn set_options(&mut self, options: &[NAOption]) {
+        self.dmx.set_options(options);
+    }
+    fn query_option_value(&self, name: &str) -> Option<NAValue> {
+        self.dmx.query_option_value(name)
+    }
+}
+
 impl From<ByteIOError> for DemuxerError {
     fn from(_: ByteIOError) -> Self { DemuxerError::IOError }
 }
@@ -435,4 +474,8 @@ impl RegisteredDemuxers {
         }
         None
     }
+    /// Provides an iterator over currently registered demuxers.
+    pub fn iter(&self) -> std::slice::Iter<&DemuxerCreator> {
+        self.dmxs.iter()
+    }
 }