aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2017-10-07 17:59:10 +0200
committerKostya Shishkov <kostya.shishkov@gmail.com>2017-10-07 17:59:10 +0200
commit2324f30bad4876e4235d54b98ceb57fc60939644 (patch)
treefa50d8eeea0ae00641f801a8e30ebf6e437c6bbf
parentbe27380cee1c95d8abf69a92d051ab7af5ff3962 (diff)
downloadnihav-2324f30bad4876e4235d54b98ceb57fc60939644.tar.gz
RealVideo 1 decoder
-rw-r--r--Cargo.toml3
-rw-r--r--src/codecs/h263/decoder.rs18
-rw-r--r--src/codecs/h263/intel263.rs3
-rw-r--r--src/codecs/h263/mod.rs50
-rw-r--r--src/codecs/mod.rs4
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<PicInfo>;
@@ -49,7 +51,7 @@ pub struct PicInfo {
mode: Type,
quant: u8,
apm: bool,
- umv: bool,
+ mvmode: MVMode,
pb: Option<PBInfo>,
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<PBInfo>, 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<PBInfo>, 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() }
@@ -177,6 +179,13 @@ impl BBlockInfo {
}
#[derive(Debug,Clone,Copy)]
+pub enum MVMode {
+ Old,
+ Long,
+ UMV,
+}
+
+#[derive(Debug,Clone,Copy)]
pub struct MV {
x: i16,
y: 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<AllocatorError> 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 },