Commit 08acfcca authored by Adrien Maglo's avatar Adrien Maglo Committed by Luca Barbato

Full pixel diamond search motion estimation

Uses the predictors of the EPZS algorithm.

Tourapis, Alexis Michael. "Enhanced predictive zonal search for single and
multiple frame motion estimation." Visual Communications and Image
Processing 2002. Vol. 4671. International Society for Optics and Photonics,
2002.
parent 05c9ac62
......@@ -127,6 +127,7 @@ pub struct SpeedSettings {
pub prediction_modes: PredictionModesSetting,
pub include_near_mvs: bool,
pub no_scene_detection: bool,
pub diamond_me: bool
}
impl Default for SpeedSettings {
......@@ -142,6 +143,7 @@ impl Default for SpeedSettings {
prediction_modes: PredictionModesSetting::Simple,
include_near_mvs: false,
no_scene_detection: false,
diamond_me: false,
}
}
}
......@@ -159,6 +161,7 @@ impl SpeedSettings {
prediction_modes: Self::prediction_modes_preset(speed),
include_near_mvs: Self::include_near_mvs_preset(speed),
no_scene_detection: Self::no_scene_detection_preset(speed),
diamond_me: Self::diamond_me_preset(speed),
}
}
......@@ -217,6 +220,10 @@ impl SpeedSettings {
fn no_scene_detection_preset(speed: usize) -> bool {
speed == 10
}
fn diamond_me_preset(speed: usize) -> bool {
speed >= 3
}
}
#[allow(dead_code, non_camel_case_types)]
......
......@@ -156,7 +156,8 @@ pub struct ReferenceFrame {
pub frame: Frame,
pub input_hres: Plane,
pub input_qres: Plane,
pub cdfs: CDFContext
pub cdfs: CDFContext,
pub frame_mvs: Vec<Vec<MotionVector>>,
}
#[derive(Debug, Clone)]
......@@ -394,6 +395,7 @@ pub struct FrameState {
pub deblock: DeblockState,
pub segmentation: SegmentationState,
pub restoration: RestorationState,
pub frame_mvs: Vec<Vec<MotionVector>>,
}
impl FrameState {
......@@ -420,6 +422,7 @@ impl FrameState {
deblock: Default::default(),
segmentation: Default::default(),
restoration: rs,
frame_mvs: vec![vec![MotionVector{row: 0, col: 0}; fi.w_in_b * fi.h_in_b]; REF_FRAMES]
}
}
}
......@@ -559,14 +562,17 @@ impl FrameInvariants {
let use_reduced_tx_set = config.speed_settings.reduced_tx_set;
let use_tx_domain_distortion = config.tune == Tune::Psnr && config.speed_settings.tx_domain_distortion;
let w_in_b = 2 * config.width.align_power_of_two_and_shift(3); // MiCols, ((width+7)/8)<<3 >> MI_SIZE_LOG2
let h_in_b = 2 * config.height.align_power_of_two_and_shift(3); // MiRows, ((height+7)/8)<<3 >> MI_SIZE_LOG2
FrameInvariants {
sequence,
width: config.width,
height: config.height,
sb_width: config.width.align_power_of_two_and_shift(6),
sb_height: config.height.align_power_of_two_and_shift(6),
w_in_b: 2 * config.width.align_power_of_two_and_shift(3), // MiCols, ((width+7)/8)<<3 >> MI_SIZE_LOG2
h_in_b: 2 * config.height.align_power_of_two_and_shift(3), // MiRows, ((height+7)/8)<<3 >> MI_SIZE_LOG2
w_in_b,
h_in_b,
number: 0,
order_hint: 0,
show_frame: true,
......@@ -2140,7 +2146,8 @@ pub fn update_rec_buffer(fi: &mut FrameInvariants, fs: FrameState) {
frame: fs.rec,
input_hres: fs.input_hres,
input_qres: fs.input_qres,
cdfs: fs.cdfs
cdfs: fs.cdfs,
frame_mvs: fs.frame_mvs.clone()
}
);
for i in 0..(REF_FRAMES as usize) {
......
This diff is collapsed.
......@@ -10,6 +10,7 @@
#![allow(non_camel_case_types)]
#![allow(dead_code)]
use std::ops;
use self::BlockSize::*;
use self::TxSize::*;
use crate::api::ChromaSampling;
......@@ -731,12 +732,35 @@ pub enum FilterIntraMode {
FILTER_INTRA_MODES
}
#[derive(Copy, Clone)]
#[derive(Copy, Debug, Clone)]
pub struct MotionVector {
pub row: i16,
pub col: i16
}
impl ops::Add<MotionVector> for MotionVector {
type Output = MotionVector;
fn add(self, _rhs: MotionVector) -> MotionVector {
MotionVector{row: self.row + _rhs.row, col: self.col + _rhs.col}
}
}
impl ops::Div<i16> for MotionVector {
type Output = MotionVector;
fn div(self, _rhs: i16) -> MotionVector {
MotionVector{row: self.row / _rhs, col: self.col / _rhs}
}
}
impl MotionVector {
pub fn quantize_to_fullpel(&self) -> MotionVector {
MotionVector{row: (self.row / 8) * 8, col: (self.col / 8) * 8}
}
}
pub const NEWMV_MODE_CONTEXTS: usize = 7;
pub const GLOBALMV_MODE_CONTEXTS: usize = 2;
pub const REFMV_MODE_CONTEXTS: usize = 6;
......
......@@ -404,9 +404,22 @@ pub fn rdo_mode_decision(fi: &FrameInvariants, fs: &mut FrameState,
let mut pmv = [MotionVector{ row: 0, col: 0 }; 2];
if mv_stack.len() > 0 { pmv[0] = mv_stack[0].this_mv; }
if mv_stack.len() > 1 { pmv[1] = mv_stack[1].this_mv; }
let cmv = pmvs[ref_slot_set[i] as usize].unwrap();
let ref_slot = ref_slot_set[i] as usize;
let cmv = pmvs[ref_slot].unwrap();
let b_me = motion_estimation(fi, fs, bsize, bo, ref_frames[0], cmv, &pmv, ref_slot);
// Fill the saved motion structure.
let frame_mvs = &mut fs.frame_mvs[ref_slot as usize];
for mi_y in (bo.y)..(bo.y + bsize.height_mi()) {
for mi_x in (bo.x)..(bo.x + bsize.width_mi()) {
let offset = mi_y * fi.w_in_b + mi_x;
frame_mvs[offset] = b_me;
}
}
mvs_from_me.push([
motion_estimation(fi, fs, bsize, bo, ref_frames[0], cmv, &pmv),
b_me,
MotionVector { row: 0, col: 0 }
]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment