1use std::cmp;
2use std::fmt::{self, Display, Debug};
3use std::mem::{self, MaybeUninit};
4use std::os::raw::{c_void, c_uint, c_int};
5use std::ptr;
6
7use fdk_aac_sys as sys;
8
9pub use sys::AACENC_InfoStruct as InfoStruct;
10
11pub struct EncoderError(sys::AACENC_ERROR);
12
13impl EncoderError {
14 fn message(&self) -> &'static str {
15 match self.0 {
16 sys::AACENC_ERROR_AACENC_OK => "Ok",
17 sys::AACENC_ERROR_AACENC_INVALID_HANDLE => "Handle passed to function call was invalid.",
18 sys::AACENC_ERROR_AACENC_MEMORY_ERROR => "Memory allocation failed.",
19 sys::AACENC_ERROR_AACENC_UNSUPPORTED_PARAMETER => "Parameter not available.",
20 sys::AACENC_ERROR_AACENC_INVALID_CONFIG => "Configuration not provided.",
21 sys::AACENC_ERROR_AACENC_INIT_ERROR => "General initialization error.",
22 sys::AACENC_ERROR_AACENC_INIT_AAC_ERROR => "AAC library initialization error.",
23 sys::AACENC_ERROR_AACENC_INIT_SBR_ERROR => "SBR library initialization error.",
24 sys::AACENC_ERROR_AACENC_INIT_TP_ERROR => "Transport library initialization error.",
25 sys::AACENC_ERROR_AACENC_INIT_META_ERROR => "Meta data library initialization error.",
26 sys::AACENC_ERROR_AACENC_INIT_MPS_ERROR => "MPS library initialization error.",
27 sys::AACENC_ERROR_AACENC_ENCODE_ERROR => "The encoding process was interrupted by an unexpected error.",
28 sys::AACENC_ERROR_AACENC_ENCODE_EOF => "End of file reached.",
29 _ => "Unknown error",
30 }
31 }
32}
33
34impl Debug for EncoderError {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 write!(f, "EncoderError {{ code: {:?}, message: {:?} }}", self.0 as c_int, self.message())
37 }
38}
39
40impl Display for EncoderError {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 write!(f, "{}", self.message())
43 }
44}
45
46fn check(e: sys::AACENC_ERROR) -> Result<(), EncoderError> {
47 if e == sys::AACENC_ERROR_AACENC_OK {
48 Ok(())
49 } else {
50 Err(EncoderError(e))
51 }
52}
53
54struct EncoderHandle {
55 ptr: sys::HANDLE_AACENCODER,
56}
57
58unsafe impl Send for EncoderHandle {}
59unsafe impl Sync for EncoderHandle {}
60
61impl EncoderHandle {
62 pub fn alloc(max_modules: usize, max_channels: usize) -> Result<Self, EncoderError> {
63 let mut ptr: sys::HANDLE_AACENCODER = ptr::null_mut();
64 check(unsafe {
65 sys::aacEncOpen(&mut ptr as *mut _, max_modules as c_uint, max_channels as c_uint)
66 })?;
67 Ok(EncoderHandle { ptr })
68 }
69}
70
71impl Drop for EncoderHandle {
72 fn drop(&mut self) {
73 unsafe { sys::aacEncClose(&mut self.ptr as *mut _); }
74 }
75}
76
77#[derive(Debug, Clone, Copy)]
78pub enum BitRate {
79 Cbr(u32),
80 VbrVeryLow,
81 VbrLow,
82 VbrMedium,
83 VbrHigh,
84 VbrVeryHigh,
85}
86
87#[derive(Debug, Clone, Copy)]
88pub enum ChannelMode {
89 Mono,
90 Stereo,
91}
92
93#[derive(Debug, Clone, Copy)]
94pub enum AudioObjectType {
95 Mpeg4LowComplexity,
99 Mpeg4HeAac,
103 Mpeg4HeAacV2,
109 Mpeg4LowDelay,
113 Mpeg4EnhancedLowDelay,
117 Mpeg2Aac,
121 Mpeg2HeAac,
125}
126
127pub struct EncoderParams {
128 pub bit_rate: BitRate,
129 pub sample_rate: u32,
130 pub transport: Transport,
131 pub channels: ChannelMode,
132 pub audio_object_type: AudioObjectType,
133}
134
135pub struct Encoder {
136 handle: EncoderHandle,
137}
138
139#[derive(Debug)]
140pub enum Transport {
141 Adts,
142 Raw,
143}
144
145#[derive(Debug)]
146pub struct EncodeInfo {
147 pub input_consumed: usize,
148 pub output_size: usize,
149}
150
151impl Encoder {
152 pub fn new(params: EncoderParams) -> Result<Self, EncoderError> {
153 let handle = EncoderHandle::alloc(0, 2 )?;
154
155 unsafe {
156 let aot = match params.audio_object_type {
157 AudioObjectType::Mpeg4LowComplexity => sys::AUDIO_OBJECT_TYPE_AOT_AAC_LC,
158 AudioObjectType::Mpeg4HeAac => sys::AUDIO_OBJECT_TYPE_AOT_SBR,
159 AudioObjectType::Mpeg4HeAacV2 => sys::AUDIO_OBJECT_TYPE_AOT_PS,
160 AudioObjectType::Mpeg4LowDelay => sys::AUDIO_OBJECT_TYPE_AOT_ER_AAC_LD,
161 AudioObjectType::Mpeg4EnhancedLowDelay => sys::AUDIO_OBJECT_TYPE_AOT_ER_AAC_ELD,
162 AudioObjectType::Mpeg2Aac => sys::AUDIO_OBJECT_TYPE_AOT_MP2_AAC_LC,
163 AudioObjectType::Mpeg2HeAac => sys::AUDIO_OBJECT_TYPE_AOT_MP2_SBR,
164 };
165
166 check(sys::aacEncoder_SetParam(handle.ptr, sys::AACENC_PARAM_AACENC_AOT, aot as u32))?;
167
168 let bitrate_mode = match params.bit_rate {
169 BitRate::Cbr(bitrate) => {
170 check(sys::aacEncoder_SetParam(handle.ptr, sys::AACENC_PARAM_AACENC_BITRATE, bitrate))?;
171 0
172 }
173 BitRate::VbrVeryLow => 1,
174 BitRate::VbrLow => 2,
175 BitRate::VbrMedium => 3,
176 BitRate::VbrHigh => 4,
177 BitRate::VbrVeryHigh => 5,
178 };
179
180 check(sys::aacEncoder_SetParam(handle.ptr, sys::AACENC_PARAM_AACENC_BITRATEMODE, bitrate_mode))?;
181
182 check(sys::aacEncoder_SetParam(handle.ptr, sys::AACENC_PARAM_AACENC_SAMPLERATE, params.sample_rate))?;
183
184 check(sys::aacEncoder_SetParam(handle.ptr, sys::AACENC_PARAM_AACENC_TRANSMUX, match params.transport {
185 Transport::Adts => 2,
186 Transport::Raw => 0,
187 }))?;
188
189 check(sys::aacEncoder_SetParam(handle.ptr, sys::AACENC_PARAM_AACENC_SBR_MODE, 0))?;
191
192 check(sys::aacEncoder_SetParam(
193 handle.ptr,
194 sys::AACENC_PARAM_AACENC_CHANNELMODE,
195 match params.channels {
196 ChannelMode::Mono => 1,
197 ChannelMode::Stereo => 2,
198 },
199 ))?;
200
201 check(sys::aacEncEncode(handle.ptr, ptr::null(), ptr::null(), ptr::null(), ptr::null_mut()))?;
203 }
204
205 Ok(Encoder { handle })
206 }
207
208 pub fn info(&self) -> Result<InfoStruct, EncoderError> {
209 let mut info = MaybeUninit::uninit();
210 check(unsafe { sys::aacEncInfo(self.handle.ptr, info.as_mut_ptr()) })?;
211 Ok(unsafe { info.assume_init() })
212 }
213
214 pub fn encode(&self, input: &[i16], output: &mut [u8]) -> Result<EncodeInfo, EncoderError> {
215 let input_len = cmp::min(i32::max_value() as usize, input.len()) as i32;
216
217 let mut input_buf = input.as_ptr() as *mut i16;
218 let mut input_buf_ident: c_int = sys::AACENC_BufferIdentifier_IN_AUDIO_DATA as c_int;
219 let mut input_buf_size: c_int = input_len as c_int;
220 let mut input_buf_el_size: c_int = mem::size_of::<i16>() as c_int;
221 let input_desc = sys::AACENC_BufDesc {
222 numBufs: 1,
223 bufs: &mut input_buf as *mut _ as *mut *mut c_void,
224 bufferIdentifiers: &mut input_buf_ident as *mut c_int,
225 bufSizes: &mut input_buf_size as *mut c_int,
226 bufElSizes: &mut input_buf_el_size as *mut c_int,
227 };
228
229 let mut output_buf = output.as_mut_ptr();
230 let mut output_buf_ident: c_int = sys::AACENC_BufferIdentifier_OUT_BITSTREAM_DATA as c_int;
231 let mut output_buf_size: c_int = output.len() as c_int;
232 let mut output_buf_el_size: c_int = mem::size_of::<u8>() as c_int;
233 let output_desc = sys::AACENC_BufDesc {
234 numBufs: 1,
235 bufs: &mut output_buf as *mut _ as *mut *mut c_void,
236 bufferIdentifiers: &mut output_buf_ident as *mut _,
237 bufSizes: &mut output_buf_size as *mut _,
238 bufElSizes: &mut output_buf_el_size as *mut _,
239 };
240
241 let in_args = sys::AACENC_InArgs {
242 numInSamples: input_len,
243 numAncBytes: 0,
244 };
245
246 let mut out_args = unsafe { mem::zeroed() };
247
248 check(unsafe { sys::aacEncEncode(self.handle.ptr, &input_desc, &output_desc, &in_args, &mut out_args) })?;
249
250 Ok(EncodeInfo {
251 output_size: out_args.numOutBytes as usize,
252 input_consumed: out_args.numInSamples as usize,
253 })
254 }
255}
256
257impl Debug for Encoder {
258 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
259 write!(f, "Encoder {{ handle: {:?} }}", self.handle.ptr)
260 }
261}