X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=src%2Fcodecs%2Fh263%2Fintel263.rs;h=0c5652aadd47df70600c0ba713f5b98c5ab33b3b;hb=1a151e53b591a45fb7f009e480d7abb5e03f0cfe;hp=f519b9c76d75e00cf3c51e4843f07408c68b8d23;hpb=2a2aa42194e01760a5209599c0257a4f55c9bb38;p=nihav.git diff --git a/src/codecs/h263/intel263.rs b/src/codecs/h263/intel263.rs index f519b9c..0c5652a 100644 --- a/src/codecs/h263/intel263.rs +++ b/src/codecs/h263/intel263.rs @@ -30,6 +30,7 @@ struct Intel263BR<'a> { gob_no: usize, mb_w: usize, is_pb: bool, + is_ipb: bool, } fn check_marker<'a>(br: &mut BitReader<'a>) -> DecoderResult<()> { @@ -46,11 +47,12 @@ impl<'a> Intel263BR<'a> { gob_no: 0, mb_w: 0, is_pb: false, + is_ipb: false, } } fn decode_block(&mut self, quant: u8, intra: bool, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()> { - let mut br = &mut self.br; + let br = &mut self.br; let mut idx = 0; if intra { let mut dc = br.read(8)?; @@ -114,19 +116,25 @@ fn decode_mv(br: &mut BitReader, mv_cb: &Codebook) -> DecoderResult { Ok(MV::new(xval, yval)) } -fn decode_b_info(br: &mut BitReader, is_pb: bool, is_intra: bool) -> DecoderResult { +fn decode_b_info(br: &mut BitReader, is_pb: bool, is_ipb: bool, is_intra: bool) -> DecoderResult { if is_pb { // as improved pb - let pb_mv_add = if is_intra { 1 } else { 0 }; - if br.read_bool()?{ - if br.read_bool()? { - let pb_mv_count = 1 - (br.read(1)? as usize); - let cbpb = br.read(6)? as u8; - Ok(BBlockInfo::new(true, cbpb, pb_mv_count + pb_mv_add, pb_mv_count == 1)) + if is_ipb { + let pb_mv_add = if is_intra { 1 } else { 0 }; + if br.read_bool()?{ + if br.read_bool()? { + let pb_mv_count = 1 - (br.read(1)? as usize); + let cbpb = br.read(6)? as u8; + Ok(BBlockInfo::new(true, cbpb, pb_mv_count + pb_mv_add, pb_mv_count == 1)) + } else { + Ok(BBlockInfo::new(true, 0, 1 + pb_mv_add, true)) + } } else { - Ok(BBlockInfo::new(true, 0, 1 + pb_mv_add, true)) + Ok(BBlockInfo::new(true, 0, pb_mv_add, false)) } } else { - Ok(BBlockInfo::new(true, 0, pb_mv_add, false)) + let mvdb = br.read_bool()?; + let cbpb = if mvdb && br.read_bool()? { br.read(6)? as u8 } else { 0 }; + Ok(BBlockInfo::new(true, cbpb, if mvdb { 1 } else { 0 }, false)) } } else { Ok(BBlockInfo::new(false, 0, 0, false)) @@ -137,10 +145,10 @@ impl<'a> BlockDecoder for Intel263BR<'a> { #[allow(unused_variables)] fn decode_pichdr(&mut self) -> DecoderResult { - let mut br = &mut self.br; + let br = &mut self.br; let syncw = br.read(22)?; validate!(syncw == 0x000020); - let tr = br.read(8)? as u8; + let tr = (br.read(8)? << 8) as u16; check_marker(br)?; let id = br.read(1)?; validate!(id == 0); @@ -155,19 +163,22 @@ impl<'a> BlockDecoder for Intel263BR<'a> { let apm = br.read_bool()?; self.is_pb = br.read_bool()?; let deblock; + let pbplus; if sfmt == 0b111 { sfmt = br.read(3)?; validate!((sfmt != 0b000) && (sfmt != 0b111)); br.read(2)?; // unknown flags deblock = br.read_bool()?; br.read(1)?; // unknown flag - let pbplus = br.read_bool()?; + pbplus = br.read_bool()?; br.read(5)?; // unknown flags let marker = br.read(5)?; validate!(marker == 1); } else { deblock = false; + pbplus = false; } + self.is_ipb = pbplus; let w; let h; if sfmt == 0b110 { let par = br.read(4)?; @@ -192,7 +203,7 @@ impl<'a> BlockDecoder for Intel263BR<'a> { if self.is_pb { let trb = br.read(3)?; let dbquant = br.read(2)?; - pbinfo = Some(PBInfo::new(trb as u8, dbquant as u8)); + pbinfo = Some(PBInfo::new(trb as u8, dbquant as u8, pbplus)); } else { pbinfo = None; } @@ -205,13 +216,14 @@ impl<'a> BlockDecoder for Intel263BR<'a> { let ftype = if is_intra { Type::I } else { Type::P }; let plusinfo = if deblock { Some(PlusInfo::new(false, deblock, false, false)) } else { None }; - let picinfo = PicInfo::new(w, h, ftype, umv, apm, quant as u8, tr, pbinfo, plusinfo); + let mvmode = if umv { MVMode::UMV } else { MVMode::Old }; + let picinfo = PicInfo::new(w, h, ftype, mvmode, umv, apm, quant as u8, tr, pbinfo, plusinfo); Ok(picinfo) } #[allow(unused_variables)] fn decode_slice_header(&mut self, info: &PicInfo) -> DecoderResult { - let mut br = &mut self.br; + let br = &mut self.br; let gbsc = br.read(17)?; validate!(gbsc == 1); let gn = br.read(5)?; @@ -225,7 +237,7 @@ impl<'a> BlockDecoder for Intel263BR<'a> { #[allow(unused_variables)] fn decode_block_header(&mut self, info: &PicInfo, slice: &SliceInfo, sstate: &SliceState) -> DecoderResult { - let mut br = &mut self.br; + let br = &mut self.br; let mut q = slice.get_quant(); match info.get_mode() { Type::I => { @@ -249,7 +261,7 @@ impl<'a> BlockDecoder for Intel263BR<'a> { let is_4x4 = (cbpc & 0x10) != 0; if is_intra { let mut mvec: Vec = Vec::new(); - let bbinfo = decode_b_info(br, self.is_pb, true)?; + let bbinfo = decode_b_info(br, self.is_pb, self.is_ipb, true)?; let cbpy = br.read_cb(&self.tables.cbpy_cb)?; let cbp = (cbpy << 2) | (cbpc & 3); if dquant { @@ -267,7 +279,7 @@ impl<'a> BlockDecoder for Intel263BR<'a> { return Ok(binfo); } - let bbinfo = decode_b_info(br, self.is_pb, false)?; + let bbinfo = decode_b_info(br, self.is_pb, self.is_ipb, false)?; let mut cbpy = br.read_cb(&self.tables.cbpy_cb)?; // if /* !aiv && */(cbpc & 3) != 3 { cbpy ^= 0xF; @@ -316,8 +328,6 @@ impl<'a> BlockDecoder for Intel263BR<'a> { } fn is_slice_end(&mut self) -> bool { self.br.peek(16) == 0 } - - fn is_gob(&mut self) -> bool { true } } impl Intel263Decoder { @@ -345,7 +355,7 @@ impl Intel263Decoder { Intel263Decoder{ info: Rc::new(DUMMY_CODEC_INFO), - dec: H263BaseDecoder::new(), + dec: H263BaseDecoder::new(true), tables: tables, bdsp: H263BlockDSP::new(), } @@ -405,6 +415,6 @@ mod test { use test::dec_video::test_file_decoding; #[test] fn test_intel263() { - test_file_decoding("avi", "assets/neal73_saber.avi", Some(16), true, false, Some("i263")); + test_file_decoding("avi", "assets/neal73_saber.avi", Some(16), true, false, None/*Some("i263")*/); } }