]> git.nihav.org Git - nihav.git/blobdiff - src/codecs/h263/mod.rs
h263+rv20: use modified dquant and chroma quant
[nihav.git] / src / codecs / h263 / mod.rs
index 4f066a6e551c6f452a835ebd1c44c91a37428be5..aa274e7275f1c6eab80a859727e456f33d81b553 100644 (file)
@@ -1,6 +1,4 @@
-use std::fmt;
-use std::ops::{Add, Sub};
-use super::DecoderResult;
+use super::{DecoderResult, MV, ZERO_MV};
 use frame::NAVideoBuffer;
 
 pub mod code;
@@ -50,14 +48,16 @@ impl Type {
 pub struct PBInfo {
     trb:        u8,
     dbquant:    u8,
+    improved:   bool,
 }
 
 impl PBInfo {
-    pub fn new(trb: u8, dbquant: u8) -> Self {
-        PBInfo{ trb: trb, dbquant: dbquant }
+    pub fn new(trb: u8, dbquant: u8, improved: bool) -> Self {
+        PBInfo{ trb: trb, dbquant: dbquant, improved: improved }
     }
     pub fn get_trb(&self) -> u8 { self.trb }
     pub fn get_dbquant(&self) -> u8 { self.dbquant }
+    pub fn is_improved(&self) -> bool { self.improved }
 }
 
 #[allow(dead_code)]
@@ -90,6 +90,13 @@ impl PicInfo {
     pub fn get_quant(&self) -> u8 { self.quant }
     pub fn get_apm(&self) -> bool { self.apm }
     pub fn is_pb(&self) -> bool { self.pb.is_some() }
+    pub fn is_ipb(&self) -> bool {
+            if let Some(ref pbi) = self.pb {
+                pbi.is_improved()
+            } else {
+                false
+            }
+        }
     pub fn get_ts(&self) -> u16 { self.ts }
     pub fn get_pbinfo(&self) -> PBInfo { self.pb.unwrap() }
     pub fn get_plusifo(&self) -> Option<PlusInfo> { self.plusinfo }
@@ -130,6 +137,7 @@ pub struct SliceState {
     pub first_mb:   bool,
     pub slice_mb_x: usize,
     pub slice_mb_y: usize,
+    pub quant:      u8,
 }
 
 const SLICE_NO_END: usize = 99999999;
@@ -153,7 +161,7 @@ impl SliceState {
     pub fn new(is_iframe: bool) -> Self {
         SliceState {
             is_iframe: is_iframe, mb_x: 0, mb_y: 0, first_line: true, first_mb: true,
-            slice_mb_x: 0, slice_mb_y: 0
+            slice_mb_x: 0, slice_mb_y: 0, quant: 0
         }
     }
     pub fn next_mb(&mut self) {
@@ -267,7 +275,8 @@ impl BlockInfo {
         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.mv2     = mv_arr;
+        self.num_mv2 = mvs.len();
     }
     pub fn is_b_fwd(&self) -> bool { self.fwd }
     pub fn set_acpred(&mut self, acpred: ACPredMode) { self.acpred = acpred }
@@ -293,46 +302,14 @@ pub enum MVMode {
     UMV,
 }
 
-#[derive(Debug,Clone,Copy)]
-pub struct MV {
-    x: i16,
-    y: i16,
+pub trait H263MVTrait {
+    fn add_umv(pred_mv: MV, add: MV, mvmode: MVMode) -> MV;
+    fn scale(&self, trb: u16, trd: u16) -> MV;
+    fn b_sub(pvec: MV, fwdvec: MV, bvec: MV, trb: u16, trd: u16) -> MV;
 }
 
-impl MV {
-    pub fn new(x: i16, y: i16) -> Self { MV{ x: x, y: y } }
-    pub fn pred(a: MV, b: MV, c: MV) -> Self {
-        let x;
-        if a.x < b.x {
-            if b.x < c.x {
-                x = b.x;
-            } else {
-                if a.x < c.x { x = c.x; } else { x = a.x; }
-            }
-        } else {
-            if b.x < c.x {
-                if a.x < c.x { x = a.x; } else { x = c.x; }
-            } else {
-                x = b.x;
-            }
-        }
-        let y;
-        if a.y < b.y {
-            if b.y < c.y {
-                y = b.y;
-            } else {
-                if a.y < c.y { y = c.y; } else { y = a.y; }
-            }
-        } else {
-            if b.y < c.y {
-                if a.y < c.y { y = a.y; } else { y = c.y; }
-            } else {
-                y = b.y;
-            }
-        }
-        MV { x: x, y: y }
-    }
-    fn add_umv(pred_mv: MV, add: MV, mvmode: MVMode) -> Self {
+impl H263MVTrait for MV {
+    fn add_umv(pred_mv: MV, add: MV, mvmode: MVMode) -> MV {
         let mut new_mv = pred_mv + add;
         match mvmode {
             MVMode::Old => {
@@ -356,14 +333,14 @@ impl MV {
         };
         new_mv
     }
-    fn scale(&self, trb: u16, trd: u16) -> Self {
+    fn scale(&self, trb: u16, trd: u16) -> MV {
         if (trd == 0) || (trb == 0) {
             ZERO_MV
         } else {
             MV { x: (((self.x as i32) * (trb as i32)) / (trd as i32)) as i16, y: (((self.y as i32) * (trb as i32)) / (trd as i32)) as i16 }
         }
     }
-    fn b_sub(pvec: MV, fwdvec: MV, bvec: MV, trb: u16, trd: u16) -> Self {
+    fn b_sub(pvec: MV, fwdvec: MV, bvec: MV, trb: u16, trd: u16) -> MV {
         let bscale = (trb as i32) - (trd as i32);
         let x = if bvec.x != 0 { fwdvec.x - pvec.x } else if trd != 0 { (bscale * (pvec.x as i32) / (trd as i32)) as i16 } else { 0 };
         let y = if bvec.y != 0 { fwdvec.y - pvec.y } else if trd != 0 { (bscale * (pvec.y as i32) / (trd as i32)) as i16 } else { 0 };
@@ -371,24 +348,6 @@ impl MV {
     }
 }
 
-pub const ZERO_MV: MV = MV { x: 0, y: 0 };
-
-impl Add for MV {
-    type Output = 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 } }
-}
-
-impl fmt::Display for MV {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "{},{}", self.x, self.y)
-    }
-}
-
 #[allow(dead_code)]
 pub struct CBPInfo {
     cbp:        Vec<u8>,