From 21c16d5fa33306f1754ad33fb0a58f75b472e9a3 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Fri, 9 Jun 2017 14:24:01 +0200 Subject: [PATCH] i263: decode B-frames somehow --- src/codecs/blockdec.rs | 261 ++++++++++++++++++++++++++++++++--------- src/codecs/h263code.rs | 66 +++++++++++ src/codecs/intel263.rs | 94 +++++++-------- 3 files changed, 314 insertions(+), 107 deletions(-) diff --git a/src/codecs/blockdec.rs b/src/codecs/blockdec.rs index 0326f84..23e22d4 100644 --- a/src/codecs/blockdec.rs +++ b/src/codecs/blockdec.rs @@ -1,5 +1,5 @@ use std::mem; -use std::ops::Add; +use std::ops::{Add, Sub}; use super::*; use super::blockdsp; use super::h263code::*; @@ -10,6 +10,21 @@ pub enum Type { I, P, Skip, Special } +#[allow(dead_code)] +#[derive(Debug,Clone,Copy)] +pub struct PBInfo { + trb: u8, + dbquant: u8, +} + +impl PBInfo { + pub fn new(trb: u8, dbquant: u8) -> Self { + PBInfo{ trb: trb, dbquant: dbquant } + } + pub fn get_trb(&self) -> u8 { self.trb } + pub fn get_dbquant(&self) -> u8 { self.dbquant } +} + #[allow(dead_code)] #[derive(Debug,Clone,Copy)] pub struct PicInfo { @@ -19,14 +34,14 @@ pub struct PicInfo { quant: u8, apm: bool, umv: bool, - pb: bool, + pb: Option, ts: u8, } #[allow(dead_code)] impl PicInfo { - pub fn new(w: usize, h: usize, mode: Type, quant: u8, apm: bool, umv: bool, pb: bool, ts: u8) -> Self { - PicInfo{ w: w, h: h, mode: mode, quant: quant, apm: apm, umv: umv, pb: pb, ts: ts } + pub fn new(w: usize, h: usize, mode: Type, quant: u8, apm: bool, umv: bool, ts: u8, pb: Option) -> Self { + PicInfo{ w: w, h: h, mode: mode, quant: quant, apm: apm, umv: umv, ts: ts, pb: pb } } pub fn get_width(&self) -> usize { self.w } pub fn get_height(&self) -> usize { self.h } @@ -34,8 +49,9 @@ impl PicInfo { pub fn get_quant(&self) -> u8 { self.quant } pub fn get_apm(&self) -> bool { self.apm } pub fn get_umv(&self) -> bool { self.umv } - pub fn is_pb(&self) -> bool { self.pb } + pub fn is_pb(&self) -> bool { self.pb.is_some() } pub fn get_ts(&self) -> u8 { self.ts } + pub fn get_pbinfo(&self) -> PBInfo { self.pb.unwrap() } } #[derive(Debug,Clone,Copy)] @@ -109,6 +125,19 @@ impl MV { } new_mv } + fn scale(&self, trb: u8, trd: u8) -> Self { + if (trd == 0) || (trb == 0) { + ZERO_MV + } else { + MV { x: (self.x * (trb as i16)) / (trd as i16), y: (self.y * (trb as i16)) / (trd as i16) } + } + } + fn b_sub(pvec: MV, fwdvec: MV, bvec: MV, trb: u8, trd: u8) -> Self { + let bscale = (trb as i16) - (trd as i16); + let x = if bvec.x != 0 { fwdvec.x - pvec.x } else if trd != 0 { bscale * pvec.x / (trd as i16) } else { 0 }; + let y = if bvec.y != 0 { fwdvec.y - pvec.y } else if trd != 0 { bscale * pvec.y / (trd as i16) } else { 0 }; + MV { x: x, y: y } + } } pub const ZERO_MV: MV = MV { x: 0, y: 0 }; @@ -118,6 +147,11 @@ impl Add for MV { fn add(self, other: MV) -> MV { MV { x: self.x + other.x, y: self.y + other.y } } } +impl Sub for MV { + type Output = MV; + fn sub(self, other: MV) -> MV { MV { x: self.x - other.x, y: self.y - other.y } } +} + #[derive(Debug,Clone,Copy)] pub struct BlockInfo { intra: bool, @@ -129,8 +163,18 @@ pub struct BlockInfo { num_mv: usize, bpart: bool, b_cbp: u8, - mv2: [MV; 4], + mv2: [MV; 2], num_mv2: usize, + fwd: bool, +} + +#[allow(dead_code)] +#[derive(Debug,Clone,Copy)] +pub struct BBlockInfo { + present: bool, + cbp: u8, + num_mv: usize, + fwd: bool, } #[allow(dead_code)] @@ -146,8 +190,9 @@ impl BlockInfo { num_mv: 0, bpart: false, b_cbp: 0, - mv2: [MV::new(0, 0), MV::new(0, 0), MV::new(0, 0), MV::new(0, 0)], + mv2: [ZERO_MV, ZERO_MV], num_mv2: 0, + fwd: false, } } pub fn is_intra(&self) -> bool { self.intra } @@ -163,28 +208,44 @@ impl BlockInfo { pub fn get_mv2(&self, idx: usize) -> MV { self.mv2[idx] } pub fn set_mv(&mut self, mvs: &[MV]) { if mvs.len() > 0 { self.skip = false; } - self.bpart = true; let mut mv_arr: [MV; 4] = [MV::new(0, 0), MV::new(0, 0), MV::new(0, 0), MV::new(0, 0)]; for i in 0..mvs.len() { mv_arr[i] = mvs[i]; } self.mv = mv_arr; self.num_mv = mvs.len(); } - pub fn set_mv2(&mut self, cbp: u8, mvs: &[MV]) { - self.bpart = true; - self.b_cbp = cbp; - let mut mv_arr: [MV; 4] = [MV::new(0, 0), MV::new(0, 0), MV::new(0, 0), MV::new(0, 0)]; + pub fn set_bpart(&mut self, bbinfo: BBlockInfo) { + self.bpart = bbinfo.present; + self.b_cbp = bbinfo.cbp; + self.fwd = bbinfo.fwd; + self.num_mv2 = bbinfo.get_num_mv(); + } + pub fn set_b_mv(&mut self, mvs: &[MV]) { + if mvs.len() > 0 { self.skip = false; } + let mut mv_arr: [MV; 2] = [ZERO_MV, ZERO_MV]; for i in 0..mvs.len() { mv_arr[i] = mvs[i]; } - self.mv2 = mv_arr; - self.num_mv2 = mvs.len(); + self.mv2 = mv_arr; + } + pub fn is_b_fwd(&self) -> bool { self.fwd } +} + +impl BBlockInfo { + pub fn new(present: bool, cbp: u8, num_mv: usize, fwd: bool) -> Self { + BBlockInfo { + present: present, + cbp: cbp, + num_mv: num_mv, + fwd: fwd, + } } + pub fn get_num_mv(&self) -> usize { self.num_mv } } pub trait BlockDecoder { fn decode_pichdr(&mut self) -> DecoderResult; fn decode_slice_header(&mut self, pinfo: &PicInfo) -> DecoderResult; fn decode_block_header(&mut self, pinfo: &PicInfo, sinfo: &Slice) -> DecoderResult; - fn decode_block_intra(&mut self, info: &BlockInfo, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()>; - fn decode_block_inter(&mut self, info: &BlockInfo, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()>; + fn decode_block_intra(&mut self, info: &BlockInfo, quant: u8, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()>; + fn decode_block_inter(&mut self, info: &BlockInfo, quant: u8, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()>; fn calc_mv(&mut self, vec: MV); fn is_slice_end(&mut self) -> bool; } @@ -286,6 +347,29 @@ fn copy_blocks(dst: &mut NAVideoBuffer, src: &NAVideoBuffer, xpos: usize blockdsp::copy_blocks(dst, src, xpos, ypos, srcx, srcy, w, h, 0, 1, mode, H263_INTERP_FUNCS); } +fn avg_blocks(dst: &mut NAVideoBuffer, src: &NAVideoBuffer, xpos: usize, ypos: usize, w: usize, h: usize, mv: MV) { + let srcx = ((mv.x >> 1) as isize) + (xpos as isize); + let srcy = ((mv.y >> 1) as isize) + (ypos as isize); + let mode = ((mv.x & 1) + (mv.y & 1) * 2) as usize; + + blockdsp::copy_blocks(dst, src, xpos, ypos, srcx, srcy, w, h, 0, 1, mode, H263_INTERP_AVG_FUNCS); +} + +#[allow(dead_code)] +#[derive(Clone,Copy)] +struct BMB { + num_mv: usize, + mv_f: [MV; 4], + mv_b: [MV; 4], + fwd: bool, + blk: [[i16; 64]; 6], + cbp: u8, +} + +impl BMB { + fn new() -> Self { BMB {blk: [[0; 64]; 6], cbp: 0, fwd: false, mv_f: [ZERO_MV; 4], mv_b: [ZERO_MV; 4], num_mv: 0} } +} + pub struct DCT8x8VideoDecoder { w: usize, h: usize, @@ -295,6 +379,9 @@ pub struct DCT8x8VideoDecoder { ftype: Type, prev_frm: Option>, cur_frm: Option>, + last_ts: u8, + has_b: bool, + b_data: Vec, } #[allow(dead_code)] @@ -304,6 +391,8 @@ impl DCT8x8VideoDecoder { w: 0, h: 0, mb_w: 0, mb_h: 0, num_mb: 0, ftype: Type::Special, prev_frm: None, cur_frm: None, + last_ts: 0, + has_b: false, b_data: Vec::new(), } } @@ -312,7 +401,7 @@ impl DCT8x8VideoDecoder { pub fn parse_frame(&mut self, bd: &mut BlockDecoder) -> DecoderResult { let pinfo = bd.decode_pichdr()?; - let mut mvi = MVInfo::new(); + let mut mvi = MVInfo::new(); //todo handle res change self.w = pinfo.w; @@ -321,10 +410,18 @@ impl DCT8x8VideoDecoder { self.mb_h = (pinfo.h + 15) >> 4; self.num_mb = self.mb_w * self.mb_h; self.ftype = pinfo.mode; + self.has_b = pinfo.is_pb(); + + if self.has_b { + self.b_data.truncate(0); + } mem::swap(&mut self.cur_frm, &mut self.prev_frm); // if self.ftype == Type::I && !pinfo.is_pb() { self.prev_frm = None; } + let tsdiff = pinfo.ts.wrapping_sub(self.last_ts); + let bsdiff = if pinfo.is_pb() { pinfo.get_pbinfo().get_trb() } else { 0 }; + let fmt = formats::YUV420_FORMAT; let vinfo = NAVideoInfo::new(self.w, self.h, false, fmt); let bufret = alloc_video_buffer(vinfo, 4); @@ -332,17 +429,6 @@ impl DCT8x8VideoDecoder { let mut bufinfo = bufret.unwrap(); let mut buf = bufinfo.get_vbuf().unwrap(); - let mut bbuf; - - if self.prev_frm.is_some() && pinfo.is_pb() { - let bufret = alloc_video_buffer(vinfo, 4); - if let Err(_) = bufret { return Err(DecoderError::InvalidData); } - let mut bbufinfo = bufret.unwrap(); - bbuf = Some(bbufinfo.get_vbuf().unwrap()); - } else { - bbuf = None; - } - let mut slice = Slice::get_default_slice(&pinfo); mvi.reset(self.mb_w, 0, pinfo.get_umv()); @@ -362,7 +448,7 @@ impl DCT8x8VideoDecoder { //println!("mb {}.{} CBP {:X} type {:?}, {} mvs skip {}", mb_x,mb_y, cbp, binfo.get_mode(), binfo.get_num_mvs(),binfo.is_skipped()); if binfo.is_intra() { for i in 0..6 { - bd.decode_block_intra(&binfo, i, (cbp & (1 << (5 - i))) != 0, &mut blk[i])?; + bd.decode_block_intra(&binfo, binfo.get_q(), i, (cbp & (1 << (5 - i))) != 0, &mut blk[i])?; h263_idct(&mut blk[i]); } blockdsp::put_blocks(&mut buf, mb_x, mb_y, &blk); @@ -387,7 +473,7 @@ impl DCT8x8VideoDecoder { //println!(""); } for i in 0..6 { - bd.decode_block_inter(&binfo, i, ((cbp >> (5 - i)) & 1) != 0, &mut blk[i])?; + bd.decode_block_inter(&binfo, 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); @@ -397,44 +483,109 @@ impl DCT8x8VideoDecoder { copy_blocks(&mut buf, srcbuf, mb_x * 16, mb_y * 16, 16, 16, ZERO_MV); } } - if pinfo.is_pb() && binfo.has_b_part() { - let mut blk: [[i16; 64]; 6] = [[0; 64]; 6]; + if pinfo.is_pb() { + let mut b_mb = BMB::new(); let cbp = binfo.get_cbp_b(); + let bq = (((pinfo.get_pbinfo().get_dbquant() + 5) as u16) * (binfo.get_q() as u16)) >> 2; + let bquant; + if bq < 1 { bquant = 1; } + else if bq > 31 { bquant = 31; } + else { bquant = bq as u8; } + + b_mb.cbp = cbp; for i in 0..6 { - bd.decode_block_inter(&binfo, i, (cbp & (1 << (5 - i))) != 0, &mut blk[i])?; - h263_idct(&mut blk[i]); + bd.decode_block_inter(&binfo, bquant, i, (cbp & (1 << (5 - i))) != 0, &mut b_mb.blk[i])?; + h263_idct(&mut b_mb.blk[i]); } - if let Some(ref mut b_buf) = bbuf { -/* let is_fwd = false; - if binfo.get_num_mvs() == 1 { //todo scale - let mv_f = MV::add_umv(binfo.get_mv(0), binfo.get_mv2(0), pinfo.get_umv()); - let mv_b = ZERO_MV//if component = 0 then scaled else mv_f - component - } else { - }*/ - if let Some(ref srcbuf) = self.prev_frm { - copy_blocks(b_buf, srcbuf, mb_x * 16, mb_y * 16, 16, 16, ZERO_MV); - blockdsp::add_blocks(b_buf, mb_x, mb_y, &blk); + + let is_fwd = binfo.is_b_fwd(); + b_mb.fwd = is_fwd; + b_mb.num_mv = binfo.get_num_mvs(); + if binfo.get_num_mvs() == 0 { + b_mb.num_mv = 1; + b_mb.mv_f[0] = binfo.get_mv2(1); + b_mb.mv_b[0] = binfo.get_mv2(0); + } if binfo.get_num_mvs() == 1 { + let src_mv = if is_fwd { ZERO_MV } else { binfo.get_mv(0).scale(bsdiff, tsdiff) }; + let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_umv()); + let mv_b = MV::b_sub(binfo.get_mv(0), mv_f, binfo.get_mv2(0), bsdiff, tsdiff); + b_mb.mv_f[0] = mv_f; + b_mb.mv_b[0] = mv_b; + } else { + for blk_no in 0..4 { + let src_mv = if is_fwd { ZERO_MV } else { binfo.get_mv(blk_no).scale(bsdiff, tsdiff) }; + let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_umv()); + let mv_b = MV::b_sub(binfo.get_mv(blk_no), mv_f, binfo.get_mv2(0), bsdiff, tsdiff); + b_mb.mv_f[blk_no] = mv_f; + b_mb.mv_b[blk_no] = mv_b; } } + self.b_data.push(b_mb); } - } mvi.update_row(); } self.cur_frm = Some(buf); - if pinfo.is_pb() { - return Ok(NABufferType::Video(bbuf.unwrap())); - } -println!("unpacked all"); + self.last_ts = pinfo.ts; +//println!("unpacked all"); Ok(bufinfo) } - pub fn get_stored_pframe(&mut self) -> DecoderResult { - if let Some(_) = self.cur_frm { - let buf = self.cur_frm.clone().unwrap(); - Ok(NABufferType::Video(buf)) - } else { - Err(DecoderError::MissingReference) + pub fn get_bframe(&mut self) -> DecoderResult { + if !self.has_b || !self.cur_frm.is_some() || !self.prev_frm.is_some() { + return Err(DecoderError::MissingReference); + } + self.has_b = false; + + let fmt = formats::YUV420_FORMAT; + let vinfo = NAVideoInfo::new(self.w, self.h, false, fmt); + let bufret = alloc_video_buffer(vinfo, 4); + if let Err(_) = bufret { return Err(DecoderError::InvalidData); } + let mut bufinfo = bufret.unwrap(); + let mut b_buf = bufinfo.get_vbuf().unwrap(); + + if let Some(ref bck_buf) = self.prev_frm { + if let Some(ref fwd_buf) = self.cur_frm { + recon_b_frame(&mut b_buf, bck_buf, fwd_buf, self.mb_w, self.mb_h, &self.b_data); + } + } + + self.b_data.truncate(0); + Ok(bufinfo) + } +} + +fn recon_b_frame(b_buf: &mut NAVideoBuffer, bck_buf: &NAVideoBuffer, fwd_buf: &NAVideoBuffer, + mb_w: usize, mb_h: usize, b_data: &Vec) { + let mut cur_mb = 0; + for mb_y in 0..mb_h { + for mb_x in 0..mb_w { + let num_mv = b_data[cur_mb].num_mv; + let is_fwd = b_data[cur_mb].fwd; + if num_mv == 0 { + copy_blocks(b_buf, bck_buf, mb_x * 16, mb_y * 16, 16, 16, ZERO_MV); + if !is_fwd { + avg_blocks(b_buf, fwd_buf, mb_x * 16, mb_y * 16, 16, 16, ZERO_MV); + } + } else if num_mv == 1 { + copy_blocks(b_buf, bck_buf, mb_x * 16, mb_y * 16, 16, 16, b_data[cur_mb].mv_f[0]); + if !is_fwd { + avg_blocks(b_buf, fwd_buf, mb_x * 16, mb_y * 16, 16, 16, b_data[cur_mb].mv_b[0]); + } + } else { + for blk_no in 0..4 { + let xpos = mb_x * 16 + (blk_no & 1) * 8; + let ypos = mb_y * 16 + (blk_no & 2) * 4; + copy_blocks(b_buf, bck_buf, xpos, ypos, 8, 8, b_data[cur_mb].mv_f[blk_no]); + if !is_fwd { + avg_blocks(b_buf, fwd_buf, xpos, ypos, 8, 8, b_data[cur_mb].mv_b[blk_no]); + } + } + } + if num_mv != 0 && b_data[cur_mb].cbp != 0 { + blockdsp::add_blocks(b_buf, mb_x, mb_y, &b_data[cur_mb].blk); + } + cur_mb += 1; } } } diff --git a/src/codecs/h263code.rs b/src/codecs/h263code.rs index d38af95..594a63c 100644 --- a/src/codecs/h263code.rs +++ b/src/codecs/h263code.rs @@ -267,3 +267,69 @@ fn h263_interp11(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: pub const H263_INTERP_FUNCS: &[fn(&mut [u8], usize, &[u8], usize, usize, usize)] = &[ h263_interp00, h263_interp01, h263_interp10, h263_interp11 ]; + +fn h263_interp00_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + for x in 0..bw { + let a = dst[didx + x] as u16; + let b = src[sidx + x] as u16; + dst[didx + x] = ((a + b + 1) >> 1) as u8; + } + didx += dstride; + sidx += sstride; + } +} + +fn h263_interp01_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + for x in 0..bw { + let a = dst[didx + x] as u16; + let b = ((src[sidx + x] as u16) + (src[sidx + x + 1] as u16) + 1) >> 1; + dst[didx + x] = ((a + b + 1) >> 1) as u8; + } + didx += dstride; + sidx += sstride; + } +} + +fn h263_interp10_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + for x in 0..bw { + let a = dst[didx + x] as u16; + let b = ((src[sidx + x] as u16) + (src[sidx + x + sstride] as u16) + 1) >> 1; + dst[didx + x] = ((a + b + 1) >> 1) as u8; + } + didx += dstride; + sidx += sstride; + } +} + +fn h263_interp11_avg(dst: &mut [u8], dstride: usize, src: &[u8], sstride: usize, bw: usize, bh: usize) +{ + let mut didx = 0; + let mut sidx = 0; + for _ in 0..bh { + for x in 0..bw { + let a = dst[didx + x] as u16; + let b = ((src[sidx + x] as u16) + + (src[sidx + x + 1] as u16) + + (src[sidx + x + sstride] as u16) + + (src[sidx + x + sstride + 1] as u16) + 2) >> 2; + dst[didx + x] = ((a + b + 1) >> 1) as u8; + } + didx += dstride; + sidx += sstride; + } +} + +pub const H263_INTERP_AVG_FUNCS: &[fn(&mut [u8], usize, &[u8], usize, usize, usize)] = &[ + h263_interp00_avg, h263_interp01_avg, h263_interp10_avg, h263_interp11_avg ]; diff --git a/src/codecs/intel263.rs b/src/codecs/intel263.rs index bb20262..61e1cc4 100644 --- a/src/codecs/intel263.rs +++ b/src/codecs/intel263.rs @@ -111,6 +111,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 { + 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)) + } else { + Ok(BBlockInfo::new(true, 0, 1 + pb_mv_add, true)) + } + } else { + Ok(BBlockInfo::new(true, 0, pb_mv_add, false)) + } + } else { + Ok(BBlockInfo::new(false, 0, 0, false)) + } +} + impl<'a> BlockDecoder for Intel263BR<'a> { #[allow(unused_variables)] @@ -162,19 +181,24 @@ impl<'a> BlockDecoder for Intel263BR<'a> { let quant = br.read(5)?; let cpm = br.read_bool()?; validate!(!cpm); + + let pbinfo; if self.is_pb { let trb = br.read(3)?; let dbquant = br.read(2)?; + pbinfo = Some(PBInfo::new(trb as u8, dbquant as u8)); + } else { + pbinfo = None; } while br.read_bool()? { // skip PEI br.read(8)?; } -println!("frame {}x{} intra: {} q {} pb {} apm {} umv {} @{}", w, h, is_intra, quant, self.is_pb, apm, umv, br.tell()); +//println!("frame {}x{} intra: {} q {} pb {} apm {} umv {} @{}", w, h, is_intra, quant, self.is_pb, apm, umv, br.tell()); self.gob_no = 0; self.mb_w = (w + 15) >> 4; let ftype = if is_intra { Type::I } else { Type::P }; - let picinfo = PicInfo::new(w, h, ftype, quant as u8, apm, umv, self.is_pb, tr); + let picinfo = PicInfo::new(w, h, ftype, quant as u8, apm, umv, tr, pbinfo); Ok(picinfo) } @@ -182,12 +206,11 @@ println!("frame {}x{} intra: {} q {} pb {} apm {} umv {} @{}", w, h, is_intra, q fn decode_slice_header(&mut self, info: &PicInfo) -> DecoderResult { let mut br = &mut self.br; let gbsc = br.read(17)?; -println!("GBSC = {}", gbsc); validate!(gbsc == 1); let gn = br.read(5)?; let gfid = br.read(2)?; let gquant = br.read(5)?; -println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); +//println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); let ret = Slice::new(0, self.gob_no, gquant as u8); self.gob_no += 1; Ok(ret) @@ -207,11 +230,9 @@ println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); let idx = br.read(2)? as usize; q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8; } -//println!("got cbp {:X}", cbp); Ok(BlockInfo::new(Type::I, cbp, q)) }, Type::P => { -//println!("@{}",br.tell()); if br.read_bool()? { return Ok(BlockInfo::new(Type::Skip, 0, info.get_quant())); } let mut cbpc = br.read_cb(&self.tables.inter_mcbpc_cb)?; while cbpc == 20 { cbpc = br.read_cb(&self.tables.inter_mcbpc_cb)?; } @@ -220,22 +241,7 @@ println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); let is_4x4 = (cbpc & 0x10) != 0; if is_intra { let mut mvec: Vec = Vec::new(); - let cbpb; - let pb_mv_count: usize; - if self.is_pb && br.read_bool()? { - let c = br.read_bool()?; - if c { - pb_mv_count = 2 - (br.read(1)? as usize); - cbpb = br.read(6)? as u8; - } else { - pb_mv_count = 2; - cbpb = 0; - } -//println!(" mvc {} cbpb {:02X}", pb_mv_count, cbpb); - } else { - cbpb = 0; - pb_mv_count = 1; - } + let bbinfo = decode_b_info(br, self.is_pb, true)?; let cbpy = br.read_cb(&self.tables.cbpy_cb)?; let cbp = (cbpy << 2) | (cbpc & 3); if dquant { @@ -243,31 +249,17 @@ println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8; } let mut binfo = BlockInfo::new(Type::I, cbp, q); + binfo.set_bpart(bbinfo); if self.is_pb { - for _ in 0..pb_mv_count { + for _ in 0..bbinfo.get_num_mv() { mvec.push(decode_mv(br, &self.tables.mv_cb)?); } - binfo.set_mv2(cbpb, mvec.as_slice()); + binfo.set_b_mv(mvec.as_slice()); } -//println!("@{}",br.tell()); return Ok(binfo); } - let cbpb; - let pb_mv_count: usize; - if self.is_pb && br.read_bool()?{ - let c = br.read_bool()?; - if c { - pb_mv_count = 1 - (br.read(1)? as usize); - cbpb = br.read(6)? as u8; - } else { - pb_mv_count = 1; - cbpb = 0; - } - } else { - cbpb = 0; - pb_mv_count = 0; - } + let bbinfo = decode_b_info(br, self.is_pb, false)?; let mut cbpy = br.read_cb(&self.tables.cbpy_cb)?; // if /* !aiv && */(cbpc & 3) != 3 { cbpy ^= 0xF; @@ -278,9 +270,9 @@ println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8; } let mut binfo = BlockInfo::new(Type::P, cbp, q); + binfo.set_bpart(bbinfo); if !is_4x4 { let mvec: [MV; 1] = [decode_mv(br, &self.tables.mv_cb)?]; -//println!("@{} CBPB = {:X} mv2 {}",br.tell(), cbpb, pb_mv_count); binfo.set_mv(&mvec); } else { let mvec: [MV; 4] = [ @@ -292,14 +284,13 @@ println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); binfo.set_mv(&mvec); } if self.is_pb { - let mut mvec: Vec = Vec::with_capacity(pb_mv_count); - for _ in 0..pb_mv_count { + let mut mvec: Vec = Vec::with_capacity(bbinfo.get_num_mv()); + for _ in 0..bbinfo.get_num_mv() { let mv = decode_mv(br, &self.tables.mv_cb)?; mvec.push(mv); } - binfo.set_mv2(cbpb, mvec.as_slice()); + binfo.set_b_mv(mvec.as_slice()); } -//println!("@{}",br.tell()); Ok(binfo) }, _ => { Err(DecoderError::InvalidData) }, @@ -307,13 +298,13 @@ println!("GOB gn {:X} id {} q {}", gn, gfid, gquant); } #[allow(unused_variables)] - fn decode_block_intra(&mut self, info: &BlockInfo, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()> { - self.decode_block(info.get_q(), true, coded, blk) + fn decode_block_intra(&mut self, info: &BlockInfo, quant: u8, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()> { + self.decode_block(quant, true, coded, blk) } #[allow(unused_variables)] - fn decode_block_inter(&mut self, info: &BlockInfo, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()> { - self.decode_block(info.get_q(), false, coded, blk) + fn decode_block_inter(&mut self, info: &BlockInfo, quant: u8, no: usize, coded: bool, blk: &mut [i16; 64]) -> DecoderResult<()> { + self.decode_block(quant, false, coded, blk) } #[allow(unused_variables)] @@ -370,7 +361,7 @@ impl NADecoder for Intel263Decoder { let src = pkt.get_buffer(); if src.len() == 8 { - let bret = self.dec.get_stored_pframe(); + let bret = self.dec.get_bframe(); let buftype; let is_skip; if let Ok(btype) = bret { @@ -382,10 +373,9 @@ impl NADecoder for Intel263Decoder { } let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), buftype); frm.set_keyframe(false); - frm.set_frame_type(if is_skip { FrameType::Skip } else { FrameType::P }); + frm.set_frame_type(if is_skip { FrameType::Skip } else { FrameType::B }); return Ok(Rc::new(RefCell::new(frm))); } -//println!("frame size {}", src.len()); let mut ibr = Intel263BR::new(&src, &self.tables); let bufinfo = self.dec.parse_frame(&mut ibr)?; -- 2.30.2