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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! AV1 frame-level processing.
//!
//! This module handles frame-level operations including frame header parsing,
//! reference frame management, and frame buffer allocation.
#![allow(dead_code)]
/// AV1 frame types as defined in the specification.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum Av1FrameType {
/// Keyframe - independently decodable.
#[default]
Key = 0,
/// Inter frame - references previous frames.
Inter = 1,
/// Intra-only frame - not a random access point.
IntraOnly = 2,
/// Switch frame - for stream switching.
Switch = 3,
}
impl From<u8> for Av1FrameType {
fn from(value: u8) -> Self {
match value {
0 | 4.. => Self::Key,
1 => Self::Inter,
2 => Self::IntraOnly,
3 => Self::Switch,
}
}
}
/// Reference frame indices.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ReferenceFrame {
/// No reference.
None = 0,
/// Intra prediction.
Intra = 1,
/// Last frame reference.
Last = 2,
/// Last2 frame reference.
Last2 = 3,
/// Last3 frame reference.
Last3 = 4,
/// Golden frame reference.
Golden = 5,
/// Backward reference.
BwdRef = 6,
/// Alternate reference 2.
AltRef2 = 7,
/// Alternate reference.
AltRef = 8,
}
/// Frame header information.
#[derive(Clone, Debug, Default)]
pub struct FrameHeader {
/// Frame type.
pub frame_type: Av1FrameType,
/// Show frame flag.
pub show_frame: bool,
/// Error resilient mode.
pub error_resilient_mode: bool,
/// Frame width.
pub frame_width: u32,
/// Frame height.
pub frame_height: u32,
/// Refresh frame flags.
pub refresh_frame_flags: u8,
}
/// Reference frame buffer.
#[derive(Clone, Debug, Default)]
pub struct RefFrameBuffer {
/// Buffer slots (up to 8).
slots: [Option<RefFrameSlot>; 8],
}
/// Single reference frame slot.
#[derive(Clone, Debug)]
pub struct RefFrameSlot {
/// Frame width.
pub width: u32,
/// Frame height.
pub height: u32,
/// Order hint.
pub order_hint: u8,
}
impl RefFrameBuffer {
/// Create a new reference frame buffer.
#[must_use]
pub const fn new() -> Self {
Self {
slots: [const { None }; 8],
}
}
/// Update reference frames based on refresh flags.
pub fn update(&mut self, refresh_flags: u8, slot: &RefFrameSlot) {
for i in 0..8 {
if refresh_flags & (1 << i) != 0 {
self.slots[i] = Some(slot.clone());
}
}
}
/// Get a reference frame slot.
#[must_use]
pub fn get(&self, index: usize) -> Option<&RefFrameSlot> {
self.slots.get(index).and_then(|s| s.as_ref())
}
/// Clear all reference frames.
pub fn clear(&mut self) {
self.slots = [const { None }; 8];
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_frame_type_from_u8() {
assert_eq!(Av1FrameType::from(0), Av1FrameType::Key);
assert_eq!(Av1FrameType::from(1), Av1FrameType::Inter);
}
#[test]
fn test_ref_frame_buffer() {
let mut buffer = RefFrameBuffer::new();
assert!(buffer.get(0).is_none());
let slot = RefFrameSlot {
width: 1920,
height: 1080,
order_hint: 0,
};
buffer.update(0b0000_0101, &slot);
assert!(buffer.get(0).is_some());
assert!(buffer.get(1).is_none());
assert!(buffer.get(2).is_some());
}
}