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(¶ms.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(¶ms, &opt)?)),
586 }
587 };
588}