]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/gremlinvideo.rs
fix let mut foo = &mut bar warning
[nihav.git] / src / codecs / gremlinvideo.rs
index e6478aa165055d4ceacb1d6921a26c22c0c7f88e..24d7a5305c9aa26b3a108eb6576178836a1bfb5d 100644 (file)
@@ -10,8 +10,8 @@ struct GremlinVideoDecoder {
     scale_h:    bool,
 }
 
-struct Bits16 {
-    queue: u16,
+struct Bits8 {
+    queue: u8,
     fill:  u8,
 }
 
@@ -22,15 +22,15 @@ struct Bits32 {
 
 const PREAMBLE_SIZE: usize = 4096;
 
-impl Bits16 {
-    fn new() -> Self { Bits16 { queue: 0, fill: 0 } }
-    fn read_2bits(&mut self, br: &mut ByteReader) -> ByteIOResult<u16> {
+impl Bits8 {
+    fn new() -> Self { Bits8 { queue: 0, fill: 0 } }
+    fn read_2bits(&mut self, br: &mut ByteReader) -> ByteIOResult<u8> {
         if self.fill == 0 {
-            self.queue |= (br.read_byte()? as u16) << self.fill;
+            self.queue  = br.read_byte()?;
             self.fill  += 8;
         }
-        let res = self.queue & 0x3;
-        self.queue >>= 2;
+        let res = self.queue >> 6;
+        self.queue <<= 2;
         self.fill   -= 2;
         Ok(res)
     }
@@ -138,7 +138,7 @@ impl GremlinVideoDecoder {
         let paloff = buf.get_offset(1);
         let stride = buf.get_stride(0);
         let mut data = buf.get_data_mut();
-        let mut dst = data.as_mut_slice();
+        let dst = data.as_mut_slice();
         let mut sidx = PREAMBLE_SIZE;
         let mut didx = 0;
 
@@ -165,13 +165,15 @@ impl GremlinVideoDecoder {
     }
 
     fn decode_method2(&mut self, br: &mut ByteReader) -> DecoderResult<()> {
-        let mut bits = Bits16::new();
+        let mut bits = Bits8::new();
 
         let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
                         self.info.get_properties().get_video_info().unwrap().get_height();
         let mut idx = PREAMBLE_SIZE;
-        for c in 0..256 {
-            for i in 0..16 { self.frame[c * 16 + i] = c as u8; }
+        if self.frame[8] != 0 {
+            for c in 0..256 {
+                for i in 0..16 { self.frame[c * 16 + i] = c as u8; }
+            }
         }
         while size > 0 {
             let tag = bits.read_2bits(br)?;
@@ -182,11 +184,11 @@ impl GremlinVideoDecoder {
             } else if tag == 1 {
                 let b = br.read_byte()?;
                 let len = ((b & 0xF) as usize) + 3;
-                let top = (b >> 4) as isize;
-                let off = (top << 8) + (br.read_byte()? as isize) - 4096;
+                let bot = (b >> 4) as isize;
+                let off = ((br.read_byte()? as isize) << 4) + bot - 4096;
                 validate!(len <= size);
                 size -= len;
-                self.lz_copy(idx, off, len)?; 
+                self.lz_copy(idx, off, len)?;
                 idx += len;
             } else if tag == 2 {
                 let len = (br.read_byte()? as usize) + 2;
@@ -201,7 +203,7 @@ impl GremlinVideoDecoder {
     }
 
     fn decode_method5(&mut self, br: &mut ByteReader, skip: usize) -> DecoderResult<()> {
-        let mut bits = Bits16::new();
+        let mut bits = Bits8::new();
 
         let mut size = self.info.get_properties().get_video_info().unwrap().get_width() *
                         self.info.get_properties().get_video_info().unwrap().get_height();
@@ -218,16 +220,16 @@ impl GremlinVideoDecoder {
             } else if tag == 1 {
                 let b = br.read_byte()?;
                 let len = ((b & 0xF) as usize) + 3;
-                let top = (b >> 4) as isize;
-                let off = (top << 8) + (br.read_byte()? as isize) - 4096;
+                let bot = (b >> 4) as isize;
+                let off = ((br.read_byte()? as isize) << 4) + bot - 4096;
                 validate!(len <= size);
                 size -= len;
-                self.lz_copy(idx, off, len)?; 
+                self.lz_copy(idx, off, len)?;
                 idx += len;
             } else if tag == 2 {
                 let b = br.read_byte()?;
                 if b == 0 { break; }
-                let len: usize = if b != 0xFF { b as usize } else { br.read_u16le()? as usize };
+                let len: usize = (if b != 0xFF { b as usize } else { br.read_u16le()? as usize }) + 1;
                 validate!(len <= size);
                 size -= len;
                 idx += len;
@@ -463,53 +465,9 @@ pub fn get_decoder() -> Box<NADecoder> {
 
 #[cfg(test)]
 mod test {
-    use codecs::*;
-    use demuxers::*;
-    use io::byteio::*;
-    use std::fs::File;
-
+    use test::dec_video::test_file_decoding;
     #[test]
     fn test_gdv() {
-        let gdv_dmx = find_demuxer("gdv").unwrap();
-        let mut file = File::open("assets/intro1.gdv").unwrap();
-        let mut fr = FileReader::new_read(&mut file);
-        let mut br = ByteReader::new(&mut fr);
-        let mut dmx = gdv_dmx.new_demuxer(&mut br);
-        dmx.open().unwrap();
-
-        let mut decs: Vec<Option<Box<NADecoder>>> = Vec::new();
-        for i in 0..dmx.get_num_streams() {
-            let s = dmx.get_stream(i).unwrap();
-            let info = s.get_info();
-            let decfunc = find_decoder(info.get_name());
-            if !info.is_video() {
-                decs.push(None);
-            } else if let Some(df) = decfunc {
-                let mut dec = (df)();
-                dec.init(info).unwrap();
-                decs.push(Some(dec));
-            } else {
-panic!("decoder {} not found", info.get_name());
-            }
-        }
-
-        loop {
-            let pktres = dmx.get_frame();
-            if let Err(e) = pktres {
-                if e == DemuxerError::EOF { break; }
-            }
-            let pkt = pktres.unwrap();
-            let streamno = pkt.get_stream().get_id() as usize;
-            if let Some(ref mut dec) = decs[streamno] {
-                let frm = dec.decode(&pkt).unwrap();
-                if pkt.get_stream().get_info().is_video() {
-                    if frm.borrow().get_frame_type() != FrameType::Skip {
-                        write_palppm("gdv", streamno, pkt.get_pts().unwrap(), frm);
-                    }
-                }
-            }
-            if pkt.get_pts().unwrap() > 8 { break; }
-        }
-//panic!("end");
+         test_file_decoding("gdv", "assets/intro1.gdv", Some(10), true, false, None);
     }
 }