1 use nihav_core::frame::*;
2 use nihav_core::demuxers::*;
5 struct FutureVisionVideoDemuxer<'a> {
6 src: &'a mut ByteReader<'a>,
16 impl<'a> DemuxCore<'a> for FutureVisionVideoDemuxer<'a> {
17 #[allow(unused_variables)]
18 fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
19 let src = &mut self.src;
21 let magic = src.read_tag()?;
22 validate!(&magic == b"2TSF");
23 let width = src.read_u32le()? as usize;
24 let height = src.read_u32le()? as usize;
25 validate!(width != 0 && height != 0);
26 let _flags = src.read_u32le()?;
27 let nframes = src.read_u32le()? as usize;
28 let fps = src.read_u32le()?;
29 let arate = src.read_u32le()?;
30 let abits = src.read_u32le()?;
32 let vhdr = NAVideoInfo::new(width, height, false, PAL8_FORMAT);
33 let vci = NACodecTypeInfo::Video(vhdr);
34 let vinfo = NACodecInfo::new("fst-video", vci, None);
35 self.v_id = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, fps, nframes as u64));
37 validate!(abits == 8 || abits == 16);
38 let ahdr = NAAudioInfo::new(arate, 1, if abits == 16 { SND_S16_FORMAT } else { SND_U8_FORMAT }, 2);
39 let ainfo = NACodecInfo::new("pcm", NACodecTypeInfo::Audio(ahdr), None);
40 self.a_id = strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, 1, arate, 2));
42 self.vsize = Vec::with_capacity(nframes);
43 self.asize = Vec::with_capacity(nframes);
45 let vsize = src.read_u32le()? as usize;
46 let asize = src.read_u16le()? as usize;
47 self.vsize.push(vsize);
48 self.asize.push(asize);
56 #[allow(unused_variables)]
57 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
58 if self.cur_frame >= self.vsize.len() { return Err(DemuxerError::EOF); }
59 let (id, size, pts) = if self.vframe {
60 self.vframe = self.a_id.is_none();
62 (self.v_id.unwrap_or(0), self.vsize[self.cur_frame], self.cur_frame as u64)
66 self.apos += (self.asize[self.cur_frame] as u64) * 2;
68 (self.a_id.unwrap_or(0), self.asize[self.cur_frame], apos)
75 let stream = strmgr.get_stream(id).unwrap();
76 let ts = stream.make_ts(Some(pts), None, None);
77 self.src.read_packet(stream, ts, true, size)
80 fn seek(&mut self, _time: NATimePoint, _seek_index: &SeekIndex) -> DemuxerResult<()> {
81 Err(DemuxerError::NotPossible)
83 fn get_duration(&self) -> u64 { 0 }
85 impl<'a> NAOptionHandler for FutureVisionVideoDemuxer<'a> {
86 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
87 fn set_options(&mut self, _options: &[NAOption]) { }
88 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
90 impl<'a> FutureVisionVideoDemuxer<'a> {
91 fn new(io: &'a mut ByteReader<'a>) -> Self {
92 FutureVisionVideoDemuxer {
105 pub struct FSTDemuxerCreator { }
107 impl DemuxerCreator for FSTDemuxerCreator {
108 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
109 Box::new(FutureVisionVideoDemuxer::new(br))
111 fn get_name(&self) -> &'static str { "fst" }
115 struct FutureVisionAudioDemuxer<'a> {
116 src: &'a mut ByteReader<'a>,
122 impl<'a> DemuxCore<'a> for FutureVisionAudioDemuxer<'a> {
123 #[allow(unused_variables)]
124 fn open(&mut self, strmgr: &mut StreamManager, _seek_index: &mut SeekIndex) -> DemuxerResult<()> {
125 let src = &mut self.src;
127 let magic = src.read_tag()?;
128 validate!(&magic == b"FCMP");
129 let size = u64::from(src.read_u32le()?);
130 let arate = src.read_u32le()?;
131 validate!(arate != 0);
132 let abits = src.read_u16le()?;
133 validate!(abits == 8 || abits == 16);
135 let ahdr = NAAudioInfo::new(arate, 1, if abits == 16 { SND_S16_FORMAT } else { SND_U8_FORMAT }, 2);
136 let ainfo = NACodecInfo::new("fst-audio", NACodecTypeInfo::Audio(ahdr), None);
137 self.a_id = strmgr.add_stream(NAStream::new(StreamType::Audio, 0, ainfo, 1, arate, 2)).unwrap();
138 self.end = self.src.tell() + size;
143 #[allow(unused_variables)]
144 fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
145 if self.src.tell() >= self.end { return Err(DemuxerError::EOF); }
146 let size = (self.end - self.src.tell()).min(0x2000) as usize;
147 let pts = (self.src.tell() - 14) * 2;
149 let stream = strmgr.get_stream(self.a_id).unwrap();
150 let ts = stream.make_ts(Some(pts), None, None);
151 self.src.read_packet(stream, ts, true, size)
154 fn seek(&mut self, _time: NATimePoint, _seek_index: &SeekIndex) -> DemuxerResult<()> {
155 Err(DemuxerError::NotPossible)
157 fn get_duration(&self) -> u64 { (self.end - 14) * 2000 / u64::from(self.arate) }
159 impl<'a> NAOptionHandler for FutureVisionAudioDemuxer<'a> {
160 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
161 fn set_options(&mut self, _options: &[NAOption]) { }
162 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
164 impl<'a> FutureVisionAudioDemuxer<'a> {
165 fn new(io: &'a mut ByteReader<'a>) -> Self {
166 FutureVisionAudioDemuxer {
175 pub struct FCMPDemuxerCreator { }
177 impl DemuxerCreator for FCMPDemuxerCreator {
178 fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
179 Box::new(FutureVisionAudioDemuxer::new(br))
181 fn get_name(&self) -> &'static str { "fcmp" }
189 // samples from the Harvester game
191 fn test_fst_demux() {
192 let mut file = File::open("assets/Game/c007.fst").unwrap();
193 let mut fr = FileReader::new_read(&mut file);
194 let mut br = ByteReader::new(&mut fr);
195 let mut dmx = FutureVisionVideoDemuxer::new(&mut br);
196 let mut sm = StreamManager::new();
197 let mut si = SeekIndex::new();
198 dmx.open(&mut sm, &mut si).unwrap();
200 let pktres = dmx.get_frame(&mut sm);
201 if let Err(e) = pktres {
202 if (e as i32) == (DemuxerError::EOF as i32) { break; }
205 let pkt = pktres.unwrap();
206 println!("Got {}", pkt);
211 fn test_fcmp_demux() {
212 let mut file = File::open("assets/Game/anxiety.cmp").unwrap();
213 let mut fr = FileReader::new_read(&mut file);
214 let mut br = ByteReader::new(&mut fr);
215 let mut dmx = FutureVisionAudioDemuxer::new(&mut br);
216 let mut sm = StreamManager::new();
217 let mut si = SeekIndex::new();
218 dmx.open(&mut sm, &mut si).unwrap();
220 let pktres = dmx.get_frame(&mut sm);
221 if let Err(e) = pktres {
222 if (e as i32) == (DemuxerError::EOF as i32) { break; }
225 let pkt = pktres.unwrap();
226 println!("Got {}", pkt);