Commit b8063c41 authored by Romain Vimont's avatar Romain Vimont Committed by Romain Vimont

Pass plane and offset to get_intra_edges()

In order to guarantee that a slice never exceeds its parent,
EdgedPlaneSlice was introduced by #1082.

However, it added complexity, and happens to be insufficient to adapt
get_intra_edges() for tiling (we can't retrieve the tile dimensions).

Instead, pass both the Plane (in the future, the plane region associated
with the tile) and the plane offset. It's simpler, and it still does not
require a slice to exceed its parent.
parent 74edd383
......@@ -975,13 +975,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.edged_slice(po, 1, 1),
tx_size,
bit_depth,
&fs.input.planes[p].cfg,
Some(mode),
);
let edge_buf = get_intra_edges(rec, po, tx_size, bit_depth, Some(mode));
mode.predict_intra(&mut rec.mut_slice(po), tx_size, bit_depth, &ac, alpha, &edge_buf);
}
......
......@@ -851,15 +851,14 @@ pub enum MvJointType {
}
pub fn get_intra_edges<T: Pixel>(
dst: &EdgedPlaneSlice<'_, T>,
dst: &Plane<T>,
po: PlaneOffset,
tx_size: TxSize,
bit_depth: usize,
plane_cfg: &PlaneConfig,
opt_mode: Option<PredictionMode>
) -> AlignedArray<[T; 4 * MAX_TX_SIZE + 1]> {
let (left_edge, top_edge) = (dst.left_edge, dst.top_edge);
debug_assert!(left_edge <= 1);
debug_assert!(top_edge <= 1);
let plane_cfg = &dst.cfg;
let dst = dst.as_slice();
let mut edge_buf: AlignedArray<[T; 4 * MAX_TX_SIZE + 1]> =
UninitializedAlignedArray();
......@@ -870,9 +869,8 @@ pub fn get_intra_edges<T: Pixel>(
let (left, not_left) = edge_buf.array.split_at_mut(2*MAX_TX_SIZE);
let (top_left, above) = not_left.split_at_mut(1);
let dst_content = dst.without_edges();
let x = dst_content.x as usize;
let y = dst_content.y as usize;
let x = po.x as usize;
let y = po.y as usize;
let mut needs_left = true;
let mut needs_topleft = true;
......@@ -882,7 +880,7 @@ pub fn get_intra_edges<T: Pixel>(
if let Some(mut mode) = opt_mode {
mode = match mode {
PredictionMode::PAETH_PRED => match (left_edge, top_edge) {
PredictionMode::PAETH_PRED => match (x, y) {
(0, 0) => PredictionMode::DC_PRED,
(_, 0) => PredictionMode::H_PRED,
(0, _) => PredictionMode::V_PRED,
......@@ -894,23 +892,23 @@ pub fn get_intra_edges<T: Pixel>(
let dc_or_cfl =
mode == PredictionMode::DC_PRED || mode == PredictionMode::UV_CFL_PRED;
needs_left = mode != PredictionMode::V_PRED && (!dc_or_cfl || left_edge != 0)
needs_left = mode != PredictionMode::V_PRED && (!dc_or_cfl || x != 0)
&& !(mode == PredictionMode::D45_PRED || mode == PredictionMode::D63_PRED);
needs_topleft = mode == PredictionMode::PAETH_PRED || mode == PredictionMode::D117_PRED
|| mode == PredictionMode::D135_PRED || mode == PredictionMode::D153_PRED;
needs_top = mode != PredictionMode::H_PRED && (!dc_or_cfl || top_edge != 0);
needs_top = mode != PredictionMode::H_PRED && (!dc_or_cfl || y != 0);
needs_topright = mode == PredictionMode::D45_PRED || mode == PredictionMode::D63_PRED;
needs_bottomleft = mode == PredictionMode::D207_PRED;
}
// Needs left
if needs_left {
if left_edge != 0 {
if x != 0 {
for i in 0..tx_size.height() {
left[2*MAX_TX_SIZE - tx_size.height() + i] = dst.ps[top_edge + tx_size.height() - 1 - i][0];
left[2*MAX_TX_SIZE - tx_size.height() + i] = dst[y + tx_size.height() - 1 - i][x - 1];
}
} else {
let val = if top_edge != 0 { dst.ps[0][0] } else { T::cast_from(base + 1) };
let val = if y != 0 { dst[y - 1][0] } else { T::cast_from(base + 1) };
for v in left[2*MAX_TX_SIZE - tx_size.height()..].iter_mut() {
*v = val
}
......@@ -919,18 +917,20 @@ pub fn get_intra_edges<T: Pixel>(
// Needs top-left
if needs_topleft {
top_left[0] = match (left_edge, top_edge) {
top_left[0] = match (x, y) {
(0, 0) => T::cast_from(base),
_ => dst.ps[0][0],
(_, 0) => dst[0][x - 1],
(0, _) => dst[y - 1][0],
_ => dst[y - 1][x - 1],
};
}
// Needs top
if needs_top {
if top_edge != 0 {
above[..tx_size.width()].copy_from_slice(&dst.ps[0][left_edge..left_edge + tx_size.width()]);
if y != 0 {
above[..tx_size.width()].copy_from_slice(&dst[y - 1][x..x + tx_size.width()]);
} else {
let val = if left_edge != 0 { dst.ps[0][0] } else { T::cast_from(base - 1) };
let val = if x != 0 { dst[0][x - 1] } else { T::cast_from(base - 1) };
for v in above[..tx_size.width()].iter_mut() {
*v = val;
}
......@@ -951,14 +951,14 @@ pub fn get_intra_edges<T: Pixel>(
tx_size.height() << plane_cfg.ydec
);
let num_avail = if top_edge != 0 && has_tr(bo, bsize) {
let num_avail = if y != 0 && has_tr(bo, bsize) {
tx_size.width().min(plane_cfg.width - x - tx_size.width())
} else {
0
};
if num_avail > 0 {
above[tx_size.width()..tx_size.width() + num_avail]
.copy_from_slice(&dst.ps[0][left_edge + tx_size.width()..left_edge + tx_size.width() + num_avail]);
.copy_from_slice(&dst[y - 1][x + tx_size.width()..x + tx_size.width() + num_avail]);
}
if num_avail < tx_size.height() {
let val = above[tx_size.width() + num_avail - 1];
......@@ -982,14 +982,14 @@ pub fn get_intra_edges<T: Pixel>(
tx_size.height() << plane_cfg.ydec
);
let num_avail = if left_edge != 0 && has_bl(bo, bsize) {
let num_avail = if x != 0 && has_bl(bo, bsize) {
tx_size.height().min(plane_cfg.height - y - tx_size.height())
} else {
0
};
if num_avail > 0 {
for i in 0..num_avail {
left[2*MAX_TX_SIZE - tx_size.height() - 1 - i] = dst.ps[top_edge + tx_size.height() + i][0];
left[2*MAX_TX_SIZE - tx_size.height() - 1 - i] = dst[y + tx_size.height() + i][x - 1];
}
}
if num_avail < tx_size.width() {
......
......@@ -730,15 +730,9 @@ pub fn rdo_mode_decision<T: Pixel>(
let intra_mode_set = RAV1E_INTRA_MODES;
let mut sads = {
let edge_buf = {
let rec = &mut fs.rec.planes[0];
let rec = &fs.rec.planes[0];
let po = bo.plane_offset(&rec.cfg);
get_intra_edges(
&rec.edged_slice(po, 1, 1),
tx_size,
fi.sequence.bit_depth,
&fs.input.planes[0].cfg,
None
)
get_intra_edges(rec, po, tx_size, fi.sequence.bit_depth, None)
};
intra_mode_set
.iter()
......@@ -918,10 +912,10 @@ pub fn rdo_cfl_alpha<T: Pixel>(
(-16i16..17i16)
.min_by_key(|&alpha| {
let edge_buf = get_intra_edges(
&rec.edged_slice(po, 1, 1),
rec,
po,
uv_tx_size,
bit_depth,
&input.cfg,
Some(PredictionMode::UV_CFL_PRED)
);
PredictionMode::UV_CFL_PRED.predict_intra(
......
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