Compare commits

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

3 commits

Author SHA1 Message Date
Rumaan Khan
229e7da0ad WIP: Loudness leveling support with uniDRCv0 config support 2025-07-30 23:11:30 +05:30
Rumaan Khan
7e1a54d5d6 add supp for linux 2025-07-30 13:07:19 +05:30
Rumaan Khan
b8360ba042 mp4 supp changes 2025-07-30 13:07:19 +05:30
5 changed files with 576 additions and 78 deletions

View file

@ -673,7 +673,7 @@ IA_ERROR_CODE impd_leveling_instructions(ia_bit_buf_struct* it_bit_buff,
}
err = impd_parse_drc_instructions_uni_drc(
it_bit_buff, 1, pstr_drc_config,
it_bit_buff, 0, pstr_drc_config,
&pstr_drc_config
->str_drc_instruction_str[pstr_drc_config->drc_instructions_uni_drc_count -
1]);

View file

@ -3101,9 +3101,17 @@ IA_ERRORCODE impd_drc_write_uni_drc_config(ia_drc_enc_state *pstr_drc_state, WOR
bit_cnt_local +=
iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_coefficients_uni_drc_count, 3);
#ifdef LOUDNESS_LEVELING_SUPPORT
UWORD32 num_ducking_only_drc_sets =
get_num_ducking_only_drc_sets(pstr_uni_drc_config->str_drc_instructions_uni_drc,
pstr_uni_drc_config->drc_instructions_uni_drc_count);
bit_cnt_local += iusace_write_bits_buf(
it_bit_buf, pstr_uni_drc_config->drc_instructions_uni_drc_count - num_ducking_only_drc_sets,
6);
#else
bit_cnt_local +=
iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_instructions_uni_drc_count, 6);
#endif
bit_cnt_local +=
iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->str_channel_layout.base_ch_count, 7);
bit_cnt_local += iusace_write_bits_buf(
@ -3138,6 +3146,12 @@ IA_ERRORCODE impd_drc_write_uni_drc_config(ia_drc_enc_state *pstr_drc_state, WOR
}
for (idx = 0; idx < pstr_uni_drc_config->drc_instructions_uni_drc_count; idx++) {
#ifdef LOUDNESS_LEVELING_SUPPORT
if (idx > 0 &&
pstr_uni_drc_config->str_drc_instructions_uni_drc[idx - 1].ducking_only_set_present) {
continue;
}
#endif
err_code = impd_drc_write_drc_instruct_uni_drc(
it_bit_buf, version, pstr_uni_drc_config, pstr_gain_enc,
&(pstr_uni_drc_config->str_drc_instructions_uni_drc[idx]), ptr_scratch, &bit_cnt_local);

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);
@ -679,6 +701,15 @@ IA_ERRORCODE ixheaacd_set_config_param(WORD32 argc, pWORD8 argv[],
}
#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;
}
@ -883,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;
@ -933,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;
@ -1210,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];
@ -1272,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
@ -1284,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);
@ -1312,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);
@ -1675,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) {
@ -1685,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 */
@ -1701,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);
@ -1732,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);
@ -1753,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);
@ -1772,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);
@ -1807,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);
@ -2093,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,
@ -2117,6 +2449,7 @@ int ixheaacd_main_process(WORD32 argc, pWORD8 argv[]) {
}
}
#ifndef SUPPORT_MP4
if (raw_testing) {
samples_written += current_samples;
@ -2126,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) {
@ -2362,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++) {
@ -2373,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;
@ -2382,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;
@ -2403,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;
@ -2417,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;
@ -2424,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) {
@ -2440,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;
@ -2456,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 -DLOUDNESS_LEVELING_SUPPORT"
"${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 -DLOUDNESS_LEVELING_SUPPORT"
"${COMMON_FLAGS} ${MP4_FLAG}"
)
endif()

View file

@ -2,41 +2,11 @@
#For a given DRC effect, when both `leveling_present` and `ducking_only_set` are set to 1, automatically the next drc instruction is treated as ducking only set.
#For example, if the second DRC effect is marked as 2048/4096 with `leveling_present` is set to 1 and `ducking_only_set` is set to 1, then the third DRC effect will be treated as ducking-only.
#For the last drc instruction, `leveling_present` and `ducking_only_set` fields are ignored and reset to 0. Maximum supported instructions are 8.
#####str_drc_instructions_uni_drc#####
drc_instructions_uni_drc_count:0
#####str_drc_coefficients_uni_drc#####
drc_coefficients_uni_drc_count:0
#####str_downmix_instructions_v1#####
downmix_instructions_v1_count:1
#n=0
target_layout:1
#s=0
downmix_coeff:0.70794578438
#end downmix coeeficients
#####str_drc_coefficients_uni_drc_v1#####
drc_coefficients_uni_drc_count_v1:1
#n=0
gain_set_count:1
#s=0
band_count:1
#gain parameters m=0
nb_points:3
x:-60.0
y:-40.0
x:-30.0
y:-30.0
x:0.0
y:-20.0
width:0.01
attack:2.0
decay:5.0
#end gain parameters
#####str_drc_instructions_uni_drc_v1#####
drc_instructions_uni_drc_count_v1:3
drc_instructions_uni_drc_count:3
#n=0
downmix_id:0
drc_set_effect:0x0001
drc_set_effect:1
gain_set_channels:8
gain_set_index:0
gain_set_index:0
@ -51,29 +21,73 @@ num_drc_channel_groups:1
downmix_id:0
drc_set_effect:0x800
gain_set_channels:8
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:1
gain_set_index:1
gain_set_index:1
gain_set_index:1
gain_set_index:1
gain_set_index:1
gain_set_index:1
gain_set_index:1
num_drc_channel_groups:1
#leveling present flag
leveling_present:1
#if ducking_only_set is one next drc instruction's set effect is set to 0x800 (ducking/leveling self)
ducking_only_set:1
#n=2
downmix_id:0
drc_set_effect:0x0800
drc_set_effect:0x800
gain_set_channels:8
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
gain_set_index:0
num_drc_channel_groups:1
gain_set_index:2
gain_set_index:2
gain_set_index:2
gain_set_index:2
gain_set_index:2
gain_set_index:2
gain_set_index:2
gain_set_index:2
num_drc_channel_groups:1
leveling_present:0
ducking_only_set:0
#####str_drc_coefficients_uni_drc#####
drc_coefficients_uni_drc_count:1
#n=0
gain_set_count:3
#s=0
band_count:1
#gain parameters m=0
nb_points:3
x:-60.0
y:-40.0
x:-30.0
y:-30.0
x:0.0
y:-20.0
width:0.01
attack:2.0
decay:5.0
#end gain parameters
#s=0
band_count:1
#gain parameters m=0
nb_points:2
x:-50.0
y:-50.0
x:0.0
y:-10.0
width:0.01
attack:2.0
decay:5.0
#end gain parameters
#s=0
band_count:1
#gain parameters m=0
nb_points:3
x:-60.0
y:-60.0
x:-20.0
y:-15.0
x:0.0
y:-5.0
width:0.01
attack:2.0
decay:5.0
#end gain parameters