ac_ffmpeg/codec/audio/
transcoder.rsuse std::collections::VecDeque;
use crate::Error;
use crate::{
codec::{
audio::{
AudioDecoder, AudioDecoderBuilder, AudioEncoder, AudioEncoderBuilder, AudioFrame,
AudioResampler,
},
AudioCodecParameters, CodecError, Decoder, Encoder,
},
packet::Packet,
time::TimeBase,
};
pub struct AudioTranscoderBuilder {
input: AudioCodecParameters,
output: AudioCodecParameters,
decoder_builder: AudioDecoderBuilder,
encoder_builder: AudioEncoderBuilder,
}
impl AudioTranscoderBuilder {
fn new(input: AudioCodecParameters, output: AudioCodecParameters) -> Result<Self, Error> {
let decoder_builder = AudioDecoder::from_codec_parameters(&input)?;
let encoder_builder = AudioEncoder::from_codec_parameters(&output)?;
let res = Self {
input,
output,
decoder_builder,
encoder_builder,
};
Ok(res)
}
pub fn set_decoder_option<V>(mut self, name: &str, value: V) -> Self
where
V: ToString,
{
self.decoder_builder = self.decoder_builder.set_option(name, value);
self
}
pub fn set_encoder_option<V>(mut self, name: &str, value: V) -> Self
where
V: ToString,
{
self.encoder_builder = self.encoder_builder.set_option(name, value);
self
}
pub fn build(self) -> Result<AudioTranscoder, Error> {
let decoder = self
.decoder_builder
.time_base(TimeBase::new(1, self.input.sample_rate()))
.build()?;
let encoder = self
.encoder_builder
.time_base(TimeBase::new(1, self.output.sample_rate()))
.build()?;
let source_channel_layout = self.input.channel_layout();
let target_channel_layout = self.output.channel_layout();
let resampler = AudioResampler::builder()
.source_channel_layout(source_channel_layout.to_owned())
.source_sample_format(self.input.sample_format())
.source_sample_rate(self.input.sample_rate())
.target_channel_layout(target_channel_layout.to_owned())
.target_sample_format(self.output.sample_format())
.target_sample_rate(self.output.sample_rate())
.target_frame_samples(encoder.samples_per_frame())
.build()?;
let res = AudioTranscoder {
audio_decoder: decoder,
audio_encoder: encoder,
audio_resampler: resampler,
ready: VecDeque::new(),
};
Ok(res)
}
}
pub struct AudioTranscoder {
audio_decoder: AudioDecoder,
audio_encoder: AudioEncoder,
audio_resampler: AudioResampler,
ready: VecDeque<Packet>,
}
impl AudioTranscoder {
pub fn new(
input: AudioCodecParameters,
output: AudioCodecParameters,
) -> Result<AudioTranscoder, Error> {
AudioTranscoderBuilder::new(input, output)?.build()
}
pub fn builder(
input: AudioCodecParameters,
output: AudioCodecParameters,
) -> Result<AudioTranscoderBuilder, Error> {
AudioTranscoderBuilder::new(input, output)
}
pub fn codec_parameters(&self) -> AudioCodecParameters {
self.audio_encoder.codec_parameters()
}
pub fn push(&mut self, packet: Packet) -> Result<(), Error> {
self.try_push(packet).map_err(|err| err.unwrap_inner())
}
pub fn try_push(&mut self, packet: Packet) -> Result<(), CodecError> {
if !self.ready.is_empty() {
return Err(CodecError::again(
"take all transcoded packets before pushing another packet for transcoding",
));
}
self.push_to_decoder(packet)?;
Ok(())
}
pub fn flush(&mut self) -> Result<(), Error> {
self.try_flush().map_err(|err| err.unwrap_inner())
}
pub fn try_flush(&mut self) -> Result<(), CodecError> {
if !self.ready.is_empty() {
return Err(CodecError::again(
"take all transcoded packets before flushing the transcoder",
));
}
self.flush_decoder()?;
self.flush_resampler()?;
self.flush_encoder()?;
Ok(())
}
pub fn take(&mut self) -> Result<Option<Packet>, Error> {
Ok(self.ready.pop_front())
}
fn push_to_decoder(&mut self, packet: Packet) -> Result<(), CodecError> {
self.audio_decoder.try_push(packet)?;
while let Some(frame) = self.audio_decoder.take()? {
if frame.pts().timestamp() >= 0 {
self.push_to_resampler(frame)?;
}
}
Ok(())
}
fn push_to_resampler(&mut self, frame: AudioFrame) -> Result<(), CodecError> {
self.audio_resampler.try_push(frame)?;
while let Some(frame) = self.audio_resampler.take()? {
self.push_to_encoder(frame)?;
}
Ok(())
}
fn push_to_encoder(&mut self, frame: AudioFrame) -> Result<(), CodecError> {
self.audio_encoder.try_push(frame)?;
while let Some(packet) = self.audio_encoder.take()? {
self.push_to_output(packet);
}
Ok(())
}
fn push_to_output(&mut self, packet: Packet) {
self.ready.push_back(packet);
}
fn flush_decoder(&mut self) -> Result<(), CodecError> {
self.audio_decoder.try_flush()?;
while let Some(frame) = self.audio_decoder.take()? {
self.push_to_resampler(frame)?;
}
Ok(())
}
fn flush_resampler(&mut self) -> Result<(), CodecError> {
self.audio_resampler.try_flush()?;
while let Some(frame) = self.audio_resampler.take()? {
self.push_to_encoder(frame)?;
}
Ok(())
}
fn flush_encoder(&mut self) -> Result<(), CodecError> {
self.audio_encoder.try_flush()?;
while let Some(packet) = self.audio_encoder.take()? {
self.push_to_output(packet);
}
Ok(())
}
}