+ srate: 0,
+ known_frames: Vec::new(),
+ build_index: false,
+ }
+ }
+ fn read_frame(&mut self) -> DemuxerResult<(Vec<u8>, u64, u64)> {
+ if self.src.is_eof() || (self.tot_samples != 0 && self.cur_samples == self.tot_samples) { return Err(DemuxerError::EOF); }
+ let mut buf = Vec::with_capacity(self.min_size);
+ let mut crc = 0;
+ let frame_start = self.src.tell();
+ for _ in 0..5 {
+ let byte = self.src.read_byte()?;
+ buf.push(byte);
+ crc = update_crc16(crc, byte);
+ }
+ let mut ref_crc = self.src.read_u16be()?;
+ loop {
+ let byte = self.src.read_byte()?;
+ let old_byte = (ref_crc >> 8) as u8;
+ buf.push(old_byte);
+ ref_crc = (ref_crc << 8) | u16::from(byte);
+ crc = update_crc16(crc, old_byte);
+ if buf.len() + 2 >= self.min_size && crc == ref_crc {
+ let ret = self.src.peek_u16be();
+ if ret.is_err() || ((ret.unwrap_or(0) & 0xFFFE) == 0xFFF8) {
+ buf.push((ref_crc >> 8) as u8);
+ buf.push(ref_crc as u8);
+ break;
+ }
+ }
+ if (self.max_size > 0) && (buf.len() > self.max_size) {
+ return Err(DemuxerError::InvalidData);
+ }
+ if buf.len() > (1 << 23) {
+ return Err(DemuxerError::InvalidData);
+ }
+ }
+
+ let (duration, pts) = if self.blk_samples != 0 {
+ validate!((buf[1] & 1) == 0);
+ let blkno = u64::from(read_utf8(&buf[4..])?);
+ self.cur_samples = blkno * u64::from(self.blk_samples);
+ (u64::from(self.blk_samples), blkno)
+ } else {
+ let mut idx = 5;
+ while idx < buf.len() && (buf[idx] & 0x80) != 0 {
+ idx += 1;
+ }
+
+ let bsz_id = buf[2] >> 4;
+ let blksamps = match bsz_id {
+ 0 => return Err(DemuxerError::InvalidData),
+ 1 => 192,
+ 2..=5 => 576 << (bsz_id - 2),
+ 6 => {
+ validate!(idx < buf.len());
+ u64::from(buf[idx]) + 1
+ },
+ 7 => {
+ validate!(idx + 2 <= buf.len());
+ u64::from(buf[idx]) * 256 + u64::from(buf[idx + 1]) + 1
+ },
+ _ => 256 << (bsz_id - 8),
+ };
+ let pts = u64::from(read_utf8(&buf[4..])?);
+
+ validate!(idx < buf.len());
+
+ (blksamps, pts)
+ };
+
+ let spos = if self.blk_samples != 0 { pts * u64::from(self.blk_samples) } else { pts };
+ if self.build_index && (self.known_frames.is_empty() || self.known_frames.last().unwrap_or(&FrameSeekInfo::default()).samplepos < spos) {
+ let sampleend = spos + duration;
+ self.known_frames.push(FrameSeekInfo{off: frame_start, size: buf.len() as u64, samplepos: spos, sampleend });