X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-game%2Fsrc%2Fdemuxers%2Fq.rs;h=3735bfaf836f61f61e286c516b5f7b5883ce0c8b;hb=8e14efb001fac3fecb0cb56df8705d23fa2231a8;hp=3f38ef77978e0fa9542e2b20b45a22c36da931e4;hpb=afe1e5babec1591d397725fbb7d37285e5b7d70c;p=nihav.git diff --git a/nihav-game/src/demuxers/q.rs b/nihav-game/src/demuxers/q.rs index 3f38ef7..3735bfa 100644 --- a/nihav-game/src/demuxers/q.rs +++ b/nihav-game/src/demuxers/q.rs @@ -24,7 +24,7 @@ impl<'a> DemuxCore<'a> for QDemuxer<'a> { validate!(hdr[0] == 0x39); validate!(hdr[1] == 0x68); let version = hdr[2]; - validate!(version >= 3 && version <= 5); + validate!(version >= 3 && version <= 7); let mut width = read_u16le(&hdr[4..])? as usize; let mut height = read_u16le(&hdr[6..])? as usize; if version > 3 { @@ -55,19 +55,21 @@ impl<'a> DemuxCore<'a> for QDemuxer<'a> { let mut buf = vec![0; size]; self.src.read_buf(&mut buf)?; let arate = read_u32le(&buf[24..])?; - let channels = buf[22]; - let abits = buf[34] as usize; - validate!(abits == 8 || abits == 16); - self.bps = (channels as usize) * abits / 8; - let bsize = read_u16le(&buf[32..])? as usize; - let ahdr = NAAudioInfo::new(arate, channels as u8, if abits == 16 { SND_S16_FORMAT } else { SND_U8_FORMAT }, bsize); - let ainfo = NACodecInfo::new("pcm", NACodecTypeInfo::Audio(ahdr), None); - self.a_id = strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, 1, arate, 2)); + if arate > 0 { + let channels = buf[22]; + let abits = buf[34] as usize; + validate!(abits == 8 || abits == 16); + self.bps = (channels as usize) * abits / 8; + let bsize = read_u16le(&buf[32..])? as usize; + let ahdr = NAAudioInfo::new(arate, channels as u8, if abits == 16 { SND_S16_FORMAT } else { SND_U8_FORMAT }, bsize); + let ainfo = NACodecInfo::new("pcm", NACodecTypeInfo::Audio(ahdr), None); + self.a_id = strmgr.add_stream(NAStream::new(StreamType::Audio, 1, ainfo, 1, arate, 2)); + } } } self.apts = 0; self.vpts = 0; - self.side_data.truncate(0); + self.side_data.clear(); Ok(()) } @@ -80,12 +82,11 @@ impl<'a> DemuxCore<'a> for QDemuxer<'a> { 0 => { if let Some(a_id) = self.a_id { let str = strmgr.get_stream(a_id).unwrap(); - let (tb_num, tb_den) = str.get_timebase(); - let ts = NATimeInfo::new(Some(self.apts), None, None, tb_num, tb_den); + let ts = str.make_ts(Some(self.apts), None, None); self.apts += (size / self.bps) as u64; return self.src.read_packet(str, ts, true, size); } else { - return Err(DemuxerError::InvalidData); + self.src.read_skip(size)?; } }, 1 => { @@ -99,8 +100,7 @@ impl<'a> DemuxCore<'a> for QDemuxer<'a> { 2 | 3 | 4 | 11 => { validate!(self.v_id.is_some()); let str = strmgr.get_stream(self.v_id.unwrap_or(0)).unwrap(); - let (tb_num, tb_den) = str.get_timebase(); - let ts = NATimeInfo::new(Some(self.vpts), None, None, tb_num, tb_den); + let ts = str.make_ts(Some(self.vpts), None, None); self.vpts += 1; let cur_len = self.side_data.len(); @@ -187,6 +187,7 @@ mod test { use super::*; use std::fs::File; + // samples from Death Gate, Mission Critical and Shannara games #[test] fn test_q_demux_v3() { let mut file = File::open("assets/Game/dgate101.q").unwrap();