]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/h263/rv20.rs
GremlinVideo audio decoder
[nihav.git] / src / codecs / h263 / rv20.rs
index c734bc923a6a773641daf9931b1e8bc181637bf4..11dbe2edb199f73390617e4dd82d67b35cb60a61 100644 (file)
@@ -1,6 +1,6 @@
-use io::bitreader::*;
-use io::codebook::*;
-use formats;
+use crate::io::bitreader::*;
+use crate::io::codebook::*;
+use crate::formats;
 use super::super::*;
 use super::*;
 use super::code::H263BlockDSP;
@@ -129,7 +129,7 @@ impl<'a> RealVideo20BR<'a> {
 
         let rl_cb = if sstate.is_iframe { &self.tables.aic_rl_cb } else { &self.tables.rl_cb };
         let q_add = if quant == 0 || sstate.is_iframe { 0i16 } else { ((quant - 1) | 1) as i16 };
-        let q = (quant * 2) as i16;
+        let q = if plane_no == 0 { (quant * 2) as i16 } else { H263_CHROMA_QUANT[quant as usize] as i16 };
         while idx < 64 {
             let code = br.read_cb(rl_cb)?;
             let run;
@@ -178,18 +178,23 @@ fn decode_mv_component(br: &mut BitReader, mv_cb: &Codebook<u8>) -> DecoderResul
 fn decode_mv(br: &mut BitReader, mv_cb: &Codebook<u8>) -> DecoderResult<MV> {
     let xval = decode_mv_component(br, mv_cb)?;
     let yval = decode_mv_component(br, mv_cb)?;
-//println!("  MV {},{} @ {}", xval, yval, br.tell());
     Ok(MV::new(xval, yval))
 }
 
+fn read_dquant(br: &mut BitReader, q: u8) -> DecoderResult<u8> {
+    if br.read_bool()? {
+        Ok(H263_MODIFIED_QUANT[br.read(1)? as usize][q as usize])
+    } else {
+        Ok(br.read(5)? as u8)
+    }
+}
+
 impl<'a> BlockDecoder for RealVideo20BR<'a> {
 
 #[allow(unused_variables)]
     fn decode_pichdr(&mut self) -> DecoderResult<PicInfo> {
         self.slice_no = 0;
-println!("decoding picture header size {}", if self.num_slices > 1 { self.slice_off[1] } else { ((self.br.tell() as u32) + (self.br.left() as u32))/8 });
         let shdr = self.read_slice_header()?;
-println!("slice ends @ {}\n", self.br.tell());
 //        self.slice_no += 1;
         validate!((shdr.mb_x == 0) && (shdr.mb_y == 0));
 /*        let mb_count;
@@ -209,7 +214,6 @@ println!("slice ends @ {}\n", self.br.tell());
 
     #[allow(unused_variables)]
     fn decode_slice_header(&mut self, info: &PicInfo) -> DecoderResult<SliceInfo> {
-//println!("read slice {} header", self.slice_no);
         let shdr = self.read_slice_header()?;
         self.slice_no += 1;
         let mb_count;
@@ -226,9 +230,9 @@ println!("slice ends @ {}\n", self.br.tell());
         Ok(ret)
     }
 
-    fn decode_block_header(&mut self, info: &PicInfo, slice: &SliceInfo, sstate: &SliceState) -> DecoderResult<BlockInfo> {
+    fn decode_block_header(&mut self, info: &PicInfo, _slice: &SliceInfo, sstate: &SliceState) -> DecoderResult<BlockInfo> {
         let br = &mut self.br;
-        let mut q = slice.get_quant();
+        let mut q = sstate.quant;
         match info.get_mode() {
             Type::I => {
                     let mut cbpc = br.read_cb(&self.tables.intra_mcbpc_cb)?;
@@ -238,21 +242,17 @@ println!("slice ends @ {}\n", self.br.tell());
                         if pi.aic {
                             let acpp = br.read_bool()?;
                             acpred = ACPredMode::DC;
-//println!("   acp {} @ {}", acpp as u8, br.tell());
                             if acpp {
                                 acpred = if br.read_bool()? { ACPredMode::Hor } else { ACPredMode::Ver };
                             }
                         }
-println!("   @ {}", br.tell());
                     }
                     let cbpy = br.read_cb(&self.tables.cbpy_cb)?;
                     let cbp = (cbpy << 2) | (cbpc & 3);
                     let dquant = (cbpc & 4) != 0;
                     if dquant {
-                        let idx = br.read(2)? as usize;
-                        q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+                        q = read_dquant(br, q)?;
                     }
-println!(" MB {},{} CBP {:X} @ {}", sstate.mb_x, sstate.mb_y, cbp, br.tell());
                     let mut binfo = BlockInfo::new(Type::I, cbp, q);
                     binfo.set_acpred(acpred);
                     Ok(binfo)
@@ -270,8 +270,7 @@ println!(" MB {},{} CBP {:X} @ {}", sstate.mb_x, sstate.mb_y, cbp, br.tell());
                         let cbpy = br.read_cb(&self.tables.cbpy_cb)?;
                         let cbp = (cbpy << 2) | (cbpc & 3);
                         if dquant {
-                            let idx = br.read(2)? as usize;
-                            q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+                            q = read_dquant(br, q)?;
                         }
                         let binfo = BlockInfo::new(Type::I, cbp, q);
                         return Ok(binfo);
@@ -283,10 +282,8 @@ println!(" MB {},{} CBP {:X} @ {}", sstate.mb_x, sstate.mb_y, cbp, br.tell());
 //                    }
                     let cbp = (cbpy << 2) | (cbpc & 3);
                     if dquant {
-                        let idx = br.read(2)? as usize;
-                        q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+                        q = read_dquant(br, q)?;
                     }
-println!(" MB {}.{} cbp = {:X}", sstate.mb_x, sstate.mb_y, cbp);
                     let mut binfo = BlockInfo::new(Type::P, cbp, q);
                     if !is_4x4 {
                         let mvec: [MV; 1] = [decode_mv(br, &self.tables.mv_cb)?];
@@ -318,12 +315,10 @@ println!(" MB {}.{} cbp = {:X}", sstate.mb_x, sstate.mb_y, cbp);
                             if !is_intra { cbpy ^= 0xF; }
                             (cbpy << 2) | (cbpc & 3)
                         } else { 0 };
-                    
+
                     if dquant {
-                        let idx = br.read(2)? as usize;
-                        q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+                        q = read_dquant(br, q)?;
                     }
-//println!(" MB B {}.{} cbp = {:X} @ {} ({} {})", sstate.mb_x, sstate.mb_y, cbp, br.tell(), mbtype, is_intra);
 
                     if is_intra {
                         let binfo = BlockInfo::new(Type::I, cbp, q);
@@ -364,7 +359,6 @@ impl<'a> RealVideo20BR<'a> {
 
         let br = &mut self.br;
         br.seek(self.slice_off[self.slice_no] * 8)?;
-//println!(" slice at off {}", br.tell());
 
         let frm_type    = br.read(2)?;
         let ftype = match frm_type {
@@ -411,7 +405,6 @@ impl<'a> RealVideo20BR<'a> {
         if (self.minor_ver <= 1) && (frm_type == 3) {
             br.skip(5)?;
         }
-println!("slice q {} mb {},{}", qscale, mb_x, mb_y);
 
         Ok(RV20SliceInfo::new(ftype, seq, qscale, mb_x, mb_y, mb_pos, w, h))
     }
@@ -435,7 +428,7 @@ impl RealVideo20Decoder {
         let aic_rl_cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
         let mut coderead = H263ShortCodeReader::new(H263_MV);
         let mv_cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
-        
+
         let tables = Tables {
             intra_mcbpc_cb: intra_mcbpc_cb,
             inter_mcbpc_cb: inter_mcbpc_cb,
@@ -478,7 +471,6 @@ impl NADecoder for RealVideo20Decoder {
             let maj_ver = ver >> 16;
             let min_ver = (ver >> 8) & 0xFF;
             let mic_ver = ver & 0xFF;
-println!("ver {:06X}", ver);
             validate!(maj_ver == 2);
             self.minor_ver = min_ver as u8;
             let rprb = src[1] & 7;
@@ -500,7 +492,6 @@ println!("ver {:06X}", ver);
     fn decode(&mut self, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
         let src = pkt.get_buffer();
 
-println!(" decode frame size {}, {} slices", src.len(), src[0]+1);
         let mut ibr = RealVideo20BR::new(&src, &self.tables, self.w, self.h, self.minor_ver, self.rpr);
 
         let bufinfo = self.dec.parse_frame(&mut ibr, &self.bdsp)?;
@@ -529,10 +520,10 @@ pub fn get_decoder() -> Box<NADecoder> {
 
 #[cfg(test)]
 mod test {
-    use test::dec_video::test_file_decoding;
+    use crate::test::dec_video::test_file_decoding;
     #[test]
     fn test_rv20() {
-        test_file_decoding("realmedia", "assets/RV/rv20_svt_atrc_640x352_realproducer_plus_8.51.rm", /*None*/Some(7000), true, false, Some("rv20"));
+        test_file_decoding("realmedia", "assets/RV/rv20_svt_atrc_640x352_realproducer_plus_8.51.rm", /*None*/Some(3000), true, false, None/*Some("rv20")*/);
 //        test_file_decoding("realmedia", "assets/RV/rv20_cook_640x352_realproducer_plus_8.51.rm", /*None*/Some(1000), true, false, Some("rv20"));
     }
 }