1 // Copyright (c) 2019-2020, 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   stride: usize, // number of cols in the underlying FrameMEStats
28   phantom: PhantomData<&'a MotionVector>,
29 }
30 
31 /// Mutable tiled view of FrameMEStats
32 #[derive(Debug)]
33 pub struct TileMEStatsMut<'a> {
34   data: *mut MEStats,
35   // expressed in mi blocks
36   // private to guarantee borrowing rules
37   x: usize,
38   y: usize,
39   cols: usize,
40   rows: usize,
41   stride: usize, // number of cols in the underlying FrameMEStats
42   phantom: PhantomData<&'a mut MotionVector>,
43 }
44 
45 // common impl for TileMotionVectors and TileMotionVectorsMut
46 macro_rules! tile_me_stats_common {
47   // $name: TileMEStats or TileMEStatsMut
48   // $opt_mut: nothing or mut
49   ($name:ident $(,$opt_mut:tt)?) => {
50     impl<'a> $name<'a> {
51 
52       #[inline(always)]
53       pub fn new(
54         frame_mvs: &'a $($opt_mut)? FrameMEStats,
55         x: usize,
56         y: usize,
57         cols: usize,
58         rows: usize,
59       ) -> Self {
60         assert!(x + cols <= frame_mvs.cols);
61         assert!(y + rows <= frame_mvs.rows);
62         Self {
63           data: & $($opt_mut)? frame_mvs[y][x],
64           x,
65           y,
66           cols,
67           rows,
68           stride: frame_mvs.cols,
69           phantom: PhantomData,
70         }
71       }
72 
73       #[inline(always)]
74       pub const fn x(&self) -> usize {
75         self.x
76       }
77 
78       #[inline(always)]
79       pub const fn y(&self) -> usize {
80         self.y
81       }
82 
83       #[inline(always)]
84       pub const fn cols(&self) -> usize {
85         self.cols
86       }
87 
88       #[inline(always)]
89       pub const fn rows(&self) -> usize {
90         self.rows
91       }
92     }
93 
94     unsafe impl Send for $name<'_> {}
95     unsafe impl Sync for $name<'_> {}
96 
97     impl Index<usize> for $name<'_> {
98       type Output = [MEStats];
99 
100       #[inline(always)]
101       fn index(&self, index: usize) -> &Self::Output {
102         assert!(index < self.rows);
103         unsafe {
104           let ptr = self.data.add(index * self.stride);
105           slice::from_raw_parts(ptr, self.cols)
106         }
107       }
108     }
109   }
110 }
111 
112 tile_me_stats_common!(TileMEStats);
113 tile_me_stats_common!(TileMEStatsMut, mut);
114 
115 impl TileMEStatsMut<'_> {
116   #[inline(always)]
as_const(&self) -> TileMEStats<'_>117   pub const fn as_const(&self) -> TileMEStats<'_> {
118     TileMEStats {
119       data: self.data,
120       x: self.x,
121       y: self.y,
122       cols: self.cols,
123       rows: self.rows,
124       stride: self.stride,
125       phantom: PhantomData,
126     }
127   }
128 }
129 
130 impl IndexMut<usize> for TileMEStatsMut<'_> {
131   #[inline(always)]
index_mut(&mut self, index: usize) -> &mut Self::Output132   fn index_mut(&mut self, index: usize) -> &mut Self::Output {
133     assert!(index < self.rows);
134     unsafe {
135       let ptr = self.data.add(index * self.stride);
136       slice::from_raw_parts_mut(ptr, self.cols)
137     }
138   }
139 }
140