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