RealVideo 1 decoder
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 7 Oct 2017 15:59:10 +0000 (17:59 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 7 Oct 2017 15:59:10 +0000 (17:59 +0200)
Cargo.toml
src/codecs/h263/decoder.rs
src/codecs/h263/intel263.rs
src/codecs/h263/mod.rs
src/codecs/mod.rs

index a1393d3f48ef7e757a62eee179fe0bb8a9d75d67..cbcc0352d063c94a21ae55bdd7ee51d67968907f 100644 (file)
@@ -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"]
index 11eb2be2fc3ede0ef874485b22b52c57adc1eea7..94e679b11bfb82116dadd7a91ee8b6d09b537836 100644 (file)
@@ -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;
index 76a1287a96b602562806df53b87097a1daa6b5b7..7bc2844c044a79578ad53b00167c7db25bbf8653 100644 (file)
@@ -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)
     }
 
index 90170e3cf6a440011fa35c752df0b4bdcb66cb38..8feda44e8a51fa23f720a1624638df14bea7a88f 100644 (file)
@@ -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() }
@@ -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 {
index c6cbcd3ace89072ff2401eb5e45580d67141d54e..a808419a592aa16dc4dc8dcb4f6d0edb4bb4b406 100644 (file)
@@ -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 },