X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-realmedia%2Fsrc%2Fdemuxers%2Frealmedia.rs;h=b37c34faa6510ec827b819464f5530c16cb8695f;hb=24d998947d55228ec37a08cd391983c6239e3c0c;hp=fa3920a0a3d0d042d7493bcf24755cf370ded324;hpb=9da33f04bbd89f18942bbafc6d135b5d3f102953;p=nihav.git diff --git a/nihav-realmedia/src/demuxers/realmedia.rs b/nihav-realmedia/src/demuxers/realmedia.rs index fa3920a..b37c34f 100644 --- a/nihav-realmedia/src/demuxers/realmedia.rs +++ b/nihav-realmedia/src/demuxers/realmedia.rs @@ -53,13 +53,15 @@ impl RMVideoStream { self.frame.resize(frame_size + self.hdr_size, 0); self.frame[0] = (num_slices - 1) as u8; self.frame_pos = 0; - self.add_slice(1, data); + self.add_slice(1, data).unwrap(); } - fn add_slice(&mut self, slice_no: usize, data: &[u8]) { + fn add_slice(&mut self, slice_no: usize, data: &[u8]) -> DemuxerResult<()> { + validate!(self.hdr_size + self.frame_pos + data.len() <= self.frame.len()); self.write_slice_info(slice_no); let dslice = &mut self.frame[self.hdr_size + self.frame_pos..][..data.len()]; dslice.copy_from_slice(data); self.frame_pos += data.len(); + Ok(()) } fn write_slice_info(&mut self, slice_no: usize) { let off = 1 + (slice_no - 1) * 8; @@ -224,7 +226,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); @@ -410,17 +412,17 @@ fn read_multiple_frame(src: &mut ByteReader, stream: NAStreamRef, keyframe: bool struct RMDemuxCommon {} impl RMDemuxCommon { - fn parse_stream_info(str_data: &mut CommonStreamData, strmgr: &mut StreamManager, stream_no: u32, edata: &Vec) -> DemuxerResult { + fn parse_stream_info(str_data: &mut CommonStreamData, strmgr: &mut StreamManager, stream_no: u32, edata: &[u8]) -> DemuxerResult { let mut is_mlti = false; - let mut mr = MemoryReader::new_read(edata.as_slice()); + let mut mr = MemoryReader::new_read(edata); let mut src = ByteReader::new(&mut mr); let tag = src.read_u32be()?; let tag2 = src.peek_u32be()?; //println!("tag1 {:X} tag2 {:X}", tag, tag2); if tag == mktag!('.', 'r', 'a', 0xFD) { - Self::parse_audio_stream(strmgr, &mut str_data.streams, stream_no, &mut src, edata.as_slice())?; + Self::parse_audio_stream(strmgr, &mut str_data.streams, stream_no, &mut src, edata)?; } 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)?; + Self::parse_video_stream(strmgr, &mut str_data.streams, stream_no, &mut src, edata, tag2)?; } else if tag == mktag!(b"LSD:") { let extradata = Some(edata.to_owned()); @@ -433,7 +435,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)); @@ -515,7 +517,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); @@ -531,11 +533,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 { @@ -548,7 +550,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(); @@ -580,7 +582,7 @@ println!(" got ainfo {:?}", ainfo); if packet_num == 1 { vstr.start_slice(num_pkts, frame_size as usize, slice_buf.as_slice()); } else { - vstr.add_slice(packet_num as usize, slice_buf.as_slice()); + vstr.add_slice(packet_num as usize, slice_buf.as_slice())?; } if (packet_num as usize) < num_pkts { return Err(DemuxerError::TryAgain); @@ -610,7 +612,7 @@ println!(" got ainfo {:?}", ainfo); if packet_num == 1 && frame_size == tail_size { vstr.start_slice(num_pkts, frame_size as usize, slice_buf.as_slice()); } else { - vstr.add_slice(packet_num as usize, slice_buf.as_slice()); + vstr.add_slice(packet_num as usize, slice_buf.as_slice())?; } while src.tell() < pos + (payload_size as u64) { @@ -738,7 +740,7 @@ impl<'a> DemuxCore<'a> for RealMediaDemuxer<'a> { } #[allow(unused_variables)] - fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> { + fn seek(&mut self, time: NATimePoint, seek_idx: &SeekIndex) -> DemuxerResult<()> { self.queued_pkts.clear(); let ret = seek_idx.find_pos(time); if ret.is_none() { @@ -762,6 +764,12 @@ impl<'a> DemuxCore<'a> for RealMediaDemuxer<'a> { } } +impl<'a> NAOptionHandler for RealMediaDemuxer<'a> { + fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } + fn set_options(&mut self, _options: &[NAOption]) { } + fn query_option_value(&self, _name: &str) -> Option { None } +} + fn read_chunk(src: &mut ByteReader) -> DemuxerResult<(u32, u32, u16)> { let id = src.read_u32be()?; if id == 0 { return Ok((0, 0, 0)); } @@ -1022,14 +1030,14 @@ impl<'a> RealMediaDemuxer<'a> { Ok(last) => { if last { break; } }, Err(DemuxerError::IOError) => { break; }, Err(etype) => { - if self.data_chunks.len() == 0 { // data is not found, report error + if self.data_chunks.is_empty() { // data is not found, report error return Err(etype); } }, }; } //println!("now @ {:X} / {}", self.src.tell(), self.data_pos); - validate!(self.data_chunks.len() > 0); + validate!(!self.data_chunks.is_empty()); self.cur_data_chunk = 0; let (pos, size, ver) = self.data_chunks[self.cur_data_chunk]; self.data_pos = pos; @@ -1124,19 +1132,29 @@ 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(()); } + if ver != 0 && ver != 2 { 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 ver == 2 { + self.src.read_u32be()?; + } + if ver == 0 { + validate!(chunk_size == num_entries * 14 + 10); + } else { + validate!(chunk_size == num_entries * 18 + 14); + } 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 iver = self.src.read_u16be()?; + validate!(iver == ver); let ts = self.src.read_u32be()? as u64; + if ver == 2 { + self.src.read_u32be()?; + } let pos = self.src.read_u32be()? as u64; let _pkt_no = self.src.read_u32be()?; idx.add_entry(SeekEntry { time: ts, pts: 0, pos }); @@ -1245,11 +1263,17 @@ println!(" got ainfo {:?}", ainfo); } #[allow(unused_variables)] - fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> { + fn seek(&mut self, time: NATimePoint, seek_idx: &SeekIndex) -> DemuxerResult<()> { Err(NotImplemented) } } +impl<'a> NAOptionHandler for RealAudioDemuxer<'a> { + fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } + fn set_options(&mut self, _options: &[NAOption]) { } + fn query_option_value(&self, _name: &str) -> Option { None } +} + impl<'a> RealAudioDemuxer<'a> { fn new(io: &'a mut ByteReader<'a>) -> Self { RealAudioDemuxer { @@ -1584,11 +1608,17 @@ println!("R1M kind"); } #[allow(unused_variables)] - fn seek(&mut self, time: u64, seek_idx: &SeekIndex) -> DemuxerResult<()> { + fn seek(&mut self, time: NATimePoint, seek_idx: &SeekIndex) -> DemuxerResult<()> { Err(NotImplemented) } } +impl<'a> NAOptionHandler for RealIVRDemuxer<'a> { + fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] } + fn set_options(&mut self, _options: &[NAOption]) { } + fn query_option_value(&self, _name: &str) -> Option { None } +} + impl<'a> RealIVRDemuxer<'a> { fn new(io: &'a mut ByteReader<'a>) -> Self { RealIVRDemuxer { @@ -1674,7 +1704,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); @@ -1696,7 +1727,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); @@ -1717,7 +1749,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);