let soniton = if (self.flags & SMK_AUD_FLAG_16BIT) != 0 { SND_S16_FORMAT } else { SND_U8_FORMAT };
let ahdr = NAAudioInfo::new(self.srate, channels, soniton, 1);
let ainfo = NACodecInfo::new(codecname, NACodecTypeInfo::Audio(ahdr), None);
- let res = strmgr.add_stream(NAStream::new(StreamType::Audio, (str_id + 1) as u32, ainfo, 1, self.srate));
+ let res = strmgr.add_stream(NAStream::new(StreamType::Audio, (str_id + 1) as u32, ainfo, 1, self.srate, 0));
validate!(res.is_some());
self.id = res.unwrap();
fn get_pts_inc(val: i32) -> u64 {
if val > 0 { (val as u64) * 100 }
- else if val < 0 { (-val as u64) }
+ else if val < 0 { -val as u64 }
else { 1 }
}
impl<'a> DemuxCore<'a> for SmackerVideoDemuxer<'a> {
- fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> {
+ #[allow(clippy::unreadable_literal)]
+ fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> {
let src = &mut self.src;
let mut magic: [u8; 4] = [0; 4];
src.read_buf(&mut magic)?;
let vhdr = NAVideoInfo::new(width, height, false, PAL8_FORMAT);
let vinfo = NACodecInfo::new("smacker-video", NACodecTypeInfo::Video(vhdr), Some(treedata));
- let res = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 100000));
+ let res = strmgr.add_stream(NAStream::new(StreamType::Video, 0, vinfo, 1, 100000, 0));
validate!(res.is_some());
self.video_id = res.unwrap();
self.start = src.tell();
self.cur_frame = 0;
self.reset_state();
-
+
Ok(())
}
+ #[allow(clippy::identity_op)]
+ #[allow(clippy::unreadable_literal)]
fn get_frame(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<NAPacket> {
if !self.queued_packets.is_empty() {
let pkt = self.queued_packets.pop().unwrap();
validate!(chunk_size > 0);
validate!(payload_size >= chunk_size);
payload_size -= chunk_size;
- let oldpal = self.pal.clone();
+ let oldpal = self.pal;
let mut idx = 0;
let endpos = self.src.tell() + (chunk_size as u64) - 1;
while idx < 256 {
let ts = NATimeInfo::new(Some(self.cur_pts), None, None, 1, 100000);
for i in 0..NUM_AUDIO_TRACKS {
if ((frame_flags >> (i + 1)) & 1) == 0 { continue; }
- validate!(self.ainfo[i].is_present());
let size = self.src.read_u32le()? as usize;
validate!(size > 4);
validate!(payload_size >= size);
payload_size -= size;
+ if !self.ainfo[i].is_present() {
+ self.src.read_skip(size - 4)?;
+ continue;
+ }
let strres = strmgr.get_stream(self.ainfo[i].id);
validate!(strres.is_some());
let stream = strres.unwrap();
Ok(pkt)
}
- #[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- if time == 0 {
+ fn seek(&mut self, time: NATimePoint, _seek_idx: &SeekIndex) -> DemuxerResult<()> {
+ let seek_to_start = matches!(time, NATimePoint::Milliseconds(0) | NATimePoint::PTS(0));
+ if seek_to_start {
let start = self.start;
self.src.seek(SeekFrom::Start(start))?;
self.cur_frame = 0;
}
Err(DemuxerError::NotImplemented)
}
+ fn get_duration(&self) -> u64 { self.frames as u64 * self.pts_inc / 100 }
+}
+
+impl<'a> NAOptionHandler for SmackerVideoDemuxer<'a> {
+ fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
+ fn set_options(&mut self, _options: &[NAOption]) { }
+ fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
}
impl<'a> SmackerVideoDemuxer<'a> {
}
}
fn reset_state(&mut self) {
- self.queued_packets.truncate(0);
+ self.queued_packets.clear();
}
}
pub struct SMKDemuxerCreator { }
impl DemuxerCreator for SMKDemuxerCreator {
- fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<DemuxCore<'a> + 'a> {
+ fn new_demuxer<'a>(&self, br: &'a mut ByteReader<'a>) -> Box<dyn DemuxCore<'a> + 'a> {
Box::new(SmackerVideoDemuxer::new(br))
}
fn get_name(&self) -> &'static str { "smacker" }
#[test]
fn test_smk_demux() {
+ // sample: https://samples.mplayerhq.hu/game-formats/smacker/20130507_audio-distortion.smk
let mut file = File::open("assets/RAD/20130507_audio-distortion.smk").unwrap();
// let mut file = File::open("assets/RAD/ajfstr1.smk").unwrap();
// let mut file = File::open("assets/RAD/credits.smk").unwrap();
let mut br = ByteReader::new(&mut fr);
let mut dmx = SmackerVideoDemuxer::new(&mut br);
let mut sm = StreamManager::new();
- dmx.open(&mut sm).unwrap();
+ let mut si = SeekIndex::new();
+ dmx.open(&mut sm, &mut si).unwrap();
loop {
let pktres = dmx.get_frame(&mut sm);
if let Err(e) = pktres {