Skip to content
Snippets Groups Projects
Commit a991c689 authored by Luca Barbato's avatar Luca Barbato Committed by Luca Barbato
Browse files

Provide iterators for PlaneSlices

And use it to compute SAD.
parent 0b1a873d
No related branches found
No related tags found
No related merge requests found
......@@ -51,6 +51,26 @@ fn bench_get_sad(b: &mut Bencher, bs: &BlockSize) {
})
}
fn bench_get_sad_iter(b: &mut Bencher, bs: &BlockSize) {
let mut ra = ChaChaRng::from_seed([0; 32]);
let bsw = bs.width();
let bsh = bs.height();
let w = 640;
let h = 480;
let input_plane = new_plane(&mut ra, w, h);
let rec_plane = new_plane(&mut ra, w, h);
let po = PlaneOffset { x: 0, y: 0 };
let mut plane_org = input_plane.slice(&po);
let mut plane_ref = rec_plane.slice(&po);
b.iter(|| {
let _ = me::get_sad_iter(&mut plane_org, &mut plane_ref, bsw, bsh);
plane_org.y = 0;
plane_ref.y = 0;
})
}
pub fn get_sad(c: &mut Criterion) {
use partition::BlockSize::*;
let blocks = vec![
......@@ -78,5 +98,6 @@ pub fn get_sad(c: &mut Criterion) {
BLOCK_64X16,
];
c.bench_function_over_inputs("get_sad", bench_get_sad, blocks);
c.bench_function_over_inputs("get_sad", bench_get_sad, blocks.clone());
c.bench_function_over_inputs("get_sad_iter", bench_get_sad_iter, blocks);
}
......@@ -39,6 +39,26 @@ pub fn get_sad(
sum
}
#[inline(always)]
pub fn get_sad_iter(
plane_org: &mut PlaneSlice, plane_ref: &mut PlaneSlice, blk_h: usize,
blk_w: usize
) -> u32 {
let mut sum = 0 as u32;
let org_iter = plane_org.iter_width(blk_w);
let ref_iter = plane_ref.iter_width(blk_w);
for (slice_org, slice_ref) in org_iter.take(blk_h).zip(ref_iter) {
sum += slice_org
.iter()
.zip(slice_ref)
.map(|(&a, &b)| (a as i32 - b as i32).abs() as u32)
.sum::<u32>();
}
sum
}
pub fn motion_estimation(
fi: &FrameInvariants, fs: &FrameState, bsize: BlockSize,
bo: &BlockOffset, ref_frame: usize, pmv: &MotionVector
......
......@@ -220,12 +220,38 @@ impl Plane {
}
}
#[derive(Clone, Copy)]
pub struct PlaneSlice<'a> {
pub plane: &'a Plane,
pub x: isize,
pub y: isize
}
pub struct IterWidth<'a> {
ps: PlaneSlice<'a>,
width: usize,
}
// TODO: Implement more methods
impl<'a> Iterator for IterWidth<'a> {
type Item = &'a [u16];
#[inline]
fn next(&mut self) -> Option<&'a [u16]> {
let x = self.ps.plane.cfg.xorigin + self.ps.x;
let y = self.ps.plane.cfg.yorigin + self.ps.y;
let stride = self.ps.plane.cfg.stride;
let base = y as usize * stride + x as usize;
if self.ps.plane.data.len() < base + self.width {
None
} else {
self.ps.y += 1;
Some(&self.ps.plane.data[base..base + self.width])
}
}
}
impl<'a> PlaneSlice<'a> {
pub fn as_slice(&'a self) -> &'a [u16] {
let stride = self.plane.cfg.stride;
......@@ -252,6 +278,10 @@ impl<'a> PlaneSlice<'a> {
&self.plane.data[base..base + width]
}
pub fn iter_width(&self, width: usize) -> IterWidth<'a> {
IterWidth { ps: *self, width }
}
pub fn subslice(&'a self, xo: usize, yo: usize) -> PlaneSlice<'a> {
PlaneSlice {
plane: self.plane,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment