zvidlib_vorbis_decoder/
lib.rs1mod vorbis_decoder;
15#[doc(hidden)]
16pub mod vorbis_simd;
17
18#[allow(unused_imports)]
19use zvidlib_core::*;
20
21use crate::vorbis_decoder::VorbisDecoder;
22use crate::{
23 AudioBuffer, AudioDecoder, CancellationToken, EncodedAudioSample, Error, ErrorKind, Limits,
24 Result,
25};
26use symphonia_core::audio::{AudioBufferRef, SampleBuffer};
27use symphonia_core::codecs::{CODEC_TYPE_VORBIS, CodecParameters, Decoder, DecoderOptions};
28use symphonia_core::formats::Packet;
29
30#[doc(inline)]
31pub use zvidlib_vorbis_syntax::{VORBIS_PREROLL_PACKETS, VorbisConfig};
32
33pub struct NativeVorbisDecoder {
41 decoder: VorbisDecoder,
42 channels: u16,
43 sample_rate: u32,
44 cold: bool,
46 limits: Limits,
47}
48
49impl NativeVorbisDecoder {
50 pub fn new(config: &VorbisConfig, limits: Limits) -> Result<Self> {
51 let channels = u16::from(config.channels);
52 if channels > limits.max_audio_channels || config.sample_rate > limits.max_sample_rate {
53 return Err(Error::new(
54 ErrorKind::ResourceLimit,
55 "Vorbis channel count or sample rate is outside configured limits",
56 ));
57 }
58 let mut extra_data = config.identification_header.clone();
59 extra_data.extend_from_slice(&config.setup_header);
60 let mut parameters = CodecParameters::new();
61 parameters
62 .for_codec(CODEC_TYPE_VORBIS)
63 .with_extra_data(extra_data.into_boxed_slice());
64 let decoder =
65 VorbisDecoder::try_new(¶meters, &DecoderOptions::default()).map_err(|error| {
66 unsupported(format!("Vorbis configuration is unsupported: {error}"))
67 })?;
68 Ok(Self {
69 decoder,
70 channels,
71 sample_rate: config.sample_rate,
72 cold: true,
73 limits,
74 })
75 }
76}
77
78impl AudioDecoder for NativeVorbisDecoder {
79 fn decode(
80 &mut self,
81 sample: &EncodedAudioSample,
82 cancellation: &CancellationToken,
83 ) -> Result<AudioBuffer> {
84 if cancellation.is_canceled() {
85 return Err(Error::new(ErrorKind::Canceled, "Vorbis decode canceled"));
86 }
87 let cold = std::mem::replace(&mut self.cold, false);
88 let channels = usize::from(self.channels);
89 let decoded = self
90 .decoder
91 .decode(&Packet::new_from_slice(
92 0,
93 sample.decoded_range.start,
94 sample.decoded_range.len(),
95 &sample.data,
96 ))
97 .map_err(|error| codec(format!("malformed Vorbis packet: {error}")))?;
98 let frames = decoded.frames();
99 let expected = sample.decoded_range.len();
100 let samples = if frames as u64 == expected {
101 interleave(decoded)
102 } else if frames == 0 && cold {
103 vec![
104 0.0;
105 usize::try_from(expected)
106 .unwrap_or(usize::MAX)
107 .saturating_mul(channels)
108 ]
109 } else {
110 return Err(codec(format!(
111 "Vorbis decoder produced {frames} frames for an indexed {expected}-frame interval"
112 )));
113 };
114 AudioBuffer::new(
115 sample.decoded_range,
116 self.sample_rate,
117 self.channels,
118 samples,
119 &self.limits,
120 )
121 }
122
123 fn reset(&mut self) -> Result<()> {
124 self.decoder.reset();
125 self.cold = true;
126 Ok(())
127 }
128}
129
130fn interleave(decoded: AudioBufferRef<'_>) -> Vec<f32> {
131 if decoded.frames() == 0 {
134 return Vec::new();
135 }
136 let mut interleaved = SampleBuffer::<f32>::new(decoded.frames() as u64, *decoded.spec());
137 interleaved.copy_interleaved_ref(decoded);
138 interleaved.samples().to_vec()
139}
140
141fn codec(message: impl Into<String>) -> Error {
142 Error::new(ErrorKind::Codec, message)
143}
144
145fn unsupported(message: impl Into<String>) -> Error {
146 Error::new(ErrorKind::Unsupported, message)
147}
148
149#[doc(hidden)]
153#[must_use]
154pub fn simd_sites() -> Vec<(&'static str, zvidlib_core::SimdIsa)> {
155 vec![("vorbis_decode", vorbis_simd::active_isa())]
156}