mediadecode_ffmpeg/
audio.rs1use derive_more::{IsVariant, TryUnwrap, Unwrap};
16use ffmpeg_next::{codec::Parameters, frame};
17use mediadecode::{Timebase, decoder::AudioStreamDecoder, frame::AudioFrame, packet::AudioPacket};
18use mediaframe::audio::ChannelLayoutDescription;
19
20use crate::{
21 Error, Ffmpeg, FfmpegBuffer, boundary,
22 convert::{self, ConvertError},
23 decoder::build_codec_context,
24 extras::{AudioFrameExtra, AudioPacketExtra},
25 frame::alloc_av_audio_frame,
26 sample_format::SampleFormat,
27};
28
29pub struct FfmpegAudioStreamDecoder {
31 decoder: ffmpeg_next::decoder::Audio,
32 scratch: frame::Audio,
33 time_base: Timebase,
34}
35
36impl FfmpegAudioStreamDecoder {
37 pub fn open(parameters: Parameters, time_base: Timebase) -> Result<Self, AudioDecodeError> {
39 let ctx = build_codec_context(¶meters).map_err(AudioDecodeError::Decode)?;
42 let decoder = ctx
43 .decoder()
44 .audio()
45 .map_err(|e| AudioDecodeError::Decode(Error::Ffmpeg(e)))?;
46 let scratch = alloc_av_audio_frame().map_err(AudioDecodeError::Decode)?;
47 Ok(Self {
48 decoder,
49 scratch,
50 time_base,
51 })
52 }
53
54 #[cfg_attr(not(tarpaulin), inline(always))]
56 pub const fn time_base(&self) -> Timebase {
57 self.time_base
58 }
59
60 #[cfg_attr(not(tarpaulin), inline(always))]
63 pub const fn inner(&self) -> &ffmpeg_next::decoder::Audio {
64 &self.decoder
65 }
66}
67
68impl AudioStreamDecoder for FfmpegAudioStreamDecoder {
69 type Adapter = Ffmpeg;
70 type Buffer = FfmpegBuffer;
71 type Error = AudioDecodeError;
72
73 fn send_packet(
74 &mut self,
75 packet: &AudioPacket<AudioPacketExtra, Self::Buffer>,
76 ) -> Result<(), Self::Error> {
77 let av_pkt = boundary::ffmpeg_packet_from_audio_packet(packet)
78 .map_err(|e| AudioDecodeError::Decode(Error::PacketBuild(e)))?;
79 self
80 .decoder
81 .send_packet(&av_pkt)
82 .map_err(|e| AudioDecodeError::Decode(Error::Ffmpeg(e)))
83 }
84
85 fn receive_frame(
86 &mut self,
87 dst: &mut AudioFrame<SampleFormat, ChannelLayoutDescription, AudioFrameExtra, Self::Buffer>,
88 ) -> Result<(), Self::Error> {
89 self
90 .decoder
91 .receive_frame(&mut self.scratch)
92 .map_err(|e| AudioDecodeError::Decode(Error::Ffmpeg(e)))?;
93 let new_frame =
97 unsafe { convert::av_frame_to_audio_frame(self.scratch.as_ptr(), self.time_base) }
98 .map_err(AudioDecodeError::Convert)?;
99 *dst = new_frame;
100 Ok(())
101 }
102
103 fn send_eof(&mut self) -> Result<(), Self::Error> {
104 self
105 .decoder
106 .send_eof()
107 .map_err(|e| AudioDecodeError::Decode(Error::Ffmpeg(e)))
108 }
109
110 fn flush(&mut self) -> Result<(), Self::Error> {
111 self.decoder.flush();
112 Ok(())
113 }
114}
115
116#[derive(thiserror::Error, Debug, Clone, IsVariant, Unwrap, TryUnwrap)]
118#[unwrap(ref, ref_mut)]
119#[try_unwrap(ref, ref_mut)]
120pub enum AudioDecodeError {
121 #[error(transparent)]
123 Decode(#[from] Error),
124 #[error(transparent)]
127 Convert(#[from] ConvertError),
128}