1use std::fmt::{Display, Formatter};
2
3pub mod av1;
4pub mod h262;
5pub mod h264;
6pub mod ivf;
7
8#[derive(Debug, Copy, Clone)]
9pub enum Codec {
10 AV1,
11 H264,
12 H262,
13}
14
15impl Codec {
16 pub fn from_fourcc(fourcc: [u8; 4]) -> Option<Self> {
17 match &fourcc {
18 b"AV01" => Some(Self::AV1),
19 b"AVC1" => Some(Self::H264),
20 _ => None,
21 }
22 }
23}
24
25impl Display for Codec {
26 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
27 write!(
28 f,
29 "{:width$}",
30 match self {
31 Codec::AV1 => "AV1",
32 Codec::H264 => "H.264/AVC",
33 Codec::H262 => "H.262/MPEG2",
34 },
35 width = f.width().unwrap_or(0)
36 )
37 }
38}
39
40#[derive(Debug, Copy, Clone)]
41pub struct ColorCharacteristics {
42 pub cp: ColourPrimaries,
43 pub mc: MatrixCoefficients,
44 pub tc: TransferCharacteristic,
45}
46
47impl ColorCharacteristics {
48 pub fn from_codec_bytes(codec: Codec, cp: u8, mc: u8, tc: u8) -> Self {
49 match codec {
50 Codec::AV1 => Self {
51 cp: av1::ColourPrimaries::from_byte(cp).into(),
52 mc: av1::MatrixCoefficients::from_byte(mc).into(),
53 tc: av1::TransferCharacteristic::from_byte(tc).into(),
54 },
55 Codec::H264 => Self {
56 cp: h264::ColourPrimaries::from_byte(cp).into(),
57 mc: h264::MatrixCoefficients::from_byte(mc).into(),
58 tc: h264::TransferCharacteristic::from_byte(tc).into(),
59 },
60 Codec::H262 => Self {
61 cp: h262::ColourPrimaries::from_byte(cp).into(),
62 mc: h262::MatrixCoefficients::from_byte(mc).into(),
63 tc: h262::TransferCharacteristic::from_byte(tc).into(),
64 },
65 }
66 }
67
68 pub fn or(self, other: Self) -> Self {
69 Self {
70 cp: if matches!(
71 self.cp,
72 ColourPrimaries::Unspecified | ColourPrimaries::Invalid
73 ) {
74 other.cp
75 } else {
76 self.cp
77 },
78 mc: if matches!(
79 self.mc,
80 MatrixCoefficients::Unspecified | MatrixCoefficients::Invalid
81 ) {
82 other.mc
83 } else {
84 self.mc
85 },
86 tc: if matches!(
87 self.tc,
88 TransferCharacteristic::Unspecified | TransferCharacteristic::Invalid
89 ) {
90 other.tc
91 } else {
92 self.tc
93 },
94 }
95 }
96}
97
98#[derive(Debug, Copy, Clone)]
99pub enum ColourPrimaries {
100 Invalid,
101 Unspecified,
102 Unsupported,
103 BT709,
104 BT601_525,
105 BT601_625,
106}
107
108impl From<av1::ColourPrimaries> for ColourPrimaries {
109 fn from(value: av1::ColourPrimaries) -> Self {
110 match value {
111 av1::ColourPrimaries::Unspecified => Self::Unspecified,
112 av1::ColourPrimaries::BT709 => Self::BT709,
113 av1::ColourPrimaries::BT601 => Self::BT601_625,
114 }
115 }
116}
117
118impl From<h264::ColourPrimaries> for ColourPrimaries {
119 fn from(value: h264::ColourPrimaries) -> Self {
120 match value {
121 h264::ColourPrimaries::Reserved | h264::ColourPrimaries::Reserved2 => Self::Invalid,
122 h264::ColourPrimaries::Unspecified => Self::Unspecified,
123 h264::ColourPrimaries::FCC => Self::Unsupported,
124 h264::ColourPrimaries::BT709 => Self::BT709,
125 h264::ColourPrimaries::BT601_525 => Self::BT601_525,
126 h264::ColourPrimaries::BT601_625 => Self::BT601_625,
127 }
128 }
129}
130
131impl From<h262::ColourPrimaries> for ColourPrimaries {
132 fn from(value: h262::ColourPrimaries) -> Self {
133 match value {
134 h262::ColourPrimaries::Reserved | h262::ColourPrimaries::Forbidden => Self::Invalid,
135 h262::ColourPrimaries::Unspecified => Self::Unspecified,
136 h262::ColourPrimaries::FCC | h262::ColourPrimaries::Smpte240m => Self::Unsupported,
137 h262::ColourPrimaries::BT709 => Self::BT709,
138 h262::ColourPrimaries::BT601_525 => Self::BT601_525,
139 h262::ColourPrimaries::BT601_625 => Self::BT601_625,
140 }
141 }
142}
143
144#[derive(Debug, Copy, Clone)]
145pub enum TransferCharacteristic {
146 Invalid,
147 Unspecified,
148 Unsupported,
149 BT709,
150}
151
152impl From<av1::TransferCharacteristic> for TransferCharacteristic {
153 fn from(value: av1::TransferCharacteristic) -> Self {
154 match value {
155 av1::TransferCharacteristic::Reserved | av1::TransferCharacteristic::Reserved2 => {
156 Self::Invalid
157 }
158 av1::TransferCharacteristic::Unspecified => Self::Unspecified,
159 av1::TransferCharacteristic::BT709 | av1::TransferCharacteristic::BT601 => Self::BT709,
160 }
161 }
162}
163
164impl From<h264::TransferCharacteristic> for TransferCharacteristic {
165 fn from(value: h264::TransferCharacteristic) -> Self {
166 match value {
167 h264::TransferCharacteristic::Reserved | h264::TransferCharacteristic::Reserved2 => {
168 Self::Invalid
169 }
170 h264::TransferCharacteristic::Unspecified => Self::Unspecified,
171 h264::TransferCharacteristic::Gamma22 | h264::TransferCharacteristic::Gamma28 => {
172 Self::Unsupported
173 }
174 h264::TransferCharacteristic::BT709 | h264::TransferCharacteristic::BT601 => {
175 Self::BT709
176 }
177 }
178 }
179}
180
181impl From<h262::TransferCharacteristic> for TransferCharacteristic {
182 fn from(value: h262::TransferCharacteristic) -> Self {
183 match value {
184 h262::TransferCharacteristic::Reserved | h262::TransferCharacteristic::Forbidden => {
185 Self::Invalid
186 }
187 h262::TransferCharacteristic::Unspecified => Self::Unspecified,
188 h262::TransferCharacteristic::Gamma22 | h262::TransferCharacteristic::Gamma28 => {
189 Self::Unsupported
190 }
191 h262::TransferCharacteristic::BT709 | h262::TransferCharacteristic::BT601 => {
192 Self::BT709
193 }
194 }
195 }
196}
197
198#[derive(Debug, Copy, Clone)]
199pub enum MatrixCoefficients {
200 Invalid,
201 Unspecified,
202 Unsupported,
203 BT709,
204 BT601_525,
205 BT601_625,
206}
207
208impl From<av1::MatrixCoefficients> for MatrixCoefficients {
209 fn from(value: av1::MatrixCoefficients) -> Self {
210 match value {
211 av1::MatrixCoefficients::Reserved => Self::Invalid,
212 av1::MatrixCoefficients::Unspecified => Self::Unspecified,
213 av1::MatrixCoefficients::Identity | av1::MatrixCoefficients::FCC => Self::Unsupported,
214 av1::MatrixCoefficients::BT709 => Self::BT709,
215 av1::MatrixCoefficients::BT601 => Self::BT601_625,
216 }
217 }
218}
219
220impl From<h264::MatrixCoefficients> for MatrixCoefficients {
221 fn from(value: h264::MatrixCoefficients) -> Self {
222 match value {
223 h264::MatrixCoefficients::Reserved => Self::Invalid,
224 h264::MatrixCoefficients::Unspecified => Self::Unspecified,
225 h264::MatrixCoefficients::Identity | h264::MatrixCoefficients::FCC => Self::Unsupported,
226 h264::MatrixCoefficients::BT709 => Self::BT709,
227 h264::MatrixCoefficients::BT601_525 => Self::BT601_525,
228 h264::MatrixCoefficients::BT601_625 => Self::BT601_625,
229 }
230 }
231}
232
233impl From<h262::MatrixCoefficients> for MatrixCoefficients {
234 fn from(value: h262::MatrixCoefficients) -> Self {
235 match value {
236 h262::MatrixCoefficients::Reserved | h262::MatrixCoefficients::Forbidden => {
237 Self::Invalid
238 }
239 h262::MatrixCoefficients::Unspecified => Self::Unspecified,
240 h262::MatrixCoefficients::FCC
241 | h262::MatrixCoefficients::Smpte240m
242 | h262::MatrixCoefficients::YCgCo => Self::Unsupported,
243 h262::MatrixCoefficients::BT709 => Self::BT709,
244 h262::MatrixCoefficients::BT601_525 => Self::BT601_525,
245 h262::MatrixCoefficients::BT601_625 => Self::BT601_625,
246 }
247 }
248}