Skip to content

Commit

Permalink
fn padding: Deduplicate w/ generics and cleanup (#330)
Browse files Browse the repository at this point in the history
Deduplicate `padding` into `looprestoration.rs` and make it generic over
bitdepth.
  • Loading branch information
randomPoison authored Jul 24, 2023
1 parent d6ec80e commit b30108e
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 379 deletions.
158 changes: 158 additions & 0 deletions src/looprestoration.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::include::common::bitdepth::BitDepth;
use crate::include::stddef::ptrdiff_t;
use crate::include::stdint::int16_t;
use crate::include::stdint::uint32_t;
Expand Down Expand Up @@ -136,3 +137,160 @@ decl_looprestorationfilter_fns! {
fn dav1d_wiener_filter7_16bpc_neon,
fn dav1d_wiener_filter5_16bpc_neon,
}

// 256 * 1.5 + 3 + 3 = 390
const REST_UNIT_STRIDE: usize = 390;

// TODO Reuse p when no padding is needed (add and remove lpf pixels in p)
// TODO Chroma only requires 2 rows of padding.
// TODO(randomPoison): Temporarily pub until remaining looprestoration fns have
// been deduplicated.
#[inline(never)]
pub(crate) unsafe fn padding<BD: BitDepth>(
mut dst: &mut [BD::Pixel; 70 /*(64 + 3 + 3)*/ * REST_UNIT_STRIDE],
mut p: *const BD::Pixel,
stride: ptrdiff_t,
mut left: *const [BD::Pixel; 4],
mut lpf: *const BD::Pixel,
mut unit_w: libc::c_int,
stripe_h: libc::c_int,
edges: LrEdgeFlags,
) {
let stride = BD::pxstride(stride as usize);

let have_left = (edges & LR_HAVE_LEFT != 0) as libc::c_int;
let have_right = (edges & LR_HAVE_RIGHT != 0) as libc::c_int;

// Copy more pixels if we don't have to pad them
unit_w += 3 * have_left + 3 * have_right;
let mut dst_l = &mut dst[(3 * (have_left == 0) as libc::c_int) as usize..];
p = p.offset(-((3 * have_left) as isize));
lpf = lpf.offset(-((3 * have_left) as isize));

if edges & LR_HAVE_TOP != 0 {
// Copy previous loop filtered rows
let above_1 = std::slice::from_raw_parts(lpf, stride + unit_w as usize);
let above_2 = &above_1[stride..];

BD::pixel_copy(dst_l, above_1, unit_w as usize);
BD::pixel_copy(&mut dst_l[REST_UNIT_STRIDE..], above_1, unit_w as usize);
BD::pixel_copy(&mut dst_l[2 * REST_UNIT_STRIDE..], above_2, unit_w as usize);
} else {
// Pad with first row
let p = std::slice::from_raw_parts(p, unit_w as usize);

BD::pixel_copy(dst_l, p, unit_w as usize);
BD::pixel_copy(&mut dst_l[REST_UNIT_STRIDE..], p, unit_w as usize);
BD::pixel_copy(&mut dst_l[2 * REST_UNIT_STRIDE..], p, unit_w as usize);

if have_left != 0 {
let left = &(*left.offset(0))[1..];
BD::pixel_copy(dst_l, left, 3);
BD::pixel_copy(&mut dst_l[REST_UNIT_STRIDE..], left, 3);
BD::pixel_copy(&mut dst_l[2 * REST_UNIT_STRIDE..], left, 3);
}
}

let mut dst_tl = &mut dst_l[3 * REST_UNIT_STRIDE..];
if edges & LR_HAVE_BOTTOM != 0 {
// Copy next loop filtered rows
let below_1 = std::slice::from_raw_parts(lpf.offset(6 * stride as isize), unit_w as usize);
let below_2 = std::slice::from_raw_parts(lpf.offset(7 * stride as isize), unit_w as usize);

BD::pixel_copy(
&mut dst_tl[stripe_h as usize * REST_UNIT_STRIDE..],
below_1,
unit_w as usize,
);
BD::pixel_copy(
&mut dst_tl[(stripe_h + 1) as usize * REST_UNIT_STRIDE..],
below_2,
unit_w as usize,
);
BD::pixel_copy(
&mut dst_tl[(stripe_h + 2) as usize * REST_UNIT_STRIDE..],
below_2,
unit_w as usize,
);
} else {
// Pad with last row
let src = std::slice::from_raw_parts(
p.offset(((stripe_h - 1) as isize * stride as isize) as isize),
unit_w as usize,
);

BD::pixel_copy(
&mut dst_tl[stripe_h as usize * REST_UNIT_STRIDE..],
src,
unit_w as usize,
);
BD::pixel_copy(
&mut dst_tl[(stripe_h + 1) as usize * REST_UNIT_STRIDE..],
src,
unit_w as usize,
);
BD::pixel_copy(
&mut dst_tl[(stripe_h + 2) as usize * REST_UNIT_STRIDE..],
src,
unit_w as usize,
);

if have_left != 0 {
let left = &(*left.offset((stripe_h - 1) as isize))[1..];

BD::pixel_copy(&mut dst_tl[stripe_h as usize * REST_UNIT_STRIDE..], left, 3);
BD::pixel_copy(
&mut dst_tl[(stripe_h + 1) as usize * REST_UNIT_STRIDE..],
left,
3,
);
BD::pixel_copy(
&mut dst_tl[(stripe_h + 2) as usize * REST_UNIT_STRIDE..],
left,
3,
);
}
}

// Inner UNIT_WxSTRIPE_H
let len = (unit_w - 3 * have_left) as usize;
for j in 0..stripe_h as usize {
let p = std::slice::from_raw_parts(
p.offset((j * stride + 3 * have_left as usize) as isize),
len,
);
BD::pixel_copy(
&mut dst_tl[j * REST_UNIT_STRIDE + (3 * have_left) as usize..],
p,
len,
);
}

if have_right == 0 {
// Pad 3x(STRIPE_H+6) with last column
for j in 0..stripe_h as usize + 6 {
let mut row_last = dst_l[(unit_w - 1) as usize + j * REST_UNIT_STRIDE];
let mut pad = &mut dst_l[unit_w as usize + j * REST_UNIT_STRIDE..];
BD::pixel_set(pad, row_last, 3);
}
}

if have_left == 0 {
// Pad 3x(STRIPE_H+6) with first column
for j in 0..stripe_h as usize + 6 {
let offset = j * REST_UNIT_STRIDE;
let val = dst[3 + offset];
BD::pixel_set(&mut dst[offset..], val, 3);
}
} else {
let dst = &mut dst[3 * REST_UNIT_STRIDE..];

for j in 0..stripe_h as usize {
BD::pixel_copy(
&mut dst[j * REST_UNIT_STRIDE..],
&(*left.offset(j as isize))[1..],
3,
);
}
};
}
Loading

0 comments on commit b30108e

Please sign in to comment.