Commit 28f0c8f9 authored by Romain Vimont's avatar Romain Vimont Committed by Thomas Daede

Use TileBlocks

Encode the single-tile frame using a single-tile TileBlocks.
parent 158620c9
......@@ -46,7 +46,8 @@ fn write_b_bench(b: &mut Bencher, tx_size: TxSize, qindex: usize) {
let mut w = ec::WriterEncoder::new();
let mut fc = CDFContext::new(fi.base_q_idx);
let mut fb = FrameBlocks::new(fi.sb_width * 16, fi.sb_height * 16);
let bc = BlockContext::new(&mut fb);
let mut tb = fb.as_tile_blocks_mut();
let bc = BlockContext::new(&mut tb);
let mut fs = FrameState::new(&fi);
let mut ts = fs.as_tile_state_mut();
// For now, restoration unit size is locked to superblock size.
......@@ -116,11 +117,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 fb = FrameBlocks::new(fi.sb_width * 16, fi.sb_height * 16);
let bc = BlockContext::new(&mut fb);
let fb = FrameBlocks::new(fi.sb_width * 16, fi.sb_height * 16);
let mut fs = FrameState::new(&fi);
b.iter(|| cdef_filter_frame(&fi, &mut fs.rec, &bc.blocks));
b.iter(|| cdef_filter_frame(&fi, &mut fs.rec, &fb));
}
fn cfl_rdo(c: &mut Criterion) {
......
......@@ -1472,16 +1472,16 @@ pub struct BlockContext<'a> {
left_tx_context: [u8; MAX_MIB_SIZE],
above_coeff_context: [Vec<u8>; PLANES],
left_coeff_context: [[u8; MAX_MIB_SIZE]; PLANES],
pub blocks: &'a mut FrameBlocks,
pub blocks: &'a mut TileBlocksMut<'a>,
}
impl<'a> BlockContext<'a> {
pub fn new(blocks: &'a mut FrameBlocks) -> Self {
pub fn new(blocks: &'a mut TileBlocksMut<'a>) -> Self {
// Align power of two
let aligned_cols = (blocks.cols + ((1 << MAX_MIB_SIZE_LOG2) - 1))
let aligned_cols = (blocks.cols() + ((1 << MAX_MIB_SIZE_LOG2) - 1))
& !((1 << MAX_MIB_SIZE_LOG2) - 1);
let above_coeff_context_size =
blocks.cols << (MI_SIZE_LOG2 - TxSize::width_log2(TxSize::TX_4X4));
blocks.cols() << (MI_SIZE_LOG2 - TxSize::width_log2(TxSize::TX_4X4));
BlockContext {
cdef_coded: false,
......@@ -2030,8 +2030,8 @@ impl<'a> ContextWriter<'a> {
debug_assert!(bsize.is_sqr());
assert!(bsize >= BlockSize::BLOCK_8X8 );
let hbs = bsize.width_mi() / 2;
let has_cols = (bo.x + hbs) < self.bc.blocks.cols;
let has_rows = (bo.y + hbs) < self.bc.blocks.rows;
let has_cols = (bo.x + hbs) < self.bc.blocks.cols();
let has_rows = (bo.y + hbs) < self.bc.blocks.rows();
let ctx = self.bc.partition_plane_context(bo, bsize);
assert!(ctx < PARTITION_CONTEXTS);
let partition_cdf = if bsize <= BlockSize::BLOCK_8X8 {
......@@ -2373,7 +2373,7 @@ impl<'a> ContextWriter<'a> {
let bc = &self.bc;
let target_n4_w = bsize.width_mi();
let end_mi = cmp::min(cmp::min(target_n4_w, bc.blocks.cols - bo.x),
let end_mi = cmp::min(cmp::min(target_n4_w, bc.blocks.cols() - bo.x),
BLOCK_64X64.width_mi());
let n4_w_8 = BLOCK_8X8.width_mi();
let n4_w_16 = BLOCK_16X16.width_mi();
......@@ -2428,7 +2428,7 @@ impl<'a> ContextWriter<'a> {
let target_n4_h = bsize.height_mi();
let end_mi = cmp::min(cmp::min(target_n4_h, bc.blocks.rows - bo.y),
let end_mi = cmp::min(cmp::min(target_n4_h, bc.blocks.rows() - bo.y),
BLOCK_64X64.height_mi());
let n4_h_8 = BLOCK_8X8.height_mi();
let n4_h_16 = BLOCK_16X16.height_mi();
......@@ -2477,7 +2477,7 @@ impl<'a> ContextWriter<'a> {
fn scan_blk_mbmi(&mut self, bo: BlockOffset, ref_frames: [RefType; 2],
mv_stack: &mut Vec<CandidateMV>, newmv_count: &mut usize,
is_compound: bool) -> bool {
if bo.x >= self.bc.blocks.cols || bo.y >= self.bc.blocks.rows {
if bo.x >= self.bc.blocks.cols() || bo.y >= self.bc.blocks.rows() {
return false;
}
......@@ -2521,7 +2521,7 @@ impl<'a> ContextWriter<'a> {
max_row_offs = -2 * 2 + row_adj as isize;
}
let rows = self.bc.blocks.rows;
let rows = self.bc.blocks.rows();
max_row_offs = self.find_valid_row_offs(max_row_offs, bo.y, rows);
}
......@@ -2605,8 +2605,8 @@ impl<'a> ContextWriter<'a> {
if mv_stack.len() < 2 {
// 7.10.2.12 Extra search process
let w4 = bsize.width_mi().min(16).min(self.bc.blocks.cols - bo.x);
let h4 = bsize.height_mi().min(16).min(self.bc.blocks.rows - bo.y);
let w4 = bsize.width_mi().min(16).min(self.bc.blocks.cols() - bo.x);
let h4 = bsize.height_mi().min(16).min(self.bc.blocks.rows() - bo.y);
let num4x4 = w4.min(h4);
let passes = if up_avail { 0 } else { 1 } .. if left_avail { 2 } else { 1 };
......@@ -2698,9 +2698,9 @@ impl<'a> ContextWriter<'a> {
let border_w = 128 + blk_w as isize * 8;
let border_h = 128 + blk_h as isize * 8;
let mvx_min = -(bo.x as isize) * (8 * MI_SIZE) as isize - border_w;
let mvx_max = (self.bc.blocks.cols - bo.x - blk_w / MI_SIZE) as isize * (8 * MI_SIZE) as isize + border_w;
let mvx_max = (self.bc.blocks.cols() - 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 = (self.bc.blocks.rows - bo.y - blk_h / MI_SIZE) as isize * (8 * MI_SIZE) as isize + border_h;
let mvy_max = (self.bc.blocks.rows() - bo.y - blk_h / MI_SIZE) as isize * (8 * MI_SIZE) as isize + border_h;
mv.this_mv.row = (mv.this_mv.row as isize).max(mvy_min).min(mvy_max) as i16;
mv.this_mv.col = (mv.this_mv.col as isize).max(mvx_min).min(mvx_max) as i16;
mv.comp_mv.row = (mv.comp_mv.row as isize).max(mvy_min).min(mvy_max) as i16;
......
......@@ -1632,7 +1632,7 @@ fn encode_partition_bottomup<T: Pixel>(
part_modes: Vec::new()
};
if tile_bo.x >= cw.bc.blocks.cols || tile_bo.y >= cw.bc.blocks.rows {
if tile_bo.x >= cw.bc.blocks.cols() || tile_bo.y >= cw.bc.blocks.rows() {
return rdo_output
}
......@@ -1837,7 +1837,7 @@ fn encode_partition_topdown<T: Pixel>(
pmvs: &mut [[Option<MotionVector>; REF_FRAMES]; 5]
) {
if tile_bo.x >= cw.bc.blocks.cols || tile_bo.y >= cw.bc.blocks.rows {
if tile_bo.x >= cw.bc.blocks.cols() || tile_bo.y >= cw.bc.blocks.rows() {
return;
}
let bsw = bsize.width_mi();
......@@ -2086,8 +2086,9 @@ fn encode_tile_group<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>)
let mut blocks = FrameBlocks::new(fi.w_in_b, fi.h_in_b);
let mut ts = fs.as_tile_state_mut();
let mut tb = blocks.as_tile_blocks_mut();
let data = encode_tile(fi, &mut ts, &mut fc, &mut blocks);
let data = encode_tile(fi, &mut ts, &mut fc, &mut tb);
/* TODO: Don't apply if lossless */
deblock_filter_optimize(fi, fs, &blocks);
......@@ -2126,11 +2127,11 @@ fn encode_tile_group<T: Pixel>(fi: &FrameInvariants<T>, fs: &mut FrameState<T>)
data
}
fn encode_tile<T: Pixel>(
fn encode_tile<'a, T: Pixel>(
fi: &FrameInvariants<T>,
ts: &mut TileStateMut<'_, T>,
fc: &mut CDFContext,
blocks: &mut FrameBlocks,
fc: &'a mut CDFContext,
blocks: &'a mut TileBlocksMut<'a>,
) -> Vec<u8> {
let mut w = WriterEncoder::new();
......
......@@ -1314,7 +1314,7 @@ pub fn rdo_loop_decision<T: Pixel>(tile_sbo: SuperBlockOffset, fi: &FrameInvaria
// 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.blocks.as_tile_blocks(), sbo_0, tile_sbo, bd))
(input, cdef_analyze_superblock(input, &cw.bc.blocks.as_const(), sbo_0, tile_sbo, bd))
});
let mut first_loop = true;
loop {
......@@ -1327,11 +1327,11 @@ pub fn rdo_loop_decision<T: Pixel>(tile_sbo: SuperBlockOffset, fi: &FrameInvaria
let mut cost = [0.; PLANES];
let mut cost_acc = 0.;
cdef_filter_superblock(fi, &cdef_input, &mut lrf_input,
&cw.bc.blocks.as_tile_blocks(), sbo_0, tile_sbo, cdef_index as u8, &cdef_dirs);
&cw.bc.blocks.as_const(), sbo_0, tile_sbo, cdef_index as u8, &cdef_dirs);
for pli in 0..3 {
match best_lrf[pli] {
RestorationFilter::None{} => {
let err = rdo_loop_plane_error(tile_sbo, fi, ts, &cw.bc.blocks.as_tile_blocks(), &lrf_input, pli);
let err = rdo_loop_plane_error(tile_sbo, fi, ts, &cw.bc.blocks.as_const(), &lrf_input, pli);
let rate = if fi.sequence.enable_restoration {
cw.count_lrf_switchable(w, &ts.restoration.as_const(), best_lrf[pli], pli)
} else {
......@@ -1349,7 +1349,7 @@ pub fn rdo_loop_decision<T: Pixel>(tile_sbo: SuperBlockOffset, fi: &FrameInvaria
&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(tile_sbo, fi, ts, &cw.bc.blocks.as_tile_blocks(), &lrf_output, pli);
let err = rdo_loop_plane_error(tile_sbo, fi, ts, &cw.bc.blocks.as_const(), &lrf_output, pli);
let rate = cw.count_lrf_switchable(w, &ts.restoration.as_const(), best_lrf[pli], pli);
cost[pli] = err as f64 + fi.lambda * rate as f64 / ((1<<OD_BITRES) as f64);
cost_acc += cost[pli];
......@@ -1377,7 +1377,7 @@ pub fn rdo_loop_decision<T: Pixel>(tile_sbo: SuperBlockOffset, fi: &FrameInvaria
// 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.blocks.as_tile_blocks(), sbo_0, tile_sbo, best_index as u8, &cdef_dirs);
&cw.bc.blocks.as_const(), sbo_0, tile_sbo, best_index as u8, &cdef_dirs);
}
// Wiener LRF decision coming soon
......@@ -1404,7 +1404,7 @@ pub fn rdo_loop_decision<T: Pixel>(tile_sbo: SuperBlockOffset, fi: &FrameInvaria
&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(tile_sbo, fi, ts, &cw.bc.blocks.as_tile_blocks(), &lrf_output, pli);
let err = rdo_loop_plane_error(tile_sbo, fi, ts, &cw.bc.blocks.as_const(), &lrf_output, pli);
let rate = cw.count_lrf_switchable(w, &ts.restoration.as_const(), 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