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;
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);
struct RealMediaDemuxer<'a> {
src: &'a mut ByteReader<'a>,
data_pos: u64,
+ data_end: u64,
next_data: u64,
data_ver: u16,
num_packets: u32,
str_data: CommonStreamData,
+ data_chunks: Vec<(u64, u32, u16)>,
+ cur_data_chunk: usize,
+
queued_pkts: Vec<NAPacket>,
slice_buf: Vec<u8>,
}
struct RMDemuxCommon {}
impl RMDemuxCommon {
- fn parse_stream_info(str_data: &mut CommonStreamData, strmgr: &mut StreamManager, stream_no: u32, edata: &Vec<u8>) -> DemuxerResult<bool> {
+ fn parse_stream_info(str_data: &mut CommonStreamData, strmgr: &mut StreamManager, stream_no: u32, edata: &[u8]) -> DemuxerResult<bool> {
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());
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));
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);
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<Vec<u8>>;
if src.left() > 0 {
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();
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);
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) {
}
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(())
}
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;
}
}
#[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> DemuxerResult<()> {
- Err(NotImplemented)
+ 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() {
+ 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)
}
}
+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<NAValue> { None }
+}
+
fn read_chunk(src: &mut ByteReader) -> DemuxerResult<(u32, u32, u16)> {
let id = src.read_u32be()?;
if id == 0 { return Ok((0, 0, 0)); }
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);
//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.is_empty() { // 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.is_empty());
+ 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(())
}
self.next_data = next_data_hdr as u64;
Ok(())
}
- fn parse_chunk(&mut self, strmgr: &mut StreamManager) -> DemuxerResult<bool> {
+ fn parse_chunk(&mut self, strmgr: &mut StreamManager, seek_idx: &mut SeekIndex) -> DemuxerResult<bool> {
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); }
Ok(())
}
+ fn parse_index(&mut self, seek_idx: &mut SeekIndex, chunk_size: usize, ver: u16) -> DemuxerResult<()> {
+ 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()?;
+ 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 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 });
+ }
+ idx.filled = true;
+ seek_idx.mode = SeekIndexMode::Present;
+ Ok(())
+ }
}
fn read_string_size(src: &mut ByteReader, size: usize) -> DemuxerResult<String> {
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()?;
}
#[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> 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<NAValue> { None }
+}
+
impl<'a> RealAudioDemuxer<'a> {
fn new(io: &'a mut ByteReader<'a>) -> Self {
RealAudioDemuxer {
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);
}
#[allow(unused_variables)]
- fn seek(&mut self, time: u64) -> 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<NAValue> { None }
+}
+
impl<'a> RealIVRDemuxer<'a> {
fn new(io: &'a mut ByteReader<'a>) -> Self {
RealIVRDemuxer {
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);
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);
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);