#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include "ixheaac_type_def.h"
#include "ixheaac_error_standards.h"
#include "ixheaacd_error_handler.h"
#include "ixheaacd_apicmd_standards.h"
#include "ixheaacd_memory_standards.h"
#include "ixheaacd_aac_config.h"
#include "impd_apicmd_standards.h"
#include "impd_drc_config_params.h"
#define DRC_DEFAULT_MOBILE_REF_LEVEL 64
#define DRC_DEFAULT_MOBILE_DRC_CUT 127
#define DRC_DEFAULT_MOBILE_DRC_BOOST 127
#define DRC_DEFAULT_MOBILE_DRC_HEAVY 1
#define DRC_DEFAULT_MOBILE_ENC_LEVEL (-1)
#define MAX_CHANNEL_COUNT 8
#define MAX_MEM_ALLOCS 100
#define IA_MAX_OUTPUT_PCM_SIZE (3)
#define IA_MAX_USAC_CH (2)
#define IA_MAX_OUT_SAMPLES_PER_FRAME (4096)
#define IA_DRC_DEC_IN_OUT_BUF_SIZE \
(IA_MAX_USAC_CH * IA_MAX_OUT_SAMPLES_PER_FRAME * IA_MAX_OUTPUT_PCM_SIZE)
class Codec {
public:
IA_ERRORCODE initDecoder(const uint8_t* data, size_t size, bool isADTS);
IA_ERRORCODE initXAACDecoder(bool isADTS);
IA_ERRORCODE initXAACDrc(const uint8_t* data, size_t size);
IA_ERRORCODE deInitXAACDecoder();
IA_ERRORCODE deInitMPEGDDDrc();
IA_ERRORCODE configXAACDecoder(uint8_t* inBuffer, uint32_t inBufferLength,
int32_t* bytesConsumed);
IA_ERRORCODE initMPEGDDDrc();
int configMPEGDDrc();
IA_ERRORCODE decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
int32_t* bytesConsumed, int32_t* outBytes);
IA_ERRORCODE getXAACStreamInfo();
IA_ERRORCODE setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
int32_t drcRefLevel, int32_t drcHeavyCompression,
int32_t drEffectType);
private:
void* mXheaacCodecHandle;
void* mMpegDDrcHandle;
uint32_t mInputBufferSize;
uint32_t mOutputFrameLength;
int8_t* mInputBuffer;
int8_t* mOutputBuffer;
int32_t mSampFreq;
int32_t mNumChannels;
int32_t mPcmWdSz;
int32_t mChannelMask;
bool mIsCodecInitialized;
bool mIsCodecConfigFlushRequired;
int8_t* mDrcInBuf;
int8_t* mDrcOutBuf;
int32_t mMpegDDRCPresent;
int32_t mDRCFlag;
std::vector<void*> mMemoryVec;
std::vector<void*> mDrcMemoryVec;
};
extern "C" IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd,
WORD32 i_idx, pVOID pv_value);
extern "C" IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd,
WORD32 i_idx, pVOID pv_value);
extern "C" IA_ERRORCODE ixheaacd_get_config_param(pVOID p_ia_process_api_obj,
pWORD32 pi_samp_freq,
pWORD32 pi_num_chan,
pWORD32 pi_pcm_wd_sz,
pWORD32 pi_channel_mask);
IA_ERRORCODE Codec::initXAACDecoder(bool isADTS) {
mInputBufferSize = 0;
mInputBuffer = nullptr;
mOutputBuffer = nullptr;
uint32_t pui_api_size;
IA_ERRORCODE err_code =
ixheaacd_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
mXheaacCodecHandle = malloc(pui_api_size);
if (!mXheaacCodecHandle) {
return IA_FATAL_ERROR;
}
mMemoryVec.push_back(mXheaacCodecHandle);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr);
err_code = ia_drc_dec_api(nullptr, IA_API_CMD_GET_API_SIZE, 0, &pui_api_size);
mMpegDDrcHandle = malloc(pui_api_size);
if (!mMpegDDrcHandle) {
return IA_FATAL_ERROR;
}
mMemoryVec.push_back(mMpegDDrcHandle);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, nullptr);
uint32_t ui_mp4_flag = isADTS ? 0 : 1;
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &ui_mp4_flag);
uint32_t ui_proc_mem_tabs_size;
pVOID pv_alloc_ptr;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEMTABS_SIZE,
0, &ui_proc_mem_tabs_size);
pv_alloc_ptr = malloc(ui_proc_mem_tabs_size);
if (!pv_alloc_ptr) {
return IA_FATAL_ERROR;
}
mMemoryVec.push_back(pv_alloc_ptr);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
pv_alloc_ptr);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
for (int i = 0; i < 4; i++) {
int ui_size = 0, ui_alignment = 0, ui_type = 0;
err_code = ixheaacd_dec_api(mXheaacCodecHandle,
IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size);
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT,
i, &ui_alignment);
err_code = ixheaacd_dec_api(mXheaacCodecHandle,
IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type);
pv_alloc_ptr = NULL;
ui_alignment = (ui_alignment + sizeof(void *) - 1) / sizeof(void *);
ui_alignment = ui_alignment * sizeof(void *);
if (0 != posix_memalign(&pv_alloc_ptr, ui_alignment, ui_size)) {
return IA_FATAL_ERROR;
}
if (!pv_alloc_ptr) {
return IA_FATAL_ERROR;
}
mMemoryVec.push_back(pv_alloc_ptr);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_MEM_PTR, i,
pv_alloc_ptr);
if (ui_type == IA_MEMTYPE_INPUT) {
mInputBuffer = (pWORD8)pv_alloc_ptr;
mInputBufferSize = ui_size;
}
if (ui_type == IA_MEMTYPE_OUTPUT) mOutputBuffer = (pWORD8)pv_alloc_ptr;
}
return IA_NO_ERROR;
}
enum {
DRC_TARGET_LEVEL_OFFSET = 6,
DRC_ATTENUATION_OFFSET,
DRC_BOOST_OFFSET,
DRC_COMPRESS_OFFSET,
DRC_EFFECT_OFFSET
#ifdef LOUDNESS_LEVELING_SUPPORT
,
DRC_LOUDNESS_LEVELING_OFFSET
#endif
};
IA_ERRORCODE Codec::initXAACDrc(const uint8_t* data, size_t size) {
IA_ERRORCODE err_code = IA_NO_ERROR;
unsigned int ui_drc_val;
size_t targetLevelOffset =
std::min((size_t)DRC_TARGET_LEVEL_OFFSET, size - 1);
int32_t targetRefLevel = data[targetLevelOffset];
ui_drc_val = (unsigned int)targetRefLevel;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
&ui_drc_val);
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &ui_drc_val);
size_t attenuationOffset = std::min((size_t)DRC_ATTENUATION_OFFSET, size - 1);
int32_t attenuationFactor = data[attenuationOffset];
ui_drc_val = (unsigned int)attenuationFactor;
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &ui_drc_val);
size_t boostOffset = std::min((size_t)DRC_BOOST_OFFSET, size - 1);
int32_t boostFactor = data[boostOffset];
ui_drc_val = (unsigned int)boostFactor;
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &ui_drc_val);
size_t compressOffset = std::min((size_t)DRC_COMPRESS_OFFSET, size - 1);
int32_t compressMode = data[compressOffset];
ui_drc_val = (unsigned int)compressMode;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
&ui_drc_val);
size_t effectOffset = std::min((size_t)DRC_EFFECT_OFFSET, size - 1);
int32_t effectType = data[effectOffset];
ui_drc_val = (unsigned int)effectType;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &ui_drc_val);
#ifdef LOUDNESS_LEVELING_SUPPORT
size_t flagOffset = std::min((size_t)DRC_LOUDNESS_LEVELING_OFFSET, size - 1);
uint8_t loudnessFlag = data[flagOffset];
ui_drc_val = (unsigned int)loudnessFlag;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING, &ui_drc_val);
#endif
return IA_NO_ERROR;
}
IA_ERRORCODE Codec::deInitXAACDecoder() {
IA_ERRORCODE err_code = IA_NO_ERROR;
if (mXheaacCodecHandle) {
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INPUT_OVER, 0, nullptr);
}
for (void* buf : mMemoryVec) {
if (buf) free(buf);
}
mMemoryVec.clear();
mXheaacCodecHandle = nullptr;
return err_code;
}
IA_ERRORCODE Codec::deInitMPEGDDDrc() {
for (void* buf : mDrcMemoryVec) {
if (buf) free(buf);
}
mDrcMemoryVec.clear();
return IA_NO_ERROR;
}
IA_ERRORCODE Codec::configXAACDecoder(uint8_t* inBuffer,
uint32_t inBufferLength,
int32_t* bytesConsumed) {
if (mInputBufferSize < inBufferLength) {
inBufferLength = mInputBufferSize;
}
memcpy(mInputBuffer, inBuffer, inBufferLength);
IA_ERRORCODE err_code = ixheaacd_dec_api(
mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
if (mIsCodecConfigFlushRequired) {
mIsCodecInitialized =
false;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_GA_HDR, nullptr);
} else {
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_PROCESS, nullptr);
}
uint32_t ui_init_done;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_DONE_QUERY, &ui_init_done);
err_code = ixheaacd_dec_api(
mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, bytesConsumed);
if (ui_init_done) {
err_code = getXAACStreamInfo();
mIsCodecInitialized = true;
err_code = configMPEGDDrc();
}
return IA_NO_ERROR;
}
IA_ERRORCODE Codec::initMPEGDDDrc() {
IA_ERRORCODE err_code = IA_NO_ERROR;
for (int i = 0; i < (WORD32)2; i++) {
WORD32 ui_size, ui_alignment, ui_type;
pVOID pv_alloc_ptr;
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_SIZE, i,
&ui_size);
err_code = ia_drc_dec_api(
mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEM_INFO_TYPE, i,
&ui_type);
pv_alloc_ptr = malloc(ui_size);
if (pv_alloc_ptr == nullptr) {
return IA_FATAL_ERROR;
}
mDrcMemoryVec.push_back(pv_alloc_ptr);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, i,
pv_alloc_ptr);
}
mDrcInBuf = (int8_t*)malloc(IA_DRC_DEC_IN_OUT_BUF_SIZE);
if (mDrcInBuf == nullptr) {
return IA_FATAL_ERROR;
}
mDrcMemoryVec.push_back(mDrcInBuf);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 2, mDrcInBuf);
mDrcOutBuf = (int8_t*)malloc(IA_DRC_DEC_IN_OUT_BUF_SIZE);
if (mDrcOutBuf == nullptr) {
return IA_FATAL_ERROR;
}
mDrcMemoryVec.push_back(mDrcOutBuf);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEM_PTR, 3, mDrcOutBuf);
return IA_NO_ERROR;
}
int Codec::configMPEGDDrc() {
IA_ERRORCODE err_code = IA_NO_ERROR;
int i_effect_type;
int i_loud_norm;
int i_target_loudness;
unsigned int i_sbr_mode;
uint32_t ui_proc_mem_tabs_size = 0;
pVOID pv_alloc_ptr = NULL;
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &mNumChannels);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
&i_effect_type);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
err_code = ixheaacd_dec_api(
mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
&i_loud_norm);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &i_sbr_mode);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_MEMTABS_SIZE, 0,
&ui_proc_mem_tabs_size);
pv_alloc_ptr = malloc(ui_proc_mem_tabs_size);
if (pv_alloc_ptr == NULL) {
return IA_FATAL_ERROR;
}
memset(pv_alloc_ptr, 0, ui_proc_mem_tabs_size);
mMemoryVec.push_back(pv_alloc_ptr);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_MEMTABS_PTR, 0,
pv_alloc_ptr);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, nullptr);
deInitMPEGDDDrc();
err_code = initMPEGDDDrc();
if (err_code != IA_NO_ERROR) {
deInitMPEGDDDrc();
return err_code;
}
{
VOID* p_array[2][16];
WORD32 ii;
WORD32 buf_sizes[2][16];
WORD32 num_elements;
WORD32 num_config_ext;
WORD32 bit_str_fmt = 1;
WORD32 uo_num_chan;
memset(buf_sizes, 0, 32 * sizeof(WORD32));
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_BUF_SIZES,
&buf_sizes[0][0]);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_EXT_ELE_PTR, &p_array);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_SET_BUFF_PTR, nullptr);
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_NUM_ELE, &num_elements);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_NUM_CONFIG_EXT,
&num_config_ext);
for (ii = 0; ii < num_config_ext; ii++) {
if (buf_sizes[0][ii] > 0) {
memcpy(mDrcInBuf, p_array[0][ii], buf_sizes[0][ii]);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IL_BS, 0,
&buf_sizes[0][ii]);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_CPY_IL_BSF_BUFF, nullptr);
mDRCFlag = 1;
}
}
for (ii = 0; ii < num_elements; ii++) {
if (buf_sizes[1][ii] > 0) {
memcpy(mDrcInBuf, p_array[1][ii], buf_sizes[1][ii]);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_IC_BS, 0,
&buf_sizes[1][ii]);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_CPY_IC_BSF_BUFF, nullptr);
mDRCFlag = 1;
}
}
if (mDRCFlag == 1) {
mMpegDDRCPresent = 1;
} else {
mMpegDDRCPresent = 0;
}
if (mMpegDDRCPresent == 1) {
WORD32 interface_is_present = 1;
if (i_sbr_mode != 0) {
if (i_sbr_mode == 1) {
mOutputFrameLength = 2048;
} else if (i_sbr_mode == 3) {
mOutputFrameLength = 4096;
} else {
mOutputFrameLength = 1024;
}
} else {
mOutputFrameLength = 4096;
}
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_FRAME_SIZE,
(WORD32*)&mOutputFrameLength);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_INT_PRESENT,
&interface_is_present);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_CPY_IN_BSF_BUFF, nullptr);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_PROCESS, nullptr);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_NUM_CHANNELS, &uo_num_chan);
}
}
return err_code;
}
IA_ERRORCODE Codec::initDecoder(const uint8_t* data, size_t size, bool isADTS) {
IA_ERRORCODE err_code = IA_NO_ERROR;
err_code = initXAACDecoder(isADTS);
if (err_code != IA_NO_ERROR) {
deInitXAACDecoder();
return IA_FATAL_ERROR;
}
err_code = initXAACDrc(data, size);
return IA_NO_ERROR;
}
IA_ERRORCODE Codec::decodeXAACStream(uint8_t* inBuffer, uint32_t inBufferLength,
int32_t* bytesConsumed,
int32_t* outBytes) {
if (mInputBufferSize < inBufferLength) {
inBufferLength = mInputBufferSize;
}
if (!mIsCodecInitialized) {
configXAACDecoder(inBuffer, inBufferLength, bytesConsumed);
}
memcpy(mInputBuffer, inBuffer, inBufferLength);
IA_ERRORCODE err_code = ixheaacd_dec_api(
mXheaacCodecHandle, IA_API_CMD_SET_INPUT_BYTES, 0, &inBufferLength);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE,
IA_CMD_TYPE_DO_EXECUTE, nullptr);
uint32_t ui_exec_done;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_EXECUTE,
IA_CMD_TYPE_DONE_QUERY, &ui_exec_done);
if (ui_exec_done != 1) {
VOID* p_array; WORD32 buf_size = 0; WORD32 bit_str_fmt = 1;
WORD32 gain_stream_flag = 1;
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_LEN, &buf_size);
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_GAIN_PAYLOAD_BUF, &p_array);
if (buf_size > 0) {
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_PARAM_BITS_FORMAT, &bit_str_fmt);
memcpy(mDrcInBuf, p_array, buf_size);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES_BS,
0, &buf_size);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_GAIN_STREAM_FLAG, &gain_stream_flag);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_INIT,
IA_CMD_TYPE_INIT_CPY_BSF_BUFF, nullptr);
mMpegDDRCPresent = 1;
}
}
err_code = ixheaacd_dec_api(
mXheaacCodecHandle, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, bytesConsumed);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_OUTPUT_BYTES,
0, outBytes);
if (mMpegDDRCPresent == 1) {
memcpy(mDrcInBuf, mOutputBuffer, *outBytes);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_INPUT_BYTES, 0,
outBytes);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_EXECUTE,
IA_CMD_TYPE_DO_EXECUTE, nullptr);
memcpy(mOutputBuffer, mDrcOutBuf, *outBytes);
}
return IA_NO_ERROR;
}
IA_ERRORCODE Codec::getXAACStreamInfo() {
IA_ERRORCODE err_code = IA_NO_ERROR;
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ, &mSampFreq);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS,
&mNumChannels);
if (mNumChannels > MAX_CHANNEL_COUNT) {
return IA_FATAL_ERROR;
}
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, &mPcmWdSz);
if ((mPcmWdSz / 8) != 2) {
return IA_FATAL_ERROR;
}
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MASK,
&mChannelMask);
uint32_t ui_channel_mode;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_CHANNEL_MODE,
&ui_channel_mode);
uint32_t ui_sbr_mode;
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_SBR_MODE, &ui_sbr_mode);
mOutputFrameLength = 1024 * (1 + ui_sbr_mode);
return IA_NO_ERROR;
}
IA_ERRORCODE Codec::setXAACDRCInfo(int32_t drcCut, int32_t drcBoost,
int32_t drcRefLevel,
int32_t drcHeavyCompression,
int32_t drEffectType) {
IA_ERRORCODE err_code = IA_NO_ERROR;
int32_t ui_drc_enable = 1;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_ENABLE,
&ui_drc_enable);
if (drcCut != -1) {
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_CUT, &drcCut);
}
if (drcBoost != -1) {
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_BOOST, &drcBoost);
}
if (drcRefLevel != -1) {
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LEVEL,
&drcRefLevel);
}
if (drcRefLevel != -1) {
err_code =
ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_DRC_TARGET_LOUDNESS, &drcRefLevel);
}
if (drcHeavyCompression != -1) {
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_HEAVY_COMP,
&drcHeavyCompression);
}
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_DRC_EFFECT_TYPE, &drEffectType);
int32_t i_effect_type, i_target_loudness, i_loud_norm;
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_EFFECT_TYPE,
&i_effect_type);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_EFFECT_TYPE, &i_effect_type);
err_code = ixheaacd_dec_api(
mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_TARGET_LOUDNESS, &i_target_loudness);
err_code =
ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_TARGET_LOUDNESS, &i_target_loudness);
err_code = ixheaacd_dec_api(mXheaacCodecHandle, IA_API_CMD_GET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_DRC_LOUD_NORM,
&i_loud_norm);
err_code = ia_drc_dec_api(mMpegDDrcHandle, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_LOUD_NORM, &i_loud_norm);
return IA_NO_ERROR;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
int status;
int num_proc_iterations = 0;
if (size < 1) return 0;
Codec* codec = new Codec();
bool isADTS = false;
if (size >= 2) {
if ((data[0] == 0xFF) && ((data[1] & 0xF0) == 0xF0)) {
isADTS = true;
}
}
status = codec->initDecoder(data, size, isADTS);
if (0 == status) {
int32_t bytesConsumed = 0;
status = codec->configXAACDecoder((uint8_t*)data, size, &bytesConsumed);
while ((int32_t)size > bytesConsumed) {
int32_t numOutBytes;
size -= bytesConsumed;
data += bytesConsumed;
status = codec->decodeXAACStream((uint8_t*)data, size, &bytesConsumed,
&numOutBytes);
num_proc_iterations++;
if (num_proc_iterations > 500)
break;
if (0 == bytesConsumed) bytesConsumed = 4;
}
}
status = codec->deInitXAACDecoder();
status = codec->deInitMPEGDDDrc();
delete codec;
return 0;
}