pito_codecs/vp9/enc/pred/
halfpel.rs1use 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}