1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use num_derive::FromPrimitive;
use crate::api::ChromaSampling;
use crate::context::SB_SIZE;
use crate::mc::SUBPEL_FILTER_SIZE;
use crate::util::*;
use crate::tiling::*;
mod plane;
pub use plane::*;
const FRAME_MARGIN: usize = 16 + SUBPEL_FILTER_SIZE;
#[derive(Debug, PartialEq, Clone, Copy, FromPrimitive)]
#[repr(C)]
pub enum FrameTypeOverride {
No,
Key,
}
#[derive(Debug, Clone, Copy)]
pub struct FrameParameters {
pub frame_type_override: FrameTypeOverride,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Frame<T: Pixel> {
pub planes: [Plane<T>; 3],
}
impl<T: Pixel> Frame<T> {
pub fn new(
width: usize, height: usize, chroma_sampling: ChromaSampling,
) -> Self {
let luma_width = width.align_power_of_two(3);
let luma_height = height.align_power_of_two(3);
let luma_padding = SB_SIZE + FRAME_MARGIN;
let (chroma_decimation_x, chroma_decimation_y) =
chroma_sampling.get_decimation().unwrap_or((0, 0));
let (chroma_width, chroma_height) =
chroma_sampling.get_chroma_dimensions(luma_width, luma_height);
let chroma_padding_x = luma_padding >> chroma_decimation_x;
let chroma_padding_y = luma_padding >> chroma_decimation_y;
Frame {
planes: [
Plane::new(luma_width, luma_height, 0, 0, luma_padding, luma_padding),
Plane::new(
chroma_width,
chroma_height,
chroma_decimation_x,
chroma_decimation_y,
chroma_padding_x,
chroma_padding_y,
),
Plane::new(
chroma_width,
chroma_height,
chroma_decimation_x,
chroma_decimation_y,
chroma_padding_x,
chroma_padding_y,
),
],
}
}
pub(crate) fn pad(&mut self, w: usize, h: usize) {
for p in self.planes.iter_mut() {
p.pad(w, h);
}
}
#[inline(always)]
pub(crate) fn as_tile(&self) -> Tile<'_, T> {
let PlaneConfig { width, height, .. } = self.planes[0].cfg;
Tile::new(self, TileRect { x: 0, y: 0, width, height })
}
#[inline(always)]
pub fn as_tile_mut(&mut self) -> TileMut<'_, T> {
let PlaneConfig { width, height, .. } = self.planes[0].cfg;
TileMut::new(self, TileRect { x: 0, y: 0, width, height })
}
}