1 | // Copyright (c) 2019-2022, The rav1e contributors. All rights reserved |
2 | // |
3 | // This source code is subject to the terms of the BSD 2 Clause License and |
4 | // the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
5 | // was not distributed with this source code in the LICENSE file, you can |
6 | // obtain it at www.aomedia.org/license/software. If the Alliance for Open |
7 | // Media Patent License 1.0 was not distributed with this source code in the |
8 | // PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
9 | |
10 | use crate::mc::MotionVector; |
11 | use crate::me::*; |
12 | |
13 | use std::marker::PhantomData; |
14 | use std::ops::{Index, IndexMut}; |
15 | use std::slice; |
16 | |
17 | /// Tiled view of `FrameMEStats` |
18 | #[derive (Debug)] |
19 | pub struct TileMEStats<'a> { |
20 | data: *const MEStats, |
21 | // expressed in mi blocks |
22 | // private to guarantee borrowing rules |
23 | x: usize, |
24 | y: usize, |
25 | cols: usize, |
26 | rows: usize, |
27 | /// number of cols in the underlying `FrameMEStats` |
28 | stride: usize, |
29 | phantom: PhantomData<&'a MotionVector>, |
30 | } |
31 | |
32 | /// Mutable tiled view of `FrameMEStats` |
33 | #[derive (Debug)] |
34 | pub struct TileMEStatsMut<'a> { |
35 | data: *mut MEStats, |
36 | // expressed in mi blocks |
37 | // private to guarantee borrowing rules |
38 | x: usize, |
39 | y: usize, |
40 | cols: usize, |
41 | rows: usize, |
42 | /// number of cols in the underlying `FrameMEStats` |
43 | stride: usize, |
44 | phantom: PhantomData<&'a mut MotionVector>, |
45 | } |
46 | |
47 | // common impl for TileMotionVectors and TileMotionVectorsMut |
48 | macro_rules! tile_me_stats_common { |
49 | // $name: TileMEStats or TileMEStatsMut |
50 | // $opt_mut: nothing or mut |
51 | ($name:ident $(,$opt_mut:tt)?) => { |
52 | impl<'a> $name<'a> { |
53 | |
54 | /// # Panics |
55 | /// |
56 | /// - If the requested dimensions are larger than the frame MV size |
57 | #[inline(always)] |
58 | pub fn new( |
59 | frame_mvs: &'a $($opt_mut)? FrameMEStats, |
60 | x: usize, |
61 | y: usize, |
62 | cols: usize, |
63 | rows: usize, |
64 | ) -> Self { |
65 | assert!(x + cols <= frame_mvs.cols); |
66 | assert!(y + rows <= frame_mvs.rows); |
67 | Self { |
68 | data: & $($opt_mut)? frame_mvs[y][x], |
69 | x, |
70 | y, |
71 | cols, |
72 | rows, |
73 | stride: frame_mvs.cols, |
74 | phantom: PhantomData, |
75 | } |
76 | } |
77 | |
78 | #[inline(always)] |
79 | pub const fn x(&self) -> usize { |
80 | self.x |
81 | } |
82 | |
83 | #[inline(always)] |
84 | pub const fn y(&self) -> usize { |
85 | self.y |
86 | } |
87 | |
88 | #[inline(always)] |
89 | pub const fn cols(&self) -> usize { |
90 | self.cols |
91 | } |
92 | |
93 | #[inline(always)] |
94 | pub const fn rows(&self) -> usize { |
95 | self.rows |
96 | } |
97 | } |
98 | |
99 | unsafe impl Send for $name<'_> {} |
100 | unsafe impl Sync for $name<'_> {} |
101 | |
102 | impl Index<usize> for $name<'_> { |
103 | type Output = [MEStats]; |
104 | |
105 | #[inline(always)] |
106 | fn index(&self, index: usize) -> &Self::Output { |
107 | assert!(index < self.rows); |
108 | // SAFETY: The above assert ensures we do not access OOB data. |
109 | unsafe { |
110 | let ptr = self.data.add(index * self.stride); |
111 | slice::from_raw_parts(ptr, self.cols) |
112 | } |
113 | } |
114 | } |
115 | } |
116 | } |
117 | |
118 | tile_me_stats_common!(TileMEStats); |
119 | tile_me_stats_common!(TileMEStatsMut, mut); |
120 | |
121 | impl TileMEStatsMut<'_> { |
122 | #[inline (always)] |
123 | pub const fn as_const(&self) -> TileMEStats<'_> { |
124 | TileMEStats { |
125 | data: self.data, |
126 | x: self.x, |
127 | y: self.y, |
128 | cols: self.cols, |
129 | rows: self.rows, |
130 | stride: self.stride, |
131 | phantom: PhantomData, |
132 | } |
133 | } |
134 | } |
135 | |
136 | impl IndexMut<usize> for TileMEStatsMut<'_> { |
137 | #[inline (always)] |
138 | fn index_mut(&mut self, index: usize) -> &mut Self::Output { |
139 | assert!(index < self.rows); |
140 | // SAFETY: The above assert ensures we do not access OOB data. |
141 | unsafe { |
142 | let ptr: *mut MEStats = self.data.add(count:index * self.stride); |
143 | slice::from_raw_parts_mut(data:ptr, self.cols) |
144 | } |
145 | } |
146 | } |
147 | |