X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=src%2Fcodecs%2Fh263%2Frv20.rs;h=3b9fa1bf631ab170224149fb9aedff30999168dd;hb=47add47cb6a02a68e6e94755ba24ff348ca2065b;hp=3298fab3aaafe38912b73cac63e395b758704fd9;hpb=9037cf6b83ce135243522ec154cd7ffb35f8c816;p=nihav.git diff --git a/src/codecs/h263/rv20.rs b/src/codecs/h263/rv20.rs index 3298fab..3b9fa1b 100644 --- a/src/codecs/h263/rv20.rs +++ b/src/codecs/h263/rv20.rs @@ -128,8 +128,8 @@ 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 { 0i16 } else { ((quant - 1) | 1) as i16 }; - let q = (quant * 2) as i16; + let q_add = if quant == 0 || sstate.is_iframe { 0i16 } else { ((quant - 1) | 1) 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) -> DecoderResul fn decode_mv(br: &mut BitReader, mv_cb: &Codebook) -> DecoderResult { 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 { + 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 { 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 { -//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 { + fn decode_block_header(&mut self, info: &PicInfo, _slice: &SliceInfo, sstate: &SliceState) -> DecoderResult { 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 { 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)?; @@ -532,7 +523,7 @@ mod test { use 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")); } }