Skip to content

Commit

Permalink
fn {{,w_}avg,mask,blend{,_v,_h}_{c => rust}: Deduplicate w/ generic…
Browse files Browse the repository at this point in the history
…s and cleanup/re-translate (#340)

I had these from when I was working off of #322. They're now rebased on
`main` and I want to get them merged before I forget too much about
them. After deduplicating `mc.rs`'s `fn`s with `BitDepth` generics, I'll
deduplicate its `fn` ptrs with type erasure.
  • Loading branch information
kkysen authored Jul 25, 2023
2 parents 6e44048 + 8ede03c commit b156be6
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 299 deletions.
5 changes: 4 additions & 1 deletion include/common/bitdepth.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::ffi::{c_int, c_uint};
use std::fmt::{self, Display, Formatter};
use std::ops::Add;
use std::ops::{Add, Mul, Shr};

use crate::include::common::intops::clip;

Expand Down Expand Up @@ -77,6 +77,9 @@ pub trait BitDepth: Clone + Copy {

type Pixel: Copy
+ Ord
+ Add<Output = Self::Pixel>
+ Mul<Output = Self::Pixel>
+ Shr<u8, Output = Self::Pixel>
+ From<u8>
+ Into<i32>
+ TryFrom<i32>
Expand Down
165 changes: 165 additions & 0 deletions src/mc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::iter;
use crate::include::common::bitdepth::{AsPrimitive, BitDepth};
use crate::include::dav1d::headers::Dav1dFilterMode;
use crate::src::tables::dav1d_mc_subpel_filters;
use crate::src::tables::dav1d_obmc_masks;

// TODO(kkysen) temporarily `pub` until `mc` callers are deduplicated
#[inline(never)]
Expand Down Expand Up @@ -661,3 +662,167 @@ pub unsafe fn prep_bilin_scaled_rust<BD: BitDepth>(
tmp = tmp.offset(w as isize);
}
}

// TODO(kkysen) temporarily `pub` until `mc` callers are deduplicated
pub unsafe fn avg_rust<BD: BitDepth>(
mut dst: *mut BD::Pixel,
dst_stride: usize,
mut tmp1: *const i16,
mut tmp2: *const i16,
w: usize,
h: usize,
bd: BD,
) {
let intermediate_bits = bd.get_intermediate_bits();
let sh = intermediate_bits + 1;
let rnd = (1 << intermediate_bits) + i32::from(BD::PREP_BIAS) * 2;
let dst_stride = BD::pxstride(dst_stride);
for _ in 0..h {
for x in 0..w {
*dst.offset(x as isize) = bd.iclip_pixel(
((*tmp1.offset(x as isize) as i32 + *tmp2.offset(x as isize) as i32 + rnd) >> sh)
.into(),
);
}

tmp1 = tmp1.offset(w as isize);
tmp2 = tmp2.offset(w as isize);
dst = dst.offset(dst_stride as isize);
}
}

// TODO(kkysen) temporarily `pub` until `mc` callers are deduplicated
pub unsafe fn w_avg_rust<BD: BitDepth>(
mut dst: *mut BD::Pixel,
dst_stride: usize,
mut tmp1: *const i16,
mut tmp2: *const i16,
w: usize,
h: usize,
weight: i32,
bd: BD,
) {
let intermediate_bits = bd.get_intermediate_bits();
let sh = intermediate_bits + 4;
let rnd = (8 << intermediate_bits) + i32::from(BD::PREP_BIAS) * 16;
let dst_stride = BD::pxstride(dst_stride);
for _ in 0..h {
for x in 0..w {
*dst.offset(x as isize) = bd.iclip_pixel(
(*tmp1.offset(x as isize) as i32 * weight
+ *tmp2.offset(x as isize) as i32 * (16 - weight)
+ rnd)
>> sh,
);
}

tmp1 = tmp1.offset(w as isize);
tmp2 = tmp2.offset(w as isize);
dst = dst.offset(dst_stride as isize);
}
}

// TODO(kkysen) temporarily `pub` until `mc` callers are deduplicated
pub unsafe fn mask_rust<BD: BitDepth>(
mut dst: *mut BD::Pixel,
dst_stride: usize,
mut tmp1: *const i16,
mut tmp2: *const i16,
w: usize,
h: usize,
mut mask: *const u8,
bd: BD,
) {
let intermediate_bits = bd.get_intermediate_bits();
let sh = intermediate_bits + 6;
let rnd = (32 << intermediate_bits) + i32::from(BD::PREP_BIAS) * 64;
let dst_stride = BD::pxstride(dst_stride);
for _ in 0..h {
for x in 0..w {
*dst.offset(x as isize) = bd.iclip_pixel(
(*tmp1.offset(x as isize) as i32 * *mask.offset(x as isize) as i32
+ *tmp2.offset(x as isize) as i32 * (64 - *mask.offset(x as isize) as i32)
+ rnd)
>> sh,
);
}

tmp1 = tmp1.offset(w as isize);
tmp2 = tmp2.offset(w as isize);
mask = mask.offset(w as isize);
dst = dst.offset(dst_stride as isize);
}
}

fn blend_px<BD: BitDepth>(a: BD::Pixel, b: BD::Pixel, m: u8) -> BD::Pixel {
let m = m as u32;
((a.as_::<u32>() * (64 - m) + b.as_::<u32>() * m + 32) >> 6).as_::<BD::Pixel>()
}

// TODO(kkysen) temporarily `pub` until `mc` callers are deduplicated
pub unsafe fn blend_rust<BD: BitDepth>(
mut dst: *mut BD::Pixel,
dst_stride: usize,
mut tmp: *const BD::Pixel,
w: usize,
h: usize,
mut mask: *const u8,
) {
let dst_stride = BD::pxstride(dst_stride);
for _ in 0..h {
for x in 0..w {
*dst.offset(x as isize) = blend_px::<BD>(
*dst.offset(x as isize),
*tmp.offset(x as isize),
*mask.offset(x as isize),
)
}

dst = dst.offset(dst_stride as isize);
tmp = tmp.offset(w as isize);
mask = mask.offset(w as isize);
}
}

// TODO(kkysen) temporarily `pub` until `mc` callers are deduplicated
pub unsafe fn blend_v_rust<BD: BitDepth>(
mut dst: *mut BD::Pixel,
dst_stride: usize,
mut tmp: *const BD::Pixel,
w: usize,
h: usize,
) {
let mask = &dav1d_obmc_masks.0[w..];
let dst_stride = BD::pxstride(dst_stride);
for _ in 0..h {
for x in 0..(w * 3 >> 2) {
*dst.offset(x as isize) =
blend_px::<BD>(*dst.offset(x as isize), *tmp.offset(x as isize), mask[x])
}

dst = dst.offset(dst_stride as isize);
tmp = tmp.offset(w as isize);
}
}

// TODO(kkysen) temporarily `pub` until `mc` callers are deduplicated
pub unsafe fn blend_h_rust<BD: BitDepth>(
mut dst: *mut BD::Pixel,
dst_stride: usize,
mut tmp: *const BD::Pixel,
w: usize,
h: usize,
) {
let mask = &dav1d_obmc_masks.0[h..];
let h = h * 3 >> 2;
let dst_stride = BD::pxstride(dst_stride);
for y in 0..h {
for x in 0..w {
*dst.offset(x as isize) =
blend_px::<BD>(*dst.offset(x as isize), *tmp.offset(x as isize), mask[y]);
}

dst = dst.offset(dst_stride as isize);
tmp = tmp.offset(w as isize);
}
}
Loading

0 comments on commit b156be6

Please sign in to comment.