Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
- cargo install cargo-kcov
- kcov --version
- RUSTFLAGS="-C link-dead-code" cargo build --features=decode_test,quick_test --tests --verbose
- cargo kcov -v --coveralls --no-clean-rebuild -- --verify --exclude-pattern=$HOME/.cargo,aom_build,.h,test
- travis_wait cargo kcov -v --coveralls --no-clean-rebuild -- --verify --exclude-pattern=$HOME/.cargo,aom_build,.h,test
- name: "Tests"
script: cargo test --verbose --release --features=decode_test -- --ignored
- name: "Bench"
Expand Down
25 changes: 16 additions & 9 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,15 @@ impl BlockOffset {
}
}

/// Convert to plane offset without decimation
#[inline]
pub fn to_luma_plane_offset(self) -> PlaneOffset {
PlaneOffset {
x: (self.x as isize) << BLOCK_TO_PLANE_SHIFT,
y: (self.y as isize) << BLOCK_TO_PLANE_SHIFT,
}
}

pub fn y_in_sb(self) -> usize {
self.y % MAX_MIB_SIZE
}
Expand All @@ -1251,10 +1260,10 @@ pub struct Block {
pub mv: [MotionVector; 2],
pub neighbors_ref_counts: [usize; TOTAL_REFS_PER_FRAME],
pub cdef_index: u8,
pub bsize: BlockSize,
pub n4_w: usize, /* block width in the unit of mode_info */
pub n4_h: usize, /* block height in the unit of mode_info */
pub tx_w: usize, /* transform width in the unit of mode_info */
pub tx_h: usize, /* transform height in the unit of mode_info */
pub txsize: TxSize,
// The block-level deblock_deltas are left-shifted by
// fi.deblock.block_delta_shift and added to the frame-configured
// deltas
Expand All @@ -1272,10 +1281,10 @@ impl Block {
mv: [ MotionVector::default(); 2],
neighbors_ref_counts: [0; TOTAL_REFS_PER_FRAME],
cdef_index: 0,
bsize: BLOCK_64X64,
n4_w: BLOCK_64X64.width_mi(),
n4_h: BLOCK_64X64.height_mi(),
tx_w: TX_64X64.width_mi(),
tx_h: TX_64X64.height_mi(),
txsize: TX_64X64,
deblock_deltas: [0, 0, 0, 0],
segmentation_idx: 0,
}
Expand Down Expand Up @@ -1539,13 +1548,11 @@ impl BlockContext {
pub fn set_block_size(&mut self, bo: BlockOffset, bsize: BlockSize) {
let n4_w = bsize.width_mi();
let n4_h = bsize.height_mi();
self.for_each(bo, bsize, |block| { block.n4_w = n4_w; block.n4_h = n4_h } );
self.for_each(bo, bsize, |block| { block.bsize = bsize; block.n4_w = n4_w; block.n4_h = n4_h } );
}

pub fn set_tx_size(&mut self, bo: BlockOffset, bsize: BlockSize, txsize: TxSize) {
let tx_w = txsize.width_mi();
let tx_h = txsize.height_mi();
self.for_each(bo, bsize, |block| { block.tx_w = tx_w; block.tx_h = tx_h } );
pub fn set_tx_size(&mut self, bo: BlockOffset, bsize: BlockSize, tx_size: TxSize) {
self.for_each(bo, bsize, |block| { block.txsize = tx_size } );
}

pub fn get_mode(&mut self, bo: BlockOffset) -> PredictionMode {
Expand Down
68 changes: 43 additions & 25 deletions src/deblock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,19 @@ fn deblock_size<T: Pixel>(
{
0
} else {
let (tx_size, prev_tx_size) = if vertical {
(cmp::max(block.tx_w >> xdec, 1), cmp::max(prev_block.tx_w >> xdec, 1))
let (txsize, prev_txsize) = if pli==0 {
(block.txsize, prev_block.txsize)
} else {
(cmp::max(block.tx_h >> ydec, 1), cmp::max(prev_block.tx_h >> ydec, 1))
(block.bsize.largest_uv_tx_size(xdec, ydec), prev_block.bsize.largest_uv_tx_size(xdec, ydec))
};
let (tx_n, prev_tx_n) = if vertical {
(cmp::max(txsize.width_mi(), 1), cmp::max(prev_txsize.width_mi(), 1))
} else {
(cmp::max(txsize.height_mi(), 1), cmp::max(prev_txsize.height_mi(), 1))
};

cmp::min(
if pli == 0 { 14 } else { 6 },
cmp::min(tx_size, prev_tx_size) << MI_SIZE_LOG2
cmp::min(tx_n, prev_tx_n) << MI_SIZE_LOG2
)
}
}
Expand Down Expand Up @@ -1023,10 +1027,11 @@ fn sse_size14<T: Pixel>(

fn filter_v_edge<T: Pixel>(
deblock: &DeblockState, bc: &BlockContext, bo: BlockOffset, p: &mut Plane<T>,
pli: usize, bd: usize
pli: usize, bd: usize, xdec: usize, ydec: usize
) {
let block = bc.at(bo);
let tx_edge = bo.x & (block.tx_w - 1) == 0;
let txsize = if pli==0 { block.txsize } else { block.bsize.largest_uv_tx_size(xdec, ydec) };
let tx_edge = bo.x >> xdec & (txsize.width_mi() - 1) == 0;
if tx_edge {
let prev_block = deblock_left(bc, bo, p);
let block_edge = bo.x & (block.n4_w - 1) == 0;
Expand Down Expand Up @@ -1060,10 +1065,11 @@ fn filter_v_edge<T: Pixel>(

fn sse_v_edge<T: Pixel>(
bc: &BlockContext, bo: BlockOffset, rec_plane: &Plane<T>, src_plane: &Plane<T>,
tally: &mut [i64; MAX_LOOP_FILTER + 2], pli: usize, bd: usize
tally: &mut [i64; MAX_LOOP_FILTER + 2], pli: usize, bd: usize, xdec: usize, ydec: usize
) {
let block = bc.at(bo);
let tx_edge = bo.x & (block.tx_w - 1) == 0;
let txsize = if pli==0 { block.txsize } else { block.bsize.largest_uv_tx_size(xdec, ydec) };
let tx_edge = bo.x >> xdec & (txsize.width_mi() - 1) == 0;
if tx_edge {
let prev_block = deblock_left(bc, bo, rec_plane);
let block_edge = bo.x & (block.n4_w - 1) == 0;
Expand Down Expand Up @@ -1126,10 +1132,11 @@ fn sse_v_edge<T: Pixel>(

fn filter_h_edge<T: Pixel>(
deblock: &DeblockState, bc: &BlockContext, bo: BlockOffset, p: &mut Plane<T>,
pli: usize, bd: usize
pli: usize, bd: usize, xdec: usize, ydec: usize
) {
let block = bc.at(bo);
let tx_edge = bo.y & (block.tx_h - 1) == 0;
let txsize = if pli==0 { block.txsize } else { block.bsize.largest_uv_tx_size(xdec, ydec) };
let tx_edge = bo.y >> ydec & (txsize.height_mi() - 1) == 0;
if tx_edge {
let prev_block = deblock_up(bc, bo, p);
let block_edge = bo.y & (block.n4_h - 1) == 0;
Expand Down Expand Up @@ -1163,10 +1170,11 @@ fn filter_h_edge<T: Pixel>(

fn sse_h_edge<T: Pixel>(
bc: &BlockContext, bo: BlockOffset, rec_plane: &Plane<T>, src_plane: &Plane<T>,
tally: &mut [i64; MAX_LOOP_FILTER + 2], pli: usize, bd: usize
tally: &mut [i64; MAX_LOOP_FILTER + 2], pli: usize, bd: usize, xdec: usize, ydec: usize
) {
let block = bc.at(bo);
let tx_edge = bo.y & (block.tx_h - 1) == 0;
let txsize = if pli==0 { block.txsize } else { block.bsize.largest_uv_tx_size(xdec, ydec) };
let tx_edge = bo.y >> ydec & (txsize.height_mi() - 1) == 0;
if tx_edge {
let prev_block = deblock_up(bc, bo, rec_plane);
let block_edge = bo.y & (block.n4_h - 1) == 0;
Expand Down Expand Up @@ -1256,7 +1264,7 @@ pub fn deblock_plane<T: Pixel>(
// edge). Unroll to avoid corner-cases.
if bc.rows > 0 {
for x in (1 << xdec..bc.cols).step_by(1 << xdec) {
filter_v_edge(deblock, bc, BlockOffset { x, y: 0 }, p, pli, bd);
filter_v_edge(deblock, bc, BlockOffset { x, y: 0 }, p, pli, bd, xdec, ydec);
}
if bc.rows > 1 << ydec {
for x in (1 << xdec..bc.cols).step_by(1 << xdec) {
Expand All @@ -1266,7 +1274,9 @@ pub fn deblock_plane<T: Pixel>(
BlockOffset { x, y: 1 << ydec },
p,
pli,
bd
bd,
xdec,
ydec
);
}
}
Expand All @@ -1277,19 +1287,21 @@ pub fn deblock_plane<T: Pixel>(
for y in ((2 << ydec)..bc.rows).step_by(1 << ydec) {
// Check for vertical edge at first MI block boundary on this row
if 1 << xdec < bc.cols {
filter_v_edge(deblock, bc, BlockOffset { x: 1 << xdec, y }, p, pli, bd);
filter_v_edge(deblock, bc, BlockOffset { x: 1 << xdec, y }, p, pli, bd, xdec, ydec);
}
// run the rest of the row with both vertical and horizontal edge filtering.
// Horizontal lags vertical edge by one row and two columns.
for x in (2 << xdec..bc.cols).step_by(1 << xdec) {
filter_v_edge(deblock, bc, BlockOffset { x, y }, p, pli, bd);
filter_v_edge(deblock, bc, BlockOffset { x, y }, p, pli, bd, xdec, ydec);
filter_h_edge(
deblock,
bc,
BlockOffset { x: x - (2 << xdec), y: y - (1 << ydec) },
p,
pli,
bd
bd,
xdec,
ydec
);
}
// ..and the last two horizontal edges for the row
Expand All @@ -1300,7 +1312,9 @@ pub fn deblock_plane<T: Pixel>(
BlockOffset { x: bc.cols - (2 << xdec), y: y - (1 << ydec) },
p,
pli,
bd
bd,
xdec,
ydec
);
if bc.cols - (1 << xdec) > 0 {
filter_h_edge(
Expand All @@ -1309,7 +1323,9 @@ pub fn deblock_plane<T: Pixel>(
BlockOffset { x: bc.cols - (1 << xdec), y: y - (1 << ydec) },
p,
pli,
bd
bd,
xdec,
ydec
);
}
}
Expand All @@ -1324,7 +1340,9 @@ pub fn deblock_plane<T: Pixel>(
BlockOffset { x, y: bc.rows - (1 << ydec) },
p,
pli,
bd
bd,
xdec,
ydec
);
}
}
Expand All @@ -1341,18 +1359,18 @@ fn sse_plane<T: Pixel>(

// No horizontal edge filtering along top of frame
for x in (1 << xdec..bc.cols).step_by(1 << xdec) {
sse_v_edge(bc, BlockOffset { x, y: 0 }, rec, src, v_sse, pli, bd);
sse_v_edge(bc, BlockOffset { x, y: 0 }, rec, src, v_sse, pli, bd, xdec, ydec);
}

// Unlike actual filtering, we're counting horizontal and vertical
// as separable cases. No need to lag the horizontal processing
// behind vertical.
for y in (1 << ydec..bc.rows).step_by(1 << ydec) {
// No vertical filtering along left edge of frame
sse_h_edge(bc, BlockOffset { x: 0, y }, rec, src, h_sse, pli, bd);
sse_h_edge(bc, BlockOffset { x: 0, y }, rec, src, h_sse, pli, bd, xdec, ydec);
for x in (1 << xdec..bc.cols).step_by(1 << xdec) {
sse_v_edge(bc, BlockOffset { x, y }, rec, src, v_sse, pli, bd);
sse_h_edge(bc, BlockOffset { x, y }, rec, src, h_sse, pli, bd);
sse_v_edge(bc, BlockOffset { x, y }, rec, src, v_sse, pli, bd, xdec, ydec);
sse_h_edge(bc, BlockOffset { x, y }, rec, src, h_sse, pli, bd, xdec, ydec);
}
}
}
Expand Down
5 changes: 0 additions & 5 deletions src/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2176,11 +2176,6 @@ fn encode_tile<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>) -> Vec
/* TODO: Don't apply if lossless */
deblock_filter_optimize(fi, fs, &mut cw.bc);

// NOTE(yushin): Temporarilly, disable deblocking-filter
// because it causes mismatch btw encoder and decoder when transform partition is enabled.
fs.deblock.levels[0] = 0;
fs.deblock.levels[1] = 0;

if fs.deblock.levels[0] != 0 || fs.deblock.levels[1] != 0 {
deblock_filter_frame(fs, &mut cw.bc, fi.sequence.bit_depth);
}
Expand Down
27 changes: 12 additions & 15 deletions src/me.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ pub fn get_subset_predictors<T: Pixel>(

pub trait MotionEstimation {
fn full_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, fs: &FrameState<T>, rec: &Arc<ReferenceFrame<T>>, po: PlaneOffset,
fi: &FrameInvariants<T>, fs: &FrameState<T>, rec: &Arc<ReferenceFrame<T>>,
bo: BlockOffset, lambda: u32,
cmv: MotionVector, pmv: [MotionVector; 2],
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
Expand All @@ -346,7 +346,7 @@ pub trait MotionEstimation {
);

fn sub_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, fs: &FrameState<T>, rec: &Arc<ReferenceFrame<T>>, po: PlaneOffset,
fi: &FrameInvariants<T>, fs: &FrameState<T>, rec: &Arc<ReferenceFrame<T>>,
bo: BlockOffset, lambda: u32, pmv: [MotionVector; 2],
mvx_min: isize, mvx_max: isize, mvy_min: isize, mvy_max: isize,
blk_w: usize, blk_h: usize, best_mv: &mut MotionVector,
Expand All @@ -362,10 +362,6 @@ pub trait MotionEstimation {
match fi.rec_buffer.frames[fi.ref_frames[ref_frame - LAST_FRAME] as usize]
{
Some(ref rec) => {
let po = PlaneOffset {
x: (bo.x as isize) << BLOCK_TO_PLANE_SHIFT,
y: (bo.y as isize) << BLOCK_TO_PLANE_SHIFT
};
let blk_w = bsize.width();
let blk_h = bsize.height();
let (mvx_min, mvx_max, mvy_min, mvy_max) =
Expand All @@ -379,12 +375,12 @@ pub trait MotionEstimation {
let mut lowest_cost = std::u64::MAX;
let mut best_mv = MotionVector::default();

Self::full_pixel_me(fi, fs, rec, po, bo, lambda, cmv, pmv,
Self::full_pixel_me(fi, fs, rec, bo, lambda, cmv, pmv,
mvx_min, mvx_max, mvy_min, mvy_max, blk_w, blk_h,
&mut best_mv, &mut lowest_cost, ref_frame);

let tmp_plane = Plane::new(blk_w, blk_h, 0, 0, 0, 0);
Self::sub_pixel_me(fi, fs, rec, po, bo, lambda, pmv,
Self::sub_pixel_me(fi, fs, rec, bo, lambda, pmv,
mvx_min, mvx_max, mvy_min, mvy_max, blk_w, blk_h,
&mut best_mv, &mut lowest_cost, ref_frame,
tmp_plane, bsize);
Expand Down Expand Up @@ -452,7 +448,7 @@ pub struct FullSearch {}
impl MotionEstimation for DiamondSearch {
fn full_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, fs: &FrameState<T>, rec: &Arc<ReferenceFrame<T>>,
po: PlaneOffset, bo: BlockOffset, lambda: u32,
bo: BlockOffset, lambda: u32,
cmv: MotionVector, pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: usize
Expand All @@ -464,7 +460,7 @@ impl MotionEstimation for DiamondSearch {

diamond_me_search(
fi,
po,
bo.to_luma_plane_offset(),
&fs.input.planes[0],
&rec.frame.planes[0],
&predictors,
Expand All @@ -486,7 +482,7 @@ impl MotionEstimation for DiamondSearch {

fn sub_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, fs: &FrameState<T>, rec: &Arc<ReferenceFrame<T>>,
po: PlaneOffset, _bo: BlockOffset, lambda: u32,
bo: BlockOffset, lambda: u32,
pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: usize,
Expand All @@ -496,7 +492,7 @@ impl MotionEstimation for DiamondSearch {
let predictors = vec![*best_mv];
diamond_me_search(
fi,
po,
bo.to_luma_plane_offset(),
&fs.input.planes[0],
&rec.frame.planes[0],
&predictors,
Expand Down Expand Up @@ -558,11 +554,12 @@ impl MotionEstimation for DiamondSearch {
impl MotionEstimation for FullSearch {
fn full_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, fs: &FrameState<T>, rec: &Arc<ReferenceFrame<T>>,
po: PlaneOffset, _bo: BlockOffset, lambda: u32,
bo: BlockOffset, lambda: u32,
cmv: MotionVector, pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, blk_w: usize, blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, _ref_frame: usize
) {
let po = bo.to_luma_plane_offset();
let range = 16;
let x_lo = po.x
+ ((-range + (cmv.col / 8) as isize).max(mvx_min / 8).min(mvx_max / 8));
Expand Down Expand Up @@ -595,7 +592,7 @@ impl MotionEstimation for FullSearch {

fn sub_pixel_me<T: Pixel>(
fi: &FrameInvariants<T>, fs: &FrameState<T>, _rec: &Arc<ReferenceFrame<T>>,
po: PlaneOffset, _bo: BlockOffset, lambda: u32,
bo: BlockOffset, lambda: u32,
pmv: [MotionVector; 2], mvx_min: isize, mvx_max: isize,
mvy_min: isize, mvy_max: isize, _blk_w: usize, _blk_h: usize,
best_mv: &mut MotionVector, lowest_cost: &mut u64, ref_frame: usize,
Expand All @@ -606,7 +603,7 @@ impl MotionEstimation for FullSearch {
fi,
fs,
bsize,
po,
bo.to_luma_plane_offset(),
lambda,
ref_frame,
pmv,
Expand Down