X-Git-Url: https://git.nihav.org/?p=nihav.git;a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fdemuxers%2Fmov.rs;h=745f4402246d0e7f1484fc5af0f4c0688261a384;hp=9a77496fc2717e70ba563b2756adacd18ae65ba6;hb=07972bf3d6de58d3e23e05101cda79482e76ac4c;hpb=0a0456a8355d0bd06c8f8612bfd3326868a6b25f diff --git a/nihav-commonfmt/src/demuxers/mov.rs b/nihav-commonfmt/src/demuxers/mov.rs index 9a77496..745f440 100644 --- a/nihav-commonfmt/src/demuxers/mov.rs +++ b/nihav-commonfmt/src/demuxers/mov.rs @@ -205,6 +205,7 @@ const MOOV_CHUNK_HANDLERS: &[RootChunkHandler] = &[ RootChunkHandler { ctype: mktag!(b"trak"), parse: read_trak }, RootChunkHandler { ctype: mktag!(b"meta"), parse: read_meta }, RootChunkHandler { ctype: mktag!(b"mvex"), parse: read_mvex }, + RootChunkHandler { ctype: mktag!(b"iods"), parse: skip_chunk_mov }, ]; fn read_mvhd(dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, size: u64) -> DemuxerResult { @@ -291,6 +292,10 @@ fn read_mvex(_dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, _size: u64) -> Ok(0) } +fn skip_chunk_mov(_dmx: &mut MOVDemuxer, _strmgr: &mut StreamManager, _size: u64) -> DemuxerResult { + Ok(0) +} + fn read_trak(dmx: &mut MOVDemuxer, strmgr: &mut StreamManager, size: u64) -> DemuxerResult { let mut track = Track::new(dmx.cur_track as u32, dmx.tb_den); track.print_chunks = dmx.print_chunks; @@ -1053,6 +1058,7 @@ struct Track { stream: Option, cur_chunk: usize, cur_sample: usize, + cur_ts: Option, samples_left: usize, last_offset: u64, pal: Option>, @@ -1077,7 +1083,7 @@ impl TimeSearcher { fn reset(&mut self) { *self = Self::default(); } - fn map_time(&mut self, sample: u32, tts: &Vec<(u32, u32)>) -> u64 { + fn map_time(&mut self, sample: u32, tts: &[(u32, u32)]) -> u64 { if tts.is_empty() { u64::from(sample) } else if sample >= self.sbase { @@ -1195,6 +1201,7 @@ impl Track { depth: 0, cur_chunk: 0, cur_sample: 0, + cur_ts: None, samples_left: 0, last_offset: 0, pal: None, @@ -1363,9 +1370,11 @@ impl Track { self.bsize } } + #[allow(clippy::collapsible_if)] fn seek(&mut self, pts: u64, tpoint: NATimePoint) -> DemuxerResult<()> { self.cur_sample = pts as usize; self.samples_left = 0; + self.cur_ts = None; if self.stream_type == StreamType::Audio { if let NATimePoint::Milliseconds(ms) = tpoint { let exp_pts = NATimeInfo::time_to_ts(ms, 1000, self.tb_num, self.tb_den); @@ -1503,6 +1512,25 @@ impl Track { } } +fn process_packet(src: &mut ByteReader, strmgr: &StreamManager, track: &mut Track, pts: NATimeInfo, offset: u64, size: usize, first: bool) -> DemuxerResult { + if let Some(cpts) = pts.get_pts() { + let ts = NATimeInfo::ts_to_time(cpts, 1000, pts.tb_num, pts.tb_den); + track.cur_ts = Some(ts); + } else { + track.cur_ts = None; + } + let str = strmgr.get_stream(track.track_str_id); + if str.is_none() { return Err(DemuxerError::InvalidData); } + let stream = str.unwrap(); + src.seek(SeekFrom::Start(offset))?; + let mut pkt = src.read_packet(stream, pts, false, size)?; + if let Some(ref pal) = track.pal { + let side_data = NASideData::Palette(first, pal.clone()); + pkt.add_side_data(side_data); + } + Ok(pkt) +} + impl<'a> DemuxCore<'a> for MOVDemuxer<'a> { fn open(&mut self, strmgr: &mut StreamManager, seek_index: &mut SeekIndex) -> DemuxerResult<()> { self.read_root(strmgr)?; @@ -1528,6 +1556,30 @@ impl<'a> DemuxCore<'a> for MOVDemuxer<'a> { if self.tracks.is_empty() { return Err(DemuxerError::EOF); } + let mut has_all_time = true; + let mut min_ts = std::u64::MAX; + for trk in self.tracks.iter() { + if let Some(ts) = trk.cur_ts { + min_ts = min_ts.min(ts); + } else { + has_all_time = false; + break; + } + } + if has_all_time { + for (trk_no, track) in self.tracks.iter_mut().enumerate() { + if let Some(ts) = track.cur_ts { + if ts == min_ts { + let first = track.cur_sample == 0; + if let Some((pts, offset, size)) = track.get_next_chunk() { + self.cur_track = trk_no + 1; + return process_packet(&mut self.src, strmgr, track, pts, offset, size, first); + } + } + } + } + } + for _ in 0..self.tracks.len() { if self.cur_track >= self.tracks.len() { self.cur_track = 0; @@ -1536,16 +1588,7 @@ impl<'a> DemuxCore<'a> for MOVDemuxer<'a> { self.cur_track += 1; let first = track.cur_sample == 0; if let Some((pts, offset, size)) = track.get_next_chunk() { - let str = strmgr.get_stream(track.track_str_id); - if str.is_none() { return Err(DemuxerError::InvalidData); } - let stream = str.unwrap(); - self.src.seek(SeekFrom::Start(offset))?; - let mut pkt = self.src.read_packet(stream, pts, false, size)?; - if let Some(ref pal) = track.pal { - let side_data = NASideData::Palette(first, pal.clone()); - pkt.add_side_data(side_data); - } - return Ok(pkt); + return process_packet(&mut self.src, strmgr, track, pts, offset, size, first); } } Err(DemuxerError::EOF) @@ -1604,6 +1647,7 @@ const DEMUXER_OPTIONS: &[NAOptionDefinition] = &[ impl<'a> NAOptionHandler for MOVDemuxer<'a> { fn get_supported_options(&self) -> &[NAOptionDefinition] { DEMUXER_OPTIONS } + #[allow(clippy::single_match)] fn set_options(&mut self, options: &[NAOption]) { for option in options.iter() { for opt_def in DEMUXER_OPTIONS.iter() {