codec_bitstream/
lib.rs

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}