ac_ffmpeg/codec/audio/
transcoder.rs

1//! Audio transcoder.
2//!
3//! This module contains just a convenience struct combining
4//! audio decoder/resampler/encoder into a single pipeline.
5
6use std::collections::VecDeque;
7
8use crate::Error;
9
10use crate::{
11    codec::{
12        audio::{
13            AudioDecoder, AudioDecoderBuilder, AudioEncoder, AudioEncoderBuilder, AudioFrame,
14            AudioResampler,
15        },
16        AudioCodecParameters, CodecError, Decoder, Encoder,
17    },
18    packet::Packet,
19    time::TimeBase,
20};
21
22/// Builder for the AudioTranscoder.
23pub struct AudioTranscoderBuilder {
24    input: AudioCodecParameters,
25    output: AudioCodecParameters,
26
27    decoder_builder: AudioDecoderBuilder,
28    encoder_builder: AudioEncoderBuilder,
29}
30
31impl AudioTranscoderBuilder {
32    /// Create a new builder.
33    fn new(input: AudioCodecParameters, output: AudioCodecParameters) -> Result<Self, Error> {
34        let decoder_builder = AudioDecoder::from_codec_parameters(&input)?;
35        let encoder_builder = AudioEncoder::from_codec_parameters(&output)?;
36
37        let res = Self {
38            input,
39            output,
40
41            decoder_builder,
42            encoder_builder,
43        };
44
45        Ok(res)
46    }
47
48    /// Set a decoder option.
49    pub fn set_decoder_option<V>(mut self, name: &str, value: V) -> Self
50    where
51        V: ToString,
52    {
53        self.decoder_builder = self.decoder_builder.set_option(name, value);
54        self
55    }
56
57    /// Set an encoder option.
58    pub fn set_encoder_option<V>(mut self, name: &str, value: V) -> Self
59    where
60        V: ToString,
61    {
62        self.encoder_builder = self.encoder_builder.set_option(name, value);
63        self
64    }
65
66    /// Build the transcoder.
67    pub fn build(self) -> Result<AudioTranscoder, Error> {
68        let decoder = self
69            .decoder_builder
70            .time_base(TimeBase::new(1, self.input.sample_rate() as i32))
71            .build()?;
72
73        let encoder = self
74            .encoder_builder
75            .time_base(TimeBase::new(1, self.output.sample_rate() as i32))
76            .build()?;
77
78        let source_channel_layout = self.input.channel_layout();
79        let target_channel_layout = self.output.channel_layout();
80
81        let resampler = AudioResampler::builder()
82            .source_channel_layout(source_channel_layout.to_owned())
83            .source_sample_format(self.input.sample_format())
84            .source_sample_rate(self.input.sample_rate())
85            .target_channel_layout(target_channel_layout.to_owned())
86            .target_sample_format(self.output.sample_format())
87            .target_sample_rate(self.output.sample_rate())
88            .target_frame_samples(encoder.samples_per_frame())
89            .build()?;
90
91        let res = AudioTranscoder {
92            audio_decoder: decoder,
93            audio_encoder: encoder,
94            audio_resampler: resampler,
95
96            ready: VecDeque::new(),
97        };
98
99        Ok(res)
100    }
101}
102
103/// Audio transcoder.
104///
105/// # Transcoder operation
106/// 1. Push a packet to the transcoder.
107/// 2. Take all packets from the transcoder until you get None.
108/// 3. If there are more packets to be transcoded, continue with 1.
109/// 4. Flush the transcoder.
110/// 5. Take all packets from the transcoder until you get None.
111pub struct AudioTranscoder {
112    audio_decoder: AudioDecoder,
113    audio_encoder: AudioEncoder,
114    audio_resampler: AudioResampler,
115
116    ready: VecDeque<Packet>,
117}
118
119impl AudioTranscoder {
120    /// Create a new transcoder for a given input and output.
121    pub fn new(
122        input: AudioCodecParameters,
123        output: AudioCodecParameters,
124    ) -> Result<AudioTranscoder, Error> {
125        AudioTranscoderBuilder::new(input, output)?.build()
126    }
127
128    /// Create a new transcoder builder for a given input and output.
129    pub fn builder(
130        input: AudioCodecParameters,
131        output: AudioCodecParameters,
132    ) -> Result<AudioTranscoderBuilder, Error> {
133        AudioTranscoderBuilder::new(input, output)
134    }
135
136    /// Get codec parameters of the transcoded stream.
137    pub fn codec_parameters(&self) -> AudioCodecParameters {
138        self.audio_encoder.codec_parameters()
139    }
140
141    /// Push a given packet to the transcoder.
142    ///
143    /// # Panics
144    /// The method panics if the operation is not expected (i.e. another
145    /// operation needs to be done).
146    pub fn push(&mut self, packet: Packet) -> Result<(), Error> {
147        self.try_push(packet).map_err(|err| err.unwrap_inner())
148    }
149
150    /// Push a given packet to the transcoder.
151    pub fn try_push(&mut self, packet: Packet) -> Result<(), CodecError> {
152        if !self.ready.is_empty() {
153            return Err(CodecError::again(
154                "take all transcoded packets before pushing another packet for transcoding",
155            ));
156        }
157
158        self.push_to_decoder(packet)?;
159
160        Ok(())
161    }
162
163    /// Flush the transcoder.
164    ///
165    /// # Panics
166    /// The method panics if the operation is not expected (i.e. another
167    /// operation needs to be done).
168    pub fn flush(&mut self) -> Result<(), Error> {
169        self.try_flush().map_err(|err| err.unwrap_inner())
170    }
171
172    /// Flush the transcoder.
173    pub fn try_flush(&mut self) -> Result<(), CodecError> {
174        if !self.ready.is_empty() {
175            return Err(CodecError::again(
176                "take all transcoded packets before flushing the transcoder",
177            ));
178        }
179
180        self.flush_decoder()?;
181        self.flush_resampler()?;
182        self.flush_encoder()?;
183
184        Ok(())
185    }
186
187    /// Take the next packet from the transcoder.
188    pub fn take(&mut self) -> Result<Option<Packet>, Error> {
189        Ok(self.ready.pop_front())
190    }
191
192    /// Push a given packet to the internal decoder, take all decoded frames
193    /// and pass them to the push_to_resampler method.
194    fn push_to_decoder(&mut self, packet: Packet) -> Result<(), CodecError> {
195        self.audio_decoder.try_push(packet)?;
196
197        while let Some(frame) = self.audio_decoder.take()? {
198            // XXX: this is to skip the initial padding; a correct solution
199            // would be to skip a given number of samples
200            if frame.pts().timestamp() >= 0 {
201                self.push_to_resampler(frame)?;
202            }
203        }
204
205        Ok(())
206    }
207
208    /// Push a given frame to the internal resampler, take all resampled frames
209    /// and pass them to the push_to_encoder method.
210    fn push_to_resampler(&mut self, frame: AudioFrame) -> Result<(), CodecError> {
211        self.audio_resampler.try_push(frame)?;
212
213        while let Some(frame) = self.audio_resampler.take()? {
214            self.push_to_encoder(frame)?;
215        }
216
217        Ok(())
218    }
219
220    /// Push a given frame to the internal encoder, take all encoded packets
221    /// and push them to the internal ready queue.
222    fn push_to_encoder(&mut self, frame: AudioFrame) -> Result<(), CodecError> {
223        self.audio_encoder.try_push(frame)?;
224
225        while let Some(packet) = self.audio_encoder.take()? {
226            self.push_to_output(packet);
227        }
228
229        Ok(())
230    }
231
232    /// Push a given packet to the output buffer.
233    fn push_to_output(&mut self, packet: Packet) {
234        self.ready.push_back(packet);
235    }
236
237    /// Flush the internal decoder, take all decoded frames and pass them to
238    /// the push_to_resampler method.
239    fn flush_decoder(&mut self) -> Result<(), CodecError> {
240        self.audio_decoder.try_flush()?;
241
242        while let Some(frame) = self.audio_decoder.take()? {
243            self.push_to_resampler(frame)?;
244        }
245
246        Ok(())
247    }
248
249    /// Flush the internal resampler, take all resampled frames and pass them
250    /// to the push_to_encoder method.
251    fn flush_resampler(&mut self) -> Result<(), CodecError> {
252        self.audio_resampler.try_flush()?;
253
254        while let Some(frame) = self.audio_resampler.take()? {
255            self.push_to_encoder(frame)?;
256        }
257
258        Ok(())
259    }
260
261    /// Flush the internal encoder, take all encoded packets and push them into
262    /// the internal ready queue.
263    fn flush_encoder(&mut self) -> Result<(), CodecError> {
264        self.audio_encoder.try_flush()?;
265
266        while let Some(packet) = self.audio_encoder.take()? {
267            self.push_to_output(packet);
268        }
269
270        Ok(())
271    }
272}