From: Kostya Shishkov Date: Tue, 28 Nov 2017 18:18:46 +0000 (+0100) Subject: h263: improve slice state a bit plus report proper frame type X-Git-Url: https://git.nihav.org/?p=nihav.git;a=commitdiff_plain;h=2eb214772b1949ec50f3d35a81352ea61012698a h263: improve slice state a bit plus report proper frame type --- diff --git a/src/codecs/h263/decoder.rs b/src/codecs/h263/decoder.rs index 420f6f8..13e289b 100644 --- a/src/codecs/h263/decoder.rs +++ b/src/codecs/h263/decoder.rs @@ -161,6 +161,16 @@ impl H263BaseDecoder { } pub fn is_intra(&self) -> bool { self.ftype == Type::I } + pub fn get_frame_type(&self) -> FrameType { + match self.ftype { + Type::I => FrameType::I, + Type::P => FrameType::P, + Type::B => FrameType::B, + Type::PB => FrameType::P, + Type::Skip => FrameType::Skip, + Type::Special => FrameType::Skip, + } + } pub fn get_dimensions(&self) -> (usize, usize) { (self.w, self.h) } pub fn parse_frame(&mut self, bd: &mut BlockDecoder, bdsp: &BlockDSP) -> DecoderResult { @@ -219,6 +229,7 @@ impl H263BaseDecoder { mvi.reset(self.mb_w, mb_x, pinfo.get_mvmode()); cbpi.reset(self.mb_w); sstate.first_line = true; + sstate.first_mb = true; } } @@ -230,7 +241,7 @@ impl H263BaseDecoder { for i in 0..6 { bd.decode_block_intra(&binfo, &sstate, binfo.get_q(), i, (cbp & (1 << (5 - i))) != 0, &mut blk[i])?; if apply_acpred && (binfo.acpred != ACPredMode::None) { - let has_b = (i == 1) || (i == 3) || (mb_x > 0); + let has_b = (i == 1) || (i == 3) || !sstate.first_mb; let has_a = (i == 2) || (i == 3) || !sstate.first_line; let (b_mb, b_blk) = if has_b { if (i == 1) || (i == 3) { @@ -299,7 +310,7 @@ impl H263BaseDecoder { } blockdsp::put_blocks(&mut buf, mb_x, mb_y, &blk); mvi.set_zero_mv(mb_x); - } else if !binfo.is_skipped() { + } else if (binfo.mode != Type::B) && !binfo.is_skipped() { if binfo.get_num_mvs() == 1 { let mv = mvi.predict(mb_x, 0, false, binfo.get_mv(0)); if let Some(ref srcbuf) = self.prev_frm { @@ -320,11 +331,20 @@ impl H263BaseDecoder { h263_idct(&mut blk[i]); } blockdsp::add_blocks(&mut buf, mb_x, mb_y, &blk); - } else { + } else if binfo.mode != Type::B { mvi.set_zero_mv(mb_x); if let Some(ref srcbuf) = self.prev_frm { bdsp.copy_blocks(&mut buf, srcbuf, mb_x * 16, mb_y * 16, 16, 16, ZERO_MV); } + } else { +//todo + if cbp != 0 { + for i in 0..6 { + bd.decode_block_inter(&binfo, &sstate, binfo.get_q(), i, ((cbp >> (5 - i)) & 1) != 0, &mut blk[i])?; + h263_idct(&mut blk[i]); + } + } + blockdsp::add_blocks(&mut buf, mb_x, mb_y, &blk); } if pinfo.is_pb() { let mut b_mb = BMB::new(); diff --git a/src/codecs/h263/mod.rs b/src/codecs/h263/mod.rs index 7e5064e..cf2350d 100644 --- a/src/codecs/h263/mod.rs +++ b/src/codecs/h263/mod.rs @@ -121,6 +121,7 @@ pub struct SliceState { pub mb_x: usize, pub mb_y: usize, pub first_line: bool, + pub first_mb: bool, } const SLICE_NO_END: usize = 99999999; @@ -142,10 +143,13 @@ impl SliceInfo { impl SliceState { pub fn new(is_iframe: bool) -> Self { - SliceState { is_iframe: is_iframe, mb_x: 0, mb_y: 0, first_line: true } + SliceState { is_iframe: is_iframe, mb_x: 0, mb_y: 0, first_line: true, first_mb: true } + } + pub fn next_mb(&mut self) { self.mb_x += 1; self.first_mb = false; } + pub fn new_row(&mut self) { + self.mb_x = 0; self.mb_y += 1; + self.first_line = false; self.first_mb = true; } - pub fn next_mb(&mut self) { self.mb_x += 1; } - pub fn new_row(&mut self) { self.mb_x = 0; self.mb_y += 1; self.first_line = false; } } #[derive(Debug,Clone,Copy)]