X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-realmedia%2Fsrc%2Fdemuxers%2Frealmedia.rs;h=feeb3904fe1ee455ae5659ff6d54a36b3ec3a850;hb=76c275c9640ed6dabf1f65ee115452ebef162e4d;hp=30b0ccd8a295c10223960ce8b7264b0ac68e36da;hpb=6011e20199143f519881660144a4ca95ba77fd2d;p=nihav.git diff --git a/nihav-realmedia/src/demuxers/realmedia.rs b/nihav-realmedia/src/demuxers/realmedia.rs index 30b0ccd..feeb390 100644 --- a/nihav-realmedia/src/demuxers/realmedia.rs +++ b/nihav-realmedia/src/demuxers/realmedia.rs @@ -106,7 +106,7 @@ const RM_ILEAVE_VBRS: u32 = mktag!(b"vbrs"); impl RMAudioStream { fn new(iinfo: Option) -> Self { let deint; - let mut buf: Vec; + let buf: Vec; if let Some(info) = iinfo { deint = match info.id { RM_ILEAVE_INT0 => Deinterleaver::None, @@ -123,8 +123,7 @@ impl RMAudioStream { Deinterleaver::Generic | Deinterleaver::Sipro => { let bsize = (info.frame_size as usize) * (info.factor as usize); - buf = Vec::with_capacity(bsize); - buf.resize(bsize, 0u8); + buf = vec![0; bsize]; }, Deinterleaver::VBR => { buf = Vec::new(); @@ -134,7 +133,7 @@ impl RMAudioStream { deint = Deinterleaver::None; buf = Vec::new(); } - RMAudioStream { deint: deint, iinfo: iinfo, buf: buf, sub_packet: 0 } + RMAudioStream { deint, iinfo, buf, sub_packet: 0 } } fn read_apackets(&mut self, queued_packets: &mut Vec, src: &mut ByteReader, stream: NAStreamRef, ts: u32, keyframe: bool, payload_size: usize) -> DemuxerResult { let (tb_num, tb_den) = stream.get_timebase(); @@ -225,7 +224,7 @@ impl RMAudioStream { self.sub_packet = 0; if self.deint == Deinterleaver::Sipro { - sipro_restore(&mut self.buf, factor, fsize); + sipro_restore(&mut self.buf, factor, iinfo.frame_size as usize); } let mut frames_iter = self.buf.chunks(fsize); @@ -350,6 +349,7 @@ impl CommonStreamData { struct RealMediaDemuxer<'a> { src: &'a mut ByteReader<'a>, data_pos: u64, + data_end: u64, next_data: u64, data_ver: u16, num_packets: u32, @@ -357,6 +357,9 @@ struct RealMediaDemuxer<'a> { str_data: CommonStreamData, + data_chunks: Vec<(u64, u32, u16)>, + cur_data_chunk: usize, + queued_pkts: Vec, slice_buf: Vec, } @@ -381,8 +384,7 @@ fn read_14or30(src: &mut ByteReader) -> DemuxerResult<(bool, u32)> { fn read_video_buf(src: &mut ByteReader, stream: NAStreamRef, ts: u32, keyframe: bool, frame_size: usize) -> DemuxerResult { let size = (frame_size as usize) + 9; - let mut vec: Vec = Vec::with_capacity(size); - vec.resize(size, 0); + let mut vec: Vec = vec![0; size]; //v[0] = 0; // 1 slice vec[4] = 1; src.read_buf(&mut vec[9..])?; @@ -420,7 +422,7 @@ impl RMDemuxCommon { } else if ((tag2 == mktag!('V', 'I', 'D', 'O')) || (tag2 == mktag!('I', 'M', 'A', 'G'))) && ((tag as usize) <= edata.len()) { Self::parse_video_stream(strmgr, &mut str_data.streams, stream_no, &mut src, edata.as_slice(), tag2)?; } else if tag == mktag!(b"LSD:") { - let extradata = Some(edata.clone()); + let extradata = Some(edata.to_owned()); src.read_skip(4)?; //version let channels = src.read_u16be()?; @@ -431,7 +433,7 @@ impl RMDemuxCommon { let soniton = NASoniton::new(samp_size as u8, SONITON_FLAG_SIGNED); let ahdr = NAAudioInfo::new(sample_rate, channels as u8, soniton, 1); let nainfo = NACodecInfo::new("ralf", NACodecTypeInfo::Audio(ahdr), extradata); - let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, sample_rate)); + let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, 1000)); if res.is_none() { return Err(MemoryError); } let astr = RMAudioStream::new(None); str_data.streams.push(RMStreamType::Audio(astr)); @@ -513,7 +515,7 @@ println!(" got ainfo {:?}", ainfo); Some(eslice.to_vec()) }; let nainfo = NACodecInfo::new(cname, NACodecTypeInfo::Audio(ahdr), extradata); - let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, srate)); + let res = strmgr.add_stream(NAStream::new(StreamType::Audio, stream_no as u32, nainfo, 1, 1000)); if res.is_none() { return Err(MemoryError); } let astr = RMAudioStream::new(ainfo.ileave_info); @@ -529,11 +531,11 @@ println!(" got ainfo {:?}", ainfo); let bpp = src.read_u16be()?; let pad_w = src.read_u16be()?; let pad_h = src.read_u16be()?; - let fps; + let _fps; if tag2 == mktag!('V', 'I', 'D', 'O') { - fps = src.read_u32be()?; + _fps = src.read_u32be()?; } else { - fps = 0x10000; + _fps = 0x10000; } let extradata: Option>; if src.left() > 0 { @@ -546,7 +548,7 @@ println!(" got ainfo {:?}", ainfo); let vhdr = NAVideoInfo::new(width, height, false, RGB24_FORMAT); let vinfo = NACodecInfo::new(cname, NACodecTypeInfo::Video(vhdr), extradata); - let res = strmgr.add_stream(NAStream::new(StreamType::Video, stream_no as u32, vinfo, 0x10000, fps)); + let res = strmgr.add_stream(NAStream::new(StreamType::Video, stream_no as u32, vinfo, 1, 1000)); if res.is_none() { return Err(DemuxerError::MemoryError); } let vstr = RMVideoStream::new(); @@ -648,9 +650,8 @@ println!(" got ainfo {:?}", ainfo); } impl<'a> DemuxCore<'a> for RealMediaDemuxer<'a> { - #[allow(unused_variables)] - fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> { - self.read_header(strmgr)?; + fn open(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<()> { + self.read_header(strmgr, seek_idx)?; Ok(()) } @@ -661,12 +662,16 @@ impl<'a> DemuxCore<'a> for RealMediaDemuxer<'a> { return Ok(pkt); } loop { - if self.cur_packet >= self.num_packets { - if (self.next_data != 0) && (self.next_data == self.src.tell()) { + if (self.cur_packet >= self.num_packets) || (self.src.tell() >= self.data_end) { + self.cur_data_chunk += 1; + if self.cur_data_chunk < self.data_chunks.len() { + let (pos, _, _) = self.data_chunks[self.cur_data_chunk]; + self.src.seek(SeekFrom::Start(pos))?; let res = read_chunk(self.src); if let Ok((id, size, ver)) = res { self.data_pos = self.src.tell(); self.data_ver = ver; + self.data_end = self.data_pos + (size as u64); if self.parse_data_start().is_ok() { continue; } @@ -733,8 +738,27 @@ impl<'a> DemuxCore<'a> for RealMediaDemuxer<'a> { } #[allow(unused_variables)] - fn seek(&mut self, time: u64) -> DemuxerResult<()> { - Err(NotImplemented) + fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> { + self.queued_pkts.clear(); + let ret = seek_idx.find_pos(time); + if ret.is_none() { + return Err(DemuxerError::SeekError); + } + let ret = ret.unwrap(); + let seek_pos = ret.pos; + for (pos, size, ver) in self.data_chunks.iter() { + if seek_pos < *pos { continue; } + let end = *pos + (*size as u64); + if seek_pos < end { + self.cur_packet = 0; + self.data_pos = seek_pos; + self.data_ver = *ver; + self.data_end = end; + self.src.seek(SeekFrom::Start(seek_pos))?; + return Ok(()); + } + } + Err(DemuxerError::SeekError) } } @@ -809,10 +833,10 @@ fn parse_aformat3(src: &mut ByteReader) -> DemuxerResult { validate!(end - start <= (header_len as u64) + 2); Ok(RealAudioInfo { - fcc: fcc, flavor: flavor, + fcc, flavor, sample_rate: 8000, sample_size: 16, channels: 1, channel_mask: 0, - granularity: granularity, bytes_per_minute: bytes_per_minute, - total_bytes: total_bytes, edata_size: 0, + granularity, bytes_per_minute, + total_bytes, edata_size: 0, ileave_info: None, }) } @@ -862,11 +886,11 @@ fn parse_aformat4(src: &mut ByteReader) -> DemuxerResult { }; Ok(RealAudioInfo { - fcc: fcc, flavor: flavor, - sample_rate: sample_rate, sample_size: sample_size as u16, channels: channels, channel_mask: 0, - granularity: granularity, bytes_per_minute: bytes_per_minute, + fcc, flavor, + sample_rate, sample_size: sample_size as u16, channels, channel_mask: 0, + granularity, bytes_per_minute, total_bytes: total_bytes & 0xFFFFFF, edata_size: 0, - ileave_info: ileave_info, + ileave_info, }) } @@ -912,7 +936,7 @@ unimplemented!("ra5 interleave pattern"); let ileave_info = if is_interleaved != 0 { Some(InterleaveInfo { - id: interleaver_id, factor: ileave_factor, block_size: ileave_block_size, frame_size: frame_size, + id: interleaver_id, factor: ileave_factor, block_size: ileave_block_size, frame_size, }) } else { None @@ -924,11 +948,11 @@ unimplemented!("ra5 interleave pattern"); } Ok(RealAudioInfo { - fcc: fcc, flavor: flavor, - sample_rate: sample_rate, sample_size: sample_size as u16, channels: channels, channel_mask: 0, - granularity: granularity, bytes_per_minute: bytes_per_minute, - total_bytes: total_bytes & 0xFFFFFF, edata_size: edata_size, - ileave_info: ileave_info, + fcc, flavor, + sample_rate, sample_size: sample_size as u16, channels, channel_mask: 0, + granularity, bytes_per_minute, + total_bytes: total_bytes & 0xFFFFFF, edata_size, + ileave_info, }) } @@ -941,17 +965,20 @@ impl<'a> RealMediaDemuxer<'a> { RealMediaDemuxer { src: io, data_pos: 0, + data_end: 0, next_data: 0, data_ver: 0, num_packets: 0, cur_packet: 0, str_data: CommonStreamData::new(), + data_chunks: Vec::new(), + cur_data_chunk: 0, queued_pkts: Vec::new(), slice_buf: Vec::new(), } } #[allow(unused_variables)] - fn read_header(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> { + fn read_header(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<()> { let (id, size, ver) = read_chunk(self.src)?; validate!((id == mktag!(b".RMF")) || (id == mktag!(b".RMP"))); validate!(size >= RMVB_HDR_SIZE); @@ -990,20 +1017,25 @@ impl<'a> RealMediaDemuxer<'a> { //warn maybe? break; } - let res = self.parse_chunk(strmgr); + let res = self.parse_chunk(strmgr, seek_idx); match res { Ok(last) => { if last { break; } }, Err(DemuxerError::IOError) => { break; }, Err(etype) => { - if self.data_pos == 0 { // data is not found, report error + if self.data_chunks.len() == 0 { // data is not found, report error return Err(etype); } }, }; } //println!("now @ {:X} / {}", self.src.tell(), self.data_pos); - validate!(self.data_pos > 0); - self.src.seek(SeekFrom::Start(self.data_pos))?; + validate!(self.data_chunks.len() > 0); + self.cur_data_chunk = 0; + let (pos, size, ver) = self.data_chunks[self.cur_data_chunk]; + self.data_pos = pos; + self.data_ver = ver; + self.data_end = pos + (size as u64); + self.src.seek(SeekFrom::Start(self.data_pos + 10))?; self.parse_data_start()?; Ok(()) } @@ -1018,15 +1050,21 @@ impl<'a> RealMediaDemuxer<'a> { self.next_data = next_data_hdr as u64; Ok(()) } - fn parse_chunk(&mut self, strmgr: &mut StreamManager) -> DemuxerResult { + fn parse_chunk(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult { let (id, size, ver) = read_chunk(self.src)?; let end_pos = self.src.tell() - 10 + (size as u64); validate!((ver == 0) || (ver == 2)); if id == mktag!(b"CONT") { self.parse_content_desc()?; } else if id == mktag!(b"MDPR") { self.parse_mdpr(strmgr)?; } - else if id == mktag!(b"DATA") { if self.data_pos == 0 { self.data_ver = ver; self.data_pos = self.src.tell(); } } - else if id == mktag!(b"INDX") { /* do nothing for now */ } + else if id == mktag!(b"DATA") { + self.data_chunks.push((self.src.tell() - 10, size, ver)); + } + else if id == mktag!(b"INDX") { + if !seek_idx.skip_index { + self.parse_index(seek_idx, (size as usize) - 10, ver)?; + } + } else if id == 0 { return Ok(true); } else { println!("unknown chunk type {:08X}", id); } @@ -1067,8 +1105,7 @@ impl<'a> RealMediaDemuxer<'a> { //println!("mime = {}", mime); let edata_size = self.src.read_u32be()? as usize; let edata: Option> = if edata_size == 0 { None } else { - let mut edvec: Vec = Vec::with_capacity(edata_size); - edvec.resize(edata_size, 0); + let mut edvec: Vec = vec![0; edata_size]; self.src.read_buf(&mut edvec)?; Some(edvec) }; @@ -1086,6 +1123,28 @@ impl<'a> RealMediaDemuxer<'a> { Ok(()) } + fn parse_index(&mut self, seek_idx: &mut SeekIndex, chunk_size: usize, ver: u16) -> DemuxerResult<()> { + if ver != 0 { return Ok(()); } + let num_entries = self.src.read_u32be()? as usize; + let str_id = self.src.read_u16be()? as u32; + let _next_idx = self.src.read_u32be()?; + validate!(chunk_size == num_entries * 14 + 10); + if num_entries == 0 { return Ok(()); } + + seek_idx.add_stream(str_id); + let idx = seek_idx.get_stream_index(str_id).unwrap(); + for _ in 0..num_entries { + let ver = self.src.read_u16be()? as u32; + validate!(ver == 0); + let ts = self.src.read_u32be()? as u64; + let pos = self.src.read_u32be()? as u64; + let _pkt_no = self.src.read_u32be()?; + idx.add_entry(SeekEntry { time: ts, pts: 0, pos }); + } + idx.filled = true; + seek_idx.mode = SeekIndexMode::Present; + Ok(()) + } } fn read_string_size(src: &mut ByteReader, size: usize) -> DemuxerResult { @@ -1113,7 +1172,7 @@ struct RealAudioDemuxer<'a> { impl<'a> DemuxCore<'a> for RealAudioDemuxer<'a> { #[allow(unused_variables)] - fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> { + fn open(&mut self, strmgr: &mut StreamManager, _seek_idx: &mut SeekIndex) -> DemuxerResult<()> { let magic = self.src.read_u32be()?; validate!(magic == mktag!(b".ra\xFD")); let ver = self.src.read_u16be()?; @@ -1146,8 +1205,7 @@ println!(" got ainfo {:?}", ainfo); let extradata = if ainfo.edata_size == 0 { None } else { - let mut dta: Vec = Vec::with_capacity(ainfo.edata_size as usize); - dta.resize(ainfo.edata_size as usize, 0); + let mut dta: Vec = vec![0; ainfo.edata_size as usize]; self.src.read_buf(dta.as_mut_slice())?; Some(dta) }; @@ -1187,7 +1245,7 @@ println!(" got ainfo {:?}", ainfo); } #[allow(unused_variables)] - fn seek(&mut self, time: u64) -> DemuxerResult<()> { + fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> { Err(NotImplemented) } } @@ -1220,8 +1278,7 @@ enum IVRRecord { impl IVRRecord { fn read_string(src: &mut ByteReader) -> DemuxerResult> { let len = src.read_u32be()? as usize; - let mut val = Vec::with_capacity(len); - val.resize(len, 0); + let mut val = vec![0; len]; src.read_buf(val.as_mut_slice())?; Ok(val) } @@ -1252,8 +1309,7 @@ impl IVRRecord { 4 => { let name = Self::read_string(src)?; let len = src.read_u32be()? as usize; - let mut val = Vec::with_capacity(len); - val.resize(len, 0); + let mut val = vec![0; len]; src.read_buf(val.as_mut_slice())?; Ok(IVRRecord::BinaryData(name, val)) }, @@ -1315,7 +1371,7 @@ impl RecordDemuxer { RecordDemuxer { start_pos: pos, cur_pos: pos, - start_str: start_str, + start_str, remap_ids: Vec::new(), } } @@ -1405,7 +1461,7 @@ impl RecordDemuxer { loop { let rec = IVRRecord::read(src)?; match rec { - IVRRecord::Packet { ts, str, flags, len, checksum: _ } => { + IVRRecord::Packet { ts, str, flags, len, .. } => { let payload_size = len; let sr = self.remap_ids.iter().position(|x| *x == str); validate!(sr.is_some()); @@ -1456,7 +1512,7 @@ struct RealIVRDemuxer<'a> { impl<'a> DemuxCore<'a> for RealIVRDemuxer<'a> { #[allow(unused_variables)] - fn open(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<()> { + fn open(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<()> { let magic = self.src.peek_u32be()?; if magic == mktag!(b".REC") { let mut rec = RecordDemuxer::new(0, 0); @@ -1528,7 +1584,7 @@ println!("R1M kind"); } #[allow(unused_variables)] - fn seek(&mut self, time: u64) -> DemuxerResult<()> { + fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> { Err(NotImplemented) } } @@ -1618,7 +1674,8 @@ mod test { let mut br = ByteReader::new(&mut fr); let mut dmx = RealMediaDemuxer::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); @@ -1640,7 +1697,8 @@ mod test { let mut br = ByteReader::new(&mut fr); let mut dmx = RealAudioDemuxer::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); @@ -1661,7 +1719,8 @@ mod test { let mut br = ByteReader::new(&mut fr); let mut dmx = RealIVRDemuxer::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);