Skip to content

Commit

Permalink
Remove unused full search implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
KyleSiefring committed Jul 23, 2020
1 parent 9d7ecbf commit 15528ee
Show file tree
Hide file tree
Showing 6 changed files with 3 additions and 244 deletions.
1 change: 0 additions & 1 deletion src/api/config/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ impl fmt::Display for EncoderConfig {
"no_scene_detection",
self.speed_settings.no_scene_detection.to_string(),
),
("diamond_me", self.speed_settings.diamond_me.to_string()),
("cdef", self.speed_settings.cdef.to_string()),
("use_satd_subpel", self.speed_settings.use_satd_subpel.to_string()),
(
Expand Down
12 changes: 0 additions & 12 deletions src/api/config/speedsettings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ pub struct SpeedSettings {
pub no_scene_detection: bool,
/// Fast scene detection mode, uses simple SAD instead of encoder cost estimates.
pub fast_scene_detection: bool,
/// Enables diamond motion vector search rather than full search.
pub diamond_me: bool,
/// Enables CDEF.
pub cdef: bool,
/// Enables LRF.
Expand Down Expand Up @@ -111,7 +109,6 @@ impl Default for SpeedSettings {
include_near_mvs: true,
no_scene_detection: false,
fast_scene_detection: false,
diamond_me: true,
cdef: true,
lrf: false,
sgr_complexity: SGRComplexityLevel::Full,
Expand Down Expand Up @@ -157,7 +154,6 @@ impl SpeedSettings {
include_near_mvs: Self::include_near_mvs_preset(speed),
no_scene_detection: Self::no_scene_detection_preset(speed),
fast_scene_detection: Self::fast_scene_detection_preset(speed),
diamond_me: Self::diamond_me_preset(speed),
cdef: Self::cdef_preset(speed),
lrf: Self::lrf_preset(speed),
sgr_complexity: Self::sgr_complexity_preset(speed),
Expand Down Expand Up @@ -239,14 +235,6 @@ impl SpeedSettings {
speed == 10
}

/// Currently Diamond ME gives better quality than full search on most videos,
/// in addition to being faster.
// There are a few outliers, such as the Wikipedia test clip.
// TODO: Revisit this setting if full search quality improves in the future.
const fn diamond_me_preset(_speed: usize) -> bool {
true
}

const fn cdef_preset(_speed: usize) -> bool {
true
}
Expand Down
2 changes: 0 additions & 2 deletions src/api/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1842,7 +1842,6 @@ fn log_q_exp_overflow() {
include_near_mvs: false,
no_scene_detection: true,
fast_scene_detection: false,
diamond_me: true,
cdef: true,
lrf: true,
use_satd_subpel: false,
Expand Down Expand Up @@ -1907,7 +1906,6 @@ fn guess_frame_subtypes_assert() {
include_near_mvs: false,
no_scene_detection: true,
fast_scene_detection: false,
diamond_me: true,
cdef: true,
lrf: true,
use_satd_subpel: false,
Expand Down
12 changes: 2 additions & 10 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3048,11 +3048,7 @@ pub(crate) fn build_half_res_pmvs<T: Pixel>(
tile_sbo: TileSuperBlockOffset,
tile_pmvs: &[[Option<MotionVector>; REF_FRAMES]],
) -> BlockPmv {
let estimate_motion_ss2 = if fi.config.speed_settings.diamond_me {
crate::me::DiamondSearch::estimate_motion_ss2
} else {
crate::me::FullSearch::estimate_motion_ss2
};
let estimate_motion_ss2 = crate::me::DiamondSearch::estimate_motion_ss2;

let TileSuperBlockOffset(SuperBlockOffset { x: sbx, y: sby }) = tile_sbo;
let mut pmvs: BlockPmv = [[None; REF_FRAMES]; 5];
Expand Down Expand Up @@ -3204,11 +3200,7 @@ pub(crate) fn build_full_res_pmvs<T: Pixel>(
tile_sbo: TileSuperBlockOffset,
half_res_pmvs: &[[[Option<MotionVector>; REF_FRAMES]; 5]],
) {
let estimate_motion = if fi.config.speed_settings.diamond_me {
crate::me::DiamondSearch::estimate_motion
} else {
crate::me::FullSearch::estimate_motion
};
let estimate_motion = crate::me::DiamondSearch::estimate_motion;

let TileSuperBlockOffset(SuperBlockOffset { x: sbx, y: sby }) = tile_sbo;
let mut pmvs: [Option<MotionVector>; REF_FRAMES] = [None; REF_FRAMES];
Expand Down
214 changes: 0 additions & 214 deletions src/me.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,6 @@ pub trait MotionEstimation {
}

pub struct DiamondSearch {}
pub struct FullSearch {}

impl MotionEstimation for DiamondSearch {
fn full_pixel_me<T: Pixel>(
Expand Down Expand Up @@ -511,136 +510,6 @@ impl MotionEstimation for DiamondSearch {
}
}

impl MotionEstimation for FullSearch {
fn full_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, ts: &TileStateMut<'_, T>,
rec: &ReferenceFrame<T>, tile_bo: TileBlockOffset, lambda: u32,
cmvs: ArrayVec<[MotionVector; 7]>, pmv: [MotionVector; 2], mvx_min: isize,
mvx_max: isize, mvy_min: isize, mvy_max: isize, bsize: BlockSize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, _ref_frame: RefType,
) {
let frame_bo = ts.to_frame_block_offset(tile_bo);
let frame_po = frame_bo.to_luma_plane_offset();
let range = 16;
for cmv in cmvs.into_iter() {
let x_lo = frame_po.x
+ ((-range + (cmv.col / 8) as isize)
.max(mvx_min / 8)
.min(mvx_max / 8));
let x_hi = frame_po.x
+ ((range + (cmv.col / 8) as isize).max(mvx_min / 8).min(mvx_max / 8));
let y_lo = frame_po.y
+ ((-range + (cmv.row / 8) as isize)
.max(mvy_min / 8)
.min(mvy_max / 8));
let y_hi = frame_po.y
+ ((range + (cmv.row / 8) as isize).max(mvy_min / 8).min(mvy_max / 8));

full_search(
fi,
x_lo,
x_hi,
y_lo,
y_hi,
bsize,
&ts.input.planes[0],
&rec.frame.planes[0],
best_mv,
lowest_cost,
frame_po,
2,
lambda,
pmv,
);
}
}

fn sub_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, ts: &TileStateMut<'_, T>,
_rec: &ReferenceFrame<T>, tile_bo: TileBlockOffset, lambda: u32,
pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize, mvy_min: isize,
mvy_max: isize, bsize: BlockSize, use_satd: bool,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: RefType,
) {
let frame_bo = ts.to_frame_block_offset(tile_bo);
telescopic_subpel_search(
fi,
ts,
frame_bo.to_luma_plane_offset(),
lambda,
ref_frame,
pmv,
mvx_min,
mvx_max,
mvy_min,
mvy_max,
bsize,
use_satd,
best_mv,
lowest_cost,
);
}

fn me_ss2<T: Pixel>(
fi: &FrameInvariants<T>, ts: &TileStateMut<'_, T>,
pmvs: &[Option<MotionVector>; 3], tile_bo_adj: TileBlockOffset,
rec: &ReferenceFrame<T>, _global_mv: [MotionVector; 2], lambda: u32,
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
bsize: BlockSize, best_mv: &mut MotionVector, lowest_cost: &mut u64,
_ref_frame: RefType,
) {
let frame_bo_adj = ts.to_frame_block_offset(tile_bo_adj);
let frame_po = PlaneOffset {
x: (frame_bo_adj.0.x as isize) << BLOCK_TO_PLANE_SHIFT >> 1,
y: (frame_bo_adj.0.y as isize) << BLOCK_TO_PLANE_SHIFT >> 1,
};
let range = 16;
for omv in pmvs.iter() {
if let Some(pmv) = omv {
let x_lo = frame_po.x
+ (((pmv.col as isize / 8 - range)
.max(mvx_min / 8)
.min(mvx_max / 8))
>> 1);
let x_hi = frame_po.x
+ (((pmv.col as isize / 8 + range)
.max(mvx_min / 8)
.min(mvx_max / 8))
>> 1);
let y_lo = frame_po.y
+ (((pmv.row as isize / 8 - range)
.max(mvy_min / 8)
.min(mvy_max / 8))
>> 1);
let y_hi = frame_po.y
+ (((pmv.row as isize / 8 + range)
.max(mvy_min / 8)
.min(mvy_max / 8))
>> 1);
full_search(
fi,
x_lo,
x_hi,
y_lo,
y_hi,
BlockSize::from_width_and_height(
bsize.width() >> 1,
bsize.height() >> 1,
),
ts.input_hres,
&rec.input_hres,
best_mv,
lowest_cost,
frame_po,
1,
lambda,
[MotionVector::default(); 2],
);
}
}
}
}

fn get_best_predictor<T: Pixel>(
fi: &FrameInvariants<T>, po: PlaneOffset, p_org: &Plane<T>,
p_ref: &Plane<T>, predictors: &[MotionVector], bit_depth: usize,
Expand Down Expand Up @@ -860,89 +729,6 @@ fn compute_mv_rd_cost<T: Pixel>(
256 * sad as u64 + rate as u64 * lambda as u64
}

fn telescopic_subpel_search<T: Pixel>(
fi: &FrameInvariants<T>, ts: &TileStateMut<'_, T>, po: PlaneOffset,
lambda: u32, ref_frame: RefType, pmv: [MotionVector; 2], mvx_min: isize,
mvx_max: isize, mvy_min: isize, mvy_max: isize, bsize: BlockSize,
use_satd: bool, best_mv: &mut MotionVector, lowest_cost: &mut u64,
) {
let mode = PredictionMode::NEWMV;
let blk_w = bsize.width();
let blk_h = bsize.height();

let steps: &[_] =
if fi.allow_high_precision_mv { &[8, 4, 2, 1] } else { &[8, 4, 2] };

let mut tmp_plane = Plane::new(blk_w, blk_h, 0, 0, 0, 0);
let tile_rect = TileRect {
x: 0,
y: 0,
width: tmp_plane.cfg.width,
height: tmp_plane.cfg.height,
};

for step in steps {
let center_mv_h = *best_mv;
for i in 0..3 {
for j in 0..3 {
// Skip the center point that was already tested
if i == 1 && j == 1 {
continue;
}

let cand_mv = MotionVector {
row: center_mv_h.row + step * (i as i16 - 1),
col: center_mv_h.col + step * (j as i16 - 1),
};

if (cand_mv.col as isize) < mvx_min || (cand_mv.col as isize) > mvx_max
{
continue;
}
if (cand_mv.row as isize) < mvy_min || (cand_mv.row as isize) > mvy_max
{
continue;
}

{
mode.predict_inter_single(
fi,
tile_rect,
0,
po,
&mut tmp_plane.as_region_mut(),
blk_w,
blk_h,
ref_frame,
cand_mv,
);
}

let plane_org =
ts.input.planes[0].region(Area::StartingAt { x: po.x, y: po.y });
let plane_ref = tmp_plane.as_region();

let cost = compute_mv_rd_cost(
fi,
pmv,
lambda,
use_satd,
fi.sequence.bit_depth,
bsize,
cand_mv,
&plane_org,
&plane_ref,
);

if cost < *lowest_cost {
*lowest_cost = cost;
*best_mv = cand_mv;
}
}
}
}
}

fn full_search<T: Pixel>(
fi: &FrameInvariants<T>, x_lo: isize, x_hi: isize, y_lo: isize, y_hi: isize,
bsize: BlockSize, p_org: &Plane<T>, p_ref: &Plane<T>,
Expand Down
6 changes: 1 addition & 5 deletions src/rdo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1030,11 +1030,7 @@ fn inter_frame_rdo_mode_decision<T: Pixel>(
};
let pmvs = ts.half_res_pmvs[pmv_idxs.0][pmv_idxs.1];

let motion_estimation = if fi.config.speed_settings.diamond_me {
crate::me::DiamondSearch::motion_estimation
} else {
crate::me::FullSearch::motion_estimation
};
let motion_estimation = crate::me::DiamondSearch::motion_estimation;

for (i, &ref_frames) in ref_frames_set.iter().enumerate() {
let mut mv_stack = ArrayVec::<[CandidateMV; 9]>::new();
Expand Down

0 comments on commit 15528ee

Please sign in to comment.