Skip to main content

pito_codecs/vp9/enc/pred/
halfpel.rs

1use super::inter::{h_pass, taps, v_pass};
2use super::*;
3
4pub struct HalfPel {
5    planes: [Vec<u8>; 3],
6    stride: usize,
7    origin: usize,
8    width: usize,
9    height: usize,
10    border: usize,
11    filter: u8,
12}
13
14const MARGIN: isize = 8;
15
16impl HalfPel {
17    pub fn new(r: &Plane, filter: u8) -> HalfPel {
18        let mut h = HalfPel {
19            planes: Default::default(),
20            stride: 0,
21            origin: 0,
22            width: 0,
23            height: 0,
24            border: 0,
25            filter,
26        };
27        h.update(r, filter);
28        h
29    }
30
31    pub fn update(&mut self, r: &Plane, filter: u8) {
32        assert!(r.border >= 2 * MARGIN as usize);
33        let rows = r.height + 2 * r.border;
34        let len = rows * r.stride;
35        for p in &mut self.planes {
36            p.resize(len, 0);
37        }
38        (self.stride, self.origin) = (r.stride, r.origin);
39        (self.width, self.height, self.border, self.filter) = (r.width, r.height, r.border, filter);
40        let f = taps(filter, 8);
41        let b = r.border as isize;
42        let first = r.at(-b, -b);
43        let span = r.width + 2 * r.border - 8;
44        let xs = (0..span).step_by(64).map(|x| x.min(span - 64));
45        let [hp, vp, hvp] = &mut self.planes;
46        let s = r.stride;
47        let vrows = rows - 8;
48        for x in xs.clone() {
49            h_pass(
50                r.data,
51                s,
52                first + x,
53                64,
54                rows - 1,
55                f,
56                &mut hp[first + x + 3..],
57                s,
58            );
59        }
60        for x in xs.clone() {
61            v_pass(
62                r.data,
63                s,
64                first + x + 3,
65                64,
66                vrows,
67                f,
68                &mut vp[first + 3 * s + x + 3..],
69                s,
70            );
71        }
72        for x in xs {
73            v_pass(
74                hp,
75                s,
76                first + x + 3,
77                64,
78                vrows,
79                f,
80                &mut hvp[first + 3 * s + x + 3..],
81                s,
82            );
83        }
84    }
85
86    pub fn filter(&self) -> u8 {
87        self.filter
88    }
89
90    pub fn covers(&self, x: isize, y: isize, w: usize, h: usize) -> bool {
91        let b = self.border as isize - MARGIN;
92        x >= -b
93            && y >= -b
94            && x + w as isize <= self.width as isize + b
95            && y + h as isize <= self.height as isize + b
96    }
97
98    pub fn at(&self, x16: isize, y16: isize) -> Option<(&[u8], usize)> {
99        let (fx, fy) = (x16 & 15, y16 & 15);
100        let k = match (fx, fy) {
101            (8, 0) => 0,
102            (0, 8) => 1,
103            (8, 8) => 2,
104            _ => return None,
105        };
106        let o = (self.origin as isize + (y16 >> 4) * self.stride as isize + (x16 >> 4)) as usize;
107        Some((&self.planes[k][o..], self.stride))
108    }
109}