From b8360ba0423a034f110d06c8be056b4412cc4f0b Mon Sep 17 00:00:00 2001 From: Rumaan Khan <100922@ittiam.com> Date: Thu, 26 Jun 2025 17:55:06 +0530 Subject: [PATCH 1/3] mp4 supp changes --- test/decoder/ixheaacd_main.c | 455 +++++++++++++++++++++++++++++++++-- test/decoder/xaacdec.cmake | 27 ++- 2 files changed, 465 insertions(+), 17 deletions(-) diff --git a/test/decoder/ixheaacd_main.c b/test/decoder/ixheaacd_main.c index 987baec..775b812 100644 --- a/test/decoder/ixheaacd_main.c +++ b/test/decoder/ixheaacd_main.c @@ -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; diff --git a/test/decoder/xaacdec.cmake b/test/decoder/xaacdec.cmake index f849989..5bb7c7d 100644 --- a/test/decoder/xaacdec.cmake +++ b/test/decoder/xaacdec.cmake @@ -5,23 +5,44 @@ list(APPEND XAACDEC_SRCS "${XAAC_ROOT}/test/decoder/ixheaacd_error.c" 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) + + set(LIBISOOSW32_INCLUDES $(XAAC_ROOT)/../isobmff/IsoLib/libisomediafile/w32) + + include_directories(${LIBXAACDEC_INCLUDES} ${LIBISOMEDIA_INCLUDES} ${LIBISOOSW32_INCLUDES}) +else() + include_directories(${LIBXAACDEC_INCLUDES}) +endif() libxaac_add_executable(xaacdec libxaacdec SOURCES ${XAACDEC_SRCS} INCLUDES ${LIBXAACDEC_INCLUDES}) +if(SUPPORT_MP4) + include_external_msproject(libisomediafile + ${XAAC_ROOT}/../isobmff/build/IsoLib/libisomediafile/libisomediafile.vcxproj) + + add_dependencies(xaacdec libisomediafile) +endif() + +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() + 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" + "-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32 -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" + "-UARM_PROFILE_HW -UARM_PROFILE_BOARD -DDRC_ENABLE -DMULTICHANNEL_ENABLE -DECLIPSE -DWIN32 ${MP4_FLAG}" ) endif() From 7e1a54d5d667df30d6656275c1618dd74e2553be Mon Sep 17 00:00:00 2001 From: Rumaan Khan <100922@ittiam.com> Date: Tue, 1 Jul 2025 15:56:13 +0530 Subject: [PATCH 2/3] add supp for linux --- test/decoder/xaacdec.cmake | 54 +++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/test/decoder/xaacdec.cmake b/test/decoder/xaacdec.cmake index 5bb7c7d..f499ea8 100644 --- a/test/decoder/xaacdec.cmake +++ b/test/decoder/xaacdec.cmake @@ -1,48 +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 +) if(SUPPORT_MP4) - set(LIBISOMEDIA_INCLUDES $(XAAC_ROOT)/../isobmff/IsoLib/libisomediafile/src) + set(LIBISOMEDIA_INCLUDES "${XAAC_ROOT}/../isobmff/IsoLib/libisomediafile/src") - set(LIBISOOSW32_INCLUDES $(XAAC_ROOT)/../isobmff/IsoLib/libisomediafile/w32) - - include_directories(${LIBXAACDEC_INCLUDES} ${LIBISOMEDIA_INCLUDES} ${LIBISOOSW32_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() -libxaac_add_executable(xaacdec libxaacdec SOURCES ${XAACDEC_SRCS} INCLUDES - ${LIBXAACDEC_INCLUDES}) +# Add xaacdec executable +libxaac_add_executable(xaacdec libxaacdec SOURCES ${XAACDEC_SRCS} INCLUDES ${LIBXAACDEC_INCLUDES}) +# Platform-specific linking of MP4 library if(SUPPORT_MP4) - include_external_msproject(libisomediafile - ${XAAC_ROOT}/../isobmff/build/IsoLib/libisomediafile/libisomediafile.vcxproj) + if(MSVC) + # Use Visual Studio project on Windows + include_external_msproject(libisomediafile + ${XAAC_ROOT}/../isobmff/build/IsoLib/libisomediafile/libisomediafile.vcxproj) - add_dependencies(xaacdec libisomediafile) + 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 ${MP4_FLAG}" + "${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 ${MP4_FLAG}" + "${COMMON_FLAGS} ${MP4_FLAG}" ) endif() From 229e7da0ad65efecacb09b7192a3f26f375aca06 Mon Sep 17 00:00:00 2001 From: Rumaan Khan <100922@ittiam.com> Date: Wed, 30 Jul 2025 14:34:02 +0530 Subject: [PATCH 3/3] WIP: Loudness leveling support with uniDRCv0 config support --- decoder/drc_src/impd_drc_dynamic_payload.c | 2 +- encoder/drc_src/impd_drc_mux.c | 16 ++- test/encoder/impd_drc_config_params.txt | 118 ++++++++++++--------- 3 files changed, 82 insertions(+), 54 deletions(-) diff --git a/decoder/drc_src/impd_drc_dynamic_payload.c b/decoder/drc_src/impd_drc_dynamic_payload.c index e005198..dbca07b 100644 --- a/decoder/drc_src/impd_drc_dynamic_payload.c +++ b/decoder/drc_src/impd_drc_dynamic_payload.c @@ -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]); diff --git a/encoder/drc_src/impd_drc_mux.c b/encoder/drc_src/impd_drc_mux.c index fa3aac1..d71fbff 100644 --- a/encoder/drc_src/impd_drc_mux.c +++ b/encoder/drc_src/impd_drc_mux.c @@ -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); diff --git a/test/encoder/impd_drc_config_params.txt b/test/encoder/impd_drc_config_params.txt index da7e9a1..fa6eb44 100644 --- a/test/encoder/impd_drc_config_params.txt +++ b/test/encoder/impd_drc_config_params.txt @@ -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 \ No newline at end of file +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