27#include <fdk-aac/aacdecoder_lib.h>
28#include <fdk-aac/aacenc_lib.h>
30#include "dsp_fdk_impl.h"
32#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ < 202003L))
43static const char* enc_err_str(AACENC_ERROR err)
49 case AACENC_INVALID_HANDLE:
50 return "AACENC_INVALID_HANDLE";
51 case AACENC_MEMORY_ERROR:
52 return "AACENC_MEMORY_ERROR";
53 case AACENC_UNSUPPORTED_PARAMETER:
54 return "AACENC_UNSUPPORTED_PARAMETER";
55 case AACENC_INVALID_CONFIG:
56 return "AACENC_INVALID_CONFIG";
57 case AACENC_INIT_ERROR:
58 return "AACENC_INIT_ERROR";
59 case AACENC_INIT_AAC_ERROR:
60 return "AACENC_INIT_AAC_ERROR";
61 case AACENC_INIT_SBR_ERROR:
62 return "AACENC_INIT_SBR_ERROR";
63 case AACENC_INIT_TP_ERROR:
64 return "AACENC_INIT_TP_ERROR";
65 case AACENC_INIT_META_ERROR:
66 return "AACENC_INIT_META_ERROR";
67#ifdef AACENC_INIT_MPS_ERROR
68 case AACENC_INIT_MPS_ERROR:
69 return "AACENC_INIT_MPS_ERROR";
71 case AACENC_ENCODE_ERROR:
72 return "AACENC_ENCODE_ERROR";
73 case AACENC_ENCODE_EOF:
74 return "AACENC_ENCODE_EOF";
76 return "AACENC_UNKNOWN";
80static const char* dec_err_str(AAC_DECODER_ERROR err)
86 case AAC_DEC_OUT_OF_MEMORY:
87 return "AAC_DEC_OUT_OF_MEMORY";
89 return "AAC_DEC_UNKNOWN";
90 case aac_dec_sync_error_start:
91 return "aac_dec_sync_error_start";
92 case AAC_DEC_TRANSPORT_SYNC_ERROR:
93 return "AAC_DEC_TRANSPORT_SYNC_ERROR";
94 case AAC_DEC_NOT_ENOUGH_BITS:
95 return "AAC_DEC_NOT_ENOUGH_BITS";
96 case aac_dec_sync_error_end:
97 return "aac_dec_sync_error_end";
98 case aac_dec_init_error_start:
99 return "aac_dec_init_error_start";
100 case AAC_DEC_INVALID_HANDLE:
101 return "AAC_DEC_INVALID_HANDLE";
102 case AAC_DEC_UNSUPPORTED_FORMAT:
103 return "AAC_DEC_UNSUPPORTED_FORMAT";
104 case AAC_DEC_UNSUPPORTED_ER_FORMAT:
105 return "AAC_DEC_UNSUPPORTED_ER_FORMAT";
106 case AAC_DEC_UNSUPPORTED_EPCONFIG:
107 return "AAC_DEC_UNSUPPORTED_EPCONFIG";
108 case AAC_DEC_UNSUPPORTED_MULTILAYER:
109 return "AAC_DEC_UNSUPPORTED_MULTILAYER";
110 case AAC_DEC_UNSUPPORTED_CHANNELCONFIG:
111 return "AAC_DEC_UNSUPPORTED_CHANNELCONFIG";
112 case AAC_DEC_UNSUPPORTED_SAMPLINGRATE:
113 return "AAC_DEC_UNSUPPORTED_SAMPLINGRATE";
114 case AAC_DEC_INVALID_SBR_CONFIG:
115 return "AAC_DEC_INVALID_SBR_CONFIG";
116 case AAC_DEC_SET_PARAM_FAIL:
117 return "AAC_DEC_SET_PARAM_FAIL";
118 case AAC_DEC_NEED_TO_RESTART:
119 return "AAC_DEC_NEED_TO_RESTART";
120 case AAC_DEC_OUTPUT_BUFFER_TOO_SMALL:
121 return "AAC_DEC_OUTPUT_BUFFER_TOO_SMALL";
122 case aac_dec_init_error_end:
123 return "aac_dec_init_error_end";
124 case aac_dec_decode_error_start:
125 return "aac_dec_decode_error_start";
126 case AAC_DEC_TRANSPORT_ERROR:
127 return "AAC_DEC_TRANSPORT_ERROR";
128 case AAC_DEC_PARSE_ERROR:
129 return "AAC_DEC_PARSE_ERROR";
130 case AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD:
131 return "AAC_DEC_UNSUPPORTED_EXTENSION_PAYLOAD";
132 case AAC_DEC_DECODE_FRAME_ERROR:
133 return "AAC_DEC_DECODE_FRAME_ERROR";
134 case AAC_DEC_CRC_ERROR:
135 return "AAC_DEC_CRC_ERROR";
136 case AAC_DEC_INVALID_CODE_BOOK:
137 return "AAC_DEC_INVALID_CODE_BOOK";
138 case AAC_DEC_UNSUPPORTED_PREDICTION:
139 return "AAC_DEC_UNSUPPORTED_PREDICTION";
140 case AAC_DEC_UNSUPPORTED_CCE:
141 return "AAC_DEC_UNSUPPORTED_CCE";
142 case AAC_DEC_UNSUPPORTED_LFE:
143 return "AAC_DEC_UNSUPPORTED_LFE";
144 case AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA:
145 return "AAC_DEC_UNSUPPORTED_GAIN_CONTROL_DATA";
146 case AAC_DEC_UNSUPPORTED_SBA:
147 return "AAC_DEC_UNSUPPORTED_SBA";
148 case AAC_DEC_TNS_READ_ERROR:
149 return "AAC_DEC_TNS_READ_ERROR";
150 case AAC_DEC_RVLC_ERROR:
151 return "AAC_DEC_RVLC_ERROR";
152 case aac_dec_decode_error_end:
153 return "aac_dec_decode_error_end";
154 case aac_dec_anc_data_error_start:
155 return "aac_dec_anc_data_error_start";
156 case AAC_DEC_ANC_DATA_ERROR:
157 return "AAC_DEC_ANC_DATA_ERROR";
158 case AAC_DEC_TOO_SMALL_ANC_BUFFER:
159 return "AAC_DEC_TOO_SMALL_ANC_BUFFER";
160 case AAC_DEC_TOO_MANY_ANC_ELEMENTS:
161 return "AAC_DEC_TOO_MANY_ANC_ELEMENTS";
162 case aac_dec_anc_data_error_end:
163 return "aac_dec_anc_data_error_end";
165 return "AAC_DEC unknown value";
169static void log_dec_info(
const CStreamInfo* info,
void (*log)(
const char* fmt, ...))
175 "aacSampleRate: %d, "
179 "pChannelIndices: %p, "
180 "aacSampleRate: %d, "
183 "channelConfig: %d, "
185 "aacSamplesPerFrame: %d, "
186 "aacNumChannels: %d, "
188 "extSamplingRate: %d, "
192 "numLostAccessUnits: %d, "
193 "numTotalBytes: %" PRIu64
", "
194 "numBadBytes: %" PRIu64
", "
195 "numTotalAccessUnits: %" PRIu64
", "
196 "numBadAccessUnits: %" PRIu64
", "
197 "drcProgRefLev: %d, "
199 info->aacSampleRate, info->frameSize, info->numChannels, info->pChannelType,
200 info->pChannelIndices, info->aacSampleRate, info->profile, info->aot, info->channelConfig,
201 info->bitRate, info->aacSamplesPerFrame, info->aacNumChannels, info->extAot,
202 info->extSamplingRate, info->outputDelay, info->flags, (
int)info->epConfig,
203 info->numLostAccessUnits,
205 info->numTotalBytes, info->numBadBytes, info->numTotalAccessUnits, info->numBadAccessUnits,
207 (
int)info->drcProgRefLev, (
int)info->drcPresMode);
210static void log_enc_info(
const AACENC_InfoStruct* info, fdk_log_fkt_t log)
212 char confBuf[1024] = { 0 };
218 size_t remain =
sizeof(confBuf) - 1;
219 int rc = snprintf(confBuf, remain,
"{");
222 offset += (size_t)rc;
224 for (
size_t x = 0; x < 64; x++)
226 rc = snprintf(&confBuf[offset], remain - offset,
"0x%02x%s", (
int)info->confBuf[x],
227 (x > 0) ?
", " :
"");
232 rc = snprintf(confBuf, remain - offset,
"}");
238 "maxOutBufBytes : %u, "
240 "inBufFillLevel : %u, "
241 "inputChannels : %u, "
249 info->maxOutBufBytes, info->maxAncBytes, info->inBufFillLevel, info->inputChannels,
252 info->nDelay, info->nDelayCore,
254 confBuf, info->confSize);
257static const char* aac_enc_param_str(AACENC_PARAM param)
264 return "AACENC_BITRATE";
265 case AACENC_BITRATEMODE:
266 return "AACENC_BITRATEMODE";
267 case AACENC_SAMPLERATE:
268 return "AACENC_SAMPLERATE";
269 case AACENC_SBR_MODE:
270 return "AACENC_SBR_MODE";
271 case AACENC_GRANULE_LENGTH:
272 return "AACENC_GRANULE_LENGTH";
273 case AACENC_CHANNELMODE:
274 return "AACENC_CHANNELMODE";
275 case AACENC_CHANNELORDER:
276 return "AACENC_CHANNELORDER";
277 case AACENC_SBR_RATIO:
278 return "AACENC_SBR_RATIO";
279 case AACENC_AFTERBURNER:
280 return "AACENC_AFTERBURNER";
281 case AACENC_BANDWIDTH:
282 return "AACENC_BANDWIDTH";
283 case AACENC_PEAK_BITRATE:
284 return "AACENC_PEAK_BITRATE";
285 case AACENC_TRANSMUX:
286 return "AACENC_TRANSMUX";
287 case AACENC_HEADER_PERIOD:
288 return "AACENC_HEADER_PERIOD";
289 case AACENC_SIGNALING_MODE:
290 return "AACENC_SIGNALING_MODE";
291 case AACENC_TPSUBFRAMES:
292 return "AACENC_TPSUBFRAMES";
293 case AACENC_AUDIOMUXVER:
294 return "AACENC_AUDIOMUXVER";
295 case AACENC_PROTECTION:
296 return "AACENC_PROTECTION";
297 case AACENC_ANCILLARY_BITRATE:
298 return "AACENC_ANCILLARY_BITRATE";
299 case AACENC_METADATA_MODE:
300 return "AACENC_METADATA_MODE";
301 case AACENC_CONTROL_STATE:
302 return "AACENC_CONTROL_STATE";
304 return "AACENC_UNKNOWN";
308int fdk_aac_dsp_impl_init(
void** handle,
int encoder, fdk_log_fkt_t log)
315 HANDLE_AACENCODER* h = (HANDLE_AACENCODER*)handle;
316 AACENC_ERROR err = aacEncOpen(h, 0, 0);
317 if (err != AACENC_OK)
319 log(WLOG_ERROR,
"aacEncOpen failed with %s", enc_err_str(err));
325 HANDLE_AACDECODER* h = (HANDLE_AACDECODER*)handle;
326 assert(
nullptr == *h);
328 *h = aacDecoder_Open(TT_MP4_RAW, 1);
331 log(WLOG_ERROR,
"aacDecoder_Open failed");
338void fdk_aac_dsp_impl_uninit(
void** handle,
int encoder, fdk_log_fkt_t log)
345 HANDLE_AACENCODER* h = (HANDLE_AACENCODER*)handle;
346 AACENC_ERROR err = aacEncClose(h);
347 if (err != AACENC_OK)
348 log(WLOG_ERROR,
"aacEncClose failed with %s", enc_err_str(err));
352 HANDLE_AACDECODER* h = (HANDLE_AACDECODER*)handle;
354 aacDecoder_Close(*h);
360ssize_t fdk_aac_dsp_impl_decode_read(
void* handle,
void* dst,
size_t dstSize, fdk_log_fkt_t log)
363 assert((dstSize /
sizeof(INT_PCM)) <= INT_MAX);
365 const INT nrsamples = (INT)(dstSize /
sizeof(INT_PCM));
367 HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
368 AAC_DECODER_ERROR err = aacDecoder_DecodeFrame(self, dst, nrsamples, flags);
372 return fdk_aac_dsp_impl_stream_info(handle, 0, log);
373 case AAC_DEC_NOT_ENOUGH_BITS:
376 log(WLOG_ERROR,
"aacDecoder_DecodeFrame failed with %s", dec_err_str(err));
381static unsigned get_channelmode(
unsigned channels)
398 return MODE_1_2_2_2_1;
401 return MODE_7_1_BACK;
409int fdk_aac_dsp_impl_config(
void* handle,
size_t* pbuffersize,
int encoder,
unsigned samplerate,
410 unsigned channels,
unsigned bytes_per_second,
411 unsigned frames_per_packet, fdk_log_fkt_t log)
418 "fdk_aac_dsp_impl_config: samplerate: %ld, channels: %ld, bytes_pers_second: %ld",
419 samplerate, channels, bytes_per_second);
427 const struct t_param_pair params[] = { { AACENC_AOT, 2 },
428 { AACENC_SAMPLERATE, samplerate },
429 { AACENC_CHANNELMODE, get_channelmode(channels) },
430 { AACENC_CHANNELORDER, 0 },
431 { AACENC_BITRATE, bytes_per_second * 8 },
432 { AACENC_TRANSMUX, 0 },
433 { AACENC_AFTERBURNER, 1 } };
434 HANDLE_AACENCODER self =
nullptr;
436 self = (HANDLE_AACENCODER)handle;
439 AACENC_ERROR err = aacEncOpen(&self, 0, channels);
440 if (err != AACENC_OK)
442 log(WLOG_ERROR,
"aacEncOpen failed with %s", enc_err_str(err));
447 for (
size_t x = 0; x <
sizeof(params) /
sizeof(params[0]); x++)
449 const struct t_param_pair* param = ¶ms[x];
451 AACENC_ERROR err = aacEncoder_SetParam(self, param->param, param->value);
452 if (err != AACENC_OK)
454 log(WLOG_ERROR,
"aacEncoder_SetParam(%s, %d) failed with %s",
455 aac_enc_param_str(param->param), param->value, enc_err_str(err));
460 AACENC_ERROR err = aacEncEncode(self,
nullptr,
nullptr,
nullptr,
nullptr);
461 if (err != AACENC_OK)
463 log(WLOG_ERROR,
"aacEncEncode failed with %s", enc_err_str(err));
467 AACENC_InfoStruct info = { 0 };
468 err = aacEncInfo(self, &info);
469 if (err != AACENC_OK)
471 log(WLOG_ERROR,
"aacEncInfo failed with %s", enc_err_str(err));
477 *pbuffersize = info.maxOutBufBytes;
478 log_enc_info(&info, log);
483 err = aacEncClose(&self);
484 if (err != AACENC_OK)
485 log(WLOG_WARN,
"aacEncClose failed with %s", enc_err_str(err));
487 *pbuffersize =
sizeof(INT_PCM) * info.frameLength * info.inputChannels;
489 HANDLE_AACDECODER aacdec = (HANDLE_AACDECODER)handle;
491 UCHAR* asc[] = { info.confBuf };
492 UINT ascSize[] = { info.confSize };
496 AAC_DECODER_ERROR decerr = aacDecoder_ConfigRaw(aacdec, asc, ascSize);
497 if (decerr != AAC_DEC_OK)
499 log(WLOG_ERROR,
"aacDecoder_ConfigRaw failed with %s", dec_err_str(decerr));
506ssize_t fdk_aac_dsp_impl_decode_fill(
void* handle,
const void* data,
size_t size, fdk_log_fkt_t log)
511 UINT leftBytes = size;
512 HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
520 UCHAR* pBuffer[] = { cnv.puc };
521 const UINT bufferSize[] = { size };
524 assert(data || (size == 0));
526 AAC_DECODER_ERROR err = aacDecoder_Fill(self, pBuffer, bufferSize, &leftBytes);
527 if (err != AAC_DEC_OK)
529 log(WLOG_ERROR,
"aacDecoder_Fill failed with %s", dec_err_str(err));
535ssize_t fdk_aac_dsp_impl_stream_info(
void* handle,
int encoder, fdk_log_fkt_t log)
542 AACENC_InfoStruct info = { 0 };
543 HANDLE_AACENCODER self = (HANDLE_AACENCODER)handle;
544 AACENC_ERROR err = aacEncInfo(self, &info);
545 if (err != AACENC_OK)
547 log(WLOG_ERROR,
"aacEncInfo failed with %s", enc_err_str(err));
550 return info.maxOutBufBytes;
554 HANDLE_AACDECODER self = (HANDLE_AACDECODER)handle;
555 CStreamInfo* info = aacDecoder_GetStreamInfo(self);
558 log(WLOG_ERROR,
"aacDecoder_GetStreamInfo failed");
562 const size_t rsize =
sizeof(INT_PCM) * info->numChannels * info->frameSize;
563 return (ssize_t)rsize;
567ssize_t fdk_aac_dsp_impl_encode(
void* handle,
const void* data,
size_t size,
void* dst,
568 size_t dstSize, fdk_log_fkt_t log)
570 INT inSizes[] = { (INT)size };
571 INT inElSizes[] = {
sizeof(INT_PCM) };
572 INT inIdentifiers[] = { IN_AUDIO_DATA };
579 void* inBuffers[] = { cnv.pv };
581 const AACENC_BufDesc inBufDesc = {
584 .bufferIdentifiers = inIdentifiers,
586 .bufElSizes = inElSizes
589 INT outSizes[] = { (INT)dstSize };
590 INT outElSizes[] = { 1 };
591 INT outIdentifiers[] = { OUT_BITSTREAM_DATA };
592 void* outBuffers[] = { dst };
593 const AACENC_BufDesc outBufDesc = { .numBufs = 1,
595 .bufferIdentifiers = outIdentifiers,
596 .bufSizes = outSizes,
597 .bufElSizes = outElSizes };
599 const AACENC_InArgs inArgs = { .numInSamples =
600 (INT)(size /
sizeof(INT_PCM)),
602 AACENC_OutArgs outArgs = { 0 };
604 HANDLE_AACENCODER self = (HANDLE_AACENCODER)handle;
609 AACENC_ERROR err = aacEncEncode(self, &inBufDesc, &outBufDesc, &inArgs, &outArgs);
610 if (err != AACENC_OK)
612 log(WLOG_ERROR,
"aacEncEncode failed with %s", enc_err_str(err));
615 return outArgs.numOutBytes;