X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-commonfmt%2Fsrc%2Fdemuxers%2Favi.rs;h=113f9e050fa3198537340a9ce616ebb114c20739;hb=eea05a77c2b998c94087825a60d1a9f0f4fe2b7d;hp=cc24fe308581882d4d34b39030d0b30bceba17de;hpb=886cde4847280b96e10d240c2f2d76abec121dc8;p=nihav.git diff --git a/nihav-commonfmt/src/demuxers/avi.rs b/nihav-commonfmt/src/demuxers/avi.rs index cc24fe3..113f9e0 100644 --- a/nihav-commonfmt/src/demuxers/avi.rs +++ b/nihav-commonfmt/src/demuxers/avi.rs @@ -140,11 +140,16 @@ impl<'a> DemuxCore<'a> for AVIDemuxer<'a> { continue; } if (tag[0] == b'i' && tag[1] == b'x') || (&tag == b"idx1") { + let idx_pos = self.src.tell() - 8; if !self.odml { return Err(EOF); } self.src.read_skip(size)?; - self.try_next_odml_chunk()?; + if idx_pos > self.movi_pos { + self.try_next_odml_chunk()?; + } else { + self.movi_pos = self.src.tell(); + } continue; } if tag[0] < b'0' || tag[0] > b'9' || tag[1] < b'0' || tag[1] > b'9' { @@ -162,9 +167,13 @@ impl<'a> DemuxCore<'a> for AVIDemuxer<'a> { } continue; } - let str = strmgr.get_stream(stream_no as usize); - if str.is_none() { return Err(InvalidData); } - let stream = str.unwrap(); + let stream = strmgr.get_stream(stream_no as usize); + if stream.is_none() { + self.src.read_skip(size)?; + self.movi_size -= size + 8; + continue; + } + let stream = stream.unwrap(); if size == 0 { self.movi_size -= 8; if self.movi_size == 0 { @@ -175,8 +184,8 @@ impl<'a> DemuxCore<'a> for AVIDemuxer<'a> { } continue; } - let (tb_num, tb_den) = stream.get_timebase(); - let mut ts = NATimeInfo::new(Some(self.cur_frame[stream_no as usize]), None, None, tb_num, tb_den); + let (tb_num, _) = stream.get_timebase(); + let mut ts = stream.make_ts(Some(self.cur_frame[stream_no as usize]), None, None); if stream.get_media_type() == StreamType::Audio && tb_num == 1 && stream.get_info().get_name() == "pcm" { ts.pts = None; } @@ -234,7 +243,7 @@ impl<'a> DemuxCore<'a> for AVIDemuxer<'a> { } if seek_info.pos < self.movi_pos { return Err(DemuxerError::SeekError); } let skip_size = (seek_info.pos - self.movi_pos) as usize; - if skip_size > self.movi_size { return Err(DemuxerError::SeekError); } + if skip_size > self.movi_orig { return Err(DemuxerError::SeekError); } self.movi_size = self.movi_orig - skip_size; self.cur_frame[seek_info.str_id as usize] = seek_info.pts; @@ -361,7 +370,7 @@ impl<'a> AVIDemuxer<'a> { if ret.is_err() { break; } let (csz, end) = ret.unwrap(); if end { - let _res = parse_idx1(&mut self.src, strmgr, seek_idx, csz, self.movi_pos, &mut self.key_offs); + let _res = parse_idx1(self.src, strmgr, seek_idx, csz, self.movi_pos, &mut self.key_offs); break; } rest_size -= csz; @@ -388,7 +397,7 @@ impl<'a> AVIDemuxer<'a> { start = 0; last_strm_no = stream_no; } - let ret = parse_odml_ix(&mut self.src, strmgr, seek_idx, stream_no, size, start); + let ret = parse_odml_ix(self.src, strmgr, seek_idx, stream_no, size, start); if let Ok(new_start) = ret { start = new_start; } else { @@ -418,18 +427,25 @@ impl<'a> AVIDemuxer<'a> { fn parse_palette_change(&mut self, stream_no: usize, size: usize) -> DemuxerResult<()> { for pe in self.pal.iter_mut() { if pe.stream_no == stream_no { - let start_clr = self.src.read_byte()? as usize; - let len = self.src.read_byte()? as usize; - let _flags = self.src.read_u16le()?; - validate!(start_clr + len <= 256); - validate!(len * 4 + 4 == size); let mut newpal = *pe.pal; - for i in start_clr..(start_clr + len) { - newpal[i * 4] = self.src.read_byte()?; - newpal[i * 4 + 1] = self.src.read_byte()?; - newpal[i * 4 + 2] = self.src.read_byte()?; - newpal[i * 4 + 3] = 0; + let mut data_left = size; + while data_left > 0 { + validate!(data_left >= 8); + let start_clr = self.src.read_byte()? as usize; + let len = self.src.read_byte()? as usize; + let len = if len == 0 { 256 } else { len }; + let _flags = self.src.read_u16le()?; + validate!(start_clr + len <= 256); + let change_size = len * 4 + 4; + validate!(change_size <= data_left); + for i in start_clr..(start_clr + len) { + newpal[i * 4] = self.src.read_byte()?; + newpal[i * 4 + 1] = self.src.read_byte()?; + newpal[i * 4 + 2] = self.src.read_byte()?; + newpal[i * 4 + 3] = 0; self.src.read_byte()?; // flags + } + data_left -= change_size; } pe.pal = Arc::new(newpal); pe.changed = true; @@ -493,6 +509,7 @@ const CHUNKS: &[RIFFParser] = &[ RIFFParser { tag: RIFFTag::Chunk(mktag!(b"indx")), parse: parse_indx }, RIFFParser { tag: RIFFTag::Chunk(mktag!(b"JUNK")), parse: parse_junk }, RIFFParser { tag: RIFFTag::List(mktag!(b"LIST"), mktag!(b"odml")), parse: parse_odml }, + RIFFParser { tag: RIFFTag::List(mktag!(b"LIST"), mktag!(b"rec ")), parse: parse_rec }, ]; fn is_list_tag(tag: u32) -> bool { @@ -521,6 +538,10 @@ fn parse_odml(dmx: &mut AVIDemuxer, _strmgr: &mut StreamManager, _size: usize) - Ok(0) } +fn parse_rec(_dmx: &mut AVIDemuxer, _strmgr: &mut StreamManager, _size: usize) -> DemuxerResult { + Ok(0) +} + #[allow(unused_variables)] fn parse_strh(dmx: &mut AVIDemuxer, strmgr: &mut StreamManager, size: usize) -> DemuxerResult { if size < 0x38 { return Err(InvalidData); } @@ -782,14 +803,14 @@ fn parse_idx1(src: &mut ByteReader, strmgr: &mut StreamManager, seek_idx: &mut S offset += add_offset; if tag[0] < b'0' || tag[0] > b'9' || tag[1] < b'0' || tag[1] > b'9' { - return Err(InvalidData); + continue; } let stream_no = ((tag[0] - b'0') * 10 + (tag[1] - b'0')) as usize; if (flags & 0x10) != 0 { - if let Some(str) = strmgr.get_stream(stream_no) { - if str.get_media_type() == StreamType::Video { - let (tb_num, tb_den) = str.get_timebase(); + if let Some(stream) = strmgr.get_stream(stream_no) { + if stream.get_media_type() == StreamType::Video { + let (tb_num, tb_den) = stream.get_timebase(); let pts = counter[stream_no]; let time = NATimeInfo::ts_to_time(pts, 1000, tb_num, tb_den); validate!(offset >= movi_pos); @@ -814,7 +835,7 @@ fn parse_odml_ix(src: &mut ByteReader, strmgr: &mut StreamManager, seek_idx: &mu let idx_type = src.read_byte()?; validate!(sub_type == 0 && idx_type == 1); let entries = src.read_u32le()? as usize; - validate!(size == 24 + entries * 4 * entry_size); + validate!(size >= 24 + entries * 4 * entry_size); src.read_tag()?; //chunk id let base_offset = src.read_u64le()?; src.read_u32le()?; //reserved