symphonia_core/
codecs.rs

1// Symphonia
2// Copyright (c) 2019-2022 The Project Symphonia Developers.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at https://mozilla.org/MPL/2.0/.
7
8//! The `codec` module provides the traits and support structures necessary to implement audio codec
9//! decoders.
10
11use std::collections::HashMap;
12use std::default::Default;
13use std::fmt;
14
15use crate::audio::{AudioBufferRef, Channels, Layout};
16use crate::errors::{unsupported_error, Result};
17use crate::formats::Packet;
18use crate::sample::SampleFormat;
19use crate::units::TimeBase;
20
21/// A `CodecType` is a unique identifier used to identify a specific codec.
22#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
23pub struct CodecType(u32);
24
25/// Declares a new `CodecType` given a character code. A character code is an ASCII string
26/// containing a maximum of 5 alphanumeric characters.
27///
28/// Note: Due to the current limitations of const fn, this function is not able to panic on error.
29/// Therefore, if the character code contains an invalid character, then the character is dropped.
30/// Additionally, any extra characters will be truncated.
31pub const fn decl_codec_type(cc: &[u8]) -> CodecType {
32    /// Map alphanumeric ASCII characters into a 6-bit code.
33    const fn map_ascii_to_bits(cc: u8) -> u32 {
34        // The mapping is defined as:
35        //  b'0'..=b'9' maps to  1..=10
36        //  b'a'..=b'z' maps to 11..=36
37        //  b'A'..=b'Z' maps to 37..=62
38        if cc.is_ascii_digit() {
39            1 + (cc - b'0') as u32
40        }
41        else if cc.is_ascii_lowercase() {
42            11 + (cc - b'a') as u32
43        }
44        else if cc.is_ascii_uppercase() {
45            37 + (cc - b'A') as u32
46        }
47        else {
48            0
49        }
50    }
51
52    // TODO: assert!(cc.len() <= 5);
53
54    // The upper-bit indicates the user codec namespace.
55    let mut id = 0x8000_0000;
56
57    let mut i = 0;
58    let mut j = 0;
59
60    while i < cc.len() && j < 5 {
61        // TODO: When const panic is stabilized, assert that the character is alphanumeric to
62        // generate an error rather than silently dropping invalid characters.
63        // assert!(cc[i].is_ascii_alphanumeric());
64
65        // Pack the ASCII characters into the allocated 30 bits (6 bits per character) in MSb order.
66        if cc[i].is_ascii_alphanumeric() {
67            id |= map_ascii_to_bits(cc[i]) << (24 - (6 * j));
68            j += 1;
69        }
70        i += 1;
71    }
72
73    CodecType(id)
74}
75
76impl fmt::Display for CodecType {
77    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78        write!(f, "{:#x}", self.0)
79    }
80}
81
82/// Null codec
83pub const CODEC_TYPE_NULL: CodecType = CodecType(0x0);
84
85// Uncompressed PCM audio codecs
86//------------------------------
87
88/// PCM signed 32-bit little-endian interleaved
89pub const CODEC_TYPE_PCM_S32LE: CodecType = CodecType(0x100);
90/// PCM signed 32-bit little-endian planar
91pub const CODEC_TYPE_PCM_S32LE_PLANAR: CodecType = CodecType(0x101);
92/// PCM signed 32-bit big-endian interleaved
93pub const CODEC_TYPE_PCM_S32BE: CodecType = CodecType(0x102);
94/// PCM signed 32-bit big-endian planar
95pub const CODEC_TYPE_PCM_S32BE_PLANAR: CodecType = CodecType(0x103);
96/// PCM signed 24-bit little-endian interleaved
97pub const CODEC_TYPE_PCM_S24LE: CodecType = CodecType(0x104);
98/// PCM signed 24-bit little-endian planar
99pub const CODEC_TYPE_PCM_S24LE_PLANAR: CodecType = CodecType(0x105);
100/// PCM signed 24-bit big-endian interleaved
101pub const CODEC_TYPE_PCM_S24BE: CodecType = CodecType(0x106);
102/// PCM signed 24-bit big-endian planar
103pub const CODEC_TYPE_PCM_S24BE_PLANAR: CodecType = CodecType(0x107);
104/// PCM signed 16-bit little-endian interleaved
105pub const CODEC_TYPE_PCM_S16LE: CodecType = CodecType(0x108);
106/// PCM signed 16-bit little-endian planar
107pub const CODEC_TYPE_PCM_S16LE_PLANAR: CodecType = CodecType(0x109);
108/// PCM signed 16-bit big-endian interleaved
109pub const CODEC_TYPE_PCM_S16BE: CodecType = CodecType(0x10a);
110/// PCM signed 16-bit big-endian planar
111pub const CODEC_TYPE_PCM_S16BE_PLANAR: CodecType = CodecType(0x10b);
112/// PCM signed 8-bit interleaved
113pub const CODEC_TYPE_PCM_S8: CodecType = CodecType(0x10c);
114/// PCM signed 8-bit planar
115pub const CODEC_TYPE_PCM_S8_PLANAR: CodecType = CodecType(0x10d);
116/// PCM unsigned 32-bit little-endian interleaved
117pub const CODEC_TYPE_PCM_U32LE: CodecType = CodecType(0x10e);
118/// PCM unsigned 32-bit little-endian planar
119pub const CODEC_TYPE_PCM_U32LE_PLANAR: CodecType = CodecType(0x10f);
120/// PCM unsigned 32-bit big-endian interleaved
121pub const CODEC_TYPE_PCM_U32BE: CodecType = CodecType(0x110);
122/// PCM unsigned 32-bit big-endian planar
123pub const CODEC_TYPE_PCM_U32BE_PLANAR: CodecType = CodecType(0x111);
124/// PCM unsigned 24-bit little-endian interleaved
125pub const CODEC_TYPE_PCM_U24LE: CodecType = CodecType(0x112);
126/// PCM unsigned 24-bit little-endian planar
127pub const CODEC_TYPE_PCM_U24LE_PLANAR: CodecType = CodecType(0x113);
128/// PCM unsigned 24-bit big-endian interleaved
129pub const CODEC_TYPE_PCM_U24BE: CodecType = CodecType(0x114);
130/// PCM unsigned 24-bit big-endian planar
131pub const CODEC_TYPE_PCM_U24BE_PLANAR: CodecType = CodecType(0x115);
132/// PCM unsigned 16-bit little-endian interleaved
133pub const CODEC_TYPE_PCM_U16LE: CodecType = CodecType(0x116);
134/// PCM unsigned 16-bit little-endian planar
135pub const CODEC_TYPE_PCM_U16LE_PLANAR: CodecType = CodecType(0x117);
136/// PCM unsigned 16-bit big-endian interleaved
137pub const CODEC_TYPE_PCM_U16BE: CodecType = CodecType(0x118);
138/// PCM unsigned 16-bit big-endian planar
139pub const CODEC_TYPE_PCM_U16BE_PLANAR: CodecType = CodecType(0x119);
140/// PCM unsigned 8-bit interleaved
141pub const CODEC_TYPE_PCM_U8: CodecType = CodecType(0x11a);
142/// PCM unsigned 8-bit planar
143pub const CODEC_TYPE_PCM_U8_PLANAR: CodecType = CodecType(0x11b);
144/// PCM 32-bit little-endian floating point interleaved
145pub const CODEC_TYPE_PCM_F32LE: CodecType = CodecType(0x11c);
146/// PCM 32-bit little-endian floating point planar
147pub const CODEC_TYPE_PCM_F32LE_PLANAR: CodecType = CodecType(0x11d);
148/// PCM 32-bit big-endian floating point interleaved
149pub const CODEC_TYPE_PCM_F32BE: CodecType = CodecType(0x11e);
150/// PCM 32-bit big-endian floating point planar
151pub const CODEC_TYPE_PCM_F32BE_PLANAR: CodecType = CodecType(0x11f);
152/// PCM 64-bit little-endian floating point interleaved
153pub const CODEC_TYPE_PCM_F64LE: CodecType = CodecType(0x120);
154/// PCM 64-bit little-endian floating point planar
155pub const CODEC_TYPE_PCM_F64LE_PLANAR: CodecType = CodecType(0x121);
156/// PCM 64-bit big-endian floating point interleaved
157pub const CODEC_TYPE_PCM_F64BE: CodecType = CodecType(0x122);
158/// PCM 64-bit big-endian floating point planar
159pub const CODEC_TYPE_PCM_F64BE_PLANAR: CodecType = CodecType(0x123);
160/// PCM A-law (G.711)
161pub const CODEC_TYPE_PCM_ALAW: CodecType = CodecType(0x124);
162/// PCM Mu-law (G.711)
163pub const CODEC_TYPE_PCM_MULAW: CodecType = CodecType(0x125);
164
165// ADPCM audio codecs
166//-------------------
167
168/// G.722 ADPCM
169pub const CODEC_TYPE_ADPCM_G722: CodecType = CodecType(0x200);
170/// G.726 ADPCM
171pub const CODEC_TYPE_ADPCM_G726: CodecType = CodecType(0x201);
172/// G.726 ADPCM little-endian
173pub const CODEC_TYPE_ADPCM_G726LE: CodecType = CodecType(0x202);
174/// Microsoft ADPCM
175pub const CODEC_TYPE_ADPCM_MS: CodecType = CodecType(0x203);
176/// ADPCM IMA WAV
177pub const CODEC_TYPE_ADPCM_IMA_WAV: CodecType = CodecType(0x204);
178/// ADPCM IMA QuickTime
179pub const CODEC_TYPE_ADPCM_IMA_QT: CodecType = CodecType(0x205);
180
181// Compressed lossy audio codecs
182//------------------------------
183
184/// Vorbis
185pub const CODEC_TYPE_VORBIS: CodecType = CodecType(0x1000);
186/// MPEG Layer 1 (MP1)
187pub const CODEC_TYPE_MP1: CodecType = CodecType(0x1001);
188/// MPEG Layer 2 (MP2)
189pub const CODEC_TYPE_MP2: CodecType = CodecType(0x1002);
190/// MPEG Layer 3 (MP3)
191pub const CODEC_TYPE_MP3: CodecType = CodecType(0x1003);
192/// Advanced Audio Coding (AAC)
193pub const CODEC_TYPE_AAC: CodecType = CodecType(0x1004);
194/// Opus
195pub const CODEC_TYPE_OPUS: CodecType = CodecType(0x1005);
196/// Speex
197pub const CODEC_TYPE_SPEEX: CodecType = CodecType(0x1006);
198/// Musepack
199pub const CODEC_TYPE_MUSEPACK: CodecType = CodecType(0x1007);
200/// Adaptive Transform Acoustic Coding (ATRAC1)
201pub const CODEC_TYPE_ATRAC1: CodecType = CodecType(0x1008);
202/// Adaptive Transform Acoustic Coding 3 (ATRAC3)
203pub const CODEC_TYPE_ATRAC3: CodecType = CodecType(0x1009);
204/// Adaptive Transform Acoustic Coding 3+ (ATRAC3+)
205pub const CODEC_TYPE_ATRAC3PLUS: CodecType = CodecType(0x100a);
206/// Adaptive Transform Acoustic Coding 9 (ATRAC9)
207pub const CODEC_TYPE_ATRAC9: CodecType = CodecType(0x100b);
208/// AC-3, E-AC-3, Dolby Digital (ATSC A/52)
209pub const CODEC_TYPE_EAC3: CodecType = CodecType(0x100c);
210/// Dolby AC-4 (ETSI TS 103 190)
211pub const CODEC_TYPE_AC4: CodecType = CodecType(0x100d);
212/// DTS Coherent Acoustics (DCA/DTS)
213pub const CODEC_TYPE_DCA: CodecType = CodecType(0x100e);
214/// Windows Media Audio
215pub const CODEC_TYPE_WMA: CodecType = CodecType(0x100f);
216
217// Compressed lossless audio codecs
218//---------------------------------
219
220/// Free Lossless Audio Codec (FLAC)
221pub const CODEC_TYPE_FLAC: CodecType = CodecType(0x2000);
222/// WavPack
223pub const CODEC_TYPE_WAVPACK: CodecType = CodecType(0x2001);
224/// Monkey's Audio (APE)
225pub const CODEC_TYPE_MONKEYS_AUDIO: CodecType = CodecType(0x2002);
226/// Apple Lossless Audio Codec (ALAC)
227pub const CODEC_TYPE_ALAC: CodecType = CodecType(0x2003);
228/// True Audio (TTA)
229pub const CODEC_TYPE_TTA: CodecType = CodecType(0x2004);
230
231/// A method and expected value to perform verification on the decoded audio.
232#[derive(Copy, Clone, Debug)]
233pub enum VerificationCheck {
234    /// CRC8 of interleaved PCM audio samples.
235    Crc8(u8),
236    /// CRC16 of interleaved PCM audio samples.
237    Crc16([u8; 2]),
238    /// CRC32 of interleaved PCM audio samples.
239    Crc32([u8; 4]),
240    /// MD5 of interleaved PCM audio samples.
241    Md5([u8; 16]),
242    /// Codec defined, up-to 16-byte code.
243    Other([u8; 16]),
244}
245
246/// Codec parameters stored in a container format's headers and metadata may be passed to a codec
247/// using the `CodecParameters` structure.
248#[derive(Clone, Debug)]
249pub struct CodecParameters {
250    /// The codec type.
251    pub codec: CodecType,
252
253    /// The sample rate of the audio in Hz.
254    pub sample_rate: Option<u32>,
255
256    /// The timebase of the stream.
257    ///
258    /// The timebase is the length of time in seconds of a single tick of a timestamp or duration.
259    /// It can be used to convert any timestamp or duration related to the stream into seconds.
260    pub time_base: Option<TimeBase>,
261
262    /// The length of the stream in number of frames.
263    ///
264    /// If a timebase is available, this field can be used to calculate the total duration of the
265    /// stream in seconds by using [`TimeBase::calc_time`] and passing the number of frames as the
266    /// timestamp.
267    pub n_frames: Option<u64>,
268
269    /// The timestamp of the first frame.
270    pub start_ts: u64,
271
272    /// The sample format of an audio sample.
273    pub sample_format: Option<SampleFormat>,
274
275    /// The number of bits per one decoded audio sample.
276    pub bits_per_sample: Option<u32>,
277
278    /// The number of bits per one encoded audio sample.
279    pub bits_per_coded_sample: Option<u32>,
280
281    /// A bitmask of all channels in the stream.
282    pub channels: Option<Channels>,
283
284    /// The channel layout.
285    pub channel_layout: Option<Layout>,
286
287    /// The number of leading frames inserted by the encoder that should be skipped during playback.
288    pub delay: Option<u32>,
289
290    /// The number of trailing frames inserted by the encoder for padding that should be skipped
291    /// during playback.
292    pub padding: Option<u32>,
293
294    /// The maximum number of frames a packet will contain.
295    pub max_frames_per_packet: Option<u64>,
296
297    /// The demuxer guarantees packet data integrity.
298    pub packet_data_integrity: bool,
299
300    /// A method and expected value that may be used to perform verification on the decoded audio.
301    pub verification_check: Option<VerificationCheck>,
302
303    /// The number of frames per block, in case packets are seperated in multiple blocks.
304    pub frames_per_block: Option<u64>,
305
306    /// Extra data (defined by the codec).
307    pub extra_data: Option<Box<[u8]>>,
308}
309
310impl CodecParameters {
311    pub fn new() -> CodecParameters {
312        CodecParameters {
313            codec: CODEC_TYPE_NULL,
314            sample_rate: None,
315            time_base: None,
316            n_frames: None,
317            start_ts: 0,
318            sample_format: None,
319            bits_per_sample: None,
320            bits_per_coded_sample: None,
321            channels: None,
322            channel_layout: None,
323            delay: None,
324            padding: None,
325            max_frames_per_packet: None,
326            packet_data_integrity: false,
327            verification_check: None,
328            frames_per_block: None,
329            extra_data: None,
330        }
331    }
332
333    /// Provide the `CodecType`.
334    pub fn for_codec(&mut self, codec: CodecType) -> &mut Self {
335        self.codec = codec;
336        self
337    }
338
339    /// Provide the sample rate in Hz.
340    pub fn with_sample_rate(&mut self, sample_rate: u32) -> &mut Self {
341        self.sample_rate = Some(sample_rate);
342        self
343    }
344
345    /// Provide the `TimeBase`.
346    pub fn with_time_base(&mut self, time_base: TimeBase) -> &mut Self {
347        self.time_base = Some(time_base);
348        self
349    }
350
351    /// Provide the total number of frames.
352    pub fn with_n_frames(&mut self, n_frames: u64) -> &mut Self {
353        self.n_frames = Some(n_frames);
354        self
355    }
356
357    /// Provide the timestamp of the first frame.
358    pub fn with_start_ts(&mut self, start_ts: u64) -> &mut Self {
359        self.start_ts = start_ts;
360        self
361    }
362
363    /// Provide the codec's decoded audio sample format.
364    pub fn with_sample_format(&mut self, sample_format: SampleFormat) -> &mut Self {
365        self.sample_format = Some(sample_format);
366        self
367    }
368
369    /// Provide the bit per sample of a decoded audio sample.
370    pub fn with_bits_per_sample(&mut self, bits_per_sample: u32) -> &mut Self {
371        self.bits_per_sample = Some(bits_per_sample);
372        self
373    }
374
375    /// Provide the bits per sample of an encoded audio sample.
376    pub fn with_bits_per_coded_sample(&mut self, bits_per_coded_sample: u32) -> &mut Self {
377        self.bits_per_coded_sample = Some(bits_per_coded_sample);
378        self
379    }
380
381    /// Provide the channel map.
382    pub fn with_channels(&mut self, channels: Channels) -> &mut Self {
383        self.channels = Some(channels);
384        self
385    }
386
387    /// Provide the channel layout.
388    pub fn with_channel_layout(&mut self, channel_layout: Layout) -> &mut Self {
389        self.channel_layout = Some(channel_layout);
390        self
391    }
392
393    /// Provide the number of delay frames.
394    pub fn with_delay(&mut self, delay: u32) -> &mut Self {
395        self.delay = Some(delay);
396        self
397    }
398
399    /// Provide the number of padding frames.
400    pub fn with_padding(&mut self, padding: u32) -> &mut Self {
401        self.padding = Some(padding);
402        self
403    }
404
405    /// Provide the maximum number of frames per packet.
406    pub fn with_max_frames_per_packet(&mut self, len: u64) -> &mut Self {
407        self.max_frames_per_packet = Some(len);
408        self
409    }
410
411    /// Specify if the packet's data integrity was guaranteed.
412    pub fn with_packet_data_integrity(&mut self, integrity: bool) -> &mut Self {
413        self.packet_data_integrity = integrity;
414        self
415    }
416
417    /// Provide the maximum number of frames per packet.
418    pub fn with_frames_per_block(&mut self, len: u64) -> &mut Self {
419        self.frames_per_block = Some(len);
420        self
421    }
422
423    /// Provide codec extra data.
424    pub fn with_extra_data(&mut self, data: Box<[u8]>) -> &mut Self {
425        self.extra_data = Some(data);
426        self
427    }
428
429    /// Provide a verification code of the final decoded audio.
430    pub fn with_verification_code(&mut self, code: VerificationCheck) -> &mut Self {
431        self.verification_check = Some(code);
432        self
433    }
434}
435
436impl Default for CodecParameters {
437    fn default() -> Self {
438        Self::new()
439    }
440}
441
442/// `FinalizeResult` contains optional information that can only be found, calculated, or
443/// determined after decoding is complete.
444#[derive(Copy, Clone, Debug, Default)]
445pub struct FinalizeResult {
446    /// If verification is enabled and supported by the decoder, provides the verification result
447    /// if available.
448    pub verify_ok: Option<bool>,
449}
450
451/// `DecoderOptions` is a common set of options that all decoders use.
452#[derive(Copy, Clone, Debug, Default)]
453pub struct DecoderOptions {
454    /// The decoded audio should be verified if possible during the decode process.
455    pub verify: bool,
456}
457
458/// A `Decoder` implements a codec's decode algorithm. It consumes `Packet`s and produces
459/// `AudioBuffer`s.
460pub trait Decoder: Send + Sync {
461    /// Attempts to instantiates a `Decoder` using the provided `CodecParameters`.
462    fn try_new(params: &CodecParameters, options: &DecoderOptions) -> Result<Self>
463    where
464        Self: Sized;
465
466    /// Gets a list of codec descriptors for the codecs supported by this Decoder.
467    fn supported_codecs() -> &'static [CodecDescriptor]
468    where
469        Self: Sized;
470
471    /// Reset the `Decoder`.
472    ///
473    /// A decoder must be reset when the next packet is discontinuous with respect to the last
474    /// decoded packet. Most notably, this occurs after a seek.
475    ///
476    /// For codecs that do a lot of pre-computation, reset should only reset the absolute minimum
477    /// amount of state.
478    fn reset(&mut self);
479
480    /// Gets a reference to an updated set of `CodecParameters` based on the parameters the
481    /// `Decoder` was instantiated with.
482    fn codec_params(&self) -> &CodecParameters;
483
484    /// Decodes a `Packet` of audio data and returns a copy-on-write generic (untyped) audio buffer
485    /// of the decoded audio.
486    ///
487    /// If a `DecodeError` or `IoError` is returned, the packet is undecodeable and should be
488    /// discarded. Decoding may be continued with the next packet. If `ResetRequired` is returned,
489    /// consumers of the decoded audio data should expect the duration and `SignalSpec` of the
490    /// decoded audio buffer to change. All other errors are unrecoverable.
491    ///
492    /// Implementors of decoders *must* `clear` the internal buffer if an error occurs.
493    fn decode(&mut self, packet: &Packet) -> Result<AudioBufferRef>;
494
495    /// Optionally, obtain post-decode information such as the verification status.
496    fn finalize(&mut self) -> FinalizeResult;
497
498    /// Allows read access to the internal audio buffer.
499    ///
500    /// After a successful call to `decode`, this will contain the audio content of the last decoded
501    /// `Packet`. If the last call to `decode` resulted in an error, then implementors *must* ensure
502    /// the returned audio buffer has zero length.
503    fn last_decoded(&self) -> AudioBufferRef;
504}
505
506/// A `CodecDescriptor` stores a description of a single logical codec. Common information such as
507/// the `CodecType`, a short name, and a long name are provided. The `CodecDescriptor` also provides
508/// an instantiation function. When the instantiation function is called, a `Decoder` for the codec
509/// is returned.
510#[derive(Copy, Clone)]
511pub struct CodecDescriptor {
512    /// The `CodecType` identifier.
513    pub codec: CodecType,
514    /// A short ASCII-only string identifying the codec.
515    pub short_name: &'static str,
516    /// A longer, more descriptive, string identifying the codec.
517    pub long_name: &'static str,
518    // An instantiation function for the codec.
519    pub inst_func: fn(&CodecParameters, &DecoderOptions) -> Result<Box<dyn Decoder>>,
520}
521
522/// A `CodecRegistry` allows the registration of codecs, and provides a method to instantiate a
523/// `Decoder` given a `CodecParameters` object.
524pub struct CodecRegistry {
525    codecs: HashMap<CodecType, CodecDescriptor>,
526}
527
528impl CodecRegistry {
529    /// Instantiate a new `CodecRegistry`.
530    pub fn new() -> Self {
531        CodecRegistry { codecs: HashMap::new() }
532    }
533
534    /// Gets the `CodecDescriptor` for a registered codec.
535    pub fn get_codec(&self, codec: CodecType) -> Option<&CodecDescriptor> {
536        self.codecs.get(&codec)
537    }
538
539    /// Registers all codecs supported by `Decoder`. If a supported codec was previously registered
540    /// by another `Decoder` it will be replaced within the registry.
541    pub fn register_all<D: Decoder>(&mut self) {
542        for descriptor in D::supported_codecs() {
543            self.register(descriptor);
544        }
545    }
546
547    /// Register a single codec. If the codec was previously registered it will be replaced within
548    /// the registry.
549    pub fn register(&mut self, descriptor: &CodecDescriptor) {
550        self.codecs.insert(descriptor.codec, *descriptor);
551    }
552
553    /// Searches the registry for a `Decoder` that supports the codec. If one is found, it will be
554    /// instantiated with the provided `CodecParameters` and returned. If a `Decoder` could not be
555    /// found, or the `CodecParameters` are either insufficient or invalid for the `Decoder`, an
556    /// error will be returned.
557    pub fn make(
558        &self,
559        params: &CodecParameters,
560        options: &DecoderOptions,
561    ) -> Result<Box<dyn Decoder>> {
562        if let Some(descriptor) = self.codecs.get(&params.codec) {
563            Ok((descriptor.inst_func)(params, options)?)
564        }
565        else {
566            unsupported_error("core (codec):unsupported codec")
567        }
568    }
569}
570
571impl Default for CodecRegistry {
572    fn default() -> Self {
573        Self::new()
574    }
575}
576
577/// Convenience macro for declaring a `CodecDescriptor`.
578#[macro_export]
579macro_rules! support_codec {
580    ($type:expr, $short_name:expr, $long_name:expr) => {
581        CodecDescriptor {
582            codec: $type,
583            short_name: $short_name,
584            long_name: $long_name,
585            inst_func: |params, opt| Ok(Box::new(Self::try_new(&params, &opt)?)),
586        }
587    };
588}