| 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 | |