]> git.nihav.org Git - nihav-encoder.git/blobdiff - src/demux.rs
add PNM image sequence as possible input source
[nihav-encoder.git] / src / demux.rs
index 73ed14fa503ffa36ba09d6ccaf1f595d58dedc47..61ddbaf08646d747fb052a6a61cbcd0e9f61cfe1 100644 (file)
@@ -6,6 +6,7 @@ use nihav_registry::detect;
 use nihav_core::io::byteio::ByteReader;
 use nihav_allstuff::*;
 use crate::null::*;
+use crate::imgseq::*;
 
 pub struct FullRegister {
     pub dmx_reg:    RegisteredDemuxers,
@@ -41,13 +42,14 @@ pub struct RawStreamCtx<'a> {
     sm:         StreamManager,
     packetiser: Box<dyn NAPacketiser + Send>,
     br:         &'a mut ByteReader<'a>,
+    pts:        u64,
 }
 
 impl<'a> RawStreamCtx<'a> {
     fn new(stream: NAStreamRef, packetiser: Box<dyn NAPacketiser + Send>, br: &'a mut ByteReader<'a>) -> Self {
         let mut sm = StreamManager::new();
         sm.add_stream_ref(stream.clone());
-        Self { stream, sm, packetiser, br }
+        Self { stream, sm, packetiser, br, pts: 0 }
     }
 }
 
@@ -56,6 +58,7 @@ pub enum DemuxerObject<'a> {
     Normal(Demuxer<'a>),
     Raw(RawDemuxer<'a>, Vec<Option<Box<dyn NAPacketiser + Send>>>, bool),
     RawStream(RawStreamCtx<'a>),
+    ImageSequence(ImgSeqDemuxer),
 }
 
 impl<'a> DemuxerObject<'a> {
@@ -69,7 +72,7 @@ impl<'a> DemuxerObject<'a> {
                 } else {
                     ""
                 };
-            if dmx_name != "" {
+            if !dmx_name.is_empty() {
                 println!("trying demuxer {} on {}", dmx_name, name);
                 if let Some(dmx_fact) = reg.dmx_reg.find_demuxer(dmx_name) {
                     br.seek(SeekFrom::Start(0)).unwrap();
@@ -80,7 +83,7 @@ impl<'a> DemuxerObject<'a> {
             if ifmt.is_some() {
                 return DemuxerObject::None;
             }
-            if dmx_name != "" {
+            if !dmx_name.is_empty() {
                 println!("trying raw demuxer {} on {}", dmx_name, name);
                 if let Some(rdmx_fact) = reg.rdmx_reg.find_demuxer(dmx_name) {
                     br.seek(SeekFrom::Start(0)).unwrap();
@@ -128,7 +131,7 @@ impl<'a> DemuxerObject<'a> {
                 break;
             }
         }
-        if pname != "" {
+        if !pname.is_empty() {
             println!("found raw stream of type {} for {}", pname, name);
             let pcreate = reg.pkt_reg.find_packetiser(pname).unwrap();
             let mut packetiser = (pcreate)();
@@ -140,16 +143,19 @@ impl<'a> DemuxerObject<'a> {
             DemuxerObject::None
         }
     }
+    pub fn create_imgseq(isd: ImgSeqDemuxer) -> Self {
+        DemuxerObject::ImageSequence(isd)
+    }
     pub fn is_none(&self) -> bool {
-        match *self {
-            DemuxerObject::None => true,
-            _ => false,
-        }
+        matches!(*self, DemuxerObject::None)
     }
     pub fn get_duration(&self) -> u64 {
         match *self {
             DemuxerObject::Normal(ref dmx) => dmx.get_duration(),
             DemuxerObject::Raw(ref dmx, _, _) => dmx.get_duration(),
+            DemuxerObject::RawStream(ref ctx) => {
+                NATimeInfo::ts_to_time(ctx.stream.duration, 1000, ctx.stream.tb_num, ctx.stream.tb_den)
+            },
             _ => 0,
         }
     }
@@ -159,6 +165,7 @@ impl<'a> DemuxerObject<'a> {
             DemuxerObject::Normal(ref dmx) => dmx.get_num_streams(),
             DemuxerObject::Raw(ref dmx, _, _) => dmx.get_num_streams(),
             DemuxerObject::RawStream(_) => 1,
+            DemuxerObject::ImageSequence(_) => 1,
         }
     }
     pub fn get_stream(&self, idx: usize) -> Option<NAStreamRef> {
@@ -166,6 +173,7 @@ impl<'a> DemuxerObject<'a> {
             DemuxerObject::Normal(ref dmx) => dmx.get_stream(idx),
             DemuxerObject::Raw(ref dmx, _, _) => dmx.get_stream(idx),
             DemuxerObject::RawStream(ref ctx) if idx == 0 => Some(ctx.stream.clone()),
+            DemuxerObject::ImageSequence(ref ctx) if idx == 0 => Some(ctx.stream.clone()),
             _ => None,
         }
     }
@@ -174,6 +182,7 @@ impl<'a> DemuxerObject<'a> {
             DemuxerObject::Normal(ref dmx) => dmx.get_streams(),
             DemuxerObject::Raw(ref dmx, _, _) => dmx.get_streams(),
             DemuxerObject::RawStream(ref ctx) => ctx.sm.iter(),
+            DemuxerObject::ImageSequence(ref ctx) => ctx.sm.iter(),
             _ => unreachable!(),
         }
     }
@@ -182,6 +191,7 @@ impl<'a> DemuxerObject<'a> {
             DemuxerObject::Normal(ref dmx) => dmx.get_stream_manager(),
             DemuxerObject::Raw(ref dmx, _, _) => dmx.get_stream_manager(),
             DemuxerObject::RawStream(ref ctx) => &ctx.sm,
+            DemuxerObject::ImageSequence(ref ctx) => &ctx.sm,
             _ => unreachable!(),
         }
     }
@@ -230,7 +240,13 @@ impl<'a> DemuxerObject<'a> {
                 let mut buf = [0; 65536];
                 loop {
                     match ctx.packetiser.get_packet(ctx.stream.clone()) {
-                        Ok(Some(packet)) => return Ok(packet),
+                        Ok(Some(mut packet)) => {
+                            if packet.get_pts().is_none() && packet.get_duration().is_some() {
+                                packet.ts.pts = Some(ctx.pts);
+                            }
+                            ctx.pts += packet.get_duration().unwrap_or(0);
+                            return Ok(packet);
+                        },
                         Ok(None) => {},
                         Err(DecoderError::ShortData) => {},
                         _ => return Err(DemuxerError::InvalidData),
@@ -241,7 +257,13 @@ impl<'a> DemuxerObject<'a> {
                         },
                         Err(_) => {
                             match ctx.packetiser.get_packet(ctx.stream.clone()) {
-                                Ok(Some(packet)) => return Ok(packet),
+                                Ok(Some(mut packet)) => {
+                                    if packet.get_pts().is_none() && packet.get_duration().is_some() {
+                                        packet.ts.pts = Some(ctx.pts);
+                                    }
+                                    ctx.pts += packet.get_duration().unwrap_or(0);
+                                    return Ok(packet);
+                                },
                                 Ok(None) | Err(DecoderError::ShortData) => return Err(DemuxerError::EOF),
                                 _ => return Err(DemuxerError::InvalidData),
                             };
@@ -249,6 +271,7 @@ impl<'a> DemuxerObject<'a> {
                     };
                 }
             },
+            DemuxerObject::ImageSequence(ref mut ctx) => ctx.get_frame(),
             _ => unreachable!(),
         }
     }
@@ -256,6 +279,7 @@ impl<'a> DemuxerObject<'a> {
         match *self {
             DemuxerObject::Normal(ref mut dmx) => dmx.seek(seek_time),
             DemuxerObject::Raw(ref mut dmx, _, _) => dmx.seek(seek_time),
+            DemuxerObject::ImageSequence(ref mut ctx) => ctx.seek(seek_time),
             _ => Err(DemuxerError::NotImplemented),
         }
     }
@@ -266,6 +290,7 @@ impl<'a> NAOptionHandler for DemuxerObject<'a> {
         match *self {
             DemuxerObject::Normal(ref dmx) => dmx.get_supported_options(),
             DemuxerObject::Raw(ref dmx, _, _) => dmx.get_supported_options(),
+            DemuxerObject::ImageSequence(ref ctx) => ctx.get_supported_options(),
             _ => &[],
         }
     }
@@ -273,6 +298,7 @@ impl<'a> NAOptionHandler for DemuxerObject<'a> {
         match *self {
             DemuxerObject::Normal(ref mut dmx) => dmx.set_options(options),
             DemuxerObject::Raw(ref mut dmx, _, _) => dmx.set_options(options),
+            DemuxerObject::ImageSequence(ref mut ctx) => ctx.set_options(options),
             _ => {},
         }
     }
@@ -280,6 +306,7 @@ impl<'a> NAOptionHandler for DemuxerObject<'a> {
         match *self {
             DemuxerObject::Normal(ref dmx) => dmx.query_option_value(name),
             DemuxerObject::Raw(ref dmx, _, _) => dmx.query_option_value(name),
+            DemuxerObject::ImageSequence(ref ctx) => ctx.query_option_value(name),
             _ => None,
         }
     }