From b20ff2908dee5e1230235679ba88632d6169aa6f Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Thu, 6 Sep 2018 14:56:08 +0200 Subject: [PATCH] rv10: fix MV prediction and remove some cruft --- src/codecs/h263/decoder.rs | 11 ++++++----- src/codecs/h263/rv10.rs | 29 +++++++++++++---------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/codecs/h263/decoder.rs b/src/codecs/h263/decoder.rs index b200bd5..d5a6b5b 100644 --- a/src/codecs/h263/decoder.rs +++ b/src/codecs/h263/decoder.rs @@ -133,6 +133,7 @@ pub struct H263BaseDecoder { b_data: Vec, pred_coeffs: Vec, is_gob: bool, + slice_reset: bool, may_have_b_frames: bool, mv_data: Vec, } @@ -153,7 +154,7 @@ fn clip_ac(ac: i16) -> i16 { #[allow(dead_code)] impl H263BaseDecoder { - pub fn new_with_opts(is_gob: bool, may_have_b_frames: bool) -> Self { + pub fn new_with_opts(is_gob: bool, slice_reset: bool, may_have_b_frames: bool) -> Self { H263BaseDecoder{ w: 0, h: 0, mb_w: 0, mb_h: 0, num_mb: 0, ftype: Type::Special, @@ -161,16 +162,16 @@ impl H263BaseDecoder { last_ts: 0, next_ts: 0, tsdiff: 0, has_b: false, b_data: Vec::new(), pred_coeffs: Vec::new(), - is_gob: is_gob, + is_gob: is_gob, slice_reset: slice_reset, may_have_b_frames: may_have_b_frames, mv_data: Vec::new(), } } pub fn new(is_gob: bool) -> Self { - Self::new_with_opts(is_gob, false) + Self::new_with_opts(is_gob, true, false) } pub fn new_b_frames(is_gob: bool) -> Self { - Self::new_with_opts(is_gob, true) + Self::new_with_opts(is_gob, true, true) } pub fn is_intra(&self) -> bool { self.ftype == Type::I } @@ -248,7 +249,7 @@ impl H263BaseDecoder { if slice.is_at_end(mb_pos) || (slice.needs_check() && mb_pos > 0 && bd.is_slice_end()) { slice = bd.decode_slice_header(&pinfo)?; - if !self.is_gob { + if !self.is_gob && self.slice_reset { mvi.reset(self.mb_w, mb_x, pinfo.get_mvmode()); if is_b || pinfo.is_pb() { mvi2.reset(self.mb_w, mb_x, pinfo.get_mvmode()); diff --git a/src/codecs/h263/rv10.rs b/src/codecs/h263/rv10.rs index 202d757..ac5b24c 100644 --- a/src/codecs/h263/rv10.rs +++ b/src/codecs/h263/rv10.rs @@ -27,6 +27,7 @@ struct RealVideo10Decoder { h: usize, new_ver: bool, bdsp: H263BlockDSP, + mvmode: MVMode, } struct RealVideo10BR<'a> { @@ -42,6 +43,7 @@ struct RealVideo10BR<'a> { new_ver: bool, dc_coded: [bool; 3], last_dc: [i16; 3], + mvmode: MVMode, } struct RV10SliceInfo { @@ -59,7 +61,7 @@ impl RV10SliceInfo { } impl<'a> RealVideo10BR<'a> { - fn new(src: &'a [u8], tables: &'a Tables, width: usize, height: usize, new_ver: bool) -> Self { + fn new(src: &'a [u8], tables: &'a Tables, width: usize, height: usize, new_ver: bool, mvmode: MVMode) -> Self { let nslices = (src[0] as usize) + 1; let mut slice_offs = Vec::with_capacity(nslices); { @@ -85,6 +87,7 @@ impl<'a> RealVideo10BR<'a> { new_ver: new_ver, dc_coded: [false; 3], last_dc: [0; 3], + mvmode: mvmode, } } @@ -94,7 +97,6 @@ impl<'a> RealVideo10BR<'a> { let mut idx = 0; if intra { let mut dc; -//println!("dc prev {} @ {} of {},{} / {}x{}", self.last_dc[plane_no], br.tell() - (self.slice_off[self.slice_no - 1] as usize) * 8, sstate.mb_x, sstate.mb_y, self.mb_w, self.mb_h); if !self.new_ver || !sstate.is_iframe { dc = br.read(8)? as i16; if dc == 255 { dc = 128; } @@ -115,7 +117,6 @@ impl<'a> RealVideo10BR<'a> { if val != 0 { diff = val - 128; } else { -println!("escape!!!"); let code = br.read(2)?; match code { 0x0 => { diff = ((br.read(7)? + 1) as i8) as i16; }, @@ -137,12 +138,10 @@ println!("escape!!!"); br.skip(4)?; diff = 1; } else { -println!("!!! wrong chroma esc"); return Err(DecoderError::InvalidData); } }, }; -println!("!!! diff = {} @ {}", diff, br.tell()); } dc = (self.last_dc[plane_no] - diff) & 0xFF; self.last_dc[plane_no] = dc; @@ -151,7 +150,6 @@ println!("!!! diff = {} @ {}", diff, br.tell()); dc = self.last_dc[plane_no]; } } -//println!("dc new {} @ {}", self.last_dc[plane_no], br.tell()); blk[0] = dc << 3; idx = 1; } @@ -208,7 +206,6 @@ 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)) } @@ -217,20 +214,18 @@ impl<'a> BlockDecoder for RealVideo10BR<'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()?; validate!((shdr.mb_x == 0) && (shdr.mb_y == 0)); let mb_end = shdr.mb_x + shdr.mb_y * self.mb_w + shdr.mb_c; let ftype = if !shdr.is_p { Type::I } else { Type::P }; - let picinfo = PicInfo::new(self.w, self.h, ftype, MVMode::Old, false, false, shdr.qscale, 0, None, None); + let picinfo = PicInfo::new(self.w, self.h, ftype, self.mvmode, false, false, shdr.qscale, 0, None, None); Ok(picinfo) } #[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_end = shdr.mb_x + shdr.mb_y * self.mb_w + shdr.mb_c; @@ -239,7 +234,7 @@ println!("decoding picture header size {}", if self.num_slices > 1 { self.slice_ 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(); match info.get_mode() { @@ -284,7 +279,6 @@ println!("decoding picture header size {}", if self.num_slices > 1 { self.slice_ let idx = br.read(2)? as usize; q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8; } -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)?]; @@ -358,7 +352,6 @@ impl<'a> RealVideo10BR<'a> { mb_count = self.mb_w * self.mb_h; } br.skip(3)?; -println!("slice q {} mb {},{} {}", qscale, mb_x, mb_y, mb_count); validate!(mb_x + mb_y * self.mb_w + mb_count <= self.mb_w * self.mb_h); Ok(RV10SliceInfo::new(is_p, qscale, mb_x, mb_y, mb_count)) @@ -397,12 +390,13 @@ impl RealVideo10Decoder { RealVideo10Decoder{ info: Rc::new(DUMMY_CODEC_INFO), - dec: H263BaseDecoder::new(false), + dec: H263BaseDecoder::new_with_opts(false, false, false), tables: tables, w: 0, h: 0, new_ver: false, bdsp: H263BlockDSP::new(), + mvmode: MVMode::Long, } } } @@ -426,6 +420,9 @@ impl NADecoder for RealVideo10Decoder { println!("ver {:06X} -> {}", ver, mic_ver); validate!(maj_ver == 1); self.new_ver = mic_ver > 1; + if (src[3] & 1) != 0 { + self.mvmode = MVMode::UMV; + } { let mut br = BitReader::new(src, src.len(), BitReaderMode::BE); println!("edata:"); @@ -441,8 +438,8 @@ println!("???"); 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 = RealVideo10BR::new(&src, &self.tables, self.w, self.h, self.new_ver); +//println!(" decode frame size {}, {} slices", src.len(), src[0]+1); + let mut ibr = RealVideo10BR::new(&src, &self.tables, self.w, self.h, self.new_ver, self.mvmode); let bufinfo = self.dec.parse_frame(&mut ibr, &self.bdsp)?; -- 2.39.5