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
10use crate::mc::MotionVector;
11use crate::me::*;
12
13use std::marker::PhantomData;
14use std::ops::{Index, IndexMut};
15use std::slice;
16
17/// Tiled view of `FrameMEStats`
18#[derive(Debug)]
19pub 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)]
34pub 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
48macro_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
118tile_me_stats_common!(TileMEStats);
119tile_me_stats_common!(TileMEStatsMut, mut);
120
121impl 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
136impl 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