Skip to main content

selene_core/media_container/
codec.rs

1use serde::{Deserialize, Serialize};
2use symphonia::core::codecs::{
3    CODEC_TYPE_AAC, CODEC_TYPE_AC4, CODEC_TYPE_ADPCM_G722, CODEC_TYPE_ADPCM_G726,
4    CODEC_TYPE_ADPCM_G726LE, CODEC_TYPE_ADPCM_IMA_QT, CODEC_TYPE_ADPCM_IMA_WAV,
5    CODEC_TYPE_ADPCM_MS, CODEC_TYPE_ALAC, CODEC_TYPE_ATRAC1, CODEC_TYPE_ATRAC3,
6    CODEC_TYPE_ATRAC3PLUS, CODEC_TYPE_ATRAC9, CODEC_TYPE_DCA, CODEC_TYPE_EAC3, CODEC_TYPE_FLAC,
7    CODEC_TYPE_MONKEYS_AUDIO, CODEC_TYPE_MP1, CODEC_TYPE_MP2, CODEC_TYPE_MP3, CODEC_TYPE_MUSEPACK,
8    CODEC_TYPE_NULL, CODEC_TYPE_OPUS, CODEC_TYPE_PCM_ALAW, CODEC_TYPE_PCM_F32BE,
9    CODEC_TYPE_PCM_F32BE_PLANAR, CODEC_TYPE_PCM_F32LE, CODEC_TYPE_PCM_F32LE_PLANAR,
10    CODEC_TYPE_PCM_F64BE, CODEC_TYPE_PCM_F64BE_PLANAR, CODEC_TYPE_PCM_F64LE,
11    CODEC_TYPE_PCM_F64LE_PLANAR, CODEC_TYPE_PCM_MULAW, CODEC_TYPE_PCM_S8, CODEC_TYPE_PCM_S8_PLANAR,
12    CODEC_TYPE_PCM_S16BE, CODEC_TYPE_PCM_S16BE_PLANAR, CODEC_TYPE_PCM_S16LE,
13    CODEC_TYPE_PCM_S16LE_PLANAR, CODEC_TYPE_PCM_S24BE, CODEC_TYPE_PCM_S24BE_PLANAR,
14    CODEC_TYPE_PCM_S24LE, CODEC_TYPE_PCM_S24LE_PLANAR, CODEC_TYPE_PCM_S32BE,
15    CODEC_TYPE_PCM_S32BE_PLANAR, CODEC_TYPE_PCM_S32LE, CODEC_TYPE_PCM_S32LE_PLANAR,
16    CODEC_TYPE_PCM_U8, CODEC_TYPE_PCM_U8_PLANAR, CODEC_TYPE_PCM_U16BE, CODEC_TYPE_PCM_U16BE_PLANAR,
17    CODEC_TYPE_PCM_U16LE, CODEC_TYPE_PCM_U16LE_PLANAR, CODEC_TYPE_PCM_U24BE,
18    CODEC_TYPE_PCM_U24BE_PLANAR, CODEC_TYPE_PCM_U24LE, CODEC_TYPE_PCM_U24LE_PLANAR,
19    CODEC_TYPE_PCM_U32BE, CODEC_TYPE_PCM_U32BE_PLANAR, CODEC_TYPE_PCM_U32LE,
20    CODEC_TYPE_PCM_U32LE_PLANAR, CODEC_TYPE_SPEEX, CODEC_TYPE_TTA, CODEC_TYPE_VORBIS,
21    CODEC_TYPE_WAVPACK, CODEC_TYPE_WMA, CodecType,
22};
23
24use crate::errors::CodecError;
25
26/// All supported audio codecs
27#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize)]
28pub enum Codec {
29    Aac,
30    Ac4,
31    AdpcmG722,
32    AdpcmG726,
33    AdpcmG726Le,
34    AdpcmImaQt,
35    AdpcmImaWav,
36    AdpcmMs,
37    Alac,
38    Atrac1,
39    Atrac3,
40    Atrac9,
41    Atrac3Plus,
42    Dca,
43    Eac3,
44    Flac,
45    MonkeysAudio,
46    Mp1,
47    Mp2,
48    Mp3,
49    Musepack,
50    Opus,
51    PcmAlaw,
52    PcmF32Be,
53    PcmF32BePlanar,
54    PcmF32Le,
55    PcmF32LePlanar,
56    PcmF64Be,
57    PcmF64BePlanar,
58    PcmF64Le,
59    PcmF64LePlanar,
60    PcmMulaw,
61    PcmS8,
62    PcmS8Planar,
63    PcmS16Be,
64    PcmS16BePlanar,
65    PcmS16Le,
66    PcmS16LePlanar,
67    PcmS24Be,
68    PcmS24BePlanar,
69    PcmS24Le,
70    PcmS24LePlanar,
71    PcmS32Be,
72    PcmS32BePlanar,
73    PcmS32Le,
74    PcmS32LePlanar,
75    PcmU8,
76    PcmU8Planar,
77    PcmU16Be,
78    PcmU16BePlanar,
79    PcmU16Le,
80    PcmU16LePlanar,
81    PcmU24Be,
82    PcmU24BePlanar,
83    PcmU24Le,
84    PcmU24LePlanar,
85    PcmU32Be,
86    PcmU32BePlanar,
87    PcmU32Le,
88    PcmU32LePlanar,
89    Speex,
90    Tta,
91    Vorbis,
92    WavPack,
93    Wma,
94}
95
96impl Codec {
97    #[must_use]
98    pub fn is_pcm(&self) -> bool {
99        matches!(
100            self,
101            Codec::PcmAlaw
102                | Codec::PcmF32Be
103                | Codec::PcmF32BePlanar
104                | Codec::PcmF32Le
105                | Codec::PcmF32LePlanar
106                | Codec::PcmF64Be
107                | Codec::PcmF64BePlanar
108                | Codec::PcmF64Le
109                | Codec::PcmF64LePlanar
110                | Codec::PcmMulaw
111                | Codec::PcmS8
112                | Codec::PcmS8Planar
113                | Codec::PcmS16Be
114                | Codec::PcmS16BePlanar
115                | Codec::PcmS16Le
116                | Codec::PcmS16LePlanar
117                | Codec::PcmS24Be
118                | Codec::PcmS24BePlanar
119                | Codec::PcmS24Le
120                | Codec::PcmS24LePlanar
121                | Codec::PcmS32Be
122                | Codec::PcmS32BePlanar
123                | Codec::PcmS32Le
124                | Codec::PcmS32LePlanar
125                | Codec::PcmU8
126                | Codec::PcmU8Planar
127                | Codec::PcmU16Be
128                | Codec::PcmU16BePlanar
129                | Codec::PcmU16Le
130                | Codec::PcmU16LePlanar
131                | Codec::PcmU24Be
132                | Codec::PcmU24BePlanar
133                | Codec::PcmU24Le
134                | Codec::PcmU24LePlanar
135                | Codec::PcmU32Be
136                | Codec::PcmU32BePlanar
137                | Codec::PcmU32Le
138                | Codec::PcmU32LePlanar
139                | Codec::Tta
140                | Codec::WavPack
141        )
142    }
143
144    #[must_use]
145    pub fn is_lossless(&self) -> bool {
146        matches!(
147            self,
148            Codec::Alac
149                | Codec::Flac
150                | Codec::MonkeysAudio
151                | Codec::PcmF32Be
152                | Codec::PcmF32BePlanar
153                | Codec::PcmF32Le
154                | Codec::PcmF32LePlanar
155                | Codec::PcmF64Be
156                | Codec::PcmF64BePlanar
157                | Codec::PcmF64Le
158                | Codec::PcmF64LePlanar
159                | Codec::PcmS8
160                | Codec::PcmS8Planar
161                | Codec::PcmS16Be
162                | Codec::PcmS16BePlanar
163                | Codec::PcmS16Le
164                | Codec::PcmS16LePlanar
165                | Codec::PcmS24Be
166                | Codec::PcmS24BePlanar
167                | Codec::PcmS24Le
168                | Codec::PcmS24LePlanar
169                | Codec::PcmS32Be
170                | Codec::PcmS32BePlanar
171                | Codec::PcmS32Le
172                | Codec::PcmS32LePlanar
173                | Codec::PcmU8
174                | Codec::PcmU8Planar
175                | Codec::PcmU16Be
176                | Codec::PcmU16BePlanar
177                | Codec::PcmU16Le
178                | Codec::PcmU16LePlanar
179                | Codec::PcmU24Be
180                | Codec::PcmU24BePlanar
181                | Codec::PcmU24Le
182                | Codec::PcmU24LePlanar
183                | Codec::PcmU32Be
184                | Codec::PcmU32BePlanar
185                | Codec::PcmU32Le
186                | Codec::PcmU32LePlanar
187        )
188    }
189
190    #[must_use]
191    pub fn is_flac(&self) -> bool {
192        matches!(self, Self::Flac)
193    }
194
195    #[must_use]
196    pub fn is_mp3(&self) -> bool {
197        matches!(self, Self::Mp3)
198    }
199
200    #[must_use]
201    pub fn is_opus(&self) -> bool {
202        matches!(self, Self::Opus)
203    }
204
205    #[must_use]
206    pub fn is_vorbis(&self) -> bool {
207        matches!(self, Self::Vorbis)
208    }
209
210    pub fn ffmpeg_encoder(&self) -> Result<&'static str, CodecError> {
211        let encoder = match self {
212            Codec::Aac => "aac",
213            Codec::Alac => "alac",
214            Codec::Eac3 => "eac3",
215            Codec::Flac => "flac",
216            Codec::Mp2 => "mp2",
217            Codec::Mp3 => "libmp3lame",
218            Codec::Opus => "libopus",
219            Codec::PcmAlaw => "pcm_alaw",
220            Codec::PcmMulaw => "pcm_mulaw",
221            Codec::PcmF32Be => "pcm_f32be",
222            Codec::PcmF32Le => "pcm_f32le",
223            Codec::PcmF64Be => "pcm_f64be",
224            Codec::PcmF64Le => "pcm_f64le",
225            Codec::PcmS8 => "pcm_s8",
226            Codec::PcmS16Be => "pcm_s16be",
227            Codec::PcmS16Le => "pcm_s16le",
228            Codec::PcmS24Be => "pcm_s24be",
229            Codec::PcmS24Le => "pcm_s24le",
230            Codec::PcmS32Be => "pcm_s32be",
231            Codec::PcmS32Le => "pcm_s32le",
232            Codec::PcmU8 => "pcm_u8",
233            Codec::PcmU16Be => "pcm_u16be",
234            Codec::PcmU16Le => "pcm_u16le",
235            Codec::PcmU24Be => "pcm_u24be",
236            Codec::PcmU24Le => "pcm_u24le",
237            Codec::PcmU32Be => "pcm_u32be",
238            Codec::PcmU32Le => "pcm_u32le",
239            Codec::Speex => "libspeex",
240            Codec::Tta => "tta",
241            Codec::Vorbis => "libvorbis",
242            Codec::WavPack => "wavpack",
243            Codec::Wma => "wmav2",
244            _ => return Err(CodecError::NoEncoder(*self)),
245        };
246        Ok(encoder)
247    }
248}
249
250impl TryFrom<CodecType> for Codec {
251    type Error = CodecError;
252
253    fn try_from(value: CodecType) -> Result<Codec, CodecError> {
254        let codec = match value {
255            CODEC_TYPE_AAC => Codec::Aac,
256            CODEC_TYPE_AC4 => Codec::Ac4,
257            CODEC_TYPE_ADPCM_G722 => Codec::AdpcmG722,
258            CODEC_TYPE_ADPCM_G726 => Codec::AdpcmG726,
259            CODEC_TYPE_ADPCM_G726LE => Codec::AdpcmG726Le,
260            CODEC_TYPE_ADPCM_IMA_QT => Codec::AdpcmImaQt,
261            CODEC_TYPE_ADPCM_IMA_WAV => Codec::AdpcmImaWav,
262            CODEC_TYPE_ADPCM_MS => Codec::AdpcmMs,
263            CODEC_TYPE_ALAC => Codec::Alac,
264            CODEC_TYPE_ATRAC1 => Codec::Atrac1,
265            CODEC_TYPE_ATRAC3 => Codec::Atrac3,
266            CODEC_TYPE_ATRAC9 => Codec::Atrac9,
267            CODEC_TYPE_ATRAC3PLUS => Codec::Atrac3Plus,
268            CODEC_TYPE_DCA => Codec::Dca,
269            CODEC_TYPE_EAC3 => Codec::Eac3,
270            CODEC_TYPE_FLAC => Codec::Flac,
271            CODEC_TYPE_MONKEYS_AUDIO => Codec::MonkeysAudio,
272            CODEC_TYPE_MP1 => Codec::Mp1,
273            CODEC_TYPE_MP2 => Codec::Mp2,
274            CODEC_TYPE_MP3 => Codec::Mp3,
275            CODEC_TYPE_MUSEPACK => Codec::Musepack,
276            CODEC_TYPE_OPUS => Codec::Opus,
277            CODEC_TYPE_PCM_ALAW => Codec::PcmAlaw,
278            CODEC_TYPE_PCM_F32BE => Codec::PcmF32Be,
279            CODEC_TYPE_PCM_F32BE_PLANAR => Codec::PcmF32BePlanar,
280            CODEC_TYPE_PCM_F32LE => Codec::PcmF32Le,
281            CODEC_TYPE_PCM_F32LE_PLANAR => Codec::PcmF32LePlanar,
282            CODEC_TYPE_PCM_F64BE => Codec::PcmF64Be,
283            CODEC_TYPE_PCM_F64BE_PLANAR => Codec::PcmF64BePlanar,
284            CODEC_TYPE_PCM_F64LE => Codec::PcmF64Le,
285            CODEC_TYPE_PCM_F64LE_PLANAR => Codec::PcmF64LePlanar,
286            CODEC_TYPE_PCM_MULAW => Codec::PcmMulaw,
287            CODEC_TYPE_PCM_S8 => Codec::PcmS8,
288            CODEC_TYPE_PCM_S8_PLANAR => Codec::PcmS8Planar,
289            CODEC_TYPE_PCM_S16BE => Codec::PcmS16Be,
290            CODEC_TYPE_PCM_S16BE_PLANAR => Codec::PcmS16BePlanar,
291            CODEC_TYPE_PCM_S16LE => Codec::PcmS16Le,
292            CODEC_TYPE_PCM_S16LE_PLANAR => Codec::PcmS16LePlanar,
293            CODEC_TYPE_PCM_S24BE => Codec::PcmS24Be,
294            CODEC_TYPE_PCM_S24BE_PLANAR => Codec::PcmS24BePlanar,
295            CODEC_TYPE_PCM_S24LE => Codec::PcmS24Le,
296            CODEC_TYPE_PCM_S24LE_PLANAR => Codec::PcmS24LePlanar,
297            CODEC_TYPE_PCM_S32BE => Codec::PcmS32Be,
298            CODEC_TYPE_PCM_S32BE_PLANAR => Codec::PcmS32BePlanar,
299            CODEC_TYPE_PCM_S32LE => Codec::PcmS32Le,
300            CODEC_TYPE_PCM_S32LE_PLANAR => Codec::PcmS32LePlanar,
301            CODEC_TYPE_PCM_U8 => Codec::PcmU8,
302            CODEC_TYPE_PCM_U8_PLANAR => Codec::PcmU8Planar,
303            CODEC_TYPE_PCM_U16BE => Codec::PcmU16Be,
304            CODEC_TYPE_PCM_U16BE_PLANAR => Codec::PcmU16BePlanar,
305            CODEC_TYPE_PCM_U16LE => Codec::PcmU16Le,
306            CODEC_TYPE_PCM_U16LE_PLANAR => Codec::PcmU16LePlanar,
307            CODEC_TYPE_PCM_U24BE => Codec::PcmU24Be,
308            CODEC_TYPE_PCM_U24BE_PLANAR => Codec::PcmU24BePlanar,
309            CODEC_TYPE_PCM_U24LE => Codec::PcmU24Le,
310            CODEC_TYPE_PCM_U24LE_PLANAR => Codec::PcmU24LePlanar,
311            CODEC_TYPE_PCM_U32BE => Codec::PcmU32Be,
312            CODEC_TYPE_PCM_U32BE_PLANAR => Codec::PcmU32BePlanar,
313            CODEC_TYPE_PCM_U32LE => Codec::PcmU32Le,
314            CODEC_TYPE_PCM_U32LE_PLANAR => Codec::PcmU32LePlanar,
315            CODEC_TYPE_SPEEX => Codec::Speex,
316            CODEC_TYPE_TTA => Codec::Tta,
317            CODEC_TYPE_VORBIS => Codec::Vorbis,
318            CODEC_TYPE_WAVPACK => Codec::WavPack,
319            CODEC_TYPE_WMA => Codec::Wma,
320            CODEC_TYPE_NULL => return Err(CodecError::NoDecoder),
321            other => return Err(CodecError::Unknown(other.to_string())),
322        };
323        Ok(codec)
324    }
325}