1use derive_more::{IsVariant, TryUnwrap, Unwrap};
19use ffmpeg_next::{codec::Parameters, frame};
20use mediadecode::{Timebase, decoder::AudioStreamDecoder, frame::AudioFrame, packet::AudioPacket};
21use mediaframe::audio::ChannelLayoutDescription;
22
23use crate::{
24 DecoderLimits, Error, Ffmpeg, boundary,
25 convert::{self, ConvertError},
26 decoder::build_codec_context,
27 extras::{AudioFrameExtra, AudioPacketExtra},
28 frame::alloc_av_audio_frame,
29 sample_format::SampleFormat,
30};
31
32pub struct CarrierAudioStreamDecoder<C: crate::FfmpegCarrier> {
34 decoder: ffmpeg_next::decoder::Audio,
35 scratch: frame::Audio,
36 time_base: Timebase,
37 limits: DecoderLimits,
38 _callback_state: Box<crate::ffi::CallbackState>,
45 scratch_pending: bool,
62 _carrier: core::marker::PhantomData<C>,
63}
64
65impl<C: crate::FfmpegCarrier + crate::CarrierOps> CarrierAudioStreamDecoder<C> {
66 pub(crate) fn open_impl(
73 parameters: Parameters,
74 time_base: Timebase,
75 limits: DecoderLimits,
76 ) -> Result<Self, AudioDecodeError> {
77 let (ctx, callback_state) =
80 build_codec_context(¶meters, limits).map_err(AudioDecodeError::Decode)?;
81 let codec = crate::decoder::find_decoder(¶meters).map_err(AudioDecodeError::Decode)?;
85 let opened = ctx
86 .decoder()
87 .open_as(codec)
88 .map_err(|e| AudioDecodeError::Decode(Error::Ffmpeg(e)))?;
89 crate::decoder::ensure_codec_type(&opened, ffmpeg_next::ffi::AVMediaType::AVMEDIA_TYPE_AUDIO)
90 .map_err(AudioDecodeError::Decode)?;
91 let decoder = ffmpeg_next::decoder::Audio(opened);
92 let scratch = alloc_av_audio_frame().map_err(AudioDecodeError::Decode)?;
93 Ok(Self {
94 decoder,
95 scratch,
96 time_base,
97 limits,
98 _callback_state: callback_state,
99 scratch_pending: false,
100 _carrier: core::marker::PhantomData,
101 })
102 }
103
104 #[cfg_attr(not(tarpaulin), inline(always))]
106 pub(crate) const fn time_base_impl(&self) -> Timebase {
107 self.time_base
108 }
109
110 #[cfg_attr(not(tarpaulin), inline(always))]
112 pub(crate) const fn limits_impl(&self) -> DecoderLimits {
113 self.limits
114 }
115
116 #[cfg_attr(not(tarpaulin), inline(always))]
119 pub(crate) const fn inner_impl(&self) -> &ffmpeg_next::decoder::Audio {
120 &self.decoder
121 }
122}
123
124impl<C: crate::FfmpegCarrier + crate::CarrierOps> CarrierAudioStreamDecoder<C> {
125 pub(crate) fn send_packet_impl(
126 &mut self,
127 packet: &AudioPacket<AudioPacketExtra, C::Buffer>,
128 ) -> Result<(), AudioDecodeError> {
129 let state: *const crate::ffi::CallbackState = &*self._callback_state;
133 let decoder = &mut self.decoder;
134 boundary::with_ffmpeg_audio_packet::<C, _>(
135 packet,
136 self.limits.packet_limits(),
137 crate::carrier::BodyRoute::Submission,
141 |av_pkt| {
142 decoder
146 .send_packet(av_pkt)
147 .map_err(|e| AudioDecodeError::Decode(crate::decoder::software_exit(state, e)))
148 },
149 )
150 .map_err(|e| AudioDecodeError::Decode(Error::PacketBuild(e)))?
151 }
152
153 pub(crate) fn receive_frame_impl(
154 &mut self,
155 dst: &mut AudioFrame<SampleFormat, ChannelLayoutDescription, AudioFrameExtra, C::Buffer>,
156 ) -> Result<(), AudioDecodeError> {
157 let state: *const crate::ffi::CallbackState = &*self._callback_state;
158 if !self.scratch_pending {
161 self
162 .decoder
163 .receive_frame(&mut self.scratch)
164 .map_err(|e| AudioDecodeError::Decode(crate::decoder::software_exit(state, e)))?;
165 }
166 let converted = unsafe {
171 convert::av_frame_to_audio_frame_as::<C>(
172 self.scratch.as_ptr(),
173 self.time_base,
174 self.limits.frame(),
175 )
176 };
177 match converted {
178 Ok(new_frame) => {
179 self.scratch_pending = false;
180 *dst = new_frame;
181 Ok(())
182 }
183 Err(e) => {
184 self.scratch_pending = e.parks_in_decode();
188 Err(AudioDecodeError::Convert(e))
189 }
190 }
191 }
192
193 pub(crate) fn send_eof_impl(&mut self) -> Result<(), AudioDecodeError> {
194 let state: *const crate::ffi::CallbackState = &*self._callback_state;
195 self
196 .decoder
197 .send_eof()
198 .map_err(|e| AudioDecodeError::Decode(crate::decoder::software_exit(state, e)))
199 }
200
201 pub(crate) fn flush_impl(&mut self) -> Result<(), AudioDecodeError> {
202 self.scratch_pending = false;
204 self.decoder.flush();
205 Ok(())
206 }
207}
208
209macro_rules! audio_lane_face {
210 ($($lane:ty),+ $(,)?) => { $(
211 impl CarrierAudioStreamDecoder<$lane> {
212 pub fn open(
214 parameters: Parameters,
215 time_base: Timebase,
216 limits: DecoderLimits,
217 ) -> Result<Self, AudioDecodeError> {
218 Self::open_impl(parameters, time_base, limits)
219 }
220
221 pub const fn time_base(&self) -> Timebase {
223 self.time_base_impl()
224 }
225
226 pub const fn limits(&self) -> DecoderLimits {
228 self.limits_impl()
229 }
230
231 pub const fn inner(&self) -> &ffmpeg_next::decoder::Audio {
233 self.inner_impl()
234 }
235 }
236
237 impl AudioStreamDecoder for CarrierAudioStreamDecoder<$lane> {
238 type Adapter = Ffmpeg;
239 type Buffer = <$lane as crate::FfmpegCarrier>::Buffer;
240 type Error = AudioDecodeError;
241
242 fn send_packet(
243 &mut self,
244 packet: &AudioPacket<AudioPacketExtra, Self::Buffer>,
245 ) -> Result<(), Self::Error> {
246 self.send_packet_impl(packet)
247 }
248
249 fn receive_frame(
250 &mut self,
251 dst: &mut AudioFrame<
252 SampleFormat,
253 ChannelLayoutDescription,
254 AudioFrameExtra,
255 Self::Buffer,
256 >,
257 ) -> Result<(), Self::Error> {
258 self.receive_frame_impl(dst)
259 }
260
261 fn send_eof(&mut self) -> Result<(), Self::Error> {
262 self.send_eof_impl()
263 }
264
265 fn flush(&mut self) -> Result<(), Self::Error> {
266 self.flush_impl()
267 }
268 }
269 )+ };
270}
271
272audio_lane_face!(crate::View, crate::Owned);
273
274#[derive(thiserror::Error, Debug, Clone, IsVariant, Unwrap, TryUnwrap)]
276#[unwrap(ref, ref_mut)]
277#[try_unwrap(ref, ref_mut)]
278pub enum AudioDecodeError {
279 #[error(transparent)]
281 Decode(#[from] Error),
282 #[error(transparent)]
285 Convert(#[from] ConvertError),
286}