]> git.nihav.org Git - nihav.git/commitdiff
tca: use the same implementation for raw TCA and TCA-in-ARMovie demuxers
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sun, 13 Apr 2025 16:37:43 +0000 (18:37 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sun, 13 Apr 2025 16:37:43 +0000 (18:37 +0200)
nihav-acorn/src/demuxers/armovie.rs
nihav-acorn/src/demuxers/tca.rs

index 96969edb997441a1e6d29c3f02677a99a43b0c49..23cf94abe4a5dc7bec4c23e33f0a0559a5542451 100644 (file)
@@ -1,7 +1,7 @@
 use nihav_core::demuxers::*;
 
 #[cfg(feature="demuxer_tca")]
-use super::tca::TCARawDemuxer;
+use super::tca::TCACoreDemuxer;
 
 const VIDEO_CODECS: &[(i32, &str)] = &[
     (  1, "movinglines"),
@@ -160,7 +160,7 @@ struct ARMovieDemuxer<'a> {
     video_id:       Option<usize>,
     audio_ids:      Vec<usize>,
     #[cfg(feature="demuxer_tca")]
-    tca:            Option<TCARawDemuxer>,
+    tca:            Option<TCACoreDemuxer>,
 }
 
 impl<'a> ARMovieDemuxer<'a> {
@@ -282,7 +282,7 @@ impl<'a> RawDemuxCore<'a> for ARMovieDemuxer<'a> {
             let tb_den = tbase as u32;
 
             self.src.seek(SeekFrom::Start(u64::from(self.chunk_offs[0].offset)))?;
-            let mut tca = TCARawDemuxer::default();
+            let mut tca = TCACoreDemuxer::default();
             tca.open(self.src, strmgr, tb_num, tb_den)?;
             self.tca = Some(tca);
             return Ok(());
@@ -366,7 +366,7 @@ impl<'a> RawDemuxCore<'a> for ARMovieDemuxer<'a> {
     fn get_data(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NARawData> {
         #[cfg(feature="demuxer_tca")]
         if let Some(ref mut tca) = self.tca {
-            return tca.get_frame(self.src, strmgr);
+            return tca.get_frame_raw(self.src, strmgr);
         }
 
         while self.cur_chunk < self.chunk_offs.len() {
index e8c6c64c5ac70ecd3500e19f394f400d1fdbfce1..16bcd0e274c25e609f378bb03153b6b6e369d7e7 100644 (file)
@@ -2,99 +2,25 @@ use nihav_core::demuxers::*;
 
 struct TCADemuxer<'a> {
     src:        &'a mut ByteReader<'a>,
-    frameno:    u64,
-    data_end:   u64,
+    tca:        TCACoreDemuxer,
 }
 
 impl<'a> TCADemuxer<'a> {
     fn new(src: &'a mut ByteReader<'a>) -> Self {
         Self {
             src,
-            frameno:    0,
-            data_end:   0,
+            tca:    TCACoreDemuxer::default()
         }
     }
 }
 
 impl<'a> DemuxCore<'a> for TCADemuxer<'a> {
     fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
-        let tag                 = self.src.peek_tag()?;
-        let is_acef = &tag == b"ACEF";
-        let acef_size = if is_acef {
-                                      self.src.read_skip(4)?;
-                                      self.src.read_u32le()?
-            } else { 0 };
-        let size2                   = self.src.read_u32le()?;
-        if is_acef {
-            validate!(acef_size > 0x44 && size2 + 8 <= acef_size);
-        }
-        self.data_end = u64::from(size2 + 8);
-
-                                      self.src.read_skip(12)?;
-
-        const HDR_SIZE: usize = 0x30;
-
-        let mut hdr = vec![0; HDR_SIZE + 4];
-        write_u32le(&mut hdr, HDR_SIZE as u32 + 4)?;
-                                      self.src.read_buf(&mut hdr[4..])?;
-
-        let width  = read_u32le(&hdr[8..])? as usize;
-        let height = read_u32le(&hdr[12..])? as usize;
-        validate!(width > 0 && height > 0);
-        validate!((width | height) & 1 == 0);
-
-        if is_acef {
-            let data_start = self.src.tell();
-
-            // scan tail for palette and such
-            if self.src.seek(SeekFrom::Start(u64::from(acef_size))).is_ok() {
-                while let Ok(tag)   = self.src.read_tag() {
-                    let size        = self.src.read_u32le()? as usize;
-                    validate!(size >= 8);
-                    if &tag == b"PALE" {
-                        validate!((0x28..=0x428).contains(&size) && (size & 3) == 0);
-                                      self.src.read_skip(0x1C)?;
-                        let nclrs = (size - 0x24) / 4;
-                        hdr.resize(HDR_SIZE + 4 + 256 * 3, 0);
-                        for _ in 0..nclrs {
-                            let idx = usize::from(self.src.read_byte()?);
-                                      self.src.read_buf(&mut hdr[HDR_SIZE + 4 + idx * 3..][..3])?;
-                        }
-                    } else {
-                                      self.src.read_skip(size - 8)?;
-                    }
-                }
-            }
-                                      self.src.seek(SeekFrom::Start(data_start))?;
-        }
-
-        let vci = NACodecTypeInfo::Video(NAVideoInfo::new(width / 2, height / 2, false, PAL8_FORMAT));
-        let vinfo = NACodecInfo::new("euclid", vci, Some(hdr));
-        let ret = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 10, 0));
-        if ret.is_none() {
-            return Err(DemuxerError::MemoryError);
-        }
-
-        Ok(())
+        self.tca.open(self.src, strmgr, 1, 10)
     }
 
     fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
-        if self.src.tell() >= self.data_end {
-            return Err(DemuxerError::EOF);
-        }
-        let fsize               = self.src.read_u32le()? as usize;
-        if fsize == 0 {
-            return Err(DemuxerError::EOF);
-        }
-        validate!((9..=1048576).contains(&fsize));
-        if let Some(stream) = strmgr.get_stream(0) {
-            let ts = stream.make_ts(Some(self.frameno), None, None);
-            self.frameno += 1;
-            // last word is the current packet size for backwards seeking so it can be omitted
-            self.src.read_packet(stream, ts, false, fsize - 4)
-        } else {
-            Err(DemuxerError::InvalidData)
-        }
+        self.tca.get_frame(self.src, strmgr)
     }
 
     fn seek(&mut self, _time: NATimePoint, _seek_index: &SeekIndex) -> DemuxerResult<()> {
@@ -119,11 +45,12 @@ impl DemuxerCreator for TCADemuxerCreator {
 }
 
 #[derive(Default)]
-pub(crate) struct TCARawDemuxer {
+pub(crate) struct TCACoreDemuxer {
     data_end:   u64,
+    frameno:    u64,
 }
 
-impl TCARawDemuxer {
+impl TCACoreDemuxer {
     pub(crate) fn open(&mut self, src: &mut ByteReader, strmgr: &mut StreamManager, tb_num: u32, tb_den: u32) -> DemuxerResult<()> {
         let start_pos = src.tell();
         let tag                     = src.peek_tag()?;
@@ -186,7 +113,7 @@ impl TCARawDemuxer {
         Ok(())
     }
 
-    pub(crate) fn get_frame(&mut self, src: &mut ByteReader, strmgr: &mut StreamManager) -> DemuxerResult<NARawData> {
+    pub(crate) fn get_frame(&mut self, src: &mut ByteReader, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
         if src.tell() >= self.data_end {
             return Err(DemuxerError::EOF);
         }
@@ -196,13 +123,18 @@ impl TCARawDemuxer {
         }
         validate!((9..=1048576).contains(&fsize));
         if let Some(stream) = strmgr.get_stream(0) {
-            let mut buf = vec![0; fsize - 4];
-                                  src.read_buf(&mut buf)?;
-            Ok(NARawData::new(stream, buf))
+            let ts = stream.make_ts(Some(self.frameno), None, None);
+            self.frameno += 1;
+            src.read_packet(stream, ts, false, fsize - 4)
         } else {
             Err(DemuxerError::InvalidData)
         }
     }
+
+    pub(crate) fn get_frame_raw(&mut self, src: &mut ByteReader, strmgr: &mut StreamManager) -> DemuxerResult<NARawData> {
+        let pkt = self.get_frame(src, strmgr)?;
+        Ok(NARawData::new_from_refbuf(pkt.get_stream(), pkt.get_buffer()))
+    }
 }
 
 #[cfg(test)]