vp6enc: split out future common parts to share them with VP7 encoder
[nihav.git] / nihav-duck / src / codecs / vp6enc / dsp.rs
index 41b72cf849c0c3081bd878a8d2cf5f73284388e8..b83cd11e09d5c96f4fb357efdbff07a52627d798 100644 (file)
@@ -4,45 +4,8 @@ use super::super::vpcommon::*;
 use super::super::vp6dsp::*;
 use super::super::vp6data::*;
 use super::ResidueMB;
-
-use std::str::FromStr;
-
-#[derive(Debug,Clone,Copy,PartialEq)]
-pub enum MVSearchMode {
-    Full,
-    Diamond,
-    Hexagon,
-}
-
-impl Default for MVSearchMode {
-    fn default() -> Self { MVSearchMode::Hexagon }
-}
-
-pub struct ParseError{}
-
-impl FromStr for MVSearchMode {
-    type Err = ParseError;
-
-    #[allow(clippy::single_match)]
-    fn from_str(s: &str) -> Result<Self, Self::Err> {
-        match s {
-            "full"  => Ok(MVSearchMode::Full),
-            "dia"   => Ok(MVSearchMode::Diamond),
-            "hex"   => Ok(MVSearchMode::Hexagon),
-            _ => Err(ParseError{}),
-        }
-    }
-}
-
-impl std::fmt::Display for MVSearchMode {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        match *self {
-            MVSearchMode::Full      => write!(f, "full"),
-            MVSearchMode::Diamond   => write!(f, "dia"),
-            MVSearchMode::Hexagon   => write!(f, "hex"),
-        }
-    }
-}
+use crate::codecs::vpenc::motion_est::*;
+pub use crate::codecs::vpenc::motion_est::MVSearchMode;
 
 
 const C1S7: i32 = 64277;
@@ -177,137 +140,6 @@ impl MVSearch for FullMVSearch {
     }
 }
 
-const DIA_PATTERN: [MV; 9] = [
-    ZERO_MV,
-    MV {x: -2, y:  0},
-    MV {x: -1, y:  1},
-    MV {x:  0, y:  2},
-    MV {x:  1, y:  1},
-    MV {x:  2, y:  0},
-    MV {x:  1, y: -1},
-    MV {x:  0, y: -2},
-    MV {x: -1, y: -1}
-];
-
-const HEX_PATTERN: [MV; 7] = [
-    ZERO_MV,
-    MV {x: -2, y:  0},
-    MV {x: -1, y:  2},
-    MV {x:  1, y:  2},
-    MV {x:  2, y:  0},
-    MV {x:  1, y: -2},
-    MV {x: -1, y: -2}
-];
-
-const REFINEMENT: [MV; 4] = [
-    MV {x: -1, y:  0},
-    MV {x:  0, y:  1},
-    MV {x:  1, y:  0},
-    MV {x:  0, y: -1}
-];
-
-macro_rules! search_template {
-    ($self: expr, $mv_est: expr, $cur_blk: expr, $mb_x: expr, $mb_y: expr, $sad_func: ident) => ({
-        let mut best_dist = MAX_DIST;
-        let mut best_mv;
-
-        let mut min_dist;
-        let mut min_idx;
-
-        $self.reset();
-        loop {
-            let mut cur_best_dist = best_dist;
-            for (dist, &point) in $self.dist.iter_mut().zip($self.point.iter()) {
-                if *dist == MAX_DIST {
-                    *dist = $mv_est.$sad_func($cur_blk, $mb_x, $mb_y, point.from_pixels(), cur_best_dist);
-                    cur_best_dist = cur_best_dist.min(*dist);
-                    if *dist <= DIST_THRESH {
-                        break;
-                    }
-                }
-            }
-            min_dist = $self.dist[0];
-            min_idx = 0;
-            for (i, &dist) in $self.dist.iter().enumerate().skip(1) {
-                if dist < min_dist {
-                    min_dist = dist;
-                    min_idx = i;
-                    if dist <= DIST_THRESH {
-                        break;
-                    }
-                }
-            }
-            if min_dist <= DIST_THRESH || min_idx == 0 || best_dist == min_dist || $self.point[min_idx].x.abs() >= $mv_est.mv_range || $self.point[min_idx].y.abs() >= $mv_est.mv_range {
-                break;
-            }
-            best_dist = min_dist;
-            $self.update($self.steps[min_idx]);
-        }
-        best_dist = min_dist;
-        best_mv   = $self.point[min_idx];
-        if best_dist <= DIST_THRESH {
-            return (best_mv.from_pixels(), best_dist);
-        }
-        for &step in REFINEMENT.iter() {
-            let mv = best_mv + step;
-            let dist = $mv_est.$sad_func($cur_blk, $mb_x, $mb_y, mv.from_pixels(), MAX_DIST);
-            if best_dist > dist {
-                best_dist = dist;
-                best_mv = mv;
-            }
-        }
-        best_mv = best_mv.from_pixels();
-        if best_dist <= DIST_THRESH {
-            return (best_mv, best_dist);
-        }
-
-        // subpel refinement
-        $self.set_new_point(best_mv, best_dist);
-        loop {
-            let mut cur_best_dist = best_dist;
-            for (dist, &point) in $self.dist.iter_mut().zip($self.point.iter()) {
-                if *dist == MAX_DIST {
-                    *dist = $mv_est.$sad_func($cur_blk, $mb_x, $mb_y, point, cur_best_dist);
-                    cur_best_dist = cur_best_dist.min(*dist);
-                    if *dist <= DIST_THRESH {
-                        break;
-                    }
-                }
-            }
-            min_dist = $self.dist[0];
-            min_idx = 0;
-            for (i, &dist) in $self.dist.iter().enumerate().skip(1) {
-                if dist < min_dist {
-                    min_dist = dist;
-                    min_idx = i;
-                    if dist <= DIST_THRESH {
-                        break;
-                    }
-                }
-            }
-            if min_dist <= DIST_THRESH || min_idx == 0 || best_dist == min_dist || $self.point[min_idx].x.abs() >= $mv_est.mv_range * 4 || $self.point[min_idx].y.abs() >= $mv_est.mv_range * 4 {
-                break;
-            }
-            best_dist = min_dist;
-            $self.update($self.steps[min_idx]);
-        }
-        best_dist = min_dist;
-        best_mv   = $self.point[min_idx];
-        if best_dist <= DIST_THRESH {
-            return (best_mv, best_dist);
-        }
-        for &step in REFINEMENT.iter() {
-            let mv = best_mv + step;
-            let dist = $mv_est.$sad_func($cur_blk, $mb_x, $mb_y, mv, MAX_DIST);
-            if best_dist > dist {
-                best_dist = dist;
-                best_mv = mv;
-            }
-        }
-        (best_mv, best_dist)
-    })
-}
-
 macro_rules! pattern_search {
     ($struct_name: ident, $patterns: expr) => {
         pub struct $struct_name {