Skip to main content

selene_core/media_container/
codec.rs

1use serde::{Deserialize, Serialize};
2
3use symphonia::core::codecs::audio::{AudioCodecId, well_known::{CODEC_ID_AAC, CODEC_ID_AC4, CODEC_ID_ADPCM_G722, CODEC_ID_ADPCM_G726, CODEC_ID_ADPCM_G726LE, CODEC_ID_ADPCM_IMA_QT, CODEC_ID_ADPCM_IMA_WAV, CODEC_ID_ADPCM_MS, CODEC_ID_ALAC, CODEC_ID_ATRAC1, CODEC_ID_ATRAC3, CODEC_ID_ATRAC9, CODEC_ID_ATRAC3PLUS, CODEC_ID_DCA, CODEC_ID_EAC3, CODEC_ID_FLAC, CODEC_ID_MONKEYS_AUDIO, CODEC_ID_MP1, CODEC_ID_MP2, CODEC_ID_MP3, CODEC_ID_MUSEPACK, CODEC_ID_OPUS, CODEC_ID_PCM_ALAW, CODEC_ID_PCM_F32BE, CODEC_ID_PCM_F32BE_PLANAR, CODEC_ID_PCM_F32LE, CODEC_ID_PCM_F32LE_PLANAR, CODEC_ID_PCM_F64BE, CODEC_ID_PCM_F64BE_PLANAR, CODEC_ID_PCM_F64LE, CODEC_ID_PCM_F64LE_PLANAR, CODEC_ID_PCM_MULAW, CODEC_ID_PCM_S8, CODEC_ID_PCM_S8_PLANAR, CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16BE_PLANAR, CODEC_ID_PCM_S16LE, CODEC_ID_PCM_S16LE_PLANAR, CODEC_ID_PCM_S24BE, CODEC_ID_PCM_S24BE_PLANAR, CODEC_ID_PCM_S24LE, CODEC_ID_PCM_S24LE_PLANAR, CODEC_ID_PCM_S32BE, CODEC_ID_PCM_S32BE_PLANAR, CODEC_ID_PCM_S32LE, CODEC_ID_PCM_S32LE_PLANAR, CODEC_ID_PCM_U8, CODEC_ID_PCM_U8_PLANAR, CODEC_ID_PCM_U16BE, CODEC_ID_PCM_U16BE_PLANAR, CODEC_ID_PCM_U16LE, CODEC_ID_PCM_U16LE_PLANAR, CODEC_ID_PCM_U24BE, CODEC_ID_PCM_U24BE_PLANAR, CODEC_ID_PCM_U24LE, CODEC_ID_PCM_U24LE_PLANAR, CODEC_ID_PCM_U32BE, CODEC_ID_PCM_U32BE_PLANAR, CODEC_ID_PCM_U32LE, CODEC_ID_PCM_U32LE_PLANAR, CODEC_ID_SPEEX, CODEC_ID_TTA, CODEC_ID_VORBIS, CODEC_ID_WAVPACK, CODEC_ID_WMA}};
4use thiserror::Error;
5
6#[derive(Debug, Error)]
7pub enum CodecError {
8    #[error("Unknown or unsupported codec: {0}")]
9    Unknown(String),
10
11    #[error("Codec '{0:?}' is missing an encoder")]
12    NoEncoder(Codec),
13
14    #[error("A codec is missing a symphonia decoder")]
15    NoDecoder,
16
17    #[error("Codec '{0:?}' is an unsupported codec")]
18    UnsupportedCodec(Codec),
19}
20
21/// All supported audio codecs
22#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
23pub enum Codec {
24    Aac,
25    Ac4,
26    AdpcmG722,
27    AdpcmG726,
28    AdpcmG726Le,
29    AdpcmImaQt,
30    AdpcmImaWav,
31    AdpcmMs,
32    Alac,
33    Atrac1,
34    Atrac3,
35    Atrac9,
36    Atrac3Plus,
37    Dca,
38    Eac3,
39    Flac,
40    MonkeysAudio,
41    Mp1,
42    Mp2,
43    Mp3,
44    Musepack,
45    Opus,
46    PcmAlaw,
47    PcmF32Be,
48    PcmF32BePlanar,
49    PcmF32Le,
50    PcmF32LePlanar,
51    PcmF64Be,
52    PcmF64BePlanar,
53    PcmF64Le,
54    PcmF64LePlanar,
55    PcmMulaw,
56    PcmS8,
57    PcmS8Planar,
58    PcmS16Be,
59    PcmS16BePlanar,
60    PcmS16Le,
61    PcmS16LePlanar,
62    PcmS24Be,
63    PcmS24BePlanar,
64    PcmS24Le,
65    PcmS24LePlanar,
66    PcmS32Be,
67    PcmS32BePlanar,
68    PcmS32Le,
69    PcmS32LePlanar,
70    PcmU8,
71    PcmU8Planar,
72    PcmU16Be,
73    PcmU16BePlanar,
74    PcmU16Le,
75    PcmU16LePlanar,
76    PcmU24Be,
77    PcmU24BePlanar,
78    PcmU24Le,
79    PcmU24LePlanar,
80    PcmU32Be,
81    PcmU32BePlanar,
82    PcmU32Le,
83    PcmU32LePlanar,
84    Speex,
85    Tta,
86    Vorbis,
87    WavPack,
88    Wma,
89}
90
91impl Codec {
92    #[must_use]
93    pub fn is_pcm(&self) -> bool {
94        matches!(
95            self,
96            Codec::PcmAlaw
97                | Codec::PcmF32Be
98                | Codec::PcmF32BePlanar
99                | Codec::PcmF32Le
100                | Codec::PcmF32LePlanar
101                | Codec::PcmF64Be
102                | Codec::PcmF64BePlanar
103                | Codec::PcmF64Le
104                | Codec::PcmF64LePlanar
105                | Codec::PcmMulaw
106                | Codec::PcmS8
107                | Codec::PcmS8Planar
108                | Codec::PcmS16Be
109                | Codec::PcmS16BePlanar
110                | Codec::PcmS16Le
111                | Codec::PcmS16LePlanar
112                | Codec::PcmS24Be
113                | Codec::PcmS24BePlanar
114                | Codec::PcmS24Le
115                | Codec::PcmS24LePlanar
116                | Codec::PcmS32Be
117                | Codec::PcmS32BePlanar
118                | Codec::PcmS32Le
119                | Codec::PcmS32LePlanar
120                | Codec::PcmU8
121                | Codec::PcmU8Planar
122                | Codec::PcmU16Be
123                | Codec::PcmU16BePlanar
124                | Codec::PcmU16Le
125                | Codec::PcmU16LePlanar
126                | Codec::PcmU24Be
127                | Codec::PcmU24BePlanar
128                | Codec::PcmU24Le
129                | Codec::PcmU24LePlanar
130                | Codec::PcmU32Be
131                | Codec::PcmU32BePlanar
132                | Codec::PcmU32Le
133                | Codec::PcmU32LePlanar
134                | Codec::Tta
135                | Codec::WavPack
136        )
137    }
138
139    #[must_use]
140    pub fn is_lossless(&self) -> bool {
141        matches!(
142            self,
143            Codec::Alac
144                | Codec::Flac
145                | Codec::MonkeysAudio
146                | Codec::PcmF32Be
147                | Codec::PcmF32BePlanar
148                | Codec::PcmF32Le
149                | Codec::PcmF32LePlanar
150                | Codec::PcmF64Be
151                | Codec::PcmF64BePlanar
152                | Codec::PcmF64Le
153                | Codec::PcmF64LePlanar
154                | Codec::PcmS8
155                | Codec::PcmS8Planar
156                | Codec::PcmS16Be
157                | Codec::PcmS16BePlanar
158                | Codec::PcmS16Le
159                | Codec::PcmS16LePlanar
160                | Codec::PcmS24Be
161                | Codec::PcmS24BePlanar
162                | Codec::PcmS24Le
163                | Codec::PcmS24LePlanar
164                | Codec::PcmS32Be
165                | Codec::PcmS32BePlanar
166                | Codec::PcmS32Le
167                | Codec::PcmS32LePlanar
168                | Codec::PcmU8
169                | Codec::PcmU8Planar
170                | Codec::PcmU16Be
171                | Codec::PcmU16BePlanar
172                | Codec::PcmU16Le
173                | Codec::PcmU16LePlanar
174                | Codec::PcmU24Be
175                | Codec::PcmU24BePlanar
176                | Codec::PcmU24Le
177                | Codec::PcmU24LePlanar
178                | Codec::PcmU32Be
179                | Codec::PcmU32BePlanar
180                | Codec::PcmU32Le
181                | Codec::PcmU32LePlanar
182        )
183    }
184
185    #[must_use]
186    pub fn is_flac(&self) -> bool {
187        matches!(self, Self::Flac)
188    }
189
190    #[must_use]
191    pub fn is_mp3(&self) -> bool {
192        matches!(self, Self::Mp3)
193    }
194
195    #[must_use]
196    pub fn is_opus(&self) -> bool {
197        matches!(self, Self::Opus)
198    }
199
200    #[must_use]
201    pub fn is_vorbis(&self) -> bool {
202        matches!(self, Self::Vorbis)
203    }
204
205    #[must_use]
206    pub(crate) fn is_ape(&self) -> bool {
207        matches!(self, Self::MonkeysAudio)
208    }
209}
210
211impl TryFrom<AudioCodecId> for Codec {
212    type Error = CodecError;
213
214    fn try_from(value: AudioCodecId) -> Result<Codec, CodecError> {
215        let codec = match value {
216            CODEC_ID_AAC => Codec::Aac,
217            CODEC_ID_AC4 => Codec::Ac4,
218            CODEC_ID_ADPCM_G722 => Codec::AdpcmG722,
219            CODEC_ID_ADPCM_G726 => Codec::AdpcmG726,
220            CODEC_ID_ADPCM_G726LE => Codec::AdpcmG726Le,
221            CODEC_ID_ADPCM_IMA_QT => Codec::AdpcmImaQt,
222            CODEC_ID_ADPCM_IMA_WAV => Codec::AdpcmImaWav,
223            CODEC_ID_ADPCM_MS => Codec::AdpcmMs,
224            CODEC_ID_ALAC => Codec::Alac,
225            CODEC_ID_ATRAC1 => Codec::Atrac1,
226            CODEC_ID_ATRAC3 => Codec::Atrac3,
227            CODEC_ID_ATRAC9 => Codec::Atrac9,
228            CODEC_ID_ATRAC3PLUS => Codec::Atrac3Plus,
229            CODEC_ID_DCA => Codec::Dca,
230            CODEC_ID_EAC3 => Codec::Eac3,
231            CODEC_ID_FLAC => Codec::Flac,
232            CODEC_ID_MONKEYS_AUDIO => Codec::MonkeysAudio,
233            CODEC_ID_MP1 => Codec::Mp1,
234            CODEC_ID_MP2 => Codec::Mp2,
235            CODEC_ID_MP3 => Codec::Mp3,
236            CODEC_ID_MUSEPACK => Codec::Musepack,
237            CODEC_ID_OPUS => Codec::Opus,
238            CODEC_ID_PCM_ALAW => Codec::PcmAlaw,
239            CODEC_ID_PCM_F32BE => Codec::PcmF32Be,
240            CODEC_ID_PCM_F32BE_PLANAR => Codec::PcmF32BePlanar,
241            CODEC_ID_PCM_F32LE => Codec::PcmF32Le,
242            CODEC_ID_PCM_F32LE_PLANAR => Codec::PcmF32LePlanar,
243            CODEC_ID_PCM_F64BE => Codec::PcmF64Be,
244            CODEC_ID_PCM_F64BE_PLANAR => Codec::PcmF64BePlanar,
245            CODEC_ID_PCM_F64LE => Codec::PcmF64Le,
246            CODEC_ID_PCM_F64LE_PLANAR => Codec::PcmF64LePlanar,
247            CODEC_ID_PCM_MULAW => Codec::PcmMulaw,
248            CODEC_ID_PCM_S8 => Codec::PcmS8,
249            CODEC_ID_PCM_S8_PLANAR => Codec::PcmS8Planar,
250            CODEC_ID_PCM_S16BE => Codec::PcmS16Be,
251            CODEC_ID_PCM_S16BE_PLANAR => Codec::PcmS16BePlanar,
252            CODEC_ID_PCM_S16LE => Codec::PcmS16Le,
253            CODEC_ID_PCM_S16LE_PLANAR => Codec::PcmS16LePlanar,
254            CODEC_ID_PCM_S24BE => Codec::PcmS24Be,
255            CODEC_ID_PCM_S24BE_PLANAR => Codec::PcmS24BePlanar,
256            CODEC_ID_PCM_S24LE => Codec::PcmS24Le,
257            CODEC_ID_PCM_S24LE_PLANAR => Codec::PcmS24LePlanar,
258            CODEC_ID_PCM_S32BE => Codec::PcmS32Be,
259            CODEC_ID_PCM_S32BE_PLANAR => Codec::PcmS32BePlanar,
260            CODEC_ID_PCM_S32LE => Codec::PcmS32Le,
261            CODEC_ID_PCM_S32LE_PLANAR => Codec::PcmS32LePlanar,
262            CODEC_ID_PCM_U8 => Codec::PcmU8,
263            CODEC_ID_PCM_U8_PLANAR => Codec::PcmU8Planar,
264            CODEC_ID_PCM_U16BE => Codec::PcmU16Be,
265            CODEC_ID_PCM_U16BE_PLANAR => Codec::PcmU16BePlanar,
266            CODEC_ID_PCM_U16LE => Codec::PcmU16Le,
267            CODEC_ID_PCM_U16LE_PLANAR => Codec::PcmU16LePlanar,
268            CODEC_ID_PCM_U24BE => Codec::PcmU24Be,
269            CODEC_ID_PCM_U24BE_PLANAR => Codec::PcmU24BePlanar,
270            CODEC_ID_PCM_U24LE => Codec::PcmU24Le,
271            CODEC_ID_PCM_U24LE_PLANAR => Codec::PcmU24LePlanar,
272            CODEC_ID_PCM_U32BE => Codec::PcmU32Be,
273            CODEC_ID_PCM_U32BE_PLANAR => Codec::PcmU32BePlanar,
274            CODEC_ID_PCM_U32LE => Codec::PcmU32Le,
275            CODEC_ID_PCM_U32LE_PLANAR => Codec::PcmU32LePlanar,
276            CODEC_ID_SPEEX => Codec::Speex,
277            CODEC_ID_TTA => Codec::Tta,
278            CODEC_ID_VORBIS => Codec::Vorbis,
279            CODEC_ID_WAVPACK => Codec::WavPack,
280            CODEC_ID_WMA => Codec::Wma,
281            other => return Err(CodecError::Unknown(other.to_string())),
282        };
283        Ok(codec)
284    }
285}