Commit 6b6c2ba8 authored by Romain Vimont's avatar Romain Vimont Committed by Thomas Daede

Use TileRect to fix intra-prediction offsets

The previous commit fixed the confusion between absolute offsets and
offsets relative to the current tile in intra prediction. To do so, it
changed the logic to pass the whole tile as a region, with an additional
block offset.

Instead, pass the region of interest (i.e. restore the previous
behavior) but with an additional TileRect to know the current tile
location.
parent 855b6d06
......@@ -1017,8 +1017,9 @@ pub fn encode_tx_block<T: Pixel>(
skip: bool, ac: &[i16], alpha: i16, rdo_type: RDOType, for_rdo_use: bool
) -> (bool, i64) {
let qidx = get_qidx(fi, ts, cw, tile_bo);
let rec = &mut ts.rec.planes[p];
let PlaneConfig { xdec, ydec, .. } = ts.input.planes[p].cfg;
let tile_rect = ts.tile_rect().decimated(xdec, ydec);
let rec = &mut ts.rec.planes[p];
let area = Area::BlockStartingAt { bo: tile_bo };
assert!(tx_size.sqr() <= TxSize::TX_32X32 || tx_type == TxType::DCT_DCT);
......@@ -1026,7 +1027,7 @@ pub fn encode_tx_block<T: Pixel>(
if mode.is_intra() {
let bit_depth = fi.sequence.bit_depth;
let edge_buf = get_intra_edges(&rec.as_const(), po, tx_size, bit_depth, Some(mode));
mode.predict_intra(rec, tile_bo, tx_size, bit_depth, &ac, alpha, &edge_buf);
mode.predict_intra(tile_rect, &mut rec.subregion_mut(area), tx_size, bit_depth, &ac, alpha, &edge_buf);
}
if skip { return (false, -1); }
......
......@@ -1009,68 +1009,69 @@ pub fn get_intra_edges<T: Pixel>(
impl PredictionMode {
pub fn predict_intra<T: Pixel>(
self, dst: &mut PlaneRegionMut<'_, T>, bo: BlockOffset, tx_size: TxSize, bit_depth: usize,
self, tile_rect: TileRect, dst: &mut PlaneRegionMut<'_, T>, tx_size: TxSize, bit_depth: usize,
ac: &[i16], alpha: i16, edge_buf: &AlignedArray<[T; 4 * MAX_TX_SIZE + 1]>
) {
assert!(self.is_intra());
match tx_size {
TxSize::TX_4X4 =>
self.predict_intra_inner::<Block4x4, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block4x4, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_8X8 =>
self.predict_intra_inner::<Block8x8, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block8x8, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_16X16 =>
self.predict_intra_inner::<Block16x16, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block16x16, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_32X32 =>
self.predict_intra_inner::<Block32x32, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block32x32, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_64X64 =>
self.predict_intra_inner::<Block64x64, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block64x64, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_4X8 =>
self.predict_intra_inner::<Block4x8, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block4x8, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_8X4 =>
self.predict_intra_inner::<Block8x4, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block8x4, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_8X16 =>
self.predict_intra_inner::<Block8x16, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block8x16, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_16X8 =>
self.predict_intra_inner::<Block16x8, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block16x8, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_16X32 =>
self.predict_intra_inner::<Block16x32, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block16x32, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_32X16 =>
self.predict_intra_inner::<Block32x16, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block32x16, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_32X64 =>
self.predict_intra_inner::<Block32x64, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block32x64, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_64X32 =>
self.predict_intra_inner::<Block64x32, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block64x32, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_4X16 =>
self.predict_intra_inner::<Block4x16, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block4x16, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_16X4 =>
self.predict_intra_inner::<Block16x4, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block16x4, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_8X32 =>
self.predict_intra_inner::<Block8x32, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block8x32, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_32X8 =>
self.predict_intra_inner::<Block32x8, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block32x8, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_16X64 =>
self.predict_intra_inner::<Block16x64, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block16x64, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
TxSize::TX_64X16 =>
self.predict_intra_inner::<Block64x16, _>(dst, bo, bit_depth, ac, alpha, edge_buf),
self.predict_intra_inner::<Block64x16, _>(tile_rect, dst, bit_depth, ac, alpha, edge_buf),
}
}
#[inline(always)]
fn predict_intra_inner<B: Intra<T>, T: Pixel>(
self, dst: &mut PlaneRegionMut<'_, T>, tile_bo: BlockOffset,
bit_depth: usize, ac: &[i16], alpha: i16,
edge_buf: &AlignedArray<[T; 4 * MAX_TX_SIZE + 1]>
self, tile_rect: TileRect, dst: &mut PlaneRegionMut<'_, T>, bit_depth: usize, ac: &[i16],
alpha: i16, edge_buf: &AlignedArray<[T; 4 * MAX_TX_SIZE + 1]>
) {
// left pixels are order from bottom to top and right-aligned
let (left, not_left) = edge_buf.array.split_at(2*MAX_TX_SIZE);
let (top_left, above) = not_left.split_at(1);
let BlockOffset { x, y, .. } = tile_bo;
let area = Area::BlockStartingAt { bo: tile_bo };
let dst = &mut dst.subregion_mut(area);
let &Rect { x: frame_x, y: frame_y, .. } = dst.rect();
debug_assert!(frame_x >= 0 && frame_y >= 0);
// x and y are expressed relative to the tile
let x = frame_x as usize - tile_rect.x;
let y = frame_y as usize - tile_rect.y;
let mode: PredictionMode = match self {
PredictionMode::PAETH_PRED => match (x, y) {
......
......@@ -733,10 +733,12 @@ pub fn rdo_mode_decision<T: Pixel>(
intra_mode_set
.iter()
.map(|&luma_mode| {
let tile_rect = ts.tile_rect();
let rec = &mut ts.rec.planes[0];
let mut rec_region = rec.subregion_mut(Area::BlockStartingAt { bo: tile_bo });
luma_mode.predict_intra(
rec,
tile_bo,
tile_rect,
&mut rec_region,
tx_size,
fi.sequence.bit_depth,
&[0i16; 2],
......@@ -745,7 +747,7 @@ pub fn rdo_mode_decision<T: Pixel>(
);
let plane_org = ts.input_tile.planes[0].subregion(Area::BlockStartingAt { bo: tile_bo });
let plane_ref = rec.subregion(Area::BlockStartingAt { bo: tile_bo });
let plane_ref = rec_region.as_const();
(
luma_mode,
......@@ -901,6 +903,8 @@ pub fn rdo_cfl_alpha<T: Pixel>(
luma_ac(&mut ac.array, ts, tile_bo, bsize);
let best_alpha: Vec<i16> = (1..3)
.map(|p| {
let &PlaneConfig { xdec, ydec, .. } = ts.rec.planes[p].plane_cfg;
let tile_rect = ts.tile_rect().decimated(xdec, ydec);
let rec = &mut ts.rec.planes[p];
let input = &ts.input_tile.planes[p];
let po = tile_bo.plane_offset(rec.plane_cfg);
......@@ -914,9 +918,10 @@ pub fn rdo_cfl_alpha<T: Pixel>(
Some(PredictionMode::UV_CFL_PRED)
);
let mut rec_region = rec.subregion_mut(Area::BlockStartingAt { bo: tile_bo });
PredictionMode::UV_CFL_PRED.predict_intra(
rec,
tile_bo,
tile_rect,
&mut rec_region,
uv_tx_size,
bit_depth,
&ac.array,
......@@ -925,7 +930,7 @@ pub fn rdo_cfl_alpha<T: Pixel>(
);
sse_wxh(
&input.subregion(Area::BlockStartingAt { bo: tile_bo }),
&rec.subregion(Area::BlockStartingAt { bo: tile_bo }),
&rec_region.as_const(),
uv_tx_size.width(),
uv_tx_size.height()
)
......
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