Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Akshay Ragir
ee7ac593ae WIP: Loudness leveling support for decoder 2025-07-23 11:28:03 +05:30
Rumaan Khan
bc0609771d add supp for linux 2025-07-01 15:56:13 +05:30
Rumaan Khan
63c8cb6ec9 mp4 supp changes 2025-06-27 18:08:29 +05:30
24 changed files with 725 additions and 45 deletions

View file

@ -50,6 +50,7 @@ function(libxaac_add_definitions)
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
add_definitions(-DX86_64 -D_X86_64_)
endif()
add_definitions(-DLOUDNESS_LEVELING_SUPPORT)
endfunction()
# Adds libraries needed for executables

View file

@ -246,7 +246,7 @@ IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_drc_dec_obj, WORD32 i_cmd, WORD32 i_idx,
case IA_API_CMD_SET_CONFIG_PARAM: {
switch (i_idx) {
case IA_DRC_DEC_CONFIG_PARAM_SAMP_FREQ: {
if (*pus_value < 8000 || *pus_value > 96000) {
if (*pus_value <= 0 || *pus_value > 96000) {
return IA_DRC_DEC_CONFIG_NON_FATAL_INVALID_SAMP_FREQ;
}
p_obj_drc->str_config.sampling_rate = *pus_value;
@ -328,6 +328,12 @@ IA_ERRORCODE ia_drc_dec_api(pVOID p_ia_drc_dec_obj, WORD32 i_cmd, WORD32 i_idx,
p_obj_drc->str_config.compress_set = 1;
break;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
case IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING: {
p_obj_drc->str_config.loudness_leveling_flag = *pus_value;
break;
}
#endif
default: { return -1; }
}
break;

View file

@ -63,6 +63,9 @@ typedef struct ia_drc_config_struct {
WORD32 apply_crossfade;
WORD32 is_config_changed;
WORD32 ln_dbgain_prev;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 loudness_leveling_flag;
#endif
} ia_drc_config_struct;
/* DRC bitsteam handler */

View file

@ -193,6 +193,9 @@ extern "C" {
#define UNIDRCCONFEXT_V1 0x2
#define UNIDRCLOUDEXT_EQ 0x1
#define UNIDRCINTERFACEEXT_EQ 0x1
#ifdef LOUDNESS_LEVELING_SUPPORT
#define UNIDRCCONFEXT_LEVELING (0x4)
#endif
#define LOUD_EQ_REQUEST_OFF 0x0
#define LOUD_EQ_REQUEST_LIGHT 0x1

View file

@ -46,4 +46,7 @@
#define IA_DRC_DEC_CONFIG_DRC_COMPRESS 0x0016
#define IA_DRC_DEC_CONFIG_PARAM_APPLY_CROSSFADE 0x0017
#define IA_DRC_DEC_CONFIG_PARAM_CONFIG_CHANGED 0x0018
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING 0x0019
#endif
#endif

View file

@ -28,6 +28,10 @@
#include "impd_drc_parser.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_rom.h"
#ifdef LOUDNESS_LEVELING_SUPPORT
#include "impd_drc_error_codes.h"
#include "ixheaacd_error_codes.h"
#endif
WORD32 impd_parse_loud_eq_instructions(
ia_bit_buf_struct* it_bit_buff,
ia_loud_eq_instructions_struct* loud_eq_instructions);
@ -646,6 +650,42 @@ WORD32 impd_parse_drc_ext_v1(ia_bit_buf_struct* it_bit_buff,
return 0;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
IA_ERROR_CODE impd_leveling_instructions(ia_bit_buf_struct* it_bit_buff,
ia_drc_config* pstr_drc_config) {
WORD32 i;
IA_ERROR_CODE err = IA_NO_ERROR;
WORD32 drc_instruction_uni_drc_count = pstr_drc_config->drc_instructions_uni_drc_count;
for (i = 0; i < drc_instruction_uni_drc_count; ++i) {
if ((pstr_drc_config->str_drc_instruction_str[i].drc_set_effect & (1 << 11)) != 0) {
pstr_drc_config->str_drc_instruction_str[i].leveling_present =
impd_read_bits_buf(it_bit_buff, 1);
if (pstr_drc_config->str_drc_instruction_str[i].leveling_present) {
WORD32 ducking_only_drc_set_present = impd_read_bits_buf(it_bit_buff, 1);
if (ducking_only_drc_set_present) {
pstr_drc_config->drc_instructions_uni_drc_count++;
if (pstr_drc_config->drc_instructions_uni_drc_count > DRC_INSTRUCTIONS_COUNT_MAX) {
return IA_XHEAAC_DEC_INIT_NONFATAL_MAX_INSTRUCTIONS_ERROR;
}
err = impd_parse_drc_instructions_uni_drc(
it_bit_buff, 1, pstr_drc_config,
&pstr_drc_config
->str_drc_instruction_str[pstr_drc_config->drc_instructions_uni_drc_count -
1]);
if (err) return err;
}
}
}
}
return err;
}
#endif
WORD32 impd_parse_filt_block(ia_bit_buf_struct* it_bit_buff,
ia_filt_block_struct* str_filter_block,
WORD32 block_count) {

View file

@ -58,10 +58,15 @@ impd_drc_dec_interface_process(ia_bit_buf_struct *it_bit_buff,
WORD32 *num_bits_read);
WORD32
impd_drc_dec_interface_add_effect_type(
ia_drc_interface_struct *pstr_drc_interface, WORD32 drc_effect_type,
WORD32 target_loudness, WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress);
impd_drc_dec_interface_add_effect_type(ia_drc_interface_struct *pstr_drc_interface,
WORD32 drc_effect_type, WORD32 target_loudness,
WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress
#ifdef LOUDNESS_LEVELING_SUPPORT
,
WORD32 loudness_leveling_flag
#endif
);
#define BITSTREAM_FILE_FORMAT_SPLIT 1
#define LIM_DEFAULT_THRESHOLD (0.89125094f)
@ -411,10 +416,15 @@ IA_ERRORCODE impd_drc_init(ia_drc_api_struct *p_obj_drc) {
p_obj_drc->str_config.compress = 1.0f;
err_code = impd_drc_dec_interface_add_effect_type(
p_obj_drc->str_payload.pstr_drc_interface,
p_obj_drc->str_config.effect_type, p_obj_drc->str_config.target_loudness,
p_obj_drc->str_config.loud_norm_flag, p_obj_drc->str_config.album_mode,
p_obj_drc->str_config.boost, p_obj_drc->str_config.compress);
p_obj_drc->str_payload.pstr_drc_interface, p_obj_drc->str_config.effect_type,
p_obj_drc->str_config.target_loudness, p_obj_drc->str_config.loud_norm_flag,
p_obj_drc->str_config.album_mode, p_obj_drc->str_config.boost,
p_obj_drc->str_config.compress
#ifdef LOUDNESS_LEVELING_SUPPORT
,
p_obj_drc->str_config.loudness_leveling_flag
#endif
);
if (err_code != IA_NO_ERROR) return err_code;

View file

@ -42,6 +42,11 @@ typedef struct {
typedef struct {
WORD32 interface_ext_count;
ia_specific_interface_extension_struct specific_interface_ext[EXT_COUNT_MAX];
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 loudness_leveling_on;
#endif
WORD32 loudness_eq_parameter_interface_flag;
WORD32 eq_ctrl_interface_flag;
ia_loudness_eq_parameter_interface_struct loudness_eq_parameter_interface;

View file

@ -29,10 +29,15 @@
#include "impd_drc_parser_interface.h"
WORD32
impd_drc_dec_interface_add_effect_type(
ia_drc_interface_struct* pstr_drc_interface, WORD32 drc_effect_type,
WORD32 target_loudness, WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress) {
impd_drc_dec_interface_add_effect_type(ia_drc_interface_struct* pstr_drc_interface,
WORD32 drc_effect_type, WORD32 target_loudness,
WORD32 loud_norm, WORD32 album_mode, FLOAT32 boost,
FLOAT32 compress
#ifdef LOUDNESS_LEVELING_SUPPORT
,
WORD32 loudness_leveling_flag
#endif
) {
WORD32 err = 0;
WORD32 i = 0;
@ -65,7 +70,9 @@ impd_drc_dec_interface_add_effect_type(
}
pstr_drc_interface->loudness_norm_ctrl_interface.target_loudness =
(FLOAT32)target_loudness;
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_drc_interface->drc_uni_interface_ext.loudness_leveling_on = loudness_leveling_flag;
#endif
pstr_drc_interface->loudness_norm_parameter_interface_flag = 1;
pstr_drc_interface->loudness_norm_param_interface.album_mode = album_mode;
pstr_drc_interface->loudness_norm_param_interface.peak_limiter = 0;

View file

@ -73,6 +73,10 @@ impd_parse_drc_ext_v1(ia_bit_buf_struct* it_bit_buff,
ia_drc_config* drc_config,
ia_drc_config_ext* str_drc_config_ext);
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 impd_leveling_instructions(ia_bit_buf_struct* it_bit_buff, ia_drc_config* pstr_drc_config);
#endif
WORD32
impd_parse_drc_config(ia_bit_buf_struct* it_bit_buff,
ia_drc_params_bs_dec_struct* ia_drc_params_struct,

View file

@ -82,6 +82,10 @@ typedef struct ia_drc_sel_proc_params_struct {
FLOAT32 playback_gain;
WORD32 eq_set_purpose_request;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 loudness_leveling_on;
#endif
FLOAT32 boost;
FLOAT32 compress;
WORD32 drc_characteristic_target;

View file

@ -30,6 +30,9 @@
#include "impd_drc_loudness_control.h"
#include "impd_drc_filter_bank.h"
#include "impd_drc_rom.h"
#ifdef LOUDNESS_LEVELING_SUPPORT
#include "ixheaac_error_standards.h"
#endif
static const WORD32 effect_types_request_table[] = {
EFFECT_BIT_NIGHT, EFFECT_BIT_NOISY, EFFECT_BIT_LIMITED,
@ -170,6 +173,12 @@ WORD32 impd_get_ducking_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
(EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
if (str_drc_instruction_str->downmix_id[k] == requested_dwnmix_id) {
#ifdef LOUDNESS_LEVELING_SUPPORT
if (drc_instructions_index != -1) break;
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on == 0 &&
str_drc_instruction_str->leveling_present == 1)
continue;
#endif
drc_instructions_index = n;
}
}
@ -186,6 +195,12 @@ WORD32 impd_get_ducking_drc_set(ia_drc_sel_pro_struct* pstr_drc_uni_sel_proc) {
(EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
for (k = 0; k < str_drc_instruction_str->dwnmix_id_count; k++) {
if (str_drc_instruction_str->downmix_id[k] == ID_FOR_BASE_LAYOUT) {
#ifdef LOUDNESS_LEVELING_SUPPORT
if (drc_instructions_index != -1) break;
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on == 0 &&
str_drc_instruction_str->leveling_present == 1)
continue;
#endif
drc_instructions_index = n;
}
}

View file

@ -104,6 +104,10 @@ WORD32 impd_drc_sel_proc_init_dflt(
pstr_drc_uni_sel_proc->eq_inst_index[0] = -1;
pstr_drc_uni_sel_proc->eq_inst_index[1] = -1;
pstr_drc_uni_sel_proc->sel_proc_request_flag = 1;
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on = 1;
#endif
} else {
return 1;
}
@ -133,6 +137,10 @@ VOID impd_drc_sel_proc_init_interface_params(
WORD32 i, j;
if (pstr_drc_uni_sel_proc != NULL && pstr_drc_interface != NULL) {
#ifdef LOUDNESS_LEVELING_SUPPORT
pstr_drc_uni_sel_proc->uni_drc_sel_proc_params.loudness_leveling_on =
pstr_drc_interface->drc_uni_interface_ext.loudness_leveling_on;
#endif
if (pstr_drc_interface->system_interface_flag) {
if (pstr_drc_uni_sel_proc->uni_drc_sel_proc_params
.target_config_request_type !=

View file

@ -954,6 +954,13 @@ impd_parse_drc_config_ext(ia_bit_buf_struct* it_bit_buff,
drc_config, str_drc_config_ext);
if (err) return (err);
break;
#ifdef LOUDNESS_LEVELING_SUPPORT
case UNIDRCCONFEXT_LEVELING:
err = impd_leveling_instructions(it_bit_buff, drc_config);
if (err) return err;
break;
#endif
default:
for (i = 0; i < str_drc_config_ext->ext_bit_size[k]; i++) {
impd_read_bits_buf(it_bit_buff, 1);

View file

@ -424,6 +424,9 @@ typedef struct {
WORD32 gain_set_idx_of_ch_group_parametric_drc[CHANNEL_GROUP_COUNT_MAX];
WORD32 parametric_drc_look_ahead_samples[CHANNEL_GROUP_COUNT_MAX];
WORD32 parametric_drc_look_ahead_samples_max;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 leveling_present;
#endif
} ia_drc_instructions_struct;
typedef struct {

View file

@ -65,6 +65,10 @@
#define IA_XHEAAC_DEC_CONFIG_PARAM_ESBR 0x0028
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING 0x0029
#endif
#define IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ IA_XHEAAC_DEC_CONFIG_PARAM_PCM_WDSZ
#define IA_ENHAACPLUS_DEC_CONFIG_PARAM_SAMP_FREQ IA_XHEAAC_DEC_CONFIG_PARAM_SAMP_FREQ
#define IA_ENHAACPLUS_DEC_CONFIG_PARAM_NUM_CHANNELS IA_XHEAAC_DEC_CONFIG_PARAM_NUM_CHANNELS

View file

@ -480,7 +480,9 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd,
p_obj_exhaacplus_dec->aac_config.ui_drc_set = 0;
p_obj_exhaacplus_dec->aac_config.ui_flush_cmd = 0;
p_obj_exhaacplus_dec->aac_config.output_level = -1;
#ifdef LOUDNESS_LEVELING_SUPPORT
p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag = 1;
#endif
p_obj_exhaacplus_dec->aac_config.ui_max_channels = 6;
p_obj_exhaacplus_dec->aac_config.ui_coupling_channel = 0;
@ -789,6 +791,16 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd,
p_obj_exhaacplus_dec->aac_config.ui_enh_sbr = *pui_value_signed;
break;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
case IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING: {
if (((*pui_value_signed) != 0) && ((*pui_value_signed) != 1)) {
p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag = 1;
return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_LOUDNESS_LEVELING_FLAG);
}
p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag = *pui_value_signed;
break;
}
#endif
default: { return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM; }
}
break;
@ -931,7 +943,15 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd,
} else {
*pui_value = AOT_AAC_LC;
}
} else {
}
#ifdef LOUDNESS_LEVELING_SUPPORT
else if (IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING == i_idx) {
WORD32 *ui_value =
(WORD32 *)(&p_obj_exhaacplus_dec->aac_config.ui_loudness_leveling_flag);
*pui_value = *ui_value;
}
#endif
else {
return IA_XHEAAC_DEC_API_FATAL_INVALID_CONFIG_PARAM;
}
break;

View file

@ -63,6 +63,9 @@
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_HQ_FLAG 0x00000815
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_FRAMELENGTHFLAG 0x00000816
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_ESBR_FLAG 0x00000817
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_LOUDNESS_LEVELING_FLAG 0x00000818
#endif
/* Fatal Errors */
#define IA_XHEAAC_DEC_CONFIG_FATAL_INVALID_SAMPLE_RATE 0xFFFF8800
@ -75,7 +78,7 @@
#define IA_XHEAAC_DEC_INIT_NONFATAL_EC_INIT_FAIL 0x00001002
#define IA_XHEAAC_DEC_INIT_NONFATAL_INSUFFICIENT_INPUT_BYTES 0x00001003
#define IA_XHEAAC_DEC_INIT_NONFATAL_DECODE_FRAME_ERROR 0x00001004
#define IA_XHEAAC_DEC_INIT_NONFATAL_MAX_INSTRUCTIONS_ERROR 0x00001005
/* Fatal Errors */
#define IA_XHEAAC_DEC_INIT_FATAL_DEC_INIT_FAIL 0xFFFF9000
#define IA_XHEAAC_DEC_INIT_FATAL_EO_INPUT_REACHED 0xFFFF9001

View file

@ -137,6 +137,9 @@ typedef struct {
WORD32 ui_err_conceal;
FLAG first_frame;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 ui_loudness_leveling_flag;
#endif
} ia_aac_dec_config_struct;
typedef struct ia_aac_dec_state_struct {

View file

@ -240,6 +240,10 @@ enum {
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) {
@ -295,6 +299,15 @@ IA_ERRORCODE Codec::initXAACDrc(const uint8_t* data, size_t size) {
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
// DRC_LOUDNESS_LEVELING_FLAG
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;
}

View file

@ -44,7 +44,9 @@
#define IA_DRC_DEC_CONFIG_PARAM_APPLY_CROSSFADE 0x0017
#define IA_DRC_DEC_CONFIG_PARAM_CONFIG_CHANGED 0x0018
#ifdef LOUDNESS_LEVELING_SUPPORT
#define IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING 0x0019
#endif
#define IA_API_CMD_SET_INPUT_BYTES_BS 0x0026
#define IA_API_CMD_SET_INPUT_BYTES_IC_BS 0x0027
#define IA_API_CMD_SET_INPUT_BYTES_IL_BS 0x0029

View file

@ -75,7 +75,12 @@ pWORD8 ixheaacd_ppb_config_non_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "Invalid target loudness value",
(pWORD8) "Invalid HQ eSBR flag option. Setting to default 0",
(pWORD8) "Invalid frame length flag option. Setting to default 0",
(pWORD8) "Invalid eSBR flag option. Setting to default 1"};
(pWORD8) "Invalid eSBR flag option. Setting to default 1"
#ifdef LOUDNESS_LEVELING_SUPPORT
,
(pWORD8) "Invalid Loudness leveling flag option. Setting to default 1"
#endif
};
/* Fatal Errors */
pWORD8 ixheaacd_ppb_config_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "Invalid Sample rate specified for RAW decoding"};
@ -87,7 +92,12 @@ pWORD8 ixheaacd_ppb_config_fatal[IA_MAX_ERROR_SUB_CODE] = {
pWORD8 ixheaacd_ppb_init_non_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "Header not found at the beginning of input data continuing syncing",
(pWORD8) "Invalid number of QMF bands", (pWORD8) "Decoder initialization failed",
(pWORD8) "Input bytes insufficient for decoding", (pWORD8) "Error in AAC decoding"};
(pWORD8) "Input bytes insufficient for decoding", (pWORD8) "Error in AAC decoding"
#ifdef LOUDNESS_LEVELING_SUPPORT
,
(pWORD8) "DRC instruction count exceeded"
#endif
};
/* Fatal Errors */
pWORD8 ixheaacd_ppb_init_fatal[IA_MAX_ERROR_SUB_CODE] = {
(pWORD8) "AAC Decoder initialization failed",

View file

@ -33,6 +33,16 @@
#include "ixheaacd_metadata_read.h"
#include "impd_drc_config_params.h"
#ifdef SUPPORT_MP4
#include "ISOMovies.h"
#define _IA_HANDLE_ERROR_MP4(a) \
if (a) \
{ \
printf("ISOBMFF parser library error. Error No: %d\n", a); \
exit(1); \
}
#endif
IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_module_obj, WORD32 i_cmd, WORD32 i_idx,
pVOID pv_value);
@ -100,13 +110,23 @@ FileWrapperPtr g_pf_inp; /* file pointer to bitstream file (mp4) */
WORD32 mpeg_d_drc_on = 0;
#ifndef SUPPORT_MP4
metadata_info meta_info; // metadata pointer;
WORD32 ixheaacd_i_bytes_to_read;
WORD32 prev_i_bytes_to_read;
WORD32 flush_frame = 0;
FILE *g_pf_meta;
WORD32 raw_testing = 0;
#else
WORD32 mp4_flag = 0;
WORD32 ixheaacd_i_bytes_to_read;
ISOMedia media;
ISOTrack trak;
ISOTrackReader reader;
ISOHandle sample_hdl;
ISOHandle decoder_cfg_hdl;
#endif
WORD32 prev_i_bytes_to_read;
WORD32 flush_frame = 0;
WORD32 eld_testing = 0;
WORD32 ec_enable = 0;
WORD32 esbr_testing = 1;
@ -387,6 +407,7 @@ IA_ERRORCODE ixheaacd_set_config_param(WORD32 argc, pWORD8 argv[],
ia_error_info_struct *p_proc_err_info = &ixheaacd_error_info;
for (i = 0; i < argc; i++) {
#ifndef SUPPORT_MP4
/* To indicate if its a MP4 file or not. */
if (!strncmp((pCHAR8)argv[i], "-mp4:", 5)) {
pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 5);
@ -396,6 +417,7 @@ IA_ERRORCODE ixheaacd_set_config_param(WORD32 argc, pWORD8 argv[],
IA_XHEAAC_DEC_CONFIG_PARAM_MP4FLAG, &ui_mp4_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#endif
/* PCM WORD Size (For single input file) */
if (!strncmp((pCHAR8)argv[i], "-pcmsz:", 7)) {
pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 7);
@ -667,7 +689,27 @@ IA_ERRORCODE ixheaacd_set_config_param(WORD32 argc, pWORD8 argv[],
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
ec_enable = ui_err_conceal;
}
#ifdef LOUDNESS_LEVELING_SUPPORT
/* For loudness leveling*/
if (!strncmp((pCHAR8)argv[i], "-loudness_leveling:", 19)) {
pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 19);
UWORD32 loudness_leveling_flag = atoi(pb_arg_val);
err_code = (*p_ia_process_api)(p_ia_process_api_obj, IA_API_CMD_SET_CONFIG_PARAM,
IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING,
&loudness_leveling_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#endif
}
#ifdef SUPPORT_MP4
{
UWORD32 ui_mp4_flag = mp4_flag;
err_code = (*p_ia_process_api)(
p_ia_process_api_obj, IA_API_CMD_SET_CONFIG_PARAM,
IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &ui_mp4_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#endif
return IA_NO_ERROR;
}
@ -872,6 +914,11 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
WORD32 prev_sampling_rate = 0;
WORD32 skip_samples = 0;
WORD32 total_samples = 0;
#ifdef SUPPORT_MP4
s64 segment_duration = 0;
s64 start_offset_duration = 0;
u32 entryIndex = 1;
#endif
WORD32 write_flag = 1;
WORD32 bytes_to_write = 0;
WORD32 ixheaacd_drc_offset = 0;
@ -899,7 +946,9 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
WORD32 drc_flag = 0;
WORD32 mpegd_drc_present = 0;
WORD32 uo_num_chan;
#ifdef LOUDNESS_LEVELING_SUPPORT
WORD32 i_loudness_leveling_flag = 1;
#endif
/* The process API function */
IA_ERRORCODE(*p_ia_process_api)
(pVOID p_ia_process_api_obj, WORD32 i_cmd, WORD32 i_idx, pVOID pv_value);
@ -920,6 +969,10 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
/* The process error info structure */
ia_error_info_struct *p_proc_err_info;
#ifdef SUPPORT_MP4
ISOErr err = ISONoErr;
#endif
/* Process struct initing */
p_ia_process_api = ixheaacd_dec_api;
p_set_config_param = ixheaacd_set_config_param;
@ -1197,6 +1250,7 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
do {
i_bytes_read = 0;
#ifndef SUPPORT_MP4
if ((ui_inp_size - (i_buff_size - i_bytes_consumed)) > 0) {
for (i = 0; i < (i_buff_size - i_bytes_consumed); i++) {
pb_inp_buf[i] = pb_inp_buf[i + i_bytes_consumed];
@ -1259,8 +1313,72 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
#endif
return 1;
}
#else
if (!mp4_flag)
{
if ((ui_inp_size - (i_buff_size - i_bytes_consumed)) > 0) {
for (i = 0; i < (i_buff_size - i_bytes_consumed); i++) {
pb_inp_buf[i] = pb_inp_buf[i + i_bytes_consumed];
}
FileWrapper_Read(g_pf_inp, (unsigned char *)(pb_inp_buf + i_buff_size -
i_bytes_consumed),
(ui_inp_size - (i_buff_size - i_bytes_consumed)),
(pUWORD32)&i_bytes_read);
i_buff_size = i_buff_size - (i_bytes_consumed - i_bytes_read);
/* Tell input is over, if algorithm returns with insufficient input and
there is no
more input left in the bitstream*/
if ((i_buff_size <= 0) ||
((err_code_reinit == 0x00001804) && i_bytes_read == 0))
{
i_buff_size = 0;
/* Tell that the input is over in this buffer */
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
}
if ((i_buff_size <= 0) ||
((err_code_reinit == 0x00001804) && i_bytes_read == 0)) {
i_buff_size = 0;
/* Tell that the input is over in this buffer */
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
#ifdef WAV_HEADER
#ifndef ARM_PROFILE_BOARD
/* ******************************************************************/
/* Get config params from API */
/* ******************************************************************/
err_code =
(*p_get_config_param)(pv_ia_process_api_obj, &i_samp_freq,
&i_num_chan, &i_pcm_wd_sz, &i_channel_mask,
&i_sbr_mode, &ui_aot);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
// This is done in those cases, where file decodes ends at init time
// Since init is incomplete, sampling freq might be zero and will result
// in
// writing invalid wave header
if (i_samp_freq == 0) i_samp_freq = prev_sampling_rate;
if (!fseek(g_pf_out, 0, SEEK_SET))
write_wav_header(g_pf_out, i_total_bytes, i_samp_freq, i_num_chan,
i_pcm_wd_sz, i_channel_mask);
#endif
#endif
return 1;
}
}
#endif
if (init_iteration == 1) {
#ifndef SUPPORT_MP4
if (raw_testing)
ixheaacd_i_bytes_to_read = get_metadata_dec_info_init(meta_info);
else
@ -1271,8 +1389,52 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
(*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES,
0, &ixheaacd_i_bytes_to_read);
init_iteration++;
#else
if (!mp4_flag)
{
ixheaacd_i_bytes_to_read = i_buff_size;
/* Set number of bytes to be processed */
err_code =
(*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES,
0, &ixheaacd_i_bytes_to_read);
}
else
{
u32 samp_desc_idx = 1, obj_type = 0, output_size;
u32 avg_br = 0, max_br = 0, strm_type = 0, strm_up = 0;
err = MP4GetMediaDecoderInformation(media,
samp_desc_idx,
&obj_type,
&strm_type,
&output_size,
&strm_up,
&max_br,
&avg_br,
decoder_cfg_hdl);
_IA_HANDLE_ERROR_MP4(err);
err = MP4GetHandleSize(decoder_cfg_hdl, &ixheaacd_i_bytes_to_read);
_IA_HANDLE_ERROR_MP4(err);
if (ixheaacd_i_bytes_to_read > (WORD32)ui_inp_size)
return IA_FATAL_ERROR;
/* Set number of bytes to be processed */
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_SET_INPUT_BYTES, 0,
&ixheaacd_i_bytes_to_read);
memcpy(pb_inp_buf, *decoder_cfg_hdl, ixheaacd_i_bytes_to_read);
if (ixheaacd_i_bytes_to_read <= 0) {
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
return IA_NO_ERROR;
}
}
init_iteration++;
#endif
} else {
#ifndef SUPPORT_MP4
if (raw_testing) {
ixheaacd_i_bytes_to_read =
get_metadata_dec_exec(meta_info, frame_counter);
@ -1299,6 +1461,44 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
err_code = (*p_ia_process_api)(
pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES, 0, &i_buff_size);
}
#else
if (mp4_flag) {
u32 unit_size;
s32 cts;
s32 dts;
u32 sample_flags;
err = MP4TrackReaderGetNextAccessUnit(
reader, sample_hdl, &unit_size, &sample_flags, &cts, &dts);
if (err)
{
if (err == ISOEOF) err = ISONoErr;
break;
}
ixheaacd_i_bytes_to_read = unit_size;
i_bytes_read = ixheaacd_i_bytes_to_read;
if (ixheaacd_i_bytes_to_read > (WORD32)ui_inp_size)
return IA_FATAL_ERROR;
if (ixheaacd_i_bytes_to_read <= 0) {
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
return IA_NO_ERROR;
}
/* Set number of bytes to be processed */
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_SET_INPUT_BYTES, 0,
&ixheaacd_i_bytes_to_read);
memcpy(pb_inp_buf, *((char **)sample_hdl), ixheaacd_i_bytes_to_read);
init_iteration++;
} else {
/* Set number of bytes to be processed */
err_code = (*p_ia_process_api)(
pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES, 0, &i_buff_size);
}
#endif
}
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
@ -1410,6 +1610,22 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#ifdef LOUDNESS_LEVELING_SUPPORT
/*Set loudness leveling */
{
err_code = (*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_GET_CONFIG_PARAM,
IA_XHEAAC_DEC_CONFIG_PARAM_DRC_LOUDNESS_LEVELING,
&i_loudness_leveling_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
err_code =
ia_drc_dec_api(pv_ia_drc_process_api_obj, IA_API_CMD_SET_CONFIG_PARAM,
IA_DRC_DEC_CONFIG_DRC_LOUDNESS_LEVELING, &i_loudness_leveling_flag);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
}
#endif
/*Set loud_norm_flag*/
{
err_code = (*p_ia_process_api)(
@ -1646,6 +1862,7 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
if (ui_aot == 42)
esbr_testing = 1;
#ifndef SUPPORT_MP4
if (raw_testing) {
skip_samples = get_start_offset_in_samples(meta_info);
if (ui_aot >= 23 && esbr_testing) {
@ -1656,6 +1873,21 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
}
if (eld_testing == 0) total_samples = get_play_time_in_samples(meta_info);
}
#else
if (mp4_flag) {
u32 entry_count = 1;
err = ISOGetTrackEditlistEntryCount(trak, &entry_count);
if (err == MP4NoErr)
{
err = ISOGetTrackEditlist(trak, &segment_duration, &start_offset_duration, 1);
if (err == MP4NoErr)
{
skip_samples = (WORD32)start_offset_duration;
if (eld_testing == 0) total_samples = (WORD32)segment_duration;
}
}
}
#endif
/* End second part */
@ -1672,26 +1904,67 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
#endif
prev_sampling_rate = i_samp_freq;
#if SUPPORT_MP4
UWORD32 number_of_frames = 0;
err = ISOGetMediaSampleCount(media, &number_of_frames);
if (err) return err;
#else
UWORD32 number_of_frames = meta_info.ia_mp4_stsz_entries;
#endif
do {
if (((WORD32)ui_inp_size - (WORD32)(i_buff_size - i_bytes_consumed)) > 0) {
if (i_sbr_mode && (ui_aot < 23) && esbr_testing) {
if (meta_info.ia_mp4_stsz_entries != frame_counter) {
if (number_of_frames != frame_counter) {
for (i = 0; i < (i_buff_size - i_bytes_consumed); i++) {
pb_inp_buf[i] = pb_inp_buf[i + i_bytes_consumed];
}
#ifndef SUPPORT_MP4
FileWrapper_Read(
g_pf_inp,
(unsigned char *)(pb_inp_buf + i_buff_size - i_bytes_consumed),
((WORD32)ui_inp_size - (WORD32)(i_buff_size - i_bytes_consumed)),
(pUWORD32)&i_bytes_read);
#else
if (!mp4_flag)
{
FileWrapper_Read(
g_pf_inp,
(unsigned char *)(pb_inp_buf + i_buff_size - i_bytes_consumed),
((WORD32)ui_inp_size - (WORD32)(i_buff_size - i_bytes_consumed)),
(pUWORD32)&i_bytes_read);
}
else
{
if (i_bytes_consumed)
{
u32 unit_size;
s32 cts;
s32 dts;
u32 sample_flags;
err = MP4TrackReaderGetNextAccessUnit(
reader, sample_hdl, &unit_size, &sample_flags, &cts, &dts);
if (err)
{
if (err == ISOEOF) err = ISONoErr;
break;
}
i_bytes_read = unit_size;
memcpy(pb_inp_buf, *((char **)sample_hdl), i_bytes_read);
}
}
#endif
i_buff_size = i_buff_size - (i_bytes_consumed - i_bytes_read);
if ((i_buff_size <= 0) ||
((err_code_reinit == 0x00001804) && i_bytes_read == 0)) {
i_buff_size = 0;
#ifndef SUPPORT_MP4
raw_testing = 0;
#else
mp4_flag = 0;
#endif
/* Tell that the input is over in this buffer */
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
@ -1703,19 +1976,49 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
for (i = 0; i < (i_buff_size - i_bytes_consumed); i++) {
pb_inp_buf[i] = pb_inp_buf[i + i_bytes_consumed];
}
#ifndef SUPPORT_MP4
FileWrapper_Read(g_pf_inp, (unsigned char *)(pb_inp_buf + i_buff_size -
i_bytes_consumed),
((WORD32)ui_inp_size - (WORD32)(i_buff_size - i_bytes_consumed)),
(pUWORD32)&i_bytes_read);
#else
if (!mp4_flag)
{
FileWrapper_Read(g_pf_inp,
(unsigned char *)(pb_inp_buf + i_buff_size - i_bytes_consumed),
((WORD32)ui_inp_size - (WORD32)(i_buff_size - i_bytes_consumed)),
(pUWORD32)&i_bytes_read);
}
else
{
if (i_bytes_consumed)
{
u32 unit_size;
s32 cts;
s32 dts;
u32 sample_flags;
err = MP4TrackReaderGetNextAccessUnit(
reader, sample_hdl, &unit_size, &sample_flags, &cts, &dts);
if (err)
{
if (err == ISOEOF) err = ISONoErr;
break;
}
i_bytes_read = unit_size;
memcpy(pb_inp_buf, *((char **)sample_hdl), i_bytes_read);
}
}
#endif
i_buff_size = i_buff_size - (i_bytes_consumed - i_bytes_read);
if ((i_buff_size <= 0) ||
((err_code_reinit == 0x00001804) && i_bytes_read == 0)) {
i_buff_size = 0;
#ifndef SUPPORT_MP4
raw_testing = 0;
#else
mp4_flag = 0;
#endif
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
@ -1724,7 +2027,8 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
}
}
if (i_sbr_mode && (ui_aot < 23) && esbr_testing) {
if (meta_info.ia_mp4_stsz_entries != frame_counter) {
if (number_of_frames != frame_counter) {
#ifndef SUPPORT_MP4
if (raw_testing) {
ixheaacd_i_bytes_to_read =
get_metadata_dec_exec(meta_info, frame_counter);
@ -1743,11 +2047,31 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
(*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES,
0, &ixheaacd_i_bytes_to_read);
} else {
#else
if (mp4_flag) {
ixheaacd_i_bytes_to_read = i_bytes_read;
if (ixheaacd_i_bytes_to_read > (WORD32)ui_inp_size)
return IA_FATAL_ERROR;
if (ixheaacd_i_bytes_to_read <= 0 && ec_enable == 0) {
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
return IA_NO_ERROR;
}
err_code =
(*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES,
0, &ixheaacd_i_bytes_to_read);
} else {
#endif
err_code = (*p_ia_process_api)(
pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES, 0, &i_buff_size);
}
}
} else {
#ifndef SUPPORT_MP4
if (raw_testing) {
ixheaacd_i_bytes_to_read =
get_metadata_dec_exec(meta_info, frame_counter);
@ -1778,6 +2102,37 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
&ixheaacd_i_bytes_to_read);
}
} else {
#else
if (mp4_flag) {
ixheaacd_i_bytes_to_read = i_bytes_read;
if (ixheaacd_i_bytes_to_read > (WORD32)ui_inp_size) return IA_FATAL_ERROR;
if (ixheaacd_i_bytes_to_read <= 0) {
err_code = (*p_ia_process_api)(pv_ia_process_api_obj,
IA_API_CMD_INPUT_OVER, 0, NULL);
_IA_HANDLE_ERROR(p_proc_err_info, (pWORD8) "", err_code);
return IA_NO_ERROR;
}
if (ec_enable == 1) {
if (ixheaacd_i_bytes_to_read != 0) {
err_code = (*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES, 0,
&ixheaacd_i_bytes_to_read);
} else {
if (i_buff_size != 0) {
err_code = (*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES, 0,
&i_buff_size);
}
}
} else {
err_code = (*p_ia_process_api)(pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES, 0,
&ixheaacd_i_bytes_to_read);
}
} else {
#endif
/* Set number of bytes to be processed */
err_code = (*p_ia_process_api)(
pv_ia_process_api_obj, IA_API_CMD_SET_INPUT_BYTES, 0, &i_buff_size);
@ -2064,7 +2419,13 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
if (total_samples != 0) // Usac stream
{
#ifndef SUPPORT_MP4
if (raw_testing) {
#else
if (mp4_flag) {
WORD32 frame_size = i_out_bytes / (i_num_chan * (i_pcm_wd_sz >> 3));
skip_samples = skip_samples % frame_size;
#endif
if (i_total_bytes <= skip_samples * i_num_chan * (i_pcm_wd_sz >> 3)) {
err_code =
(*p_get_config_param)(pv_ia_process_api_obj, &i_samp_freq,
@ -2088,6 +2449,7 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
}
}
#ifndef SUPPORT_MP4
if (raw_testing) {
samples_written += current_samples;
@ -2097,6 +2459,17 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
if (i_out_bytes < 0) i_out_bytes = 0;
}
}
#else
if (mp4_flag) {
samples_written += current_samples;
if (samples_written > total_samples) {
i_out_bytes = (total_samples - (samples_written - current_samples)) *
(i_num_chan * (i_pcm_wd_sz >> 3));
if (i_out_bytes < 0) i_out_bytes = 0;
}
}
#endif
}
if (write_flag) {
@ -2238,6 +2611,9 @@ void print_usage() {
printf("\n[-peak_limiter_off:<peak_limiter_off_flag>]");
printf("\n[-err_conceal:<error_concealment_flag>]");
printf("\n[-esbr:<esbr_flag>]");
#ifdef LOUDNESS_LEVELING_SUPPORT
printf("\n[-loudness_leveling:<loudness_leveling_flag>]");
#endif
printf("\n\nwhere, \n <input_file> is the input AAC-LC/HE-AACv1/HE-AACv2//AAC-LD/AAC-ELD/AAC-ELDv2/USAC file name");
printf("\n <meta_data_file> is a text file which contains metadata.");
printf("\n To be given when -mp4:1 is enabled");
@ -2294,6 +2670,10 @@ void print_usage() {
printf("\n <error_concealment_flag> is to enable / disable error concealment.");
printf("\n Default value is 0");
printf("\n <esbr_flag> is to enable / disable eSBR. Default value is 1\n\n");
#ifdef LOUDNESS_LEVELING_SUPPORT
printf("\n <loudness_leveling_flag>] is to enable / disable loudness leveling.");
printf("\n Default value is 1");
#endif
}
/*******************************************************************************/
@ -2326,10 +2706,17 @@ void print_usage() {
int main(WORD32 argc, char *argv[]) {
WORD32 i, err_code = IA_NO_ERROR;
#ifdef SUPPORT_MP4
ISOErr err;
u32 handler_type;
ISOMovie moov;
#endif
ia_testbench_error_handler_init();
g_pf_inp = NULL;
#ifndef SUPPORT_MP4
g_pf_meta = NULL;
#endif
g_pf_out = NULL;
for (i = 1; i < argc; i++) {
@ -2337,7 +2724,7 @@ int main(WORD32 argc, char *argv[]) {
if (!strncmp((const char *)argv[i], "-ifile:", 7)) {
pWORD8 pb_arg_val = (pWORD8)argv[i] + 7;
#ifndef SUPPORT_MP4
g_pf_inp = FileWrapper_Open((char *)pb_arg_val);
if (g_pf_inp == NULL) {
err_code = IA_TESTBENCH_MFMAN_FATAL_FILE_OPEN_FAILED;
@ -2346,8 +2733,43 @@ int main(WORD32 argc, char *argv[]) {
exit(1);
}
raw_testing = 0;
#else
err = ISOOpenMovieFile(&moov, (char *)pb_arg_val,
MP4OpenMovieNormal);
if (err != MP4NoErr)
{
mp4_flag = 0;
g_pf_inp = FileWrapper_Open((char *)pb_arg_val);
if (g_pf_inp == NULL) {
err_code = IA_TESTBENCH_MFMAN_FATAL_FILE_OPEN_FAILED;
ixheaacd_error_handler(&ixheaacd_ia_testbench_error_info,
(pWORD8) "Input File", err_code);
exit(1);
}
}
else
{
u32 tot_num_tracks = 0;
mp4_flag = 1;
err = ISOGetMovieTrackCount(moov, &tot_num_tracks);
_IA_HANDLE_ERROR_MP4(err);
err = ISOGetMovieIndTrack(moov, tot_num_tracks, &trak);
_IA_HANDLE_ERROR_MP4(err);
err = ISOGetTrackMedia(trak, &media);
_IA_HANDLE_ERROR_MP4(err);
err = ISOGetMediaHandlerDescription(
media, &handler_type, NULL);
_IA_HANDLE_ERROR_MP4(err);
err = ISONewHandle(0, &decoder_cfg_hdl);
_IA_HANDLE_ERROR_MP4(err);
err = ISONewHandle(0, &sample_hdl);
_IA_HANDLE_ERROR_MP4(err);
err = ISOCreateTrackReader(trak, &reader);
_IA_HANDLE_ERROR_MP4(err);
}
#endif
}
#ifndef SUPPORT_MP4
if (!strncmp((const char *)argv[i], "-imeta:", 7)) {
pWORD8 pb_arg_val = (pWORD8)argv[i] + 7;
@ -2367,6 +2789,7 @@ int main(WORD32 argc, char *argv[]) {
}
raw_testing = 1;
}
#endif
if (!strncmp((const char *)argv[i], "-ofile:", 7)) {
pWORD8 pb_arg_val = (pWORD8)argv[i] + 7;
@ -2381,6 +2804,7 @@ int main(WORD32 argc, char *argv[]) {
}
}
#ifndef SUPPORT_MP4
if ((g_pf_inp == NULL) || (g_pf_out == NULL)) {
print_usage();
err_code = IA_TESTBENCH_MFMAN_FATAL_FILE_OPEN_FAILED;
@ -2388,11 +2812,33 @@ int main(WORD32 argc, char *argv[]) {
(pWORD8) "Input or Output File", err_code);
exit(1);
}
#else
if (!mp4_flag)
{
if ((g_pf_inp == NULL) || (g_pf_out == NULL)) {
print_usage();
err_code = IA_TESTBENCH_MFMAN_FATAL_FILE_OPEN_FAILED;
ixheaacd_error_handler(&ixheaacd_ia_testbench_error_info,
(pWORD8) "Input or Output File", err_code);
exit(1);
}
}
else
{
if (g_pf_out == NULL) {
print_usage();
err_code = IA_TESTBENCH_MFMAN_FATAL_FILE_OPEN_FAILED;
ixheaacd_error_handler(&ixheaacd_ia_testbench_error_info,
(pWORD8) "Output File", err_code);
exit(1);
}
}
#endif
g_w_malloc_count = 0;
printf("\n");
#ifndef SUPPORT_MP4
for (i = 0; i < argc; i++) {
if (!strcmp((pCHAR8)argv[i], "-mp4:1")) {
if (g_pf_meta == NULL) {
@ -2404,7 +2850,7 @@ int main(WORD32 argc, char *argv[]) {
}
}
}
#endif
for (i = 0; i < argc; i++) {
if (strcmp((pCHAR8)argv[i], "-eld_testing:1"))
eld_testing = 0;
@ -2420,12 +2866,29 @@ int main(WORD32 argc, char *argv[]) {
if (g_pv_arr_alloc_memory[i]) free(g_pv_arr_alloc_memory[i]);
}
if (g_pf_out) fclose(g_pf_out);
#ifndef SUPPORT_MP4
if (g_pf_meta) {
fclose(g_pf_meta);
metadata_mp4_stsz_size_free(&meta_info);
}
FileWrapper_Close(g_pf_inp);
#else
if (!mp4_flag)
{
FileWrapper_Close(g_pf_inp);
}
else
{
err = ISODisposeHandle(sample_hdl);
_IA_HANDLE_ERROR_MP4(err);
err = ISODisposeHandle(decoder_cfg_hdl);
_IA_HANDLE_ERROR_MP4(err);
err = ISODisposeTrackReader(reader);
_IA_HANDLE_ERROR_MP4(err);
err = ISODisposeMovie(moov);
_IA_HANDLE_ERROR_MP4(err);
}
#endif
mpeg_d_drc_on = 0;
return IA_NO_ERROR;

View file

@ -1,27 +1,70 @@
list(APPEND XAACDEC_SRCS "${XAAC_ROOT}/test/decoder/ixheaacd_error.c"
"${XAAC_ROOT}/test/decoder/ixheaacd_fileifc.c" "${XAAC_ROOT}/test/decoder/ixheaacd_main.c"
"${XAAC_ROOT}/test/decoder/ixheaacd_metadata_read.c")
list(APPEND XAACDEC_SRCS
"${XAAC_ROOT}/test/decoder/ixheaacd_error.c"
"${XAAC_ROOT}/test/decoder/ixheaacd_fileifc.c"
"${XAAC_ROOT}/test/decoder/ixheaacd_main.c"
"${XAAC_ROOT}/test/decoder/ixheaacd_metadata_read.c"
)
set(LIBXAACDEC_INCLUDES ${XAAC_ROOT}/decoder ${XAAC_ROOT}/test/decoder/
${XAAC_ROOT}/decoder/drc_src)
set(LIBXAACDEC_INCLUDES
${XAAC_ROOT}/decoder
${XAAC_ROOT}/test/decoder/
${XAAC_ROOT}/decoder/drc_src
)
include_directories(${LIBXAACDEC_INCLUDES})
if(SUPPORT_MP4)
set(LIBISOMEDIA_INCLUDES "${XAAC_ROOT}/../isobmff/IsoLib/libisomediafile/src")
libxaac_add_executable(xaacdec libxaacdec SOURCES ${XAACDEC_SRCS} INCLUDES
${LIBXAACDEC_INCLUDES})
# Platform-specific includes
if(MSVC)
set(LIBISOOSW32_INCLUDES "${XAAC_ROOT}/../isobmff/IsoLib/libisomediafile/w32")
include_directories(${LIBXAACDEC_INCLUDES} ${LIBISOMEDIA_INCLUDES} ${LIBISOOSW32_INCLUDES})
else()
set(LIBISOMEDIA_PLATFORM_INCLUDES ${XAAC_ROOT}/../isobmff/IsoLib/libisomediafile/linux)
include_directories(${LIBXAACDEC_INCLUDES} ${LIBISOMEDIA_INCLUDES} ${LIBISOMEDIA_PLATFORM_INCLUDES})
endif()
else()
include_directories(${LIBXAACDEC_INCLUDES})
endif()
# Add xaacdec executable
libxaac_add_executable(xaacdec libxaacdec SOURCES ${XAACDEC_SRCS} INCLUDES ${LIBXAACDEC_INCLUDES})
# Platform-specific linking of MP4 library
if(SUPPORT_MP4)
if(MSVC)
# Use Visual Studio project on Windows
include_external_msproject(libisomediafile
${XAAC_ROOT}/../isobmff/build/IsoLib/libisomediafile/libisomediafile.vcxproj)
add_dependencies(xaacdec libisomediafile)
else()
# Linux: link prebuilt static .a library
set(LIBISOMEDIA_LIB_PATH "${XAAC_ROOT}/../isobmff/lib/liblibisomediafile.a")
target_link_libraries(xaacdec ${LIBISOMEDIA_LIB_PATH})
endif()
endif()
# Common compile flags
set(COMMON_FLAGS "-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32 -DLOUDNESS_LEVELING_SUPPORT")
if(SUPPORT_MP4)
set(MP4_FLAG "-DSUPPORT_MP4")
endif()
# Apply compile flags per platform
if(MSVC)
set_target_properties(
xaacdec
PROPERTIES
COMPILE_FLAGS
"-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32 -D_CRT_SECURE_NO_WARNINGS"
"${COMMON_FLAGS} -D_CRT_SECURE_NO_WARNINGS ${MP4_FLAG}"
)
else()
set_target_properties(
xaacdec
PROPERTIES
COMPILE_FLAGS
"-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32"
"${COMMON_FLAGS} ${MP4_FLAG}"
)
endif()