Overview
The Decoder trait implements codec decode algorithms. Decoders consume Packets from a FormatReader and produce AudioBuffers containing decoded PCM audio samples.
Decoder Trait
Definition
pub trait Decoder: Send + Sync {
fn try_new(params: &CodecParameters, options: &DecoderOptions) -> Result<Self>
where
Self: Sized;
fn supported_codecs() -> &'static [CodecDescriptor]
where
Self: Sized;
fn reset(&mut self);
fn codec_params(&self) -> &CodecParameters;
fn decode(&mut self, packet: &Packet) -> Result<AudioBufferRef<'_>>;
fn finalize(&mut self) -> FinalizeResult;
fn last_decoded(&self) -> AudioBufferRef<'_>;
}
A decoder that consumes encoded packets and produces decoded audio buffers.
Methods
try_new
fn try_new(params: &CodecParameters, options: &DecoderOptions) -> Result<Self>
where
Self: Sized
Attempt to instantiate a decoder using the provided codec parameters and options.
Codec parameters from the track
Decoder options (verification, etc.)
The instantiated decoder or an error
Example:
use symphonia::core::codecs::{DecoderOptions, CodecParameters};
use symphonia::codec_vorbis::VorbisDecoder;
let params = CodecParameters::new();
let options = DecoderOptions { verify: true };
let decoder = VorbisDecoder::try_new(¶ms, &options)?;
supported_codecs
fn supported_codecs() -> &'static [CodecDescriptor]
where
Self: Sized
Get a list of codec descriptors for the codecs supported by this decoder.
&[CodecDescriptor]
&'static [CodecDescriptor]
List of supported codec descriptors
decode
fn decode(&mut self, packet: &Packet) -> Result<AudioBufferRef<'_>>
Decode a packet of audio data and return a generic (untyped) audio buffer of the decoded audio.
AudioBufferRef
Result<AudioBufferRef<'_>>
A copy-on-write reference to the decoded audio buffer
If a DecodeError or IoError is returned, the packet is undecodeable and should be discarded. If ResetRequired is returned, the decoder must be recreated. All other errors are unrecoverable.
Implementors must clear the internal buffer if an error occurs during decoding.
Example:
loop {
let packet = format.next_packet()?;
if packet.track_id() != track.id {
continue;
}
match decoder.decode(&packet) {
Ok(decoded) => {
// Process decoded audio
println!("Decoded {} frames", decoded.frames());
},
Err(Error::DecodeError(_)) => {
// Skip bad packet and continue
continue;
},
Err(err) => return Err(err),
}
}
reset
Reset the decoder state.
A decoder must be reset when the next packet is discontinuous with respect to the last decoded packet. This occurs after a seek operation.
Example:
// Seek to a new position
let seeked = format.seek(SeekMode::Accurate, seek_to)?;
// Reset decoder after seek
decoder.reset();
// Continue decoding from new position
let packet = format.next_packet()?;
let decoded = decoder.decode(&packet)?;
codec_params
fn codec_params(&self) -> &CodecParameters
Get a reference to the updated codec parameters.
The current codec parameters (may be updated from initial parameters)
Example:
let params = decoder.codec_params();
println!("Sample rate: {:?}", params.sample_rate);
println!("Channels: {:?}", params.channels);
last_decoded
fn last_decoded(&self) -> AudioBufferRef<'_>
Get read access to the internal audio buffer containing the last decoded packet.
Reference to the last decoded audio buffer
If the last call to decode resulted in an error, the returned audio buffer will have zero length.
Example:
let decoded = decoder.decode(&packet)?;
let buffer = decoder.last_decoded();
println!("Last decoded: {} frames", buffer.frames());
finalize
fn finalize(&mut self) -> FinalizeResult
Optionally obtain post-decode information such as verification status.
Information available only after decoding is complete
Example:
// After decoding all packets
let result = decoder.finalize();
if let Some(verify_ok) = result.verify_ok {
if verify_ok {
println!("Verification passed!");
} else {
println!("Verification failed!");
}
}
Supporting Types
CodecParameters
pub struct CodecParameters {
pub codec: CodecType,
pub sample_rate: Option<u32>,
pub time_base: Option<TimeBase>,
pub n_frames: Option<u64>,
pub start_ts: u64,
pub sample_format: Option<SampleFormat>,
pub bits_per_sample: Option<u32>,
pub bits_per_coded_sample: Option<u32>,
pub channels: Option<Channels>,
pub channel_layout: Option<Layout>,
pub delay: Option<u32>,
pub padding: Option<u32>,
pub max_frames_per_packet: Option<u64>,
pub packet_data_integrity: bool,
pub verification_check: Option<VerificationCheck>,
pub frames_per_block: Option<u64>,
pub extra_data: Option<Box<[u8]>>,
}
Codec parameters stored in container format headers and metadata.
The codec type identifier
Sample rate of the audio in Hz
Timebase of the stream (length of one tick in seconds)
Total length of the stream in frames
Timestamp of the first frame
Sample format of decoded audio
Bits per decoded audio sample
Bits per encoded audio sample
Bitmask of all channels in the stream
Leading frames inserted by the encoder (encoder delay)
Trailing frames inserted by the encoder (padding)
Maximum frames a packet will contain
Whether the demuxer guarantees packet data integrity
verification_check
Option<VerificationCheck>
Method and expected value for verifying decoded audio
Frames per block for multi-block packets
Codec-specific extra data
Builder Methods
pub fn new() -> CodecParameters
pub fn for_codec(&mut self, codec: CodecType) -> &mut Self
pub fn with_sample_rate(&mut self, sample_rate: u32) -> &mut Self
pub fn with_time_base(&mut self, time_base: TimeBase) -> &mut Self
pub fn with_n_frames(&mut self, n_frames: u64) -> &mut Self
pub fn with_start_ts(&mut self, start_ts: u64) -> &mut Self
pub fn with_sample_format(&mut self, sample_format: SampleFormat) -> &mut Self
pub fn with_bits_per_sample(&mut self, bits_per_sample: u32) -> &mut Self
pub fn with_bits_per_coded_sample(&mut self, bits_per_coded_sample: u32) -> &mut Self
pub fn with_channels(&mut self, channels: Channels) -> &mut Self
pub fn with_channel_layout(&mut self, channel_layout: Layout) -> &mut Self
pub fn with_delay(&mut self, delay: u32) -> &mut Self
pub fn with_padding(&mut self, padding: u32) -> &mut Self
pub fn with_max_frames_per_packet(&mut self, len: u64) -> &mut Self
pub fn with_packet_data_integrity(&mut self, integrity: bool) -> &mut Self
pub fn with_frames_per_block(&mut self, len: u64) -> &mut Self
pub fn with_extra_data(&mut self, data: Box<[u8]>) -> &mut Self
pub fn with_verification_code(&mut self, code: VerificationCheck) -> &mut Self
Example:
use symphonia::core::codecs::{CodecParameters, CODEC_TYPE_VORBIS};
use symphonia::core::audio::Channels;
let mut params = CodecParameters::new();
params
.for_codec(CODEC_TYPE_VORBIS)
.with_sample_rate(44100)
.with_channels(Channels::FRONT_LEFT | Channels::FRONT_RIGHT);
DecoderOptions
pub struct DecoderOptions {
pub verify: bool,
}
Common options for all decoders.
Whether the decoded audio should be verified during the decode process (if supported). Default: false.
Example:
let options = DecoderOptions { verify: true };
let decoder = codec_registry.make(&track.codec_params, &options)?;
FinalizeResult
pub struct FinalizeResult {
pub verify_ok: Option<bool>,
}
Optional information available only after decoding is complete.
Verification result if verification was enabled and supported. Some(true) if verification passed, Some(false) if it failed, None if not available.
CodecType
pub struct CodecType(u32);
A unique identifier for a specific codec.
Common Codec Types
PCM Codecs:
CODEC_TYPE_PCM_S16LE // PCM signed 16-bit little-endian
CODEC_TYPE_PCM_S24LE // PCM signed 24-bit little-endian
CODEC_TYPE_PCM_S32LE // PCM signed 32-bit little-endian
CODEC_TYPE_PCM_F32LE // PCM 32-bit float little-endian
CODEC_TYPE_PCM_F64LE // PCM 64-bit float little-endian
Lossy Codecs:
CODEC_TYPE_VORBIS // Vorbis
CODEC_TYPE_MP3 // MPEG Layer 3
CODEC_TYPE_AAC // Advanced Audio Coding
CODEC_TYPE_OPUS // Opus
Lossless Codecs:
CODEC_TYPE_FLAC // Free Lossless Audio Codec
CODEC_TYPE_ALAC // Apple Lossless Audio Codec
CODEC_TYPE_WAVPACK // WavPack
CODEC_TYPE_MONKEYS_AUDIO // Monkey's Audio (APE)
Custom Codec Types
pub const fn decl_codec_type(cc: &[u8]) -> CodecType
Declare a custom codec type using a character code (max 5 alphanumeric ASCII characters).
ASCII character code for the codec
The codec type identifier
Example:
const MY_CODEC: CodecType = decl_codec_type(b"mycd1");
VerificationCheck
pub enum VerificationCheck {
Crc8(u8),
Crc16([u8; 2]),
Crc32([u8; 4]),
Md5([u8; 16]),
Other([u8; 16]),
}
A method and expected value to verify decoded audio.
CRC8 of interleaved PCM audio samples
CRC16 of interleaved PCM audio samples
CRC32 of interleaved PCM audio samples
MD5 hash of interleaved PCM audio samples
Codec-defined verification code (up to 16 bytes)
CodecDescriptor
pub struct CodecDescriptor {
pub codec: CodecType,
pub short_name: &'static str,
pub long_name: &'static str,
pub inst_func: fn(&CodecParameters, &DecoderOptions) -> Result<Box<dyn Decoder>>,
}
Stores a description of a single codec including instantiation function.
The codec type identifier
Short ASCII-only name for the codec
Longer, descriptive name for the codec
inst_func
fn(&CodecParameters, &DecoderOptions) -> Result<Box<dyn Decoder>>
Function to instantiate a decoder for this codec
Complete Example
use symphonia::core::codecs::{DecoderOptions, CODEC_TYPE_FLAC};
use symphonia::core::formats::FormatOptions;
use symphonia::core::meta::MetadataOptions;
use symphonia::core::probe::Hint;
use symphonia::core::io::MediaSourceStream;
use symphonia::core::audio::SampleBuffer;
use std::fs::File;
fn decode_file(path: &str) -> Result<(), Box<dyn std::error::Error>> {
// Open and probe the file
let file = File::open(path)?;
let mss = MediaSourceStream::new(Box::new(file), Default::default());
let mut hint = Hint::new();
hint.with_extension("flac");
let probe = symphonia::default::get_probe();
let probed = probe.format(
&hint,
mss,
&FormatOptions::default(),
&MetadataOptions::default()
)?;
let mut format = probed.format;
let track = format.default_track().unwrap();
// Verify it's a FLAC file
assert_eq!(track.codec_params.codec, CODEC_TYPE_FLAC);
// Create decoder with verification enabled
let codec_registry = symphonia::default::get_codecs();
let decoder_opts = DecoderOptions { verify: true };
let mut decoder = codec_registry.make(&track.codec_params, &decoder_opts)?;
// Print codec information
let params = decoder.codec_params();
println!("Sample rate: {} Hz", params.sample_rate.unwrap());
println!("Channels: {:?}", params.channels.unwrap());
if let Some(n_frames) = params.n_frames {
println!("Total frames: {}", n_frames);
}
// Decode all packets
let mut sample_buf = None;
let mut frames_decoded = 0;
loop {
let packet = match format.next_packet() {
Ok(packet) => packet,
Err(_) => break,
};
if packet.track_id() != track.id {
continue;
}
match decoder.decode(&packet) {
Ok(decoded) => {
frames_decoded += decoded.frames();
// Convert to sample buffer on first packet
if sample_buf.is_none() {
let spec = *decoded.spec();
let duration = decoded.capacity() as u64;
sample_buf = Some(SampleBuffer::<f32>::new(duration, spec));
}
// Copy decoded samples to buffer
if let Some(buf) = &mut sample_buf {
buf.copy_interleaved_ref(decoded);
// Process samples in buf.samples()...
}
},
Err(err) => {
eprintln!("Decode error: {}", err);
continue;
}
}
}
// Check verification result
let result = decoder.finalize();
if let Some(verify_ok) = result.verify_ok {
println!("Verification: {}", if verify_ok { "PASSED" } else { "FAILED" });
}
println!("Decoded {} frames", frames_decoded);
Ok(())
}
See Also