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' {
}
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 {
}
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;
}
}
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;
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;
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 {
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;
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 {
Ok(0)
}
+fn parse_rec(_dmx: &mut AVIDemuxer, _strmgr: &mut StreamManager, _size: usize) -> DemuxerResult<usize> {
+ Ok(0)
+}
+
#[allow(unused_variables)]
fn parse_strh(dmx: &mut AVIDemuxer, strmgr: &mut StreamManager, size: usize) -> DemuxerResult<usize> {
if size < 0x38 { return Err(InvalidData); }
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);
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
#[test]
fn test_avi_demux() {
+ //test sample: https://samples.mplayerhq.hu/V-codecs/RT21/320x240/laser05.avi
let mut file = File::open("assets/Indeo/laser05.avi").unwrap();
let mut fr = FileReader::new_read(&mut file);
let mut br = ByteReader::new(&mut fr);