use std::fmt::{self, Display, Debug};
use std::os::raw::{c_uint, c_int};
use fdk_aac_sys as sys;
pub use sys::CStreamInfo as StreamInfo;
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct DecoderError(sys::AAC_DECODER_ERROR);
impl DecoderError {
pub const OUT_OF_MEMORY: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_OUT_OF_MEMORY);
pub const UNKNOWN: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNKNOWN);
pub const TRANSPORT_SYNC_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_TRANSPORT_SYNC_ERROR);
pub const NOT_ENOUGH_BITS: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_NOT_ENOUGH_BITS);
pub const INVALID_HANDLE: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_INVALID_HANDLE);
pub const UNSUPPORTED_AOT: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_AOT);
pub const UNSUPPORTED_FORMAT: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_FORMAT);
pub const UNSUPPORTED_ER_FORMAT: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_ER_FORMAT);
pub const UNSUPPORTED_EPCONFIG: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_EPCONFIG);
pub const UNSUPPORTED_MULTILAYER: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_MULTILAYER);
pub const UNSUPPORTED_CHANNELCONFIG: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_CHANNELCONFIG);
pub const UNSUPPORTED_SAMPLINGRATE: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_SAMPLINGRATE);
pub const INVALID_SBR_CONFIG: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_INVALID_SBR_CONFIG);
pub const SET_PARAM_FAIL: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_SET_PARAM_FAIL);
pub const NEED_TO_RESTART: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_NEED_TO_RESTART);
pub const OUTPUT_BUFFER_TOO_SMALL: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_OUTPUT_BUFFER_TOO_SMALL);
pub const TRANSPORT_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_TRANSPORT_ERROR);
pub const PARSE_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_PARSE_ERROR);
pub const UNSUPPORTED_EXTENSION_PAYLOAD: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD);
pub const DECODE_FRAME_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_DECODE_FRAME_ERROR);
pub const CRC_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_CRC_ERROR);
pub const INVALID_CODE_BOOK: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_INVALID_CODE_BOOK);
pub const UNSUPPORTED_PREDICTION: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_PREDICTION);
pub const UNSUPPORTED_CCE: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_CCE);
pub const UNSUPPORTED_LFE: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_LFE);
pub const UNSUPPORTED_GAIN_CONTROL_DATA: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA);
pub const UNSUPPORTED_SBA: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_SBA);
pub const TNS_READ_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_TNS_READ_ERROR);
pub const RVLC_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_RVLC_ERROR);
pub const ANC_DATA_ERROR: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_ANC_DATA_ERROR);
pub const TOO_SMALL_ANC_BUFFER: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_TOO_SMALL_ANC_BUFFER);
pub const TOO_MANY_ANC_ELEMENTS: DecoderError = DecoderError(sys::AAC_DECODER_ERROR_AAC_DEC_TOO_MANY_ANC_ELEMENTS);
pub fn message(&self) -> &'static str {
match self.0 {
sys::AAC_DECODER_ERROR_AAC_DEC_OK => "No error occurred. Output buffer is valid and error free.",
sys::AAC_DECODER_ERROR_AAC_DEC_OUT_OF_MEMORY => "Heap returned NULL pointer. Output buffer is invalid.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNKNOWN => "Error condition is of unknown reason, or from a another module. Output buffer is invalid.",
sys::AAC_DECODER_ERROR_aac_dec_sync_error_start => "Synchronization errors. Output buffer is invalid.",
sys::AAC_DECODER_ERROR_AAC_DEC_TRANSPORT_SYNC_ERROR => "The transport decoder had synchronization problems. Do not exit decoding. Just feed new bitstream data.",
sys::AAC_DECODER_ERROR_AAC_DEC_NOT_ENOUGH_BITS => "The input buffer ran out of bits.",
sys::AAC_DECODER_ERROR_aac_dec_init_error_start => "Initialization errors. Output buffer is invalid.",
sys::AAC_DECODER_ERROR_AAC_DEC_INVALID_HANDLE => "The handle passed to the function call was invalid (NULL).",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_AOT => "The AOT found in the configuration is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_FORMAT => "The bitstream format is not supported. ",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_ER_FORMAT => "The error resilience tool format is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_EPCONFIG => "The error protection format is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_MULTILAYER => "More than one layer for AAC scalable is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_CHANNELCONFIG => "The channel configuration (either number or arrangement) is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_SAMPLINGRATE => "The sample rate specified in the configuration is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_INVALID_SBR_CONFIG => "The SBR configuration is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_SET_PARAM_FAIL => "The parameter could not be set. Either the value was out of range or the parameter does not exist.",
sys::AAC_DECODER_ERROR_AAC_DEC_NEED_TO_RESTART => "The decoder needs to be restarted, since the required configuration change cannot be performed.",
sys::AAC_DECODER_ERROR_AAC_DEC_OUTPUT_BUFFER_TOO_SMALL => "The provided output buffer is too small.",
sys::AAC_DECODER_ERROR_aac_dec_decode_error_start => "Decode errors. Output buffer is valid but concealed.",
sys::AAC_DECODER_ERROR_AAC_DEC_TRANSPORT_ERROR => "The transport decoder encountered an unexpected error.",
sys::AAC_DECODER_ERROR_AAC_DEC_PARSE_ERROR => "Error while parsing the bitstream. Most probably it is corrupted, or the system crashed.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD => "Error while parsing the extension payload of the bitstream. The extension payload type found is not supported.",
sys::AAC_DECODER_ERROR_AAC_DEC_DECODE_FRAME_ERROR => "The parsed bitstream value is out of range. Most probably the bitstream is corrupt, or the system crashed.",
sys::AAC_DECODER_ERROR_AAC_DEC_CRC_ERROR => "The embedded CRC did not match.",
sys::AAC_DECODER_ERROR_AAC_DEC_INVALID_CODE_BOOK => "An invalid codebook was signaled. Most probably the bitstream is corrupt, or the system crashed.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_PREDICTION => "Predictor found, but not supported in the AAC Low Complexity profile. Most probably the bitstream is corrupt, or has a wrong format.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_CCE => "A CCE element was found which is not supported. Most probably the bitstream is corrupt, or has a wrong format.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_LFE => "A LFE element was found which is not supported. Most probably the bitstream is corrupt, or has a wrong format.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA => "Gain control data found but not supported. Most probably the bitstream is corrupt, or has a wrong format.",
sys::AAC_DECODER_ERROR_AAC_DEC_UNSUPPORTED_SBA => "SBA found, but currently not supported in the BSAC profile.",
sys::AAC_DECODER_ERROR_AAC_DEC_TNS_READ_ERROR => "Error while reading TNS data. Most probably the bitstream is corrupt or the system crashed.",
sys::AAC_DECODER_ERROR_AAC_DEC_RVLC_ERROR => "Error while decoding error resilient data.",
sys::AAC_DECODER_ERROR_aac_dec_anc_data_error_start => "Ancillary data errors. Output buffer is valid.",
sys::AAC_DECODER_ERROR_AAC_DEC_ANC_DATA_ERROR => "Non severe error concerning the ancillary data handling.",
sys::AAC_DECODER_ERROR_AAC_DEC_TOO_SMALL_ANC_BUFFER => "The registered ancillary data buffer is too small to receive the parsed data.",
sys::AAC_DECODER_ERROR_AAC_DEC_TOO_MANY_ANC_ELEMENTS => "More than the allowed number of ancillary data elements should be written to buffer.",
_ => "Unknown error",
}
}
}
impl Debug for DecoderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DecoderError {{ code: {:?}, message: {:?} }}", self.0 as c_int, self.message())
}
}
impl Display for DecoderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.message())
}
}
fn check(e: sys::AACENC_ERROR) -> Result<(), DecoderError> {
if e == sys::AAC_DECODER_ERROR_AAC_DEC_OK {
Ok(())
} else {
Err(DecoderError(e))
}
}
#[derive(Debug)]
pub struct Decoder {
handle: sys::HANDLE_AACDECODER,
}
unsafe impl Send for Decoder {}
unsafe impl Sync for Decoder {}
impl Decoder {
pub fn new(transport: Transport) -> Self {
let handle = match transport {
Transport::Raw => {
unsafe { sys::aacDecoder_Open(sys::TRANSPORT_TYPE_TT_MP4_RAW, 1) }
}
Transport::Adts => {
unsafe { sys::aacDecoder_Open(sys::TRANSPORT_TYPE_TT_MP4_ADTS, 1) }
}
};
Decoder { handle }
}
pub fn config_raw(&mut self, audio_specic_config: &[u8]) -> Result<(), DecoderError> {
unsafe {
let mut asc_ptr = audio_specic_config.as_ptr() as *mut u8;
let asc_len = audio_specic_config.len() as c_uint;
check(sys::aacDecoder_ConfigRaw(self.handle, &mut asc_ptr as *mut _, &asc_len as *const _))
}
}
pub fn set_min_output_channels(&mut self, channels: usize) -> Result<(), DecoderError> {
unsafe {
check(sys::aacDecoder_SetParam(self.handle,
sys::AACDEC_PARAM_AAC_PCM_MIN_OUTPUT_CHANNELS,
channels as i32))
}
}
pub fn set_max_output_channels(&mut self, channels: usize) -> Result<(), DecoderError> {
unsafe {
check(sys::aacDecoder_SetParam(self.handle,
sys::AACDEC_PARAM_AAC_PCM_MAX_OUTPUT_CHANNELS,
channels as i32))
}
}
pub fn fill(&mut self, data: &[u8]) -> Result<usize, DecoderError> {
unsafe {
let mut data_ptr = data.as_ptr() as *const u8 as *mut u8;
let data_len = data.len() as c_uint;
let mut bytes_valid: c_uint = data_len;
check(sys::aacDecoder_Fill(self.handle,
&mut data_ptr as *mut _,
&data_len as *const _,
&mut bytes_valid as *mut _))?;
Ok(data.len() - bytes_valid as usize)
}
}
pub fn decode_frame(&mut self, pcm: &mut [i16]) -> Result<(), DecoderError> {
unsafe {
check(sys::aacDecoder_DecodeFrame(self.handle,
pcm.as_mut_ptr() as *mut i16,
pcm.len() as c_int,
0))
}
}
pub fn decoded_frame_size(&self) -> usize {
let stream_info = self.stream_info();
stream_info.numChannels as usize * stream_info.frameSize as usize
}
pub fn stream_info(&self) -> &StreamInfo {
unsafe { &*sys::aacDecoder_GetStreamInfo(self.handle) }
}
}
impl Drop for Decoder {
fn drop(&mut self) {
unsafe { sys::aacDecoder_Close(self.handle); }
}
}
#[derive(Clone, Copy, Debug)]
pub enum Transport {
Raw,
Adts,
}