]> git.nihav.org Git - nihav.git/blobdiff - nihav-realmedia/src/demuxers/realmedia.rs
arxel-vid: support 2-pixel tiles
[nihav.git] / nihav-realmedia / src / demuxers / realmedia.rs
index f889284a79d8d2f2abca6faddb901c2aa45370c8..322fdc00d63836ff43dd0f98788522655ac772ac 100644 (file)
@@ -13,6 +13,20 @@ macro_rules! mktag {
     });
 }
 
+trait ReadSize {
+    fn read_size(&mut self, ver: u16) -> ByteIOResult<u64>;
+}
+
+impl<'a> ReadSize for ByteReader<'a> {
+    fn read_size(&mut self, ver: u16) -> ByteIOResult<u64> {
+        match ver {
+            0 => Ok(u64::from(self.read_u32be()?)),
+            2 => self.read_u64be(),
+            _ => unreachable!(),
+        }
+    }
+}
+
 const RM_SIPRO_BLOCK_SIZES: [usize; 4] = [ 29, 19, 37, 20 ];
 const RM_SIPRO_SWAPS:   [[u8; 2]; 38] = [
     [  0, 63 ], [  1, 22 ], [  2, 44 ], [  3, 90 ],
@@ -138,8 +152,7 @@ impl RMAudioStream {
         RMAudioStream { deint, iinfo, buf, sub_packet: 0 }
     }
     fn read_apackets(&mut self, queued_packets: &mut Vec<NAPacket>, src: &mut ByteReader, stream: NAStreamRef, ts: u32, keyframe: bool, payload_size: usize) -> DemuxerResult<NAPacket> {
-        let (tb_num, tb_den) = stream.get_timebase();
-        let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
+        let ts = stream.make_ts(Some(ts as u64), None, None);
 
         if keyframe {
             self.sub_packet = 0;
@@ -200,7 +213,7 @@ impl RMAudioStream {
                         sizes.push(sz);
                     }
                     validate!(tot_size + num_entries * 2 + 2 == payload_size);
-                    let pkt_ts = NATimeInfo::new(None, None, None, tb_num, tb_den);
+                    let pkt_ts = stream.make_ts(None, None, None);
                     let mut first = true;
                     for size in sizes.iter() {
                         let cur_ts = if first { ts } else { pkt_ts };
@@ -232,7 +245,7 @@ impl RMAudioStream {
         let mut frames_iter = self.buf.chunks(fsize);
         let pkt0 = frames_iter.next().unwrap();
 
-        let pkt_ts = NATimeInfo::new(None, None, None, tb_num, tb_den);
+        let pkt_ts = stream.make_ts(None, None, None);
         for pkts in frames_iter {
             let pkt = NAPacket::new(stream.clone(), pkt_ts, true, pkts.to_vec());
             queued_packets.push(pkt);
@@ -391,8 +404,7 @@ fn read_video_buf(src: &mut ByteReader, stream: NAStreamRef, ts: u32, keyframe:
     vec[4] = 1;
     src.read_buf(&mut vec[9..])?;
 
-    let (tb_num, tb_den) = stream.get_timebase();
-    let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
+    let ts = stream.make_ts(Some(ts as u64), None, None);
     Ok(NAPacket::new(stream, ts, keyframe, vec))
 }
 
@@ -589,8 +601,7 @@ println!(" got ainfo {:?}", ainfo);
                                     return Err(DemuxerError::TryAgain);
                                 }
                                 //todo: check if full frame is received
-                                let (tb_num, tb_den) = stream.get_timebase();
-                                let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
+                                let ts = stream.make_ts(Some(ts as u64), None, None);
                                 let pkt = NAPacket::new(stream, ts, keyframe, vstr.get_frame_data());
                                 Ok(pkt)
                             },
@@ -622,8 +633,7 @@ println!(" got ainfo {:?}", ainfo);
                                     queued_pkts.push(res.unwrap());
                                 }
                                 queued_pkts.reverse();
-                                let (tb_num, tb_den) = stream.get_timebase();
-                                let ts = NATimeInfo::new(Some(ts as u64), None, None, tb_num, tb_den);
+                                let ts = stream.make_ts(Some(ts as u64), None, None);
                                 let pkt = NAPacket::new(stream, ts, keyframe, vstr.get_frame_data());
                                 Ok(pkt)
                         },
@@ -1023,10 +1033,7 @@ impl<'a> RealMediaDemuxer<'a> {
         let num_pkt     = self.src.read_u32be()? as usize;
         let duration    = self.src.read_u32be()?;
         let preroll     = self.src.read_u32be()?;
-        if ver == 2 {
-                          self.src.read_skip(4)?;
-        }
-        let idx_off     = self.src.read_u32be()?;
+        let idx_off     = self.src.read_size(ver)?;
         let data_off    = self.src.read_u32be()?;
         let num_streams = self.src.read_u16be()? as usize;
         let flags       = self.src.read_u16be()?;
@@ -1149,10 +1156,7 @@ impl<'a> RealMediaDemuxer<'a> {
         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()?;
-        }
+        let _next_idx       = self.src.read_size(ver)?;
         if ver == 0 {
             validate!(chunk_size == num_entries * 14 + 10);
         } else {
@@ -1166,10 +1170,7 @@ impl<'a> RealMediaDemuxer<'a> {
             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 pos         = self.src.read_size(ver)?;
             let _pkt_no     = self.src.read_u32be()?;
             idx.add_entry(SeekEntry { time: ts, pts: 0, pos });
         }
@@ -1185,8 +1186,7 @@ fn read_string_size(src: &mut ByteReader, size: usize) -> DemuxerResult<String>
         let c = src.read_byte()?;
         vec.push(c);
     }
-    let str = String::from_utf8(vec);
-    if let Ok(res) = str {
+    if let Ok(res) = String::from_utf8(vec) {
         Ok(res)
     } else {
         Ok(String::new())
@@ -1306,7 +1306,7 @@ impl<'a> RealAudioDemuxer<'a> {
 enum IVRRecord {
     Invalid(u8),
     StreamProperties(usize),
-    Packet { ts: u32, str: u32, flags: u32, len: usize, checksum: u32 },
+    Packet { ts: u32, strm: u32, flags: u32, len: usize, checksum: u32 },
     IntValue(Vec<u8>, u32),
     BinaryData(Vec<u8>, Vec<u8>),
     StringData(Vec<u8>, Vec<u8>),
@@ -1332,12 +1332,12 @@ impl IVRRecord {
                 },
             2 => {
                     let ts      = src.read_u32be()?;
-                    let str     = src.read_u16be()? as u32;
+                    let strm    = src.read_u16be()? as u32;
                     let flags   = src.read_u32be()?;
                     let len     = src.read_u32be()? as usize;
                     let chk     = src.read_u32be()?;
                     validate!((len > 0) && (len < (1 << 24)));
-                    Ok(IVRRecord::Packet { ts, str, flags, len, checksum: chk })
+                    Ok(IVRRecord::Packet { ts, strm, flags, len, checksum: chk })
                 },
             3 => {
                     let name = Self::read_string(src)?;
@@ -1381,8 +1381,8 @@ impl fmt::Display for IVRRecord {
             IVRRecord::Invalid(typ) => write!(f, "Invalid({:02X})", typ),
             IVRRecord::StreamProperties(num) =>
                 write!(f, "({} stream properties)", num),
-            IVRRecord::Packet { ts, str, flags, len, checksum } =>
-                write!(f, "paket({}, {}, {:X}, {}, {})", ts, str, flags, len, checksum),
+            IVRRecord::Packet { ts, strm, flags, len, checksum } =>
+                write!(f, "paket({}, {}, {:X}, {}, {})", ts, strm, flags, len, checksum),
             IVRRecord::IntValue(ref name, val) =>
                 write!(f, "({} = {})", String::from_utf8_lossy(name), val),
             IVRRecord::BinaryData(ref name, ref val) =>
@@ -1502,9 +1502,9 @@ impl RecordDemuxer {
         loop {
             let rec = IVRRecord::read(src)?;
             match rec {
-                IVRRecord::Packet { ts, str, flags, len, .. } => {
+                IVRRecord::Packet { ts, strm, flags, len, .. } => {
                         let payload_size = len;
-                        let sr = self.remap_ids.iter().position(|x| *x == str);
+                        let sr = self.remap_ids.iter().position(|x| *x == strm);
                         validate!(sr.is_some());
                         let str_no = self.start_str + (sr.unwrap() as u32);
                         let pkt_grp = ((flags >> 8) & 0xFF) as u16;