From 727aa32e5c2ff014dfd575d2580090d3a0945b4d Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sun, 13 Apr 2025 18:37:43 +0200 Subject: [PATCH] tca: use the same implementation for raw TCA and TCA-in-ARMovie demuxers --- nihav-acorn/src/demuxers/armovie.rs | 8 +-- nihav-acorn/src/demuxers/tca.rs | 100 +++++----------------------- 2 files changed, 20 insertions(+), 88 deletions(-) diff --git a/nihav-acorn/src/demuxers/armovie.rs b/nihav-acorn/src/demuxers/armovie.rs index 96969ed..23cf94a 100644 --- a/nihav-acorn/src/demuxers/armovie.rs +++ b/nihav-acorn/src/demuxers/armovie.rs @@ -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, audio_ids: Vec, #[cfg(feature="demuxer_tca")] - tca: Option, + tca: Option, } 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 { #[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() { diff --git a/nihav-acorn/src/demuxers/tca.rs b/nihav-acorn/src/demuxers/tca.rs index e8c6c64..16bcd0e 100644 --- a/nihav-acorn/src/demuxers/tca.rs +++ b/nihav-acorn/src/demuxers/tca.rs @@ -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 { - 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 { + pub(crate) fn get_frame(&mut self, src: &mut ByteReader, strmgr: &mut StreamManager) -> DemuxerResult { 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 { + let pkt = self.get_frame(src, strmgr)?; + Ok(NARawData::new_from_refbuf(pkt.get_stream(), pkt.get_buffer())) + } } #[cfg(test)] -- 2.39.5