Unverified Commit b6d766bf authored by Yushin Cho's avatar Yushin Cho Committed by GitHub

[WIP] ME use predicted search center for topdown partition search (#569)

ME use predicted search center for topdown partition search
parent a51b8ef5
......@@ -1678,7 +1678,8 @@ fn encode_partition_bottomup(seq: &Sequence, fi: &FrameInvariants, fs: &mut Fram
cw.write_partition(w, bo, partition, bsize);
cost = (w.tell_frac() - tell) as f64 * get_lambda(fi, seq.bit_depth)/ ((1 << OD_BITRES) as f64);
}
let mode_decision = rdo_mode_decision(seq, fi, fs, cw, bsize, bo).part_modes[0].clone();
let pmv = MotionVector { row: 0, col: 0 };
let mode_decision = rdo_mode_decision(seq, fi, fs, cw, bsize, bo, &pmv).part_modes[0].clone();
let (mode_luma, mode_chroma) = (mode_decision.pred_mode_luma, mode_decision.pred_mode_chroma);
let cfl = mode_decision.pred_cfl_params;
let ref_frame = mode_decision.ref_frame;
......@@ -1818,6 +1819,7 @@ fn encode_partition_topdown(seq: &Sequence, fi: &FrameInvariants, fs: &mut Frame
let hbs = bs >> 1; // Half the block size in blocks
let subsize = get_subsize(bsize, partition);
let pmv = MotionVector { row: 0, col: 0 };
if bsize >= BlockSize::BLOCK_8X8 {
let w: &mut dyn Writer = if cw.bc.cdef_coded {w_post_cdef} else {w_pre_cdef};
......@@ -1831,7 +1833,7 @@ fn encode_partition_topdown(seq: &Sequence, fi: &FrameInvariants, fs: &mut Frame
rdo_output.part_modes[0].clone()
} else {
// Make a prediction mode decision for blocks encoded with no rdo_partition_decision call (e.g. edges)
rdo_mode_decision(seq, fi, fs, cw, bsize, bo).part_modes[0].clone()
rdo_mode_decision(seq, fi, fs, cw, bsize, bo, &pmv).part_modes[0].clone()
};
let mut mode_luma = part_decision.pred_mode_luma;
......
......@@ -41,7 +41,7 @@ pub fn get_sad(
pub fn motion_estimation(
fi: &FrameInvariants, fs: &mut FrameState, bsize: BlockSize,
bo: &BlockOffset, ref_frame: usize
bo: &BlockOffset, ref_frame: usize, pmv: &MotionVector
) -> MotionVector {
match fi.rec_buffer.frames[fi.ref_frames[ref_frame - LAST_FRAME]] {
Some(ref rec) => {
......@@ -58,10 +58,10 @@ pub fn motion_estimation(
let mvx_max = (fi.w_in_b - bo.x - blk_w / MI_SIZE) as isize * (8 * MI_SIZE) as isize + border_w;
let mvy_min = -(bo.y as isize) * (8 * MI_SIZE) as isize - border_h;
let mvy_max = (fi.h_in_b - bo.y - blk_h / MI_SIZE) as isize * (8 * MI_SIZE) as isize + border_h;
let x_lo = po.x + ((-range).max(mvx_min / 8));
let x_hi = po.x + (range.min(mvx_max / 8));
let y_lo = po.y + ((-range).max(mvy_min / 8));
let y_hi = po.y + (range.min(mvy_max / 8));
let x_lo = po.x + ((-range + (pmv.col / 8) as isize).max(mvx_min / 8));
let x_hi = po.x + ((range + (pmv.col / 8) as isize).min(mvx_max / 8));
let y_lo = po.y + ((-range + (pmv.row / 8) as isize).max(mvy_min / 8));
let y_hi = po.y + ((range + (pmv.row / 8) as isize).min(mvy_max / 8));
let mut lowest_sad = 128 * 128 * 4096 as u32;
let mut best_mv = MotionVector { row: 0, col: 0 };
......
......@@ -251,7 +251,8 @@ pub fn rdo_tx_size_type(
// RDO-based mode decision
pub fn rdo_mode_decision(
seq: &Sequence, fi: &FrameInvariants, fs: &mut FrameState,
cw: &mut ContextWriter, bsize: BlockSize, bo: &BlockOffset
cw: &mut ContextWriter, bsize: BlockSize, bo: &BlockOffset,
pmv: &MotionVector
) -> RDOOutput {
let mut best_mode_luma = PredictionMode::DC_PRED;
let mut best_mode_chroma = PredictionMode::DC_PRED;
......@@ -312,7 +313,7 @@ pub fn rdo_mode_decision(
let ref_frame =
if luma_mode_is_intra { INTRA_FRAME } else { LAST_FRAME };
let mv = match luma_mode {
PredictionMode::NEWMV => motion_estimation(fi, fs, bsize, bo, ref_frame),
PredictionMode::NEWMV => motion_estimation(fi, fs, bsize, bo, ref_frame, pmv),
PredictionMode::NEARESTMV => if mv_stack.len() > 0 {
mv_stack[0].this_mv
} else {
......@@ -578,6 +579,7 @@ pub fn rdo_partition_decision(
let mut rd: f64;
let mut child_modes = std::vec::Vec::new();
let mut pmv = MotionVector { row: 0, col: 0 };
match partition {
PartitionType::PARTITION_NONE => {
......@@ -589,7 +591,7 @@ pub fn rdo_partition_decision(
.part_modes
.get(0)
.unwrap_or(
&rdo_mode_decision(seq, fi, fs, cw, bsize, bo).part_modes[0]
&rdo_mode_decision(seq, fi, fs, cw, bsize, bo, &pmv).part_modes[0]
).clone();
child_modes.push(mode_decision);
}
......@@ -599,32 +601,33 @@ pub fn rdo_partition_decision(
if subsize == BlockSize::BLOCK_INVALID {
continue;
}
pmv = best_pred_modes[0].mv;
assert!(best_pred_modes.len() <= 4);
let bs = bsize.width_mi();
let hbs = bs >> 1; // Half the block size in blocks
let offset = BlockOffset { x: bo.x, y: bo.y };
let mode_decision =
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset).part_modes[0]
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
.clone();
child_modes.push(mode_decision);
let offset = BlockOffset { x: bo.x + hbs as usize, y: bo.y };
let mode_decision =
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset).part_modes[0]
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
.clone();
child_modes.push(mode_decision);
let offset = BlockOffset { x: bo.x, y: bo.y + hbs as usize };
let mode_decision =
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset).part_modes[0]
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
.clone();
child_modes.push(mode_decision);
let offset =
BlockOffset { x: bo.x + hbs as usize, y: bo.y + hbs as usize };
let mode_decision =
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset).part_modes[0]
rdo_mode_decision(seq, fi, fs, cw, subsize, &offset, &pmv).part_modes[0]
.clone();
child_modes.push(mode_decision);
}
......
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