From 2324f30bad4876e4235d54b98ceb57fc60939644 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Sat, 7 Oct 2017 17:59:10 +0200 Subject: [PATCH] RealVideo 1 decoder --- Cargo.toml | 3 ++- src/codecs/h263/decoder.rs | 18 ++++++------- src/codecs/h263/intel263.rs | 3 ++- src/codecs/h263/mod.rs | 50 +++++++++++++++++++++++++------------ src/codecs/mod.rs | 4 ++- 5 files changed, 50 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a1393d3..cbcc035 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,13 +21,14 @@ dsp_window = ["dsp"] all_decoders = ["all_video_decoders", "all_audio_decoders"] -all_video_decoders = ["decoder_gdvvid", "decoder_indeo2", "decoder_indeo3", "decoder_indeo4", "decoder_indeo5", "decoder_intel263"] +all_video_decoders = ["decoder_gdvvid", "decoder_indeo2", "decoder_indeo3", "decoder_indeo4", "decoder_indeo5", "decoder_intel263", "decoder_realvideo1"] decoder_gdvvid = ["decoders"] decoder_indeo2 = ["decoders"] decoder_indeo3 = ["decoders"] decoder_indeo4 = ["decoders"] decoder_indeo5 = ["decoders"] decoder_intel263 = ["h263", "decoders"] +decoder_realvideo1 = ["h263", "decoders"] all_audio_decoders = ["decoder_pcm", "decoder_imc"] decoder_pcm = ["decoders"] diff --git a/src/codecs/h263/decoder.rs b/src/codecs/h263/decoder.rs index 11eb2be..94e679b 100644 --- a/src/codecs/h263/decoder.rs +++ b/src/codecs/h263/decoder.rs @@ -13,18 +13,18 @@ struct MVInfo { mb_stride: usize, mb_start: usize, top: bool, - umv: bool, + mvmode: MVMode, } impl MVInfo { - fn new() -> Self { MVInfo{ mv: Vec::new(), mb_w: 0, mb_stride: 0, mb_start: 0, top: true, umv: false } } - fn reset(&mut self, mb_w: usize, mb_start: usize, umv: bool) { + fn new() -> Self { MVInfo{ mv: Vec::new(), mb_w: 0, mb_stride: 0, mb_start: 0, top: true, mvmode: MVMode::Old } } + fn reset(&mut self, mb_w: usize, mb_start: usize, mvmode: MVMode) { self.mb_start = mb_start; self.mb_w = mb_w; self.mb_stride = mb_w * 2; self.top = true; self.mv.resize(self.mb_stride * 3, ZERO_MV); - self.umv = umv; + self.mvmode = mvmode; } fn update_row(&mut self) { self.mb_start = self.mb_w + 1; @@ -67,7 +67,7 @@ impl MVInfo { _ => { return ZERO_MV; } } let pred_mv = MV::pred(A, B, C); - let new_mv = MV::add_umv(pred_mv, diff, self.umv); + let new_mv = MV::add_umv(pred_mv, diff, self.mvmode); if !use4 { self.mv[self.mb_stride * 1 + mb_x * 2 + 0] = new_mv; self.mv[self.mb_stride * 1 + mb_x * 2 + 1] = new_mv; @@ -184,7 +184,7 @@ impl H263BaseDecoder { let mut buf = bufinfo.get_vbuf().unwrap(); let mut slice = Slice::get_default_slice(&pinfo); - mvi.reset(self.mb_w, 0, pinfo.get_umv()); + mvi.reset(self.mb_w, 0, pinfo.get_mvmode()); cbpi.reset(self.mb_w); let mut blk: [[i16; 64]; 6] = [[0; 64]; 6]; @@ -194,7 +194,7 @@ impl H263BaseDecoder { if ((mb_x != 0) || (mb_y != 0)) && bd.is_slice_end() { slice = bd.decode_slice_header(&pinfo)?; - mvi.reset(self.mb_w, mb_x, pinfo.get_umv()); + //mvi.reset(self.mb_w, mb_x, pinfo.get_mvmode()); //cbpi.reset(self.mb_w); } @@ -260,14 +260,14 @@ impl H263BaseDecoder { b_mb.mv_b[0] = binfo.get_mv2(0); } else if binfo.get_num_mvs() == 1 { let src_mv = binfo.get_mv(0).scale(bsdiff, tsdiff); - let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_umv()); + let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_mvmode()); 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 = 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_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_mvmode()); 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; diff --git a/src/codecs/h263/intel263.rs b/src/codecs/h263/intel263.rs index 76a1287..7bc2844 100644 --- a/src/codecs/h263/intel263.rs +++ b/src/codecs/h263/intel263.rs @@ -202,7 +202,8 @@ impl<'a> BlockDecoder for Intel263BR<'a> { 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, tr, pbinfo, deblock); + let mvmode = if umv { MVMode::UMV } else { MVMode::Long }; + let picinfo = PicInfo::new(w, h, ftype, quant as u8, apm, mvmode, tr, pbinfo, deblock); Ok(picinfo) } diff --git a/src/codecs/h263/mod.rs b/src/codecs/h263/mod.rs index 90170e3..8feda44 100644 --- a/src/codecs/h263/mod.rs +++ b/src/codecs/h263/mod.rs @@ -9,6 +9,8 @@ pub mod decoder; #[cfg(feature="decoder_intel263")] pub mod intel263; +#[cfg(feature="decoder_realvideo1")] +pub mod rv10; pub trait BlockDecoder { fn decode_pichdr(&mut self) -> DecoderResult; @@ -49,7 +51,7 @@ pub struct PicInfo { mode: Type, quant: u8, apm: bool, - umv: bool, + mvmode: MVMode, pb: Option, ts: u8, deblock: bool, @@ -57,15 +59,15 @@ pub struct PicInfo { #[allow(dead_code)] impl PicInfo { - pub fn new(w: usize, h: usize, mode: Type, quant: u8, apm: bool, umv: bool, ts: u8, pb: Option, deblock: bool) -> Self { - PicInfo{ w: w, h: h, mode: mode, quant: quant, apm: apm, umv: umv, ts: ts, pb: pb, deblock: deblock } + pub fn new(w: usize, h: usize, mode: Type, quant: u8, apm: bool, mvmode: MVMode, ts: u8, pb: Option, deblock: bool) -> Self { + PicInfo{ w: w, h: h, mode: mode, quant: quant, apm: apm, mvmode: mvmode, ts: ts, pb: pb, deblock: deblock } } pub fn get_width(&self) -> usize { self.w } pub fn get_height(&self) -> usize { self.h } pub fn get_mode(&self) -> Type { self.mode } 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 get_mvmode(&self) -> MVMode { self.mvmode } 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() } @@ -176,6 +178,13 @@ impl BBlockInfo { pub fn get_num_mv(&self) -> usize { self.num_mv } } +#[derive(Debug,Clone,Copy)] +pub enum MVMode { + Old, + Long, + UMV, +} + #[derive(Debug,Clone,Copy)] pub struct MV { x: i16, @@ -215,19 +224,28 @@ impl MV { } MV { x: x, y: y } } - fn add_umv(pred_mv: MV, add: MV, umv: bool) -> Self { + fn add_umv(pred_mv: MV, add: MV, mvmode: MVMode) -> Self { let mut new_mv = pred_mv + add; - if umv { - if pred_mv.x > 32 && new_mv.x > 63 { new_mv.x -= 64; } - if pred_mv.x < -31 && new_mv.x < -63 { new_mv.x += 64; } - if pred_mv.y > 32 && new_mv.y > 63 { new_mv.y -= 64; } - if pred_mv.y < -31 && new_mv.y < -63 { new_mv.y += 64; } - } else { - if new_mv.x > 31 { new_mv.x -= 64; } - else if new_mv.x < -32 { new_mv.x += 64; } - if new_mv.y > 31 { new_mv.y -= 64; } - else if new_mv.y < -32 { new_mv.y += 64; } - } + match mvmode { + MVMode::Old => { + if new_mv.x >= 64 { new_mv.x -= 64; } + else if new_mv.x <= -64 { new_mv.x += 64; } + if new_mv.y >= 64 { new_mv.y -= 64; } + else if new_mv.y <= -64 { new_mv.y += 64; } + }, + MVMode::Long => { + if new_mv.x > 31 { new_mv.x -= 64; } + else if new_mv.x < -32 { new_mv.x += 64; } + if new_mv.y > 31 { new_mv.y -= 64; } + else if new_mv.y < -32 { new_mv.y += 64; } + }, + MVMode::UMV => { + if pred_mv.x > 32 && new_mv.x > 63 { new_mv.x -= 64; } + if pred_mv.x < -31 && new_mv.x < -63 { new_mv.x += 64; } + if pred_mv.y > 32 && new_mv.y > 63 { new_mv.y -= 64; } + if pred_mv.y < -31 && new_mv.y < -63 { new_mv.y += 64; } + }, + }; new_mv } fn scale(&self, trb: u8, trd: u8) -> Self { diff --git a/src/codecs/mod.rs b/src/codecs/mod.rs index c6cbcd3..a808419 100644 --- a/src/codecs/mod.rs +++ b/src/codecs/mod.rs @@ -42,7 +42,7 @@ impl From for DecoderError { } macro_rules! validate { - ($a:expr) => { if !$a { return Err(DecoderError::InvalidData); } }; + ($a:expr) => { if !$a { println!("check failed at {}:{}", file!(), line!()); return Err(DecoderError::InvalidData); } }; } #[allow(dead_code)] @@ -139,6 +139,8 @@ const DECODERS: &[DecoderInfo] = &[ DecoderInfo { name: "indeo5", get_decoder: indeo::indeo5::get_decoder }, #[cfg(feature="decoder_intel263")] DecoderInfo { name: "intel263", get_decoder: h263::intel263::get_decoder }, +#[cfg(feature="decoder_realvideo1")] + DecoderInfo { name: "realvideo1", get_decoder: h263::rv10::get_decoder }, #[cfg(feature="decoder_pcm")] DecoderInfo { name: "pcm", get_decoder: pcm::get_decoder }, -- 2.30.2