Commit 3c29f358 authored by Romain Vimont's avatar Romain Vimont Committed by Romain Vimont

Pass FrameBlocks instead of BlockContext

FrameBlocks is part of the BlockContext structure. Many functions which
used only the FrameBlocks (but not the other BlockContext fields)
received a reference to the whole BlockContext as parameter.

FrameBlocks will survive tiles-encoding: it will be accessed through a
tiled version for each tile, then frame-wise after all tiles are
encoded.

However, BlockContext will only be used tile-wise: there will be one
instance per tile, destroyed once the tile is encoded. Therefore,
frame-wise functions may not receive the whole BlockContext anymore
(all tile-specific BlockContext instances won't exist anymore).
parent 7debdde3
......@@ -113,10 +113,10 @@ fn cdef_frame_bench(b: &mut Bencher, width: usize, height: usize) {
};
let sequence = Sequence::new(&Default::default());
let fi = FrameInvariants::<u16>::new(config, sequence);
let mut bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
let bc = BlockContext::new(fi.sb_width * 16, fi.sb_height * 16);
let mut fs = FrameState::new(&fi);
b.iter(|| cdef_filter_frame(&fi, &mut fs.rec, &mut bc));
b.iter(|| cdef_filter_frame(&fi, &mut fs.rec, &bc.blocks));
}
fn cfl_rdo(c: &mut Criterion) {
......
......@@ -205,7 +205,7 @@ fn adjust_strength(strength: i32, var: i32) -> i32 {
pub fn cdef_analyze_superblock<T: Pixel>(
in_frame: &Frame<T>,
bc_global: &BlockContext,
blocks: &FrameBlocks,
sbo: SuperBlockOffset,
sbo_global: SuperBlockOffset,
bit_depth: usize,
......@@ -215,16 +215,16 @@ pub fn cdef_analyze_superblock<T: Pixel>(
// Each direction block is 8x8 in y, and direction computation only looks at y
for by in 0..8 {
for bx in 0..8 {
// The bc and global SBO are only to determine frame
// The blocks and global SBO are only to determine frame
// boundaries and skips in the event we're passing in a
// single-SB copy 'frame' that represents some superblock
// in the main frame.
let global_block_offset = sbo_global.block_offset(bx<<1, by<<1);
if global_block_offset.x < bc_global.cols && global_block_offset.y < bc_global.rows {
let skip = bc_global.blocks[global_block_offset].skip
& bc_global.blocks[sbo_global.block_offset(2*bx+1, 2*by)].skip
& bc_global.blocks[sbo_global.block_offset(2*bx, 2*by+1)].skip
& bc_global.blocks[sbo_global.block_offset(2*bx+1, 2*by+1)].skip;
if global_block_offset.x < blocks.cols && global_block_offset.y < blocks.rows {
let skip = blocks[global_block_offset].skip
& blocks[sbo_global.block_offset(2*bx+1, 2*by)].skip
& blocks[sbo_global.block_offset(2*bx, 2*by+1)].skip
& blocks[sbo_global.block_offset(2*bx+1, 2*by+1)].skip;
if !skip {
let mut var: i32 = 0;
......@@ -332,7 +332,7 @@ pub fn cdef_filter_superblock<T: Pixel>(
fi: &FrameInvariants<T>,
in_frame: &Frame<u16>,
out_frame: &mut Frame<T>,
bc_global: &BlockContext,
blocks: &FrameBlocks,
sbo: SuperBlockOffset,
sbo_global: SuperBlockOffset,
cdef_index: u8,
......@@ -357,11 +357,11 @@ pub fn cdef_filter_superblock<T: Pixel>(
for by in 0..8 {
for bx in 0..8 {
let global_block_offset = sbo_global.block_offset(bx<<1, by<<1);
if global_block_offset.x < bc_global.cols && global_block_offset.y < bc_global.rows {
let skip = bc_global.blocks[global_block_offset].skip
& bc_global.blocks[sbo_global.block_offset(2*bx+1, 2*by)].skip
& bc_global.blocks[sbo_global.block_offset(2*bx, 2*by+1)].skip
& bc_global.blocks[sbo_global.block_offset(2*bx+1, 2*by+1)].skip;
if global_block_offset.x < blocks.cols && global_block_offset.y < blocks.rows {
let skip = blocks[global_block_offset].skip
& blocks[sbo_global.block_offset(2*bx+1, 2*by)].skip
& blocks[sbo_global.block_offset(2*bx, 2*by+1)].skip
& blocks[sbo_global.block_offset(2*bx+1, 2*by+1)].skip;
if !skip {
let dir = cdef_dirs.dir[bx][by];
let var = cdef_dirs.var[bx][by];
......@@ -420,7 +420,7 @@ pub fn cdef_filter_superblock<T: Pixel>(
// CDEF parameters are stored for each 64 by 64 block of pixels.
// The CDEF filter is applied on each 8 by 8 block of pixels.
// Reference: http://av1-spec.argondesign.com/av1-spec/av1-spec.html#cdef-process
pub fn cdef_filter_frame<T: Pixel>(fi: &FrameInvariants<T>, rec: &mut Frame<T>, bc: &BlockContext) {
pub fn cdef_filter_frame<T: Pixel>(fi: &FrameInvariants<T>, rec: &mut Frame<T>, blocks: &FrameBlocks) {
// Each filter block is 64x64, except right and/or bottom for non-multiple-of-64 sizes.
// FIXME: 128x128 SB support will break this, we need FilterBlockOffset etc.
let fb_width = (rec.planes[0].cfg.width + 63) / 64;
......@@ -480,9 +480,9 @@ pub fn cdef_filter_frame<T: Pixel>(fi: &FrameInvariants<T>, rec: &mut Frame<T>,
for fby in 0..fb_height {
for fbx in 0..fb_width {
let sbo = SuperBlockOffset { x: fbx, y: fby };
let cdef_index = bc.blocks[sbo.block_offset(0, 0)].cdef_index;
let cdef_dirs = cdef_analyze_superblock(&cdef_frame, bc, sbo, sbo, fi.sequence.bit_depth);
cdef_filter_superblock(fi, &cdef_frame, rec, bc, sbo, sbo, cdef_index, &cdef_dirs);
let cdef_index = blocks[sbo.block_offset(0, 0)].cdef_index;
let cdef_dirs = cdef_analyze_superblock(&cdef_frame, blocks, sbo, sbo, fi.sequence.bit_depth);
cdef_filter_superblock(fi, &cdef_frame, rec, blocks, sbo, sbo, cdef_index, &cdef_dirs);
}
}
}
......
This diff is collapsed.
......@@ -2184,9 +2184,9 @@ fn encode_tile<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>) -> Vec
}
}
/* TODO: Don't apply if lossless */
deblock_filter_optimize(fi, fs, &cw.bc);
deblock_filter_optimize(fi, fs, &cw.bc.blocks);
if fs.deblock.levels[0] != 0 || fs.deblock.levels[1] != 0 {
deblock_filter_frame(fs, &cw.bc, fi.sequence.bit_depth);
deblock_filter_frame(fs, &cw.bc.blocks, fi.sequence.bit_depth);
}
// Until the loop filters are pipelined, we'll need to keep
// around a copy of both the pre- and post-cdef frame.
......@@ -2194,7 +2194,7 @@ fn encode_tile<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>) -> Vec
/* TODO: Don't apply if lossless */
if fi.sequence.enable_cdef {
cdef_filter_frame(fi, &mut fs.rec, &cw.bc);
cdef_filter_frame(fi, &mut fs.rec, &cw.bc.blocks);
}
/* TODO: Don't apply if lossless */
if fi.sequence.enable_restoration {
......
......@@ -1232,7 +1232,7 @@ pub fn rdo_partition_decision<T: Pixel>(
}
fn rdo_loop_plane_error<T: Pixel>(sbo: SuperBlockOffset, fi: &FrameInvariants<T>,
fs: &FrameState<T>, bc: &BlockContext,
fs: &FrameState<T>, blocks: &FrameBlocks,
test: &Frame<T>, pli: usize) -> u64 {
let sbo_0 = SuperBlockOffset { x: 0, y: 0 };
let sb_blocks = if fi.sequence.use_128x128_superblock {16} else {8};
......@@ -1242,8 +1242,8 @@ fn rdo_loop_plane_error<T: Pixel>(sbo: SuperBlockOffset, fi: &FrameInvariants<T>
for by in 0..sb_blocks {
for bx in 0..sb_blocks {
let bo = sbo.block_offset(bx<<1, by<<1);
if bo.x < bc.cols && bo.y < bc.rows {
let skip = bc.blocks[bo].skip;
if bo.x < blocks.cols && bo.y < blocks.rows {
let skip = blocks[bo].skip;
if !skip {
let in_plane = &fs.input.planes[pli];
let in_po = sbo.block_offset(bx<<1, by<<1).plane_offset(&in_plane.cfg);
......@@ -1318,7 +1318,7 @@ pub fn rdo_loop_decision<T: Pixel>(sbo: SuperBlockOffset, fi: &FrameInvariants<T
// If LRF choice changed for any plane, repeat last two steps.
let bd = fi.sequence.bit_depth;
let cdef_data = cdef_input.as_ref().map(|input| {
(input, cdef_analyze_superblock(input, &cw.bc, sbo_0, sbo, bd))
(input, cdef_analyze_superblock(input, &cw.bc.blocks, sbo_0, sbo, bd))
});
let mut first_loop = true;
loop {
......@@ -1331,11 +1331,11 @@ pub fn rdo_loop_decision<T: Pixel>(sbo: SuperBlockOffset, fi: &FrameInvariants<T
let mut cost = [0.; PLANES];
let mut cost_acc = 0.;
cdef_filter_superblock(fi, &cdef_input, &mut lrf_input,
&cw.bc, sbo_0, sbo, cdef_index as u8, &cdef_dirs);
&cw.bc.blocks, sbo_0, sbo, cdef_index as u8, &cdef_dirs);
for pli in 0..3 {
match best_lrf[pli] {
RestorationFilter::None{} => {
let err = rdo_loop_plane_error(sbo, fi, fs, &cw.bc, &lrf_input, pli);
let err = rdo_loop_plane_error(sbo, fi, fs, &cw.bc.blocks, &lrf_input, pli);
let rate = if fi.sequence.enable_restoration {
cw.count_lrf_switchable(w, &fs.restoration, best_lrf[pli], pli)
} else {
......@@ -1353,7 +1353,7 @@ pub fn rdo_loop_decision<T: Pixel>(sbo: SuperBlockOffset, fi: &FrameInvariants<T
&lrf_input.planes[pli].slice(PlaneOffset{x:0, y:0}),
&lrf_input.planes[pli].slice(PlaneOffset{x:0, y:0}),
&mut lrf_output.planes[pli].mut_slice(PlaneOffset{x:0, y:0}));
let err = rdo_loop_plane_error(sbo, fi, fs, &cw.bc, &lrf_output, pli);
let err = rdo_loop_plane_error(sbo, fi, fs, &cw.bc.blocks, &lrf_output, pli);
let rate = cw.count_lrf_switchable(w, &fs.restoration, best_lrf[pli], pli);
cost[pli] = err as f64 + fi.lambda * rate as f64 / ((1<<OD_BITRES) as f64);
cost_acc += cost[pli];
......@@ -1380,7 +1380,7 @@ pub fn rdo_loop_decision<T: Pixel>(sbo: SuperBlockOffset, fi: &FrameInvariants<T
// need cdef output from best index, not just last iteration
if let Some((cdef_input, cdef_dirs)) = cdef_data.as_ref() {
cdef_filter_superblock(fi, &cdef_input, &mut lrf_input,
&cw.bc, sbo_0, sbo, best_index as u8, &cdef_dirs);
&cw.bc.blocks, sbo_0, sbo, best_index as u8, &cdef_dirs);
}
// Wiener LRF decision coming soon
......@@ -1408,7 +1408,7 @@ pub fn rdo_loop_decision<T: Pixel>(sbo: SuperBlockOffset, fi: &FrameInvariants<T
&lrf_input.planes[pli].slice(PlaneOffset{x:0, y:0}),
&mut lrf_output.planes[pli].mut_slice(PlaneOffset{x:0, y:0}));
}
let err = rdo_loop_plane_error(sbo, fi, fs, &cw.bc, &lrf_output, pli);
let err = rdo_loop_plane_error(sbo, fi, fs, &cw.bc.blocks, &lrf_output, pli);
let rate = cw.count_lrf_switchable(w, &fs.restoration, current_lrf, pli);
let cost = err as f64 + fi.lambda * rate as f64 / ((1<<OD_BITRES) as f64);
if best_cost[pli] < 0. || cost < best_cost[pli] {
......
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