From dc0940ceacec7834cc732880eaeb2b0f9b4de9d2 Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 11 Aug 2025 16:13:45 +0700 Subject: [PATCH 01/29] start no submodules --- .gitmodules | 3 --- externals/libxaac | 1 - 2 files changed, 4 deletions(-) delete mode 160000 externals/libxaac diff --git a/.gitmodules b/.gitmodules index 3141162..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "externals/libxaac"] - path = externals/libxaac - url = https://code.ucomsite.my.id/wrapper/libxaac diff --git a/externals/libxaac b/externals/libxaac deleted file mode 160000 index 80a67bd..0000000 --- a/externals/libxaac +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 80a67bda85225d6c4a1b122691004dec170c0612 From b929e62222367d1f3f67fe9ca89cae2be13d44af Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 11 Aug 2025 16:14:01 +0700 Subject: [PATCH 02/29] b --- .gitmodules | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29..0000000 From 821a8e169c3dfb287d9c70cfc3282c9a5e72f8cc Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 11 Aug 2025 17:30:13 +0700 Subject: [PATCH 03/29] externals done --- CMakeLists.txt | 2 +- externals/CMakeLists.txt | 17 ----------------- externals/externals.txt | 14 ++++++++++++++ patch/libxaac.patch | 10 ++++++++++ source/libaac/CMakeLists.txt | 10 ++++++++-- 5 files changed, 33 insertions(+), 20 deletions(-) delete mode 100644 externals/CMakeLists.txt create mode 100644 externals/externals.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 5951f45..80e3980 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,10 +207,10 @@ endif() # Project modules # +include(externals/externals.txt) add_subdirectory(source) add_subdirectory(docs) add_subdirectory(deploy) -add_subdirectory(externals) # # Deployment (global project files) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt deleted file mode 100644 index fc04fa9..0000000 --- a/externals/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Always build externals as static libraries, even when libaac-next is built as shared -if (BUILD_SHARED_LIBS) - set(BUILD_SHARED_LIBS OFF) - set(CMAKE_POSITION_INDEPENDENT_CODE ON) - set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL ON) -endif() - -# Allow options shadowing with normal variables when subproject use old cmake policy -set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) - -# Disable tests in all externals supporting the standard option name -set(BUILD_TESTING OFF) - -# For libraries that already come with a CMakeLists file, -# simply add the directory to that file as a subdirectory -# to have CMake automatically recognize them. -add_subdirectory(libxaac) \ No newline at end of file diff --git a/externals/externals.txt b/externals/externals.txt new file mode 100644 index 0000000..b4fae69 --- /dev/null +++ b/externals/externals.txt @@ -0,0 +1,14 @@ +include(ExternalProject) +ExternalProject_Add(libxaac + GIT_REPOSITORY http://github.com/ittiam-systems/libxaac.git + GIT_TAG main + CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release + SOURCE_DIR "${CMAKE_SOURCE_DIR}/externals/libxaac/" + BINARY_DIR "" + INSTALL_COMMAND "" + TEST_COMMAND "" + PATCH_COMMAND git apply --reject --whitespace=fix "${CMAKE_SOURCE_DIR}/patch/libxaac.patch" +) + +ExternalProject_Get_Property(libxaac BINARY_DIR) +set(XAAC_BIN_DIR ${BINARY_DIR}) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 2145e71..e28862d 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -1,3 +1,13 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 82539b7..4996c67 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -27,3 +27,5 @@ include("${XAAC_ROOT}/encoder/libxaacenc.cmake") + include("${XAAC_ROOT}/test/encoder/xaacenc.cmake") + include("${XAAC_ROOT}/fuzzer/xaac_enc_fuzzer.cmake") + ++set_property(TARGET libxaacenc PROPERTY POSITION_INDEPENDENT_CODE 1) ++set_property(TARGET libxaacdec PROPERTY POSITION_INDEPENDENT_CODE 1) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index 5d9cd37..3196501 100644 --- a/cmake/utils.cmake diff --git a/source/libaac/CMakeLists.txt b/source/libaac/CMakeLists.txt index 216b88c..f772c0c 100644 --- a/source/libaac/CMakeLists.txt +++ b/source/libaac/CMakeLists.txt @@ -59,6 +59,8 @@ add_library(${target} ${headers} ) +add_dependencies(${target} libxaac) + # Create namespaced alias add_library(${META_PROJECT_NAME}::${target} ALIAS ${target}) @@ -128,11 +130,15 @@ target_include_directories(${target} # # Libraries # +target_link_directories(${target} + PRIVATE + ${XAAC_BIN_DIR} +) target_link_libraries(${target} PRIVATE - libxaacenc - libxaacdec + xaacenc + xaacdec PUBLIC ${DEFAULT_LIBRARIES} From 480c91bc52c3a3a26d12464c1f9b2d16070106e3 Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 11 Aug 2025 17:43:17 +0700 Subject: [PATCH 04/29] use specific commit --- externals/externals.txt | 4 +++- externals/libxaac | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) create mode 160000 externals/libxaac diff --git a/externals/externals.txt b/externals/externals.txt index b4fae69..df95a58 100644 --- a/externals/externals.txt +++ b/externals/externals.txt @@ -1,7 +1,9 @@ include(ExternalProject) ExternalProject_Add(libxaac GIT_REPOSITORY http://github.com/ittiam-systems/libxaac.git - GIT_TAG main + GIT_TAG "388435c8f8f43fe0e44bf0d31dd3965283f119ec" + GIT_PROGRESS ON + UPDATE_DISCONNECTED 1 CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release SOURCE_DIR "${CMAKE_SOURCE_DIR}/externals/libxaac/" BINARY_DIR "" diff --git a/externals/libxaac b/externals/libxaac new file mode 160000 index 0000000..388435c --- /dev/null +++ b/externals/libxaac @@ -0,0 +1 @@ +Subproject commit 388435c8f8f43fe0e44bf0d31dd3965283f119ec From 237f1a7e8f5a1c967c992fe9e9dd2aefa992b0ce Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 11 Aug 2025 19:59:52 +0700 Subject: [PATCH 05/29] error handler --- source/examples/aacdec/aacdec.cpp | 1 + source/libaac/include/aacnext/libaac.h | 9 ++++ source/libaac/source/libaac.c | 69 ++++++++++++++++---------- 3 files changed, 53 insertions(+), 26 deletions(-) diff --git a/source/examples/aacdec/aacdec.cpp b/source/examples/aacdec/aacdec.cpp index 9f4a322..b58ff76 100644 --- a/source/examples/aacdec/aacdec.cpp +++ b/source/examples/aacdec/aacdec.cpp @@ -278,6 +278,7 @@ int main(int argc, char *argv[]) { } outpFile.save(outFile); + aac_decode_close(decoder); #if 0 #if 0 diff --git a/source/libaac/include/aacnext/libaac.h b/source/libaac/include/aacnext/libaac.h index 513b8a0..e996140 100644 --- a/source/libaac/include/aacnext/libaac.h +++ b/source/libaac/include/aacnext/libaac.h @@ -24,6 +24,8 @@ typedef struct { uint32_t ascSize; // AudioSpecific config size uint32_t in_buf_offset; // Input buffer offset int32_t inputDelay; // Input delay + void (* errorHandler)(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle); // Error handler + void * errorHandleCtx; // Error handler object } AACContext; typedef struct { @@ -38,6 +40,8 @@ typedef struct { uint32_t frameSize; // Custom frame size bool eSBR; // Enhanced SBR uint32_t iq; // Inverse quant + void (* errorHandler)(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle); // Error handler + void * errorHandleCtx; // Error handler object } AACSettings; AACNEXT_API AACContext * aac_encode_open(AACSettings info); @@ -63,6 +67,8 @@ typedef struct { uint32_t sbrMode; // SBR mode bool eSBR; // Enhanced SBR uint64_t frameCounter; // Frame counter + void (* errorHandler)(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle); // Error handler + void * errorHandleCtx; // Error handler object } AACDecode; typedef struct { @@ -72,6 +78,9 @@ typedef struct { int32_t bitsPerSamples; // Bits per samples uint32_t frameSize; // Frame size bool eSBR; // Enhanced SBR + bool errorConceal; // Error concealment + void (* errorHandler)(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle); // Error handler + void * errorHandleCtx; // Error handler object } AACDecodeSettings; AACNEXT_API AACDecode * aac_decode_open(AACDecodeSettings cfg); diff --git a/source/libaac/source/libaac.c b/source/libaac/source/libaac.c index b0f37fb..3ccfc6d 100644 --- a/source/libaac/source/libaac.c +++ b/source/libaac/source/libaac.c @@ -313,14 +313,18 @@ void aac_encode_strerror(unsigned int error, char *errorStr, int *isFatal) { } } -int aac_encode_handle_error(IA_ERRORCODE ret, const char *section) { +int aac_encode_handle_error(AACContext * aac, IA_ERRORCODE ret, const char *section) { char strerror[8192] = {0}; int isFatal; if (ret == IA_NO_ERROR) return 0; aac_encode_strerror(ret, strerror, &isFatal); - fprintf(stderr, "libaac%s %s: %s\n", isFatal ? " fatal error:" : "", section, strerror); + if (aac->errorHandler == NULL) { + fprintf(stderr, "libaac%s %s: %s\n", isFatal ? " fatal error:" : "", section, strerror); + } else { + aac->errorHandler(ret, section, strerror, isFatal, aac->errorHandleCtx); + } return isFatal; } @@ -431,8 +435,11 @@ AACContext * aac_encode_open(AACSettings info) { aac_in_config->ui_pcm_wd_sz = info.bitsPerSamples; // Fixed point only although float computing is possible aac_in_config->aac_config.length = 0; + aac->errorHandler = info.errorHandler; + aac->errorHandleCtx = info.errorHandleCtx; + ret = ixheaace_create(aac->pstr_in_cfg, aac->pstr_out_cfg); - if (aac_encode_handle_error(ret, "init-encoder")) goto fail; + if (aac_encode_handle_error(aac, ret, "init-encoder")) goto fail; aac->no_samples = aac_out_config->input_size / (aac_in_config->ui_pcm_wd_sz == 32 ? 4 : 2); aac->max_out_bytes = aac_out_config->mem_info_table[IA_MEMTYPE_OUTPUT].ui_size; @@ -477,7 +484,7 @@ int aac_encode(AACContext *aac, unsigned char *inData, unsigned int inDataSize, aac->in_buf_offset = 0; IA_ERRORCODE ret = ixheaace_process(aac_out_config->pv_ia_process_api_obj, aac->pstr_in_cfg, aac->pstr_out_cfg); - if (aac_encode_handle_error(ret, "encode")) return -1; + if (aac_encode_handle_error(aac, ret, "encode")) return -1; memcpy(outData, aac_out_buf, aac_out_config->i_out_bytes); *outSize = aac_out_config->i_out_bytes; @@ -650,14 +657,18 @@ void aac_decode_strerror(unsigned int error, char *errorStr, int *isFatal) { } } -int aac_decode_handle_error(IA_ERRORCODE ret, const char *section) { +int aac_decode_handle_error(AACDecode * aacDec, IA_ERRORCODE ret, const char *section) { char strerror[8192] = {0}; int isFatal; if (ret == IA_NO_ERROR) return 0; aac_decode_strerror(ret, strerror, &isFatal); - fprintf(stderr, "libaac%s %s: %s\n", isFatal ? " fatal error:" : "", section, strerror); + if (aacDec->errorHandler == NULL) { + fprintf(stderr, "libaac%s %s: %s\n", isFatal ? " fatal error:" : "", section, strerror); + } else { + aacDec->errorHandler(ret, section, strerror, isFatal, aacDec->errorHandleCtx); + } return isFatal; } @@ -679,27 +690,33 @@ AACDecode * aac_decode_open(AACDecodeSettings cfg) { if (aacDec->apiObj == NULL) goto fail; /* 02 - API Init */ + aacDec->errorHandler = cfg.errorHandler; + aacDec->errorHandleCtx = cfg.errorHandleCtx; + ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_API_PRE_CONFIG_PARAMS, NULL); - if (aac_decode_handle_error(ret, "preconfig")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "preconfig")) goto fail; /* 03 - Configuration starts here */ int isMP4 = cfg.ascSize > 0; ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &isMP4); - if (aac_decode_handle_error(ret, "updating mp4 flag")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "updating mp4 flag")) goto fail; ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_ENHAACPLUS_DEC_CONFIG_PARAM_PCM_WDSZ, &cfg.bitsPerSamples); - if (aac_decode_handle_error(ret, "updating bits per samples")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "updating bits per samples")) goto fail; int is480FrameSize = cfg.frameSize == 480; ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMESIZE, &is480FrameSize); - if (aac_decode_handle_error(ret, "updating frame length (ld)")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "updating frame length (ld)")) goto fail; int is960FrameSize = cfg.frameSize == 960; ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_ENHAACPLUS_DEC_CONFIG_PARAM_FRAMELENGTH_FLAG, &is960FrameSize); - if (aac_decode_handle_error(ret, "updating frame length")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "updating frame length")) goto fail; ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_XHEAAC_DEC_CONFIG_PARAM_ESBR, &cfg.eSBR); - if (aac_decode_handle_error(ret, "updating esbr")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "updating esbr")) goto fail; + + ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_XHEAAC_DEC_CONFIG_ERROR_CONCEALMENT, &cfg.errorConceal); + if (aac_decode_handle_error(aacDec, ret, "updating error conceal")) goto fail; aacDec->eSBR = cfg.eSBR; aacDec->asc = cfg.asc; @@ -708,32 +725,32 @@ AACDecode * aac_decode_open(AACDecodeSettings cfg) { /* 04 - Decoder Memory */ ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_GET_MEMTABS_SIZE, 0, &mem_info_size); - if (aac_decode_handle_error(ret, "memtab size")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "memtab size")) goto fail; aacDec->memInfoTab = malloc(mem_info_size); if (aacDec->memInfoTab == NULL) goto fail; ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_MEMTABS_PTR, 0, aacDec->memInfoTab); - if (aac_decode_handle_error(ret, "set memtabs ptr")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "set memtabs ptr")) goto fail; /* 05 - Post Config */ ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_API_POST_CONFIG_PARAMS, NULL); - if (aac_decode_handle_error(ret, "postconfig")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "postconfig")) goto fail; for (int i = 0; i < 4; i++) { int ui_size = 0, ui_alignment = 0, ui_type = 0; /* Get memory size */ ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_GET_MEM_INFO_SIZE, i, &ui_size); - if (aac_decode_handle_error(ret, "get meminfo 1")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "get meminfo 1")) goto fail; /* Get memory alignment */ ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_GET_MEM_INFO_ALIGNMENT, i, &ui_alignment); - if (aac_decode_handle_error(ret, "get meminfo 2")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "get meminfo 2")) goto fail; /* Get memory type */ ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_GET_MEM_INFO_TYPE, i, &ui_type); - if (aac_decode_handle_error(ret, "get meminfo 3")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "get meminfo 3")) goto fail; ui_alignment = (ui_alignment + sizeof(void *) - 1) / sizeof(void *); ui_alignment = ui_alignment * sizeof(void *); @@ -746,7 +763,7 @@ AACDecode * aac_decode_open(AACDecodeSettings cfg) { /* Set the buffer pointer */ ret = ixheaacd_dec_api(aacDec->apiObj, IA_API_CMD_SET_MEM_PTR, i, temp); - if (aac_decode_handle_error(ret, "set meminfo")) goto fail; + if (aac_decode_handle_error(aacDec, ret, "set meminfo")) goto fail; aacDec->memBuffer[i] = temp; @@ -763,7 +780,7 @@ AACDecode * aac_decode_open(AACDecodeSettings cfg) { fail: if (aacDec) { - for (int i = 0; i < 4; i++) free(aacDec->memBuffer[i]); + for (int i = 0; i < 4; i++) free_global(aacDec->memBuffer[i]); free(aacDec->memInfoTab); free(aacDec->apiObj); @@ -777,7 +794,7 @@ void aac_decode_write_buffer(AACDecode *aacd, unsigned char *data, unsigned int memcpy(aacd->inBuf, data, dataSize); ret = ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_SET_INPUT_BYTES, 0, &dataSize); - aac_decode_handle_error(ret, "upload buffer"); + aac_decode_handle_error(aacd, ret, "upload buffer"); } int aac_decode_init(AACDecode *aacd, bool *isInitDone, unsigned int *noBytes) { @@ -814,7 +831,7 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, if (aacd->ascSize > 0 && !aacd->ascDone) { aac_decode_write_buffer(aacd, aacd->asc, aacd->ascSize); ret = aac_decode_init(aacd, &aacd->isInitDone, bytesRead); - if (aac_decode_handle_error(ret, "init-decoder")) return -1; + if (aac_decode_handle_error(aacd, ret, "init-decoder")) return -1; aacd->ascDone = 1; timeInited++; @@ -822,7 +839,7 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, aac_decode_write_buffer(aacd, inData, inDataSize); ret = aac_decode_init(aacd, &aacd->isInitDone, bytesRead); - if (aac_decode_handle_error(ret, "init-decoder")) return -1; + if (aac_decode_handle_error(aacd, ret, "init-decoder")) return -1; if (ret == IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES) return 0; @@ -855,14 +872,14 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, aac_decode_write_buffer(aacd, inData, inDataSize); ret = aac_decode_execute(aacd, &isDecodeDone, bytesRead, &prerolls); - if (aac_decode_handle_error(ret, "decode")) return -1; + if (aac_decode_handle_error(aacd, ret, "decode")) return -1; int prerollOffset = 0; *outSize = 0; do { ret = ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_GET_OUTPUT_BYTES, 0, &outByteTemp); - if (aac_decode_handle_error(ret, "preroll handling")) return -1; + if (aac_decode_handle_error(aacd, ret, "preroll handling")) return -1; if (aacd->sbrMode && (aacd->aot < 23) && aacd->eSBR) { if (aacd->frameCounter > 0) @@ -884,7 +901,7 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, void aac_decode_close(AACDecode *aacd) { ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INPUT_OVER, 0, NULL); - for (int i = 0; i < 4; i++) free(aacd->memBuffer[i]); + for (int i = 0; i < 4; i++) free_global(aacd->memBuffer[i]); free(aacd->memInfoTab); free(aacd->apiObj); From bceac8a9eea632b82a74e7eba09d18a6fae888c2 Mon Sep 17 00:00:00 2001 From: wrapper Date: Tue, 12 Aug 2025 22:39:26 +0700 Subject: [PATCH 06/29] flush buffers --- source/libaac/include/aacnext/libaac.h | 2 ++ source/libaac/source/libaac.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/source/libaac/include/aacnext/libaac.h b/source/libaac/include/aacnext/libaac.h index e996140..77229a1 100644 --- a/source/libaac/include/aacnext/libaac.h +++ b/source/libaac/include/aacnext/libaac.h @@ -85,6 +85,8 @@ typedef struct { AACNEXT_API AACDecode * aac_decode_open(AACDecodeSettings cfg); AACNEXT_API int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, unsigned char *outData, unsigned int *outSize, unsigned int *bytesRead); +AACNEXT_API void aac_dec_reset(AACDecode *aacd); +AACNEXT_API void aac_dec_flush_buffer(AACDecode *aacd); AACNEXT_API void aac_decode_close(AACDecode *aacd); #ifdef __cplusplus diff --git a/source/libaac/source/libaac.c b/source/libaac/source/libaac.c index 3ccfc6d..ae9368c 100644 --- a/source/libaac/source/libaac.c +++ b/source/libaac/source/libaac.c @@ -899,6 +899,14 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, return 1; } +void aac_dec_reset(AACDecode *aacd) { + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_GA_HDR, NULL); +} + +void aac_dec_flush_buffer(AACDecode *aacd) { + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL); +} + void aac_decode_close(AACDecode *aacd) { ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INPUT_OVER, 0, NULL); for (int i = 0; i < 4; i++) free_global(aacd->memBuffer[i]); From 7faf49a81ca00c51ea1d2a85b43a50ddef3591ac Mon Sep 17 00:00:00 2001 From: wrapper Date: Tue, 12 Aug 2025 22:41:51 +0700 Subject: [PATCH 07/29] rename --- source/libaac/include/aacnext/libaac.h | 4 ++-- source/libaac/source/libaac.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/libaac/include/aacnext/libaac.h b/source/libaac/include/aacnext/libaac.h index 77229a1..377c826 100644 --- a/source/libaac/include/aacnext/libaac.h +++ b/source/libaac/include/aacnext/libaac.h @@ -85,8 +85,8 @@ typedef struct { AACNEXT_API AACDecode * aac_decode_open(AACDecodeSettings cfg); AACNEXT_API int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, unsigned char *outData, unsigned int *outSize, unsigned int *bytesRead); -AACNEXT_API void aac_dec_reset(AACDecode *aacd); -AACNEXT_API void aac_dec_flush_buffer(AACDecode *aacd); +AACNEXT_API void aac_decode_reset(AACDecode *aacd); +AACNEXT_API void aac_decode_flush_buffer(AACDecode *aacd); AACNEXT_API void aac_decode_close(AACDecode *aacd); #ifdef __cplusplus diff --git a/source/libaac/source/libaac.c b/source/libaac/source/libaac.c index ae9368c..70cd1e1 100644 --- a/source/libaac/source/libaac.c +++ b/source/libaac/source/libaac.c @@ -899,11 +899,11 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, return 1; } -void aac_dec_reset(AACDecode *aacd) { +void aac_decode_reset(AACDecode *aacd) { ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_GA_HDR, NULL); } -void aac_dec_flush_buffer(AACDecode *aacd) { +void aac_decode_flush_buffer(AACDecode *aacd) { ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL); } From d13979f664a05f89366da3232bec5ae52dbd2245 Mon Sep 17 00:00:00 2001 From: wrapper Date: Wed, 13 Aug 2025 07:17:27 +0700 Subject: [PATCH 08/29] patch again --- patch/libxaac.patch | 150 +++++++------------------------------------- 1 file changed, 21 insertions(+), 129 deletions(-) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index e28862d..c77825c 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -67,7 +67,7 @@ index 982a6aa..d827687 100644 WORD8 *out_24bit = (WORD8 *)out_buf; for (i = 0; i < num; i++) { diff --git a/encoder/ixheaace_api.c b/encoder/ixheaace_api.c -index 6d5c47e..22fe7e4 100644 +index 6d5c47e..ea870d4 100644 --- a/encoder/ixheaace_api.c +++ b/encoder/ixheaace_api.c @@ -831,7 +831,7 @@ static IA_ERRORCODE ixheaace_set_config_params(ixheaace_api_struct *pstr_api_str @@ -99,7 +99,7 @@ index 6d5c47e..22fe7e4 100644 } pstr_api_struct->config[0].aac_config.full_bandwidth = pstr_input_config->aac_config.full_bandwidth; -+ pstr_api_struct->config[0].aac_config.band_width = ++ pstr_api_struct->config[0].aac_config.band_width = + pstr_input_config->aac_config.bandwidth; } @@ -325,143 +325,26 @@ index eb9e882..e85b300 100644 const FLOAT32 tns_coeff_3_borders[8]; const FLOAT32 tns_coeff_4[16]; diff --git a/encoder/ixheaace_sbr_freq_scaling.c b/encoder/ixheaace_sbr_freq_scaling.c -index 7eec5a9..192907e 100644 +index 7eec5a9..e3e7921 100644 --- a/encoder/ixheaace_sbr_freq_scaling.c +++ b/encoder/ixheaace_sbr_freq_scaling.c -@@ -158,31 +158,31 @@ static WORD32 ixheaace_get_start_freq(WORD32 fs, WORD32 start_freq) { - WORD32 minimum_k0; - - switch (fs) { -- case 16000: -+ case 8000: - minimum_k0 = 24; - break; -- case 22050: -+ case 11025: - minimum_k0 = 17; - break; -- case 24000: -+ case 12000: - minimum_k0 = 16; - break; -- case 32000: -+ case 16000: - minimum_k0 = 16; - break; -- case 44100: -+ case 22050: - minimum_k0 = 12; - break; -- case 48000: -+ case 24000: - minimum_k0 = 11; - break; -- case 64000: -+ case 32000: - minimum_k0 = 10; - break; -- case 88200: -+ case 44100: - minimum_k0 = 7; - break; -- case 96000: -+ case 48000: - minimum_k0 = 7; - break; - default: -@@ -190,30 +190,30 @@ static WORD32 ixheaace_get_start_freq(WORD32 fs, WORD32 start_freq) { - } - - switch (fs) { -- case 16000: { -+ case 8000: { - return (minimum_k0 + vector_offset_16k[start_freq]); - } break; - -- case 22050: { -+ case 11025: { - return (minimum_k0 + vector_offset_22k[start_freq]); - } break; - -- case 24000: { -+ case 12000: { - return (minimum_k0 + vector_offset_24k[start_freq]); - } break; - -- case 32000: { -+ case 16000: { - return (minimum_k0 + vector_offset_32k[start_freq]); - } break; - -- case 44100: -- case 48000: -- case 64000: { -+ case 22050: -+ case 24000: -+ case 32000: { - return (minimum_k0 + vector_offset_44_48_64[start_freq]); - } break; - -- case 88200: -- case 96000: { -+ case 44100: -+ case 48000: { - return (minimum_k0 + vector_offset_88_96[start_freq]); - } break; - -@@ -230,36 +230,54 @@ static WORD32 ixheaace_get_stop_freq(WORD32 fs, WORD32 stop_freq) { - WORD32 v_dstop[13]; - - switch (fs) { -- case 16000: -+ case 8000: - k1_min = ixheaace_stop_freq_16k[0]; - v_stop_freq = (WORD32 *)&ixheaace_stop_freq_16k[0]; - break; -- case 22050: -+ case 11025: - k1_min = ixheaace_stop_freq_22k[0]; - v_stop_freq = (WORD32 *)&ixheaace_stop_freq_22k[0]; - break; -- case 24000: -+ case 12000: - k1_min = ixheaace_stop_freq_24k[0]; - v_stop_freq = (WORD32 *)&ixheaace_stop_freq_24k[0]; - break; -- case 32000: -+ case 16000: - k1_min = 32; - - v_stop_freq = (WORD32 *)vector_stop_freq_32; - break; - -- case 44100: -+ case 22050: - k1_min = 23; - - v_stop_freq = (WORD32 *)vector_stop_freq_44; - break; - -- case 48000: -+ case 24000: - k1_min = 21; - +@@ -260,6 +260,24 @@ static WORD32 ixheaace_get_stop_freq(WORD32 fs, WORD32 stop_freq) { v_stop_freq = (WORD32 *)vector_stop_freq_48; break; -+ case 32000: ++ case 64000: + k1_min = 20; + + v_stop_freq = (WORD32 *)vector_stop_freq_64; + break; + -+ case 44100: ++ case 88200: + k1_min = 15; + + v_stop_freq = (WORD32 *)vector_stop_freq_88; + break; + -+ case 48000: ++ case 96000: + k1_min = 13; + + v_stop_freq = (WORD32 *)vector_stop_freq_96; @@ -471,7 +354,7 @@ index 7eec5a9..192907e 100644 v_stop_freq = (WORD32 *)vector_stop_freq_32; k1_min = 21; /* illegal fs */ diff --git a/encoder/ixheaace_sbr_main.c b/encoder/ixheaace_sbr_main.c -index 893d215..9e13b13 100644 +index 893d215..b8594e8 100644 --- a/encoder/ixheaace_sbr_main.c +++ b/encoder/ixheaace_sbr_main.c @@ -100,7 +100,7 @@ FLOAT32 *ixheaace_get_hbe_resample_buffer(ixheaace_pstr_sbr_enc pstr_env_enc) { @@ -499,8 +382,17 @@ index 893d215..9e13b13 100644 *ptr_core_sr = sample_rate_input / 2; +@@ -965,7 +967,7 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg + pstr_env_enc->str_sbr_cfg.stereo_mode = + (params->codec_settings.num_channels == 2) ? params->stereo_mode : IXHEAACE_SBR_MODE_MONO; + +- if (params->codec_settings.sample_freq <= 24000) { ++ if (params->codec_settings.sample_freq <= 24000 || !params->is_ld_sbr) { + pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_DUAL_RATE; + if (params->sbr_codec == USAC_SBR) { + pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; diff --git a/encoder/ixheaace_sbr_rom.c b/encoder/ixheaace_sbr_rom.c -index 90e94c5..435fc2e 100644 +index 90e94c5..8856138 100644 --- a/encoder/ixheaace_sbr_rom.c +++ b/encoder/ixheaace_sbr_rom.c @@ -48,6 +48,9 @@ const WORD32 vector_offset_def[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 2 @@ -772,7 +664,7 @@ index 90e94c5..435fc2e 100644 + {{ + /*** 12000hz 1ch ***/ + {8000, 32000, {1, 0}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, -+ {0}}, ++ {0}}, + { + {0}}}, + @@ -826,7 +718,7 @@ index 90e94c5..435fc2e 100644 + {76000, 82000, {12, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {82000, 128001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, -+ + + {{ + /*** 24000hz 1ch ***/ + {8000, 12000, {1, 1}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, @@ -868,7 +760,7 @@ index 90e94c5..435fc2e 100644 + {112000, 144000, {11, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {144000, 256001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, - ++ + {{ + /*** 44100hz 1ch ***/ + {24000, 36000, {4, 9}, 3, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, From bc4c113b68295d518bfc465fbd389f82e8f05b51 Mon Sep 17 00:00:00 2001 From: wrapper Date: Wed, 13 Aug 2025 09:23:15 +0700 Subject: [PATCH 09/29] ffmpeg patch --- ffmpeg-git.patch | 532 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 532 insertions(+) create mode 100644 ffmpeg-git.patch diff --git a/ffmpeg-git.patch b/ffmpeg-git.patch new file mode 100644 index 0000000..77eaf6c --- /dev/null +++ b/ffmpeg-git.patch @@ -0,0 +1,532 @@ +diff --git a/configure b/configure +index 727c3daea8..540219d6bf 100755 +--- a/configure ++++ b/configure +@@ -212,6 +212,7 @@ External library support: + --enable-jni enable JNI support [no] + --enable-ladspa enable LADSPA audio filtering [no] + --enable-lcms2 enable ICC profile support via LittleCMS 2 [no] ++ --enable-libaac-next enable AAC encoding using libaac-next [no] + --enable-libaom enable AV1 video encoding/decoding via libaom [no] + --enable-libaribb24 enable ARIB text and caption decoding via libaribb24 [no] + --enable-libaribcaption enable ARIB text and caption decoding via libaribcaption [no] +@@ -1901,6 +1902,7 @@ EXTERNAL_LIBRARY_NONFREE_LIST=" + + EXTERNAL_LIBRARY_VERSION3_LIST=" + gmp ++ libaac_next + libaribb24 + liblensfun + libopencore_amrnb +@@ -3592,6 +3594,9 @@ hevc_videotoolbox_encoder_deps="pthreads" + hevc_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder" + prores_videotoolbox_encoder_deps="pthreads" + prores_videotoolbox_encoder_select="videotoolbox_encoder" ++libaac_next_decoder_deps="libaac_next" ++libaac_next_encoder_deps="libaac_next" ++libaac_next_encoder_select="audio_frame_queue" + libaom_av1_decoder_deps="libaom" + libaom_av1_encoder_deps="libaom" + libaom_av1_encoder_select="extract_extradata_bsf dovi_rpuenc" +@@ -7017,6 +7022,7 @@ enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gn + enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; } + enabled ladspa && require_headers "ladspa.h dlfcn.h" + enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext ++enabled libaac_next && require_pkg_config libaac_next "libaac >= 1.0.0" libaac.h aac_encode_open + enabled libaom && require_pkg_config libaom "aom >= 2.0.0" aom/aom_codec.h aom_codec_version + enabled liboapv && require_pkg_config liboapv "oapv >= 0.2.0.0" "oapv/oapv.h" oapve_encode + enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new || +diff --git a/libavcodec/Makefile b/libavcodec/Makefile +index 83ef92963a..45d634ae8f 100644 +--- a/libavcodec/Makefile ++++ b/libavcodec/Makefile +@@ -1144,6 +1144,8 @@ OBJS-$(CONFIG_ALAC_AT_ENCODER) += audiotoolboxenc.o + OBJS-$(CONFIG_ILBC_AT_ENCODER) += audiotoolboxenc.o + OBJS-$(CONFIG_PCM_ALAW_AT_ENCODER) += audiotoolboxenc.o + OBJS-$(CONFIG_PCM_MULAW_AT_ENCODER) += audiotoolboxenc.o ++OBJS-$(CONFIG_LIBAAC_NEXT_ENCODER) += libaac_nextenc.o ++OBJS-$(CONFIG_LIBAAC_NEXT_DECODER) += libaac_nextdec.o + OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o libaom.o + OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o libaom.o + OBJS-$(CONFIG_LIBARIBB24_DECODER) += libaribb24.o ass.o +diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c +index f5ec2e01e8..8fcd1a806c 100644 +--- a/libavcodec/allcodecs.c ++++ b/libavcodec/allcodecs.c +@@ -766,6 +766,8 @@ extern const FFCodec ff_pcm_mulaw_at_encoder; + extern const FFCodec ff_pcm_mulaw_at_decoder; + extern const FFCodec ff_qdmc_at_decoder; + extern const FFCodec ff_qdm2_at_decoder; ++extern const FFCodec ff_libaac_next_encoder; ++extern const FFCodec ff_libaac_next_decoder; + extern FFCodec ff_libaom_av1_encoder; + /* preferred over libaribb24 */ + extern const FFCodec ff_libaribcaption_decoder; +diff --git a/libavcodec/libaac_nextdec.c b/libavcodec/libaac_nextdec.c +new file mode 100644 +index 0000000000..c71cc3c8c1 +--- /dev/null ++++ b/libavcodec/libaac_nextdec.c +@@ -0,0 +1,154 @@ ++/* ++ * Libaac-next decoder (libxaac based) ++ * Copyright (c) 2025 Wrapper ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/** ++ * @file ++ * Interface to libaac-next decoder. ++ */ ++ ++#include "avcodec.h" ++#include ++#include "libavcodec/codec_id.h" ++#include "libavutil/channel_layout.h" ++#include "libavutil/error.h" ++#include "libavutil/opt.h" ++#include "avcodec.h" ++#include "codec_internal.h" ++#include "decode.h" ++#include "libavutil/samplefmt.h" ++ ++typedef struct { ++ AACDecode *decoder; ++ int error_conceal; ++ int esbr; ++} libaacDecodeCTX; ++ ++static const AVChannelLayout aac_ch_layouts[6] = { ++ AV_CHANNEL_LAYOUT_MONO, ++ AV_CHANNEL_LAYOUT_STEREO, ++ AV_CHANNEL_LAYOUT_SURROUND, ++ AV_CHANNEL_LAYOUT_4POINT0, ++ AV_CHANNEL_LAYOUT_5POINT0_BACK, ++ AV_CHANNEL_LAYOUT_5POINT1_BACK, ++}; ++ ++static const AVOption aac_dec_options[] = { ++ { "conceal", "Error concealment", offsetof(libaacDecodeCTX, error_conceal), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, ++ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacDecodeCTX, esbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, ++ { NULL } ++}; ++ ++static const AVClass aac_dec_class = { ++ .class_name = "libaac", ++ .item_name = av_default_item_name, ++ .option = aac_dec_options, ++ .version = LIBAVUTIL_VERSION_INT, ++}; ++ ++static void aac_dec_error_handler(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle) { ++ AVCodecContext *ctx = (AVCodecContext *)handle; ++ av_log(ctx, AV_LOG_ERROR, "%s: %s (0x%08X)\n", section, errorMsg, errorCode); ++} ++ ++static av_cold int libaac_decode_init(AVCodecContext *avctx) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ AACDecodeSettings cfg = {0}; ++ ++ cfg.bitsPerSamples = 16; ++ cfg.errorConceal = s->error_conceal; ++ cfg.eSBR = s->esbr; ++ cfg.frameSize = 0; ++ cfg.asc = avctx->extradata; ++ cfg.ascSize = avctx->extradata_size; ++ cfg.errorHandleCtx = avctx; ++ cfg.errorHandler = aac_dec_error_handler; ++ ++ s->decoder = aac_decode_open(cfg); ++ if (!s->decoder) ++ { ++ return AVERROR(EINVAL); ++ } ++ ++ avctx->sample_fmt = AV_SAMPLE_FMT_S16; ++ return 0; ++} ++ ++static av_cold int libaac_decode_close(AVCodecContext *avctx) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ ++ if (s->decoder) ++ aac_decode_close(s->decoder); ++ ++ return 0; ++} ++ ++static int libaac_decode_frame(AVCodecContext *avctx, AVFrame *frame, ++ int *got_frame_ptr, AVPacket *avpkt) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ uint32_t decode_size, frame_size; ++ int ret; ++ ++ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) ++ return ret; ++ ++ ret = aac_decode(s->decoder, avpkt->data, avpkt->size, frame->data[0], &decode_size, &frame_size); ++ if (ret < 0) ++ return AVERROR_EXTERNAL; ++ ++ avctx->sample_rate = s->decoder->sampleRate; ++ avctx->profile = s->decoder->aot - 1; ++ avctx->ch_layout = aac_ch_layouts[s->decoder->noChannels - 1]; ++ avctx->frame_size = 1024; ++ ++ frame->nb_samples = avctx->frame_size; ++ ++ *got_frame_ptr = 1; ++ return frame_size; ++} ++ ++static av_cold void libaac_decode_flush(AVCodecContext *avctx) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ ++ if (!s->decoder) ++ return; ++ ++ aac_decode_flush_buffer(s->decoder); ++} ++ ++const FFCodec ff_libaac_next_decoder = { ++ .p.name = "libaac", ++ CODEC_LONG_NAME("custom libxaac-based AAC decoder"), ++ .p.type = AVMEDIA_TYPE_AUDIO, ++ .p.id = AV_CODEC_ID_AAC, ++ .priv_data_size = sizeof(libaacDecodeCTX), ++ .init = libaac_decode_init, ++ FF_CODEC_DECODE_CB(libaac_decode_frame), ++ .close = libaac_decode_close, ++ .flush = libaac_decode_flush, ++ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, ++ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, ++ .p.priv_class = &aac_dec_class, ++ .p.wrapper_name = "libaac", ++}; +diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c +new file mode 100755 +index 0000000000..1fbe37dc46 +--- /dev/null ++++ b/libavcodec/libaac_nextenc.c +@@ -0,0 +1,302 @@ ++/* ++ * Libaac-next encoder (libxaac based) ++ * Copyright (c) 2025 Wrapper ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/** ++ * @file ++ * Interface to libaac-next encoder. ++ */ ++ ++#include ++ ++#include "libavcodec/defs.h" ++#include "libavutil/channel_layout.h" ++#include "libavutil/intreadwrite.h" ++#include "libavutil/log.h" ++#include "libavutil/opt.h" ++#include "libavutil/mem.h" ++#include "avcodec.h" ++#include "audio_frame_queue.h" ++#include "codec_internal.h" ++#include "encode.h" ++#include "libavutil/samplefmt.h" ++#include "profiles.h" ++ ++typedef struct ++{ ++ const AVClass *class; ++ AACContext *encoder; ++ int delay_sent; ++ int flush_delay; ++ ++ int eld_v2; ++ int esbr; ++ int frame_length; ++ int iq; ++ int tns; ++ ++ AudioFrameQueue afq; ++} libaacEncodeCTX; ++ ++static const AVOption aac_enc_options[] = { ++ { "eld_v2", "Enable ELDv2 (LD-MPS extension for ELD stereo signals)", offsetof(libaacEncodeCTX, eld_v2), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacEncodeCTX, esbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "frame_length", "The desired frame length", offsetof(libaacEncodeCTX, frame_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1024, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "iq", "Inverse quantization", offsetof(libaacEncodeCTX, frame_length), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 2, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "tns", "Temporal Noise Shaping", offsetof(libaacEncodeCTX, tns), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ FF_AAC_PROFILE_OPTS ++ { NULL } ++}; ++ ++static const AVClass aac_enc_class = { ++ .class_name = "libaac", ++ .item_name = av_default_item_name, ++ .option = aac_enc_options, ++ .version = LIBAVUTIL_VERSION_INT, ++}; ++ ++static void aac_enc_error_handler(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle) { ++ AVCodecContext *ctx = (AVCodecContext *)handle; ++ av_log(ctx, AV_LOG_ERROR, "%s: %s (0x%08X)\n", section, errorMsg, errorCode); ++} ++ ++static av_cold int libaac_encode_init(AVCodecContext *avctx) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ AACSettings cfg = {0}; ++ ++ /* number of channels */ ++ if (avctx->ch_layout.nb_channels < 1 || avctx->ch_layout.nb_channels > 6) ++ { ++ av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->ch_layout.nb_channels); ++ return AVERROR(EINVAL); ++ } ++ ++ cfg.sampleRate = avctx->sample_rate; ++ cfg.noChannels = avctx->ch_layout.nb_channels; ++ cfg.bitsPerSamples = avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? 32 : 16; ++ cfg.bitrate = avctx->bit_rate; ++ cfg.adts = !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER); ++ cfg.cutoff = avctx->cutoff; ++ switch (avctx->profile) { ++ case AV_PROFILE_AAC_LOW: ++ case AV_PROFILE_UNKNOWN: ++ cfg.profile = AAC_LC; ++ break; ++ ++ case AV_PROFILE_AAC_HE: ++ cfg.profile = AAC_HE; ++ break; ++ ++ case AV_PROFILE_AAC_HE_V2: ++ cfg.profile = AAC_HEV2; ++ break; ++ ++ case AV_PROFILE_AAC_LD: ++ cfg.profile = AAC_LD; ++ break; ++ ++ case AV_PROFILE_AAC_ELD: ++ cfg.profile = AAC_ELD; ++ break; ++ } ++ cfg.tns = s->tns; ++ cfg.frameSize = s->frame_length; ++ cfg.eSBR = s->esbr; ++ cfg.iq = s->iq; ++ ++ cfg.errorHandleCtx = avctx; ++ cfg.errorHandler = aac_enc_error_handler; ++ ++ s->encoder = aac_encode_open(cfg); ++ ++ if (!s->encoder) ++ { ++ return AVERROR(EINVAL); ++ } ++ ++ avctx->frame_size = s->encoder->no_samples / avctx->ch_layout.nb_channels; ++ avctx->initial_padding = s->encoder->inputDelay; ++ s->flush_delay = s->encoder->inputDelay; ++ ++ av_log(avctx, AV_LOG_TRACE, "frame size: %d, initial delay: %d\n", avctx->frame_size, avctx->initial_padding); ++ ++ ff_af_queue_init(avctx, &s->afq); ++ ++ /* Set decoder specific info */ ++ avctx->extradata_size = 0; ++ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ++ { ++ avctx->extradata = av_mallocz(s->encoder->ascSize + AV_INPUT_BUFFER_PADDING_SIZE); ++ ++ if (!avctx->extradata) ++ { ++ return AVERROR(ENOMEM); ++ } ++ ++ memcpy(avctx->extradata, s->encoder->asc, s->encoder->ascSize); ++ } ++ return 0; ++} ++ ++static int libaac_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ++ const AVFrame *frame, int *got_packet) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ int ret; ++ int discard_padding; ++ ++ if ((ret = ff_alloc_packet(avctx, pkt, s->encoder->max_out_bytes)) < 0) ++ return ret; ++ ++ if (!frame) ++ { ++ int isFlush = s->encoder->in_buf_offset <= 0; ++ av_log(avctx, AV_LOG_TRACE, "frame_queue_count: %d, frame_queue_size: %d, in_buf: %d, is_flush: %d, flush_delay: %d\n", s->afq.frame_count, s->afq.remaining_samples, s->encoder->in_buf_offset, isFlush, s->flush_delay); ++ ++ if (isFlush && s->flush_delay <= 0) ++ return 0; ++ ++ /* Flushing */ ++ if ((ret = aac_encode(s->encoder, NULL, 0, pkt->data, (unsigned int *)&pkt->size)) < 0) ++ { ++ return AVERROR(EINVAL); ++ } ++ ++ if (isFlush) ++ s->flush_delay -= avctx->frame_size; ++ } ++ else ++ { ++ /* Encoding */ ++ if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) ++ return ret; ++ ++ int encodeSize = (avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? 4 : 2) * avctx->ch_layout.nb_channels * frame->nb_samples; ++ av_log(avctx, AV_LOG_TRACE, "encode size: %d\n", encodeSize); ++ ++ if ((ret = aac_encode(s->encoder, frame->data[0], encodeSize, pkt->data, (unsigned int *)&pkt->size)) < 0) ++ { ++ return AVERROR(EINVAL); ++ } ++ } ++ ++ ff_af_queue_remove(&s->afq, avctx->frame_size, &pkt->pts, &pkt->duration); ++ ++ /* discard padding copied from fdkaac encoder */ ++ discard_padding = avctx->frame_size - pkt->duration; ++ ++ // Check if subtraction resulted in an overflow ++ if ((discard_padding < avctx->frame_size) != (pkt->duration > 0)) ++ { ++ av_log(avctx, AV_LOG_ERROR, "discard padding overflow\n"); ++ return AVERROR(EINVAL); ++ } ++ ++ if ((!s->delay_sent && avctx->initial_padding > 0) || discard_padding > 0) ++ { ++ uint8_t *side_data = ++ av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10); ++ if (!side_data) ++ return AVERROR(ENOMEM); ++ if (!s->delay_sent) ++ { ++ AV_WL32(side_data, avctx->initial_padding); ++ s->delay_sent = 1; ++ } ++ AV_WL32(side_data + 4, discard_padding); ++ } ++ ++ pkt->flags |= AV_PKT_FLAG_KEY; ++ *got_packet = 1; ++ return 0; ++} ++ ++static void libaac_encode_flush(AVCodecContext *avctx) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ uint8_t sink_null[32768]; ++ int64_t pts, duration; ++ uint32_t out_bytes; ++ ++ av_log(avctx, AV_LOG_TRACE, "encoder flush\n"); ++ ff_af_queue_remove(&s->afq, s->afq.frame_count, &pts, &duration); ++ aac_encode(s->encoder, NULL, 0, sink_null, &out_bytes); ++} ++ ++static av_cold int libaac_encode_close(AVCodecContext *avctx) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ ++ if (s->encoder) ++ aac_encode_close(s->encoder); ++ ++ ff_af_queue_close(&s->afq); ++ ++ return 0; ++} ++ ++static const FFCodecDefault defaults[] = { ++ {"b", "128000"}, ++ {NULL}}; ++ ++static const AVProfile libaac_profiles[] = { ++ { AV_PROFILE_AAC_LOW, "LC" }, ++ { AV_PROFILE_AAC_HE, "HE-AAC" }, ++ { AV_PROFILE_AAC_HE_V2, "HE-AACv2" }, ++ { AV_PROFILE_AAC_LD, "LD" }, ++ { AV_PROFILE_AAC_ELD, "ELD" }, ++ {AV_PROFILE_UNKNOWN}, ++}; ++ ++static const int aac_sample_rates[] = { ++ 96000, 88200, 64000, 48000, 44100, 32000, ++ 24000, 22050, 16000, 12000, 11025, 8000, 0 ++}; ++ ++static const AVChannelLayout aac_ch_layouts[6] = { ++ AV_CHANNEL_LAYOUT_MONO, ++ AV_CHANNEL_LAYOUT_STEREO, ++ AV_CHANNEL_LAYOUT_SURROUND, ++ AV_CHANNEL_LAYOUT_4POINT0, ++ AV_CHANNEL_LAYOUT_5POINT0_BACK, ++ AV_CHANNEL_LAYOUT_5POINT1_BACK, ++}; ++ ++const FFCodec ff_libaac_next_encoder = { ++ .p.name = "libaac", ++ CODEC_LONG_NAME("custom libxaac-based AAC encoder"), ++ .p.type = AVMEDIA_TYPE_AUDIO, ++ .p.id = AV_CODEC_ID_AAC, ++ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_ENCODER_FLUSH, ++ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, ++ .priv_data_size = sizeof(libaacEncodeCTX), ++ .init = libaac_encode_init, ++ FF_CODEC_ENCODE_CB(libaac_encode_frame), ++ .flush = libaac_encode_flush, ++ .close = libaac_encode_close, ++ CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), ++ .p.priv_class = &aac_enc_class, ++ .defaults = defaults, ++ .p.profiles = libaac_profiles, ++ CODEC_SAMPLERATES_ARRAY(aac_sample_rates), ++ .p.wrapper_name = "libaac", ++ CODEC_CH_LAYOUTS_ARRAY(aac_ch_layouts), ++}; From fbfc2cde3ac14e8c7fbf6b86d4eb0170b33968d9 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 14 Aug 2025 09:58:16 +0700 Subject: [PATCH 10/29] fix vector stop freq --- patch/libxaac.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index c77825c..1448e5a 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -392,14 +392,14 @@ index 893d215..b8594e8 100644 if (params->sbr_codec == USAC_SBR) { pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; diff --git a/encoder/ixheaace_sbr_rom.c b/encoder/ixheaace_sbr_rom.c -index 90e94c5..8856138 100644 +index 90e94c5..576b3bc 100644 --- a/encoder/ixheaace_sbr_rom.c +++ b/encoder/ixheaace_sbr_rom.c @@ -48,6 +48,9 @@ const WORD32 vector_offset_def[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 2 const WORD32 vector_stop_freq_32[14] = {32, 34, 36, 38, 40, 42, 44, 46, 49, 52, 55, 58, 61, 64}; const WORD32 vector_stop_freq_44[14] = {23, 25, 27, 29, 32, 34, 37, 40, 43, 47, 51, 55, 59, 64}; const WORD32 vector_stop_freq_48[14] = {21, 23, 25, 27, 30, 32, 35, 38, 42, 45, 49, 54, 59, 64}; -+const WORD32 vector_stop_freq_64[14] = {20, 22, 24, 26, 28, 31, 34, 37, 41, 45, 49, 54, 59, 64}; ++const WORD32 vector_stop_freq_64[14] = {20, 22, 24, 26, 29, 31, 34, 37, 41, 45, 49, 54, 59, 64}; +const WORD32 vector_stop_freq_88[14] = {15, 17, 19, 21, 23, 26, 29, 33, 37, 41, 46, 51, 57, 64}; +const WORD32 vector_stop_freq_96[14] = {13, 15, 17, 19, 21, 24, 27, 31, 35, 39, 44, 50, 57, 64}; From 267a6b140ec701a200f6af4f0564412445cbd7a3 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 14 Aug 2025 11:00:04 +0700 Subject: [PATCH 11/29] fix stop freq --- patch/libxaac.patch | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 1448e5a..109813d 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -325,9 +325,32 @@ index eb9e882..e85b300 100644 const FLOAT32 tns_coeff_3_borders[8]; const FLOAT32 tns_coeff_4[16]; diff --git a/encoder/ixheaace_sbr_freq_scaling.c b/encoder/ixheaace_sbr_freq_scaling.c -index 7eec5a9..e3e7921 100644 +index 7eec5a9..1f08fbd 100644 --- a/encoder/ixheaace_sbr_freq_scaling.c +++ b/encoder/ixheaace_sbr_freq_scaling.c +@@ -231,16 +231,16 @@ static WORD32 ixheaace_get_stop_freq(WORD32 fs, WORD32 stop_freq) { + + switch (fs) { + case 16000: +- k1_min = ixheaace_stop_freq_16k[0]; +- v_stop_freq = (WORD32 *)&ixheaace_stop_freq_16k[0]; ++ k1_min = ixheaace_usac_stop_freq_16k[0]; ++ v_stop_freq = (WORD32 *)&ixheaace_usac_stop_freq_16k[0]; + break; + case 22050: +- k1_min = ixheaace_stop_freq_22k[0]; +- v_stop_freq = (WORD32 *)&ixheaace_stop_freq_22k[0]; ++ k1_min = ixheaace_usac_stop_freq_22k[0]; ++ v_stop_freq = (WORD32 *)&ixheaace_usac_stop_freq_22k[0]; + break; + case 24000: +- k1_min = ixheaace_stop_freq_24k[0]; +- v_stop_freq = (WORD32 *)&ixheaace_stop_freq_24k[0]; ++ k1_min = ixheaace_usac_stop_freq_24k[0]; ++ v_stop_freq = (WORD32 *)&ixheaace_usac_stop_freq_24k[0]; + break; + case 32000: + k1_min = 32; @@ -260,6 +260,24 @@ static WORD32 ixheaace_get_stop_freq(WORD32 fs, WORD32 stop_freq) { v_stop_freq = (WORD32 *)vector_stop_freq_48; break; From a7c4a0e42e1c6acee13b04e04b101c14e6e3c8d2 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 14 Aug 2025 13:55:19 +0700 Subject: [PATCH 12/29] fix sbr preset --- patch/libxaac.patch | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 109813d..3ce3a24 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -67,7 +67,7 @@ index 982a6aa..d827687 100644 WORD8 *out_24bit = (WORD8 *)out_buf; for (i = 0; i < num; i++) { diff --git a/encoder/ixheaace_api.c b/encoder/ixheaace_api.c -index 6d5c47e..ea870d4 100644 +index 6d5c47e..749cac6 100644 --- a/encoder/ixheaace_api.c +++ b/encoder/ixheaace_api.c @@ -831,7 +831,7 @@ static IA_ERRORCODE ixheaace_set_config_params(ixheaace_api_struct *pstr_api_str @@ -104,6 +104,15 @@ index 6d5c47e..ea870d4 100644 } return IA_NO_ERROR; +@@ -2474,7 +2478,7 @@ static IA_ERRORCODE ia_enhaacplus_enc_init(ixheaace_api_struct *pstr_api_struct, + pstr_aac_config->bit_rate, + (pstr_api_struct->pstr_state->mps_enable + ? 1 +- : pstr_api_struct->config[ele_idx].chmode_nchannels), ++ : pstr_aac_config->num_out_channels), + pstr_aac_config->sample_rate, &core_sample_rate, + pstr_api_struct->spectral_band_replication_tabs.ptr_qmf_tab, + pstr_api_struct->pstr_state->aot)) { @@ -2692,6 +2696,7 @@ static IA_ERRORCODE ia_enhaacplus_enc_execute(ixheaace_api_struct *pstr_api_stru iexheaac_encoder_str **pstr_aac_enc; iaace_config *pstr_aac_config; From adbb65ac3132cd5b4a1e758e9bd9fa0ff85bb2f5 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 14 Aug 2025 14:55:22 +0700 Subject: [PATCH 13/29] return code --- source/examples/aacdec/aacdec.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/examples/aacdec/aacdec.cpp b/source/examples/aacdec/aacdec.cpp index b58ff76..260adb0 100644 --- a/source/examples/aacdec/aacdec.cpp +++ b/source/examples/aacdec/aacdec.cpp @@ -176,6 +176,7 @@ int main(int argc, char *argv[]) { int16_t *outBuf = new int16_t[decoder->outBufSize / sizeof(int16_t)]; uint32_t outSize; uint32_t nBytes; + int32_t res = 0; ProgressBar bar{ option::BarWidth{50}, @@ -246,6 +247,7 @@ int main(int argc, char *argv[]) { int ret = aac_decode(decoder, readBuf, bufReadSize, (uint8_t *)outBuf, &outSize, &nBytes); if (ret == -1) { std::cerr << "Decode frame " << adtsCount << " failed" << std::endl; + res = 1; break; } @@ -280,6 +282,7 @@ int main(int argc, char *argv[]) { outpFile.save(outFile); aac_decode_close(decoder); + return res; #if 0 #if 0 AACFileReader inData("asc.es", 4096); From a3300cdb914b45a6c207a21eef48dbfe111c0c74 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 14 Aug 2025 17:11:45 +0700 Subject: [PATCH 14/29] fix mean --- patch/libxaac.patch | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 3ce3a24..6447f2b 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -423,6 +423,23 @@ index 893d215..b8594e8 100644 pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_DUAL_RATE; if (params->sbr_codec == USAC_SBR) { pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; +diff --git a/encoder/ixheaace_sbr_noise_floor_est.c b/encoder/ixheaace_sbr_noise_floor_est.c +index c5fcd99..344d2b0 100644 +--- a/encoder/ixheaace_sbr_noise_floor_est.c ++++ b/encoder/ixheaace_sbr_noise_floor_est.c +@@ -136,8 +136,10 @@ static VOID ia_enhaacplus_enc_qmf_based_noise_floor_detection( + mean_org += ton_org; + mean_sbr += ton_sbr; + } +- mean_org /= (stop_channel - start_channel); +- mean_sbr /= (stop_channel - start_channel); ++ if ((stop_channel - start_channel) > 0) { ++ mean_org /= (stop_channel - start_channel); ++ mean_sbr /= (stop_channel - start_channel); ++ } + } + + if (mean_org < SBR_TON_MEAN_P0009 && mean_sbr < SBR_TON_MEAN_P0009) { diff --git a/encoder/ixheaace_sbr_rom.c b/encoder/ixheaace_sbr_rom.c index 90e94c5..576b3bc 100644 --- a/encoder/ixheaace_sbr_rom.c From c7067d90891a9121f16bb7de905ef14ea25cd116 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 14 Aug 2025 20:08:31 +0700 Subject: [PATCH 15/29] fix error conceal flag --- source/examples/aacdec/aacdec.cpp | 3 +++ source/libaac/include/aacnext/libaac.h | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/examples/aacdec/aacdec.cpp b/source/examples/aacdec/aacdec.cpp index 260adb0..4fff675 100644 --- a/source/examples/aacdec/aacdec.cpp +++ b/source/examples/aacdec/aacdec.cpp @@ -78,6 +78,7 @@ int main(int argc, char *argv[]) { ap.add_argument("input"); ap.add_argument("output"); + ap.add_argument("-c", "--conceal").help("Error concealment").flag(); ap.add_argument("-e", "--enhanced-sbr").help("Enhanced SBR").flag(); ap.add_argument("-f", "--frame-size").help("Frame size").default_value(0).scan<'i', int>(); @@ -91,12 +92,14 @@ int main(int argc, char *argv[]) { auto inFile = ap.get("input"); auto outFile = ap.get("output"); + auto errorConceal = ap.get("-c"); auto eSBR = ap.get("-e"); auto frameSize = ap.get("-f"); AACDecodeSettings aacConf = {}; aacConf.bitsPerSamples = 16; aacConf.eSBR = eSBR; + aacConf.errorConceal = errorConceal; aacConf.frameSize = frameSize; FILE * inpFile = fopen(inFile.c_str(), "rb"); diff --git a/source/libaac/include/aacnext/libaac.h b/source/libaac/include/aacnext/libaac.h index 377c826..480aea2 100644 --- a/source/libaac/include/aacnext/libaac.h +++ b/source/libaac/include/aacnext/libaac.h @@ -77,8 +77,8 @@ typedef struct { uint64_t noChannels; // Number of channels int32_t bitsPerSamples; // Bits per samples uint32_t frameSize; // Frame size - bool eSBR; // Enhanced SBR - bool errorConceal; // Error concealment + int32_t eSBR; // Enhanced SBR + int32_t errorConceal; // Error concealment void (* errorHandler)(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle); // Error handler void * errorHandleCtx; // Error handler object } AACDecodeSettings; From 07efeec79f5600eca7d6c38d19045f25b0801af7 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 14 Aug 2025 20:36:56 +0700 Subject: [PATCH 16/29] new git patch --- ffmpeg-git.patch | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/ffmpeg-git.patch b/ffmpeg-git.patch index 77eaf6c..5341245 100644 --- a/ffmpeg-git.patch +++ b/ffmpeg-git.patch @@ -64,10 +64,10 @@ index f5ec2e01e8..8fcd1a806c 100644 extern const FFCodec ff_libaribcaption_decoder; diff --git a/libavcodec/libaac_nextdec.c b/libavcodec/libaac_nextdec.c new file mode 100644 -index 0000000000..c71cc3c8c1 +index 0000000000..7450c14322 --- /dev/null +++ b/libavcodec/libaac_nextdec.c -@@ -0,0 +1,154 @@ +@@ -0,0 +1,170 @@ +/* + * Libaac-next decoder (libxaac based) + * Copyright (c) 2025 Wrapper @@ -99,16 +99,20 @@ index 0000000000..c71cc3c8c1 +#include "libavcodec/codec_id.h" +#include "libavutil/channel_layout.h" +#include "libavutil/error.h" ++#include "libavutil/log.h" +#include "libavutil/opt.h" +#include "avcodec.h" +#include "codec_internal.h" +#include "decode.h" +#include "libavutil/samplefmt.h" ++#include "libavutil/mem.h" + +typedef struct { ++ AVClass *class; + AACDecode *decoder; + int error_conceal; + int esbr; ++ unsigned char *decode_buffer; +} libaacDecodeCTX; + +static const AVChannelLayout aac_ch_layouts[6] = { @@ -157,7 +161,13 @@ index 0000000000..c71cc3c8c1 + { + return AVERROR(EINVAL); + } -+ ++ ++ s->decode_buffer = av_mallocz(4096 * 8); ++ if (!s->decode_buffer) ++ { ++ return AVERROR(ENOMEM); ++ } ++ + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + return 0; +} @@ -173,16 +183,13 @@ index 0000000000..c71cc3c8c1 +} + +static int libaac_decode_frame(AVCodecContext *avctx, AVFrame *frame, -+ int *got_frame_ptr, AVPacket *avpkt) ++ int *got_frame_ptr, AVPacket *avpkt) +{ + libaacDecodeCTX *s = avctx->priv_data; -+ uint32_t decode_size, frame_size; ++ uint32_t decode_size, read_size; + int ret; + -+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) -+ return ret; -+ -+ ret = aac_decode(s->decoder, avpkt->data, avpkt->size, frame->data[0], &decode_size, &frame_size); ++ ret = aac_decode(s->decoder, avpkt->data, avpkt->size, s->decode_buffer, &decode_size, &read_size); + if (ret < 0) + return AVERROR_EXTERNAL; + @@ -191,10 +198,19 @@ index 0000000000..c71cc3c8c1 + avctx->ch_layout = aac_ch_layouts[s->decoder->noChannels - 1]; + avctx->frame_size = 1024; + -+ frame->nb_samples = avctx->frame_size; ++ if (decode_size <= 0) ++ return AVERROR_EOF; ++ ++ frame->nb_samples = decode_size / av_get_bytes_per_sample(avctx->sample_fmt) / avctx->ch_layout.nb_channels; ++ ++ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) ++ return ret; ++ ++ av_log(avctx, AV_LOG_TRACE, "aac decode size: %d, decode buf: %d\n", decode_size, avctx->ch_layout.nb_channels * frame->nb_samples * av_get_bytes_per_sample(avctx->sample_fmt)); ++ memcpy(frame->data[0], s->decode_buffer, decode_size); + + *got_frame_ptr = 1; -+ return frame_size; ++ return read_size; +} + +static av_cold void libaac_decode_flush(AVCodecContext *avctx) @@ -224,7 +240,7 @@ index 0000000000..c71cc3c8c1 +}; diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c new file mode 100755 -index 0000000000..1fbe37dc46 +index 0000000000..c5b21f2095 --- /dev/null +++ b/libavcodec/libaac_nextenc.c @@ -0,0 +1,302 @@ @@ -351,7 +367,7 @@ index 0000000000..1fbe37dc46 + cfg.frameSize = s->frame_length; + cfg.eSBR = s->esbr; + cfg.iq = s->iq; -+ ++ + cfg.errorHandleCtx = avctx; + cfg.errorHandler = aac_enc_error_handler; + From 084af3e6f05dcfb5e4f7a064c0c5d6208140f8d7 Mon Sep 17 00:00:00 2001 From: wrapper Date: Fri, 15 Aug 2025 13:32:34 +0700 Subject: [PATCH 17/29] new patch, new externals --- externals/externals.txt | 7 +++---- patch/libxaac.patch | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/externals/externals.txt b/externals/externals.txt index df95a58..d17625a 100644 --- a/externals/externals.txt +++ b/externals/externals.txt @@ -1,15 +1,14 @@ include(ExternalProject) ExternalProject_Add(libxaac - GIT_REPOSITORY http://github.com/ittiam-systems/libxaac.git - GIT_TAG "388435c8f8f43fe0e44bf0d31dd3965283f119ec" - GIT_PROGRESS ON + URL https://github.com/ittiam-systems/libxaac/archive/eb62778aee21a98b9f6f5c27e0a1f2546a175172.zip + DOWNLOAD_EXTRACT_TIMESTAMP OFF UPDATE_DISCONNECTED 1 CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release SOURCE_DIR "${CMAKE_SOURCE_DIR}/externals/libxaac/" BINARY_DIR "" INSTALL_COMMAND "" TEST_COMMAND "" - PATCH_COMMAND git apply --reject --whitespace=fix "${CMAKE_SOURCE_DIR}/patch/libxaac.patch" + PATCH_COMMAND patch -p1 < "${CMAKE_SOURCE_DIR}/patch/libxaac.patch" ) ExternalProject_Get_Property(libxaac BINARY_DIR) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 6447f2b..d17f19d 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -21,7 +21,7 @@ index 5d9cd37..3196501 100644 # Adds libraries needed for executables diff --git a/decoder/ixheaacd_api.c b/decoder/ixheaacd_api.c -index 5e6a0ac..c4ae8e0 100644 +index 5e6a0ac..53cb371 100644 --- a/decoder/ixheaacd_api.c +++ b/decoder/ixheaacd_api.c @@ -579,7 +579,7 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd, @@ -33,6 +33,23 @@ index 5e6a0ac..c4ae8e0 100644 p_obj_exhaacplus_dec->aac_config.ui_pcm_wdsz = 16; return (IA_XHEAAC_DEC_CONFIG_NONFATAL_INVALID_PCM_WDSZ); } +@@ -940,6 +940,7 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd, + } else { + *pui_value = p_obj_exhaacplus_dec->p_state_aac->audio_object_type; + } ++ if (*pui_value == AOT_AAC_LC) *pui_value = p_obj_exhaacplus_dec->p_state_aac->init_sbr_flag ? (p_obj_exhaacplus_dec->p_state_aac->init_ps_flag ? AOT_PS : AOT_SBR) : AOT_AAC_LC; + } else { + *pui_value = AOT_AAC_LC; + } +@@ -2530,6 +2531,8 @@ IA_ERRORCODE ixheaacd_dec_init( + p_obj_exhaacplus_dec->aac_config.ui_n_channels = num_channels_1; + p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate; + p_state_enhaacplus_dec->ui_init_done = 1; ++ p_state_enhaacplus_dec->init_sbr_flag = sbr_present_flag; ++ p_state_enhaacplus_dec->init_ps_flag = p_obj_exhaacplus_dec->aac_config.ui_sbr_mode == 1; + + memcpy(it_bit_buff, &temp_bit_buff, sizeof(struct ia_bit_buf_struct)); + diff --git a/decoder/ixheaacd_decode_main.c b/decoder/ixheaacd_decode_main.c index 982a6aa..d827687 100644 --- a/decoder/ixheaacd_decode_main.c @@ -66,6 +83,19 @@ index 982a6aa..d827687 100644 } else { WORD8 *out_24bit = (WORD8 *)out_buf; for (i = 0; i < num; i++) { +diff --git a/decoder/ixheaacd_struct_def.h b/decoder/ixheaacd_struct_def.h +index fea3b56..8518407 100644 +--- a/decoder/ixheaacd_struct_def.h ++++ b/decoder/ixheaacd_struct_def.h +@@ -162,6 +162,8 @@ typedef struct ia_aac_dec_state_struct { + UWORD32 ui_input_over; + UWORD32 header_dec_done; + WORD32 frame_counter; ++ WORD32 init_sbr_flag; ++ WORD32 init_ps_flag; + ia_aac_decoder_struct *pstr_aac_dec_info[MAX_BS_ELEMENT]; + + UWORD32 ch_config; diff --git a/encoder/ixheaace_api.c b/encoder/ixheaace_api.c index 6d5c47e..749cac6 100644 --- a/encoder/ixheaace_api.c From 23b6b30870063e3d3acd5b399426f2cb1f15fb70 Mon Sep 17 00:00:00 2001 From: wrapper Date: Fri, 15 Aug 2025 14:23:23 +0700 Subject: [PATCH 18/29] finally --- .gitignore | 3 ++- patch/libxaac.patch | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index db72140..6a5acaa 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,5 @@ _start-cmd.bat wiki .cache/ -unused/ \ No newline at end of file +unused/ +externals/libxaac/ \ No newline at end of file diff --git a/patch/libxaac.patch b/patch/libxaac.patch index d17f19d..239ba53 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -21,7 +21,7 @@ index 5d9cd37..3196501 100644 # Adds libraries needed for executables diff --git a/decoder/ixheaacd_api.c b/decoder/ixheaacd_api.c -index 5e6a0ac..53cb371 100644 +index 5e6a0ac..3504a10 100644 --- a/decoder/ixheaacd_api.c +++ b/decoder/ixheaacd_api.c @@ -579,7 +579,7 @@ IA_ERRORCODE ixheaacd_dec_api(pVOID p_ia_xheaac_dec_obj, WORD32 i_cmd, @@ -46,7 +46,7 @@ index 5e6a0ac..53cb371 100644 p_obj_exhaacplus_dec->aac_config.ui_samp_freq = sample_rate; p_state_enhaacplus_dec->ui_init_done = 1; + p_state_enhaacplus_dec->init_sbr_flag = sbr_present_flag; -+ p_state_enhaacplus_dec->init_ps_flag = p_obj_exhaacplus_dec->aac_config.ui_sbr_mode == 1; ++ p_state_enhaacplus_dec->init_ps_flag = !p_obj_exhaacplus_dec->aac_config.ui_channel_mode; memcpy(it_bit_buff, &temp_bit_buff, sizeof(struct ia_bit_buf_struct)); From 65f200b87fb58c34e6c75907ef3dada41ff3baed Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 18 Aug 2025 16:46:35 +0700 Subject: [PATCH 19/29] update git --- ffmpeg-git.patch | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/ffmpeg-git.patch b/ffmpeg-git.patch index 5341245..e462be5 100644 --- a/ffmpeg-git.patch +++ b/ffmpeg-git.patch @@ -1,5 +1,5 @@ diff --git a/configure b/configure -index 727c3daea8..540219d6bf 100755 +index 416cd2d1d6..eaa52b63ad 100755 --- a/configure +++ b/configure @@ -212,6 +212,7 @@ External library support: @@ -28,7 +28,7 @@ index 727c3daea8..540219d6bf 100755 libaom_av1_decoder_deps="libaom" libaom_av1_encoder_deps="libaom" libaom_av1_encoder_select="extract_extradata_bsf dovi_rpuenc" -@@ -7017,6 +7022,7 @@ enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gn +@@ -7016,6 +7021,7 @@ enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gn enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; } enabled ladspa && require_headers "ladspa.h dlfcn.h" enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext @@ -37,7 +37,7 @@ index 727c3daea8..540219d6bf 100755 enabled liboapv && require_pkg_config liboapv "oapv >= 0.2.0.0" "oapv/oapv.h" oapve_encode enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new || diff --git a/libavcodec/Makefile b/libavcodec/Makefile -index 83ef92963a..45d634ae8f 100644 +index fb22541f8d..740a008131 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1144,6 +1144,8 @@ OBJS-$(CONFIG_ALAC_AT_ENCODER) += audiotoolboxenc.o @@ -240,10 +240,10 @@ index 0000000000..7450c14322 +}; diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c new file mode 100755 -index 0000000000..c5b21f2095 +index 0000000000..8bc7fccb0f --- /dev/null +++ b/libavcodec/libaac_nextenc.c -@@ -0,0 +1,302 @@ +@@ -0,0 +1,305 @@ +/* + * Libaac-next encoder (libxaac based) + * Copyright (c) 2025 Wrapper @@ -272,13 +272,14 @@ index 0000000000..c5b21f2095 + +#include + -+#include "libavcodec/defs.h" +#include "libavutil/channel_layout.h" ++#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" +#include "libavutil/mem.h" +#include "avcodec.h" ++#include "defs.h" +#include "audio_frame_queue.h" +#include "codec_internal.h" +#include "encode.h" @@ -362,6 +363,10 @@ index 0000000000..c5b21f2095 + case AV_PROFILE_AAC_ELD: + cfg.profile = AAC_ELD; + break; ++ ++ default: ++ av_log(avctx, AV_LOG_ERROR, "unsupported profile, supported profiles are LC, HE, HEv2, LD and ELD\n"); ++ return AVERROR(EINVAL); + } + cfg.tns = s->tns; + cfg.frameSize = s->frame_length; @@ -414,10 +419,9 @@ index 0000000000..c5b21f2095 + + if (!frame) + { -+ int isFlush = s->encoder->in_buf_offset <= 0; -+ av_log(avctx, AV_LOG_TRACE, "frame_queue_count: %d, frame_queue_size: %d, in_buf: %d, is_flush: %d, flush_delay: %d\n", s->afq.frame_count, s->afq.remaining_samples, s->encoder->in_buf_offset, isFlush, s->flush_delay); ++ av_log(avctx, AV_LOG_TRACE, "flush_delay: %d\n", s->flush_delay); + -+ if (isFlush && s->flush_delay <= 0) ++ if (s->flush_delay <= 0) + return 0; + + /* Flushing */ @@ -426,8 +430,7 @@ index 0000000000..c5b21f2095 + return AVERROR(EINVAL); + } + -+ if (isFlush) -+ s->flush_delay -= avctx->frame_size; ++ s->flush_delay -= avctx->frame_size; + } + else + { @@ -435,7 +438,7 @@ index 0000000000..c5b21f2095 + if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) + return ret; + -+ int encodeSize = (avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? 4 : 2) * avctx->ch_layout.nb_channels * frame->nb_samples; ++ int encodeSize = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->ch_layout.nb_channels * frame->nb_samples; + av_log(avctx, AV_LOG_TRACE, "encode size: %d\n", encodeSize); + + if ((ret = aac_encode(s->encoder, frame->data[0], encodeSize, pkt->data, (unsigned int *)&pkt->size)) < 0) From a5d2e4f584cf108d58572c401aab4ae28192c663 Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 18 Aug 2025 20:48:28 +0700 Subject: [PATCH 20/29] work on static lib --- source/examples/aacdec/CMakeLists.txt | 4 ++++ source/examples/aacenc/CMakeLists.txt | 4 ++++ source/libaac/CMakeLists.txt | 14 ++++++++++++-- source/libaac/pkg-config.pc.in | 2 +- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/examples/aacdec/CMakeLists.txt b/source/examples/aacdec/CMakeLists.txt index b450984..16edb4e 100644 --- a/source/examples/aacdec/CMakeLists.txt +++ b/source/examples/aacdec/CMakeLists.txt @@ -55,6 +55,10 @@ set_target_properties(${target} # # Include directories # +target_link_directories(${target} + PRIVATE + ${XAAC_BIN_DIR} +) target_include_directories(${target} PRIVATE diff --git a/source/examples/aacenc/CMakeLists.txt b/source/examples/aacenc/CMakeLists.txt index 4f624cb..1af95e8 100644 --- a/source/examples/aacenc/CMakeLists.txt +++ b/source/examples/aacenc/CMakeLists.txt @@ -67,6 +67,10 @@ target_include_directories(${target} # # Libraries # +target_link_directories(${target} + PRIVATE + ${XAAC_BIN_DIR} +) target_link_libraries(${target} PRIVATE diff --git a/source/libaac/CMakeLists.txt b/source/libaac/CMakeLists.txt index f772c0c..3ca996d 100644 --- a/source/libaac/CMakeLists.txt +++ b/source/libaac/CMakeLists.txt @@ -137,11 +137,13 @@ target_link_directories(${target} target_link_libraries(${target} PRIVATE - xaacenc - xaacdec + $<$:xaacenc> + $<$:xaacdec> PUBLIC ${DEFAULT_LIBRARIES} + $<$>:xaacenc> + $<$>:xaacdec> INTERFACE ) @@ -233,5 +235,13 @@ install(EXPORT ${target}-export ) # pkg-config +if (BUILD_SHARED_LIBS) + set(LIBAAC_LINKERS "-l${target}") +else() + set(LIBAAC_LINKERS "-l${target} -lxaacenc -lxaacdec -lm") + install(FILES ${PROJECT_BINARY_DIR}/libxaac-prefix/src/libxaac-build/libxaacdec.a DESTINATION ${INSTALL_LIB}/ COMPONENT dev) + install(FILES ${PROJECT_BINARY_DIR}/libxaac-prefix/src/libxaac-build/libxaacenc.a DESTINATION ${INSTALL_LIB}/ COMPONENT dev) +endif() + configure_file(pkg-config.pc.in ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${META_PROJECT_NAME}.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/${META_PROJECT_NAME}.pc DESTINATION ${INSTALL_LIB}/pkgconfig COMPONENT dev) \ No newline at end of file diff --git a/source/libaac/pkg-config.pc.in b/source/libaac/pkg-config.pc.in index ee70d20..4415c7a 100644 --- a/source/libaac/pkg-config.pc.in +++ b/source/libaac/pkg-config.pc.in @@ -7,5 +7,5 @@ toolsdir=${exec_prefix}/bin Name: @PROJECT_NAME@ Description: @PROJECT_DESCRIPTION@ Version: @PROJECT_VERSION@ -Libs: -L${libdir} -l@target@ +Libs: -L${libdir} @LIBAAC_LINKERS@ Cflags: -I${includedir} From b6c2951529af4665fb1962856608c3c8900ccadf Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 18 Aug 2025 21:49:53 +0700 Subject: [PATCH 21/29] fix overrun --- source/libaac/source/libaac.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/libaac/source/libaac.c b/source/libaac/source/libaac.c index 70cd1e1..e05a3c2 100644 --- a/source/libaac/source/libaac.c +++ b/source/libaac/source/libaac.c @@ -799,24 +799,28 @@ void aac_decode_write_buffer(AACDecode *aacd, unsigned char *data, unsigned int int aac_decode_init(AACDecode *aacd, bool *isInitDone, unsigned int *noBytes) { IA_ERRORCODE ret; + int done; ret = ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_PROCESS, NULL); - ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_DONE_QUERY, isInitDone); + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_DONE_QUERY, &done); ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, noBytes); + *isInitDone = done; return ret; } int aac_decode_execute(AACDecode *aacd, bool *isDone, unsigned int *noBytesIn, int *preroll) { IA_ERRORCODE ret; + int done; ret = ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DO_EXECUTE, NULL); - ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DONE_QUERY, isDone); + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DONE_QUERY, &done); ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_GET_CURIDX_INPUT_BUF, 0, noBytesIn); ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_GET_CONFIG_PARAM, IA_ENHAACPLUS_DEC_CONFIG_GET_NUM_PRE_ROLL_FRAMES, preroll); + *isDone = done; return ret; } From 93e8e929ba3d64e28d84846204f0b932374f0a54 Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 18 Aug 2025 22:28:36 +0700 Subject: [PATCH 22/29] fix channel enumerate bug --- ffmpeg-git.patch | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ffmpeg-git.patch b/ffmpeg-git.patch index e462be5..671cf43 100644 --- a/ffmpeg-git.patch +++ b/ffmpeg-git.patch @@ -1,5 +1,5 @@ diff --git a/configure b/configure -index 416cd2d1d6..eaa52b63ad 100755 +index e1809a3e58..fa4fbfb1cb 100755 --- a/configure +++ b/configure @@ -212,6 +212,7 @@ External library support: @@ -64,10 +64,10 @@ index f5ec2e01e8..8fcd1a806c 100644 extern const FFCodec ff_libaribcaption_decoder; diff --git a/libavcodec/libaac_nextdec.c b/libavcodec/libaac_nextdec.c new file mode 100644 -index 0000000000..7450c14322 +index 0000000000..3de2fd79e6 --- /dev/null +++ b/libavcodec/libaac_nextdec.c -@@ -0,0 +1,170 @@ +@@ -0,0 +1,171 @@ +/* + * Libaac-next decoder (libxaac based) + * Copyright (c) 2025 Wrapper @@ -115,13 +115,14 @@ index 0000000000..7450c14322 + unsigned char *decode_buffer; +} libaacDecodeCTX; + -+static const AVChannelLayout aac_ch_layouts[6] = { ++static const AVChannelLayout aac_ch_layouts[7] = { + AV_CHANNEL_LAYOUT_MONO, + AV_CHANNEL_LAYOUT_STEREO, + AV_CHANNEL_LAYOUT_SURROUND, + AV_CHANNEL_LAYOUT_4POINT0, + AV_CHANNEL_LAYOUT_5POINT0_BACK, + AV_CHANNEL_LAYOUT_5POINT1_BACK, ++ { 0 }, +}; + +static const AVOption aac_dec_options[] = { @@ -240,10 +241,10 @@ index 0000000000..7450c14322 +}; diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c new file mode 100755 -index 0000000000..8bc7fccb0f +index 0000000000..6a1e4f58ea --- /dev/null +++ b/libavcodec/libaac_nextenc.c -@@ -0,0 +1,305 @@ +@@ -0,0 +1,306 @@ +/* + * Libaac-next encoder (libxaac based) + * Copyright (c) 2025 Wrapper @@ -520,13 +521,14 @@ index 0000000000..8bc7fccb0f + 24000, 22050, 16000, 12000, 11025, 8000, 0 +}; + -+static const AVChannelLayout aac_ch_layouts[6] = { ++static const AVChannelLayout aac_ch_layouts[7] = { + AV_CHANNEL_LAYOUT_MONO, + AV_CHANNEL_LAYOUT_STEREO, + AV_CHANNEL_LAYOUT_SURROUND, + AV_CHANNEL_LAYOUT_4POINT0, + AV_CHANNEL_LAYOUT_5POINT0_BACK, + AV_CHANNEL_LAYOUT_5POINT1_BACK, ++ { 0 }, +}; + +const FFCodec ff_libaac_next_encoder = { From 939c17a0d8cdcbf09b048c81123fc078c5211362 Mon Sep 17 00:00:00 2001 From: wrapper Date: Thu, 21 Aug 2025 23:13:59 +0700 Subject: [PATCH 23/29] flush must be called 2 times --- source/libaac/source/libaac.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/libaac/source/libaac.c b/source/libaac/source/libaac.c index e05a3c2..ad148dc 100644 --- a/source/libaac/source/libaac.c +++ b/source/libaac/source/libaac.c @@ -905,10 +905,24 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, void aac_decode_reset(AACDecode *aacd) { ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_GA_HDR, NULL); + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_GA_HDR, NULL); + + aacd->isInitDone = false; + aacd->ascDone = false; + + int isMP4 = aacd->ascSize > 0; + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &isMP4); } void aac_decode_flush_buffer(AACDecode *aacd) { ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL); + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_FLUSH_MEM, NULL); + + aacd->isInitDone = false; + aacd->ascDone = false; + + int isMP4 = aacd->ascSize > 0; + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_SET_CONFIG_PARAM, IA_ENHAACPLUS_DEC_CONFIG_PARAM_ISMP4, &isMP4); } void aac_decode_close(AACDecode *aacd) { From 118cf93d997b45499d90a933574a69106ef79983 Mon Sep 17 00:00:00 2001 From: wrapper Date: Fri, 22 Aug 2025 20:22:00 +0700 Subject: [PATCH 24/29] force dual rate --- patch/libxaac.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 239ba53..468a9b7 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -416,7 +416,7 @@ index 7eec5a9..1f08fbd 100644 v_stop_freq = (WORD32 *)vector_stop_freq_32; k1_min = 21; /* illegal fs */ diff --git a/encoder/ixheaace_sbr_main.c b/encoder/ixheaace_sbr_main.c -index 893d215..b8594e8 100644 +index 893d215..62928da 100644 --- a/encoder/ixheaace_sbr_main.c +++ b/encoder/ixheaace_sbr_main.c @@ -100,7 +100,7 @@ FLOAT32 *ixheaace_get_hbe_resample_buffer(ixheaace_pstr_sbr_enc pstr_env_enc) { @@ -449,7 +449,7 @@ index 893d215..b8594e8 100644 (params->codec_settings.num_channels == 2) ? params->stereo_mode : IXHEAACE_SBR_MODE_MONO; - if (params->codec_settings.sample_freq <= 24000) { -+ if (params->codec_settings.sample_freq <= 24000 || !params->is_ld_sbr) { ++ if (1) { pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_DUAL_RATE; if (params->sbr_codec == USAC_SBR) { pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; From 3f57d168266a19c0c3c602f5a4965d500b819a2d Mon Sep 17 00:00:00 2001 From: wrapper Date: Fri, 22 Aug 2025 20:37:49 +0700 Subject: [PATCH 25/29] int to bool --- ffmpeg-git.patch | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ffmpeg-git.patch b/ffmpeg-git.patch index 671cf43..c9b9375 100644 --- a/ffmpeg-git.patch +++ b/ffmpeg-git.patch @@ -64,7 +64,7 @@ index f5ec2e01e8..8fcd1a806c 100644 extern const FFCodec ff_libaribcaption_decoder; diff --git a/libavcodec/libaac_nextdec.c b/libavcodec/libaac_nextdec.c new file mode 100644 -index 0000000000..3de2fd79e6 +index 0000000000..61345ec021 --- /dev/null +++ b/libavcodec/libaac_nextdec.c @@ -0,0 +1,171 @@ @@ -126,8 +126,8 @@ index 0000000000..3de2fd79e6 +}; + +static const AVOption aac_dec_options[] = { -+ { "conceal", "Error concealment", offsetof(libaacDecodeCTX, error_conceal), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, -+ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacDecodeCTX, esbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, ++ { "conceal", "Error concealment", offsetof(libaacDecodeCTX, error_conceal), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, ++ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacDecodeCTX, esbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, + { NULL } +}; + @@ -241,7 +241,7 @@ index 0000000000..3de2fd79e6 +}; diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c new file mode 100755 -index 0000000000..6a1e4f58ea +index 0000000000..3c34c24a63 --- /dev/null +++ b/libavcodec/libaac_nextenc.c @@ -0,0 +1,306 @@ @@ -304,11 +304,11 @@ index 0000000000..6a1e4f58ea +} libaacEncodeCTX; + +static const AVOption aac_enc_options[] = { -+ { "eld_v2", "Enable ELDv2 (LD-MPS extension for ELD stereo signals)", offsetof(libaacEncodeCTX, eld_v2), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, -+ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacEncodeCTX, esbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "eld_v2", "Enable ELDv2 (LD-MPS extension for ELD stereo signals)", offsetof(libaacEncodeCTX, eld_v2), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacEncodeCTX, esbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, + { "frame_length", "The desired frame length", offsetof(libaacEncodeCTX, frame_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1024, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, + { "iq", "Inverse quantization", offsetof(libaacEncodeCTX, frame_length), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 2, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, -+ { "tns", "Temporal Noise Shaping", offsetof(libaacEncodeCTX, tns), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "tns", "Temporal Noise Shaping", offsetof(libaacEncodeCTX, tns), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, + FF_AAC_PROFILE_OPTS + { NULL } +}; From ef95c58ba8365f8aab178cfe41ccfcd8a593482b Mon Sep 17 00:00:00 2001 From: wrapper Date: Sun, 24 Aug 2025 09:51:56 +0700 Subject: [PATCH 26/29] sbr readjust --- externals/externals.txt | 2 +- patch/libxaac.patch | 150 +++++++++++++++------------------------- 2 files changed, 57 insertions(+), 95 deletions(-) diff --git a/externals/externals.txt b/externals/externals.txt index d17625a..c9ef275 100644 --- a/externals/externals.txt +++ b/externals/externals.txt @@ -1,6 +1,6 @@ include(ExternalProject) ExternalProject_Add(libxaac - URL https://github.com/ittiam-systems/libxaac/archive/eb62778aee21a98b9f6f5c27e0a1f2546a175172.zip + URL https://github.com/ittiam-systems/libxaac/archive/ae572598c3d9f4757fd743553750981c673ddfb5.zip DOWNLOAD_EXTRACT_TIMESTAMP OFF UPDATE_DISCONNECTED 1 CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 468a9b7..c48281d 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -471,7 +471,7 @@ index c5fcd99..344d2b0 100644 if (mean_org < SBR_TON_MEAN_P0009 && mean_sbr < SBR_TON_MEAN_P0009) { diff --git a/encoder/ixheaace_sbr_rom.c b/encoder/ixheaace_sbr_rom.c -index 90e94c5..576b3bc 100644 +index 90e94c5..0a739ed 100644 --- a/encoder/ixheaace_sbr_rom.c +++ b/encoder/ixheaace_sbr_rom.c @@ -48,6 +48,9 @@ const WORD32 vector_offset_def[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 2 @@ -492,13 +492,13 @@ index 90e94c5..576b3bc 100644 {{{{8000, 10000, {7, 11}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, {10000, 12000, {11, 13}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, {12000, 48001, {14, 13}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, -@@ -738,6 +742,238 @@ const ixheaace_str_qmf_tabs ixheaace_qmf_tab = { +@@ -738,6 +742,200 @@ const ixheaace_str_qmf_tabs ixheaace_qmf_tab = { {0}}} }, +#else + {{{ -+ /*** 8000hz 1ch ***/ ++ /*** 8000hz 1ch SBR_AAC ***/ + {8000, 10000, {7, 11}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {10000, 12000, {11, 13}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {12000, 16000, {14, 13}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, @@ -507,7 +507,7 @@ index 90e94c5..576b3bc 100644 + {32000, 48001, {14, 15}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 8000hz 2ch ***/ ++ /*** 8000hz 2ch SBR_AAC ***/ + {16000, 24000, {6, 9}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {24000, 28000, {9, 11}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {28000, 36000, {11, 11}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, @@ -519,7 +519,7 @@ index 90e94c5..576b3bc 100644 + {0}}}, + + {{ -+ /*** 11025hz 1ch ***/ ++ /*** 11025hz 1ch SBR_AAC ***/ + {8000, 10000, {5, 6}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {10000, 12000, {8, 12}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {12000, 16000, {12, 13}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, @@ -527,10 +527,10 @@ index 90e94c5..576b3bc 100644 + {20000, 24000, {13, 13}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {24000, 32000, {14, 14}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {32000, 48000, {15, 15}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {48000, 64001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {48000, 66001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 11025hz 2ch ***/ ++ /*** 11025hz 2ch SBR_AAC ***/ + {16000, 24000, {7, 9}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {24000, 28000, {10, 10}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {28000, 36000, {12, 12}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, @@ -538,11 +538,11 @@ index 90e94c5..576b3bc 100644 + {44000, 52000, {14, 13}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {52000, 60000, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {60000, 76000, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {76000, 128001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 132301, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 12000hz 1ch ***/ ++ /*** 12000hz 1ch SBR_AAC ***/ + {8000, 10000, {4, 6}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {10000, 12000, {7, 11}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {12000, 16000, {11, 12}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, @@ -550,10 +550,10 @@ index 90e94c5..576b3bc 100644 + {20000, 24000, {12, 12}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {24000, 32000, {13, 13}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {32000, 48000, {14, 14}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {48000, 64001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {48000, 72001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 12000hz 2ch ***/ ++ /*** 12000hz 2ch SBR_AAC ***/ + {16000, 24000, {6, 9}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {24000, 28000, {9, 10}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {28000, 36000, {11, 12}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, @@ -561,11 +561,11 @@ index 90e94c5..576b3bc 100644 + {44000, 52000, {13, 13}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {52000, 60000, {14, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {60000, 76000, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {76000, 128001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 144001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 16000hz 1ch ***/ ++ /*** 16000hz 1ch SBR_AAC ***/ + {6000, 8000, {0, 0}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {8000, 10000, {1, 0}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {10000, 12000, {2, 6}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, @@ -575,10 +575,10 @@ index 90e94c5..576b3bc 100644 + {22000, 28000, {10, 12}, 2, {2, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {28000, 36000, {12, 13}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {36000, 44000, {14, 13}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {44000, 64001, {15, 13}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {44000, 96001, {15, 13}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 16000hz 2ch ***/ ++ /*** 16000hz 2ch SBR_AAC ***/ + {16000, 24000, {4, 1}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {24000, 28000, {8, 10}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {28000, 36000, {10, 12}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, @@ -586,11 +586,11 @@ index 90e94c5..576b3bc 100644 + {44000, 52000, {15, 13}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {52000, 60000, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {60000, 76000, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {76000, 128001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 192001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 22050hz 1ch ***/ ++ /*** 22050hz 1ch SBR_AAC ***/ + {8000, 11369, {1, 1}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {11369, 16000, {3, 4}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {16000, 18000, {3, 5}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, @@ -598,12 +598,10 @@ index 90e94c5..576b3bc 100644 + {22000, 28000, {7, 8}, 2, {2, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {28000, 36000, {10, 9}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {36000, 44000, {11, 10}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {44000, 52000, {13, 11}, 1, {2, 0, 0}, IXHEAACE_SBR_MODE_MONO}, -+ {52000, 68000, {14, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, -+ {68000, 96001, {14, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, ++ {44000, 132151, {13, 12}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 22050hz 2ch ***/ ++ /*** 22050hz 2ch SBR_AAC ***/ + {16000, 24000, {2, 1}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {24000, 28000, {5, 6}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {28000, 32000, {5, 8}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, @@ -612,11 +610,11 @@ index 90e94c5..576b3bc 100644 + {44000, 52000, {12, 9}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {52000, 60000, {13, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {60000, 101000, {14, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {101000, 128001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {101000, 264601, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 24000hz 1ch ***/ ++ /*** 24000hz 1ch SBR_AAC ***/ + {8000, 12000, {1, 1}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {12000, 16000, {3, 4}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {16000, 18000, {3, 5}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, @@ -624,12 +622,10 @@ index 90e94c5..576b3bc 100644 + {22000, 28000, {7, 8}, 2, {2, 0, 6}, IXHEAACE_SBR_MODE_MONO}, + {28000, 36000, {10, 9}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {36000, 44000, {11, 10}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {44000, 52000, {13, 11}, 1, {3, 0, 0}, IXHEAACE_SBR_MODE_MONO}, -+ {52000, 68000, {15, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, -+ {68000, 96001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, ++ {44000, 144001, {13, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 24000hz 2ch ***/ ++ /*** 24000hz 2ch SBR_AAC ***/ + {16000, 24000, {2, 1}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {24000, 28000, {5, 6}, 3, {1, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {28000, 36000, {7, 8}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, @@ -637,92 +633,58 @@ index 90e94c5..576b3bc 100644 + {44000, 52000, {12, 9}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {52000, 60000, {13, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {60000, 76000, {14, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {76000, 128001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 288001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 32000hz 1ch ***/ ++ /*** 32000hz 1ch SBR_AAC ***/ + {24000, 36000, {4, 4}, 3, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {36000, 60000, {7, 6}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {60000, 72000, {9, 8}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {72000, 100000, {11, 10}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {100000, 160001, {13, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {100000, 192001, {13, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 32000hz 2ch ***/ ++ /*** 32000hz 2ch SBR_AAC ***/ + {32000, 60000, {4, 4}, 3, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, -+ {60000, 80000, {11, 6}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, -+ {80000, 112000, {12, 8}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {112000, 144000, {13, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {144000, 256001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {60000, 80000, {7, 6}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, ++ {80000, 112000, {9, 8}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {112000, 144000, {11, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {144000, 384001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 44100hz 1ch ***/ -+ {12000, 16000, {0, 0}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {16000, 22000, {1, 1}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {22000, 30000, {2, 3}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {30000, 36000, {4, 4}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {36000, 40000, {5, 4}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {40000, 48000, {6, 5}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {48000, 60000, {7, 6}, 1, {3, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {60000, 72000, {9, 6}, 1, {3, 0, 0}, IXHEAACE_SBR_MODE_MONO}, -+ {72000, 88000, {10, 8}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, -+ {88000, 160001, {12, 9}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, -+ {160001, 288001, {13, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, ++ /*** 44100hz 1ch SBR_AAC ***/ ++ {24000, 36000, {4, 4}, 3, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {36000, 60000, {7, 6}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {60000, 72000, {9, 8}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {72000, 100000, {11, 10}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {100000, 264601, {13, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 44100hz 2ch ***/ -+ {12000, 16000, {0, 0}, 0, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, -+ {16000, 22000, {1, 0}, 0, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, -+ {22000, 26000, {2, 1}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {26000, 30000, {3, 3}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {30000, 34000, {3, 3}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {34000, 38000, {4, 4}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {38000, 44000, {5, 4}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {44000, 52000, {6, 4}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {52000, 60000, {8, 5}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {60000, 68000, {9, 6}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {68000, 76000, {10, 6}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {76000, 90000, {11, 7}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {90000, 112000, {11, 8}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {112000, 132000, {12, 9}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {132000, 180000, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {180000, 288001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ /*** 44100hz 2ch SBR_AAC ***/ ++ {32000, 60000, {4, 4}, 3, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, ++ {60000, 80000, {7, 6}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, ++ {80000, 112000, {9, 8}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {112000, 144000, {11, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {144000, 529201, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 48000hz 1ch ***/ -+ {12000, 16000, {0, 0}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {16000, 22000, {1, 1}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {22000, 30000, {2, 3}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {30000, 36000, {4, 4}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {36000, 40000, {5, 4}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {40000, 48000, {6, 5}, 0, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {48000, 60000, {7, 6}, 1, {3, 0, 3}, IXHEAACE_SBR_MODE_MONO}, -+ {60000, 72000, {9, 6}, 1, {3, 0, 0}, IXHEAACE_SBR_MODE_MONO}, -+ {72000, 88000, {10, 8}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, -+ {88000, 160001, {12, 9}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, -+ {160001, 288001, {13, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_MONO}, ++ /*** 48000hz 1ch SBR_AAC ***/ ++ {24000, 36000, {4, 9}, 3, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {36000, 60000, {7, 10}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {60000, 72000, {9, 10}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {72000, 100000, {11, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {100000, 288001, {13, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 48000hz 2ch ***/ -+ {12000, 16000, {0, 0}, 0, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, -+ {16000, 22000, {0, 0}, 0, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, -+ {22000, 26000, {1, 1}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {26000, 30000, {2, 3}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {30000, 34000, {3, 3}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {34000, 38000, {4, 4}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {38000, 44000, {2, 4}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {44000, 52000, {6, 4}, 0, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {52000, 60000, {8, 5}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {60000, 68000, {9, 6}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {68000, 76000, {10, 6}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {76000, 90000, {11, 7}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {90000, 112000, {11, 8}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {112000, 132000, {12, 9}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {132000, 180000, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, -+ {180000, 288001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ /*** 48000hz 2ch SBR_AAC ***/ ++ {32000, 60000, {4, 9}, 3, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, ++ {60000, 80000, {7, 10}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, ++ {80000, 112000, {9, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {112000, 144000, {11, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {144000, 576001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}} + + }, @@ -731,7 +693,7 @@ index 90e94c5..576b3bc 100644 {{{{0}}}, {{{0}}}, -@@ -824,7 +1060,146 @@ const ixheaace_str_qmf_tabs ixheaace_qmf_tab = { +@@ -824,7 +1022,146 @@ const ixheaace_str_qmf_tabs ixheaace_qmf_tab = { {144000, 176000, {12, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, {176000, 256001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, {0}}}} From 71d5253fc5477e262158f65d9dcc0603d987cf30 Mon Sep 17 00:00:00 2001 From: wrapper Date: Sun, 24 Aug 2025 14:32:55 +0700 Subject: [PATCH 27/29] sbr fix 2 --- patch/libxaac.patch | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patch/libxaac.patch b/patch/libxaac.patch index c48281d..4487f89 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -471,7 +471,7 @@ index c5fcd99..344d2b0 100644 if (mean_org < SBR_TON_MEAN_P0009 && mean_sbr < SBR_TON_MEAN_P0009) { diff --git a/encoder/ixheaace_sbr_rom.c b/encoder/ixheaace_sbr_rom.c -index 90e94c5..0a739ed 100644 +index 90e94c5..bb52192 100644 --- a/encoder/ixheaace_sbr_rom.c +++ b/encoder/ixheaace_sbr_rom.c @@ -48,6 +48,9 @@ const WORD32 vector_offset_def[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 2 @@ -681,7 +681,7 @@ index 90e94c5..0a739ed 100644 + { + /*** 48000hz 2ch SBR_AAC ***/ + {32000, 60000, {4, 9}, 3, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, -+ {60000, 80000, {7, 10}, 2, {3, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, ++ {60000, 80000, {7, 10}, 2, {2, 0, -3}, IXHEAACE_SBR_MODE_SWITCH_LRC}, + {80000, 112000, {9, 10}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {112000, 144000, {11, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {144000, 576001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, From 0050f855c390ea7c44c57881f50e180b7c49d8b0 Mon Sep 17 00:00:00 2001 From: wrapper Date: Mon, 25 Aug 2025 09:40:20 +0700 Subject: [PATCH 28/29] s16 only ffmpeg patch --- ffmpeg-git-s16only.patch | 553 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100644 ffmpeg-git-s16only.patch diff --git a/ffmpeg-git-s16only.patch b/ffmpeg-git-s16only.patch new file mode 100644 index 0000000..8223fee --- /dev/null +++ b/ffmpeg-git-s16only.patch @@ -0,0 +1,553 @@ +diff --git a/configure b/configure +index e1809a3e58..fa4fbfb1cb 100755 +--- a/configure ++++ b/configure +@@ -212,6 +212,7 @@ External library support: + --enable-jni enable JNI support [no] + --enable-ladspa enable LADSPA audio filtering [no] + --enable-lcms2 enable ICC profile support via LittleCMS 2 [no] ++ --enable-libaac-next enable AAC encoding using libaac-next [no] + --enable-libaom enable AV1 video encoding/decoding via libaom [no] + --enable-libaribb24 enable ARIB text and caption decoding via libaribb24 [no] + --enable-libaribcaption enable ARIB text and caption decoding via libaribcaption [no] +@@ -1901,6 +1902,7 @@ EXTERNAL_LIBRARY_NONFREE_LIST=" + + EXTERNAL_LIBRARY_VERSION3_LIST=" + gmp ++ libaac_next + libaribb24 + liblensfun + libopencore_amrnb +@@ -3592,6 +3594,9 @@ hevc_videotoolbox_encoder_deps="pthreads" + hevc_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder" + prores_videotoolbox_encoder_deps="pthreads" + prores_videotoolbox_encoder_select="videotoolbox_encoder" ++libaac_next_decoder_deps="libaac_next" ++libaac_next_encoder_deps="libaac_next" ++libaac_next_encoder_select="audio_frame_queue" + libaom_av1_decoder_deps="libaom" + libaom_av1_encoder_deps="libaom" + libaom_av1_encoder_select="extract_extradata_bsf dovi_rpuenc" +@@ -7016,6 +7021,7 @@ enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gn + enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; } + enabled ladspa && require_headers "ladspa.h dlfcn.h" + enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext ++enabled libaac_next && require_pkg_config libaac_next "libaac >= 1.0.0" libaac.h aac_encode_open + enabled libaom && require_pkg_config libaom "aom >= 2.0.0" aom/aom_codec.h aom_codec_version + enabled liboapv && require_pkg_config liboapv "oapv >= 0.2.0.0" "oapv/oapv.h" oapve_encode + enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new || +diff --git a/libavcodec/Makefile b/libavcodec/Makefile +index fb22541f8d..740a008131 100644 +--- a/libavcodec/Makefile ++++ b/libavcodec/Makefile +@@ -1144,6 +1144,8 @@ OBJS-$(CONFIG_ALAC_AT_ENCODER) += audiotoolboxenc.o + OBJS-$(CONFIG_ILBC_AT_ENCODER) += audiotoolboxenc.o + OBJS-$(CONFIG_PCM_ALAW_AT_ENCODER) += audiotoolboxenc.o + OBJS-$(CONFIG_PCM_MULAW_AT_ENCODER) += audiotoolboxenc.o ++OBJS-$(CONFIG_LIBAAC_NEXT_ENCODER) += libaac_nextenc.o ++OBJS-$(CONFIG_LIBAAC_NEXT_DECODER) += libaac_nextdec.o + OBJS-$(CONFIG_LIBAOM_AV1_DECODER) += libaomdec.o libaom.o + OBJS-$(CONFIG_LIBAOM_AV1_ENCODER) += libaomenc.o libaom.o + OBJS-$(CONFIG_LIBARIBB24_DECODER) += libaribb24.o ass.o +diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c +index f5ec2e01e8..8fcd1a806c 100644 +--- a/libavcodec/allcodecs.c ++++ b/libavcodec/allcodecs.c +@@ -766,6 +766,8 @@ extern const FFCodec ff_pcm_mulaw_at_encoder; + extern const FFCodec ff_pcm_mulaw_at_decoder; + extern const FFCodec ff_qdmc_at_decoder; + extern const FFCodec ff_qdm2_at_decoder; ++extern const FFCodec ff_libaac_next_encoder; ++extern const FFCodec ff_libaac_next_decoder; + extern FFCodec ff_libaom_av1_encoder; + /* preferred over libaribb24 */ + extern const FFCodec ff_libaribcaption_decoder; +diff --git a/libavcodec/libaac_nextdec.c b/libavcodec/libaac_nextdec.c +new file mode 100644 +index 0000000000..61345ec021 +--- /dev/null ++++ b/libavcodec/libaac_nextdec.c +@@ -0,0 +1,171 @@ ++/* ++ * Libaac-next decoder (libxaac based) ++ * Copyright (c) 2025 Wrapper ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/** ++ * @file ++ * Interface to libaac-next decoder. ++ */ ++ ++#include "avcodec.h" ++#include ++#include "libavcodec/codec_id.h" ++#include "libavutil/channel_layout.h" ++#include "libavutil/error.h" ++#include "libavutil/log.h" ++#include "libavutil/opt.h" ++#include "avcodec.h" ++#include "codec_internal.h" ++#include "decode.h" ++#include "libavutil/samplefmt.h" ++#include "libavutil/mem.h" ++ ++typedef struct { ++ AVClass *class; ++ AACDecode *decoder; ++ int error_conceal; ++ int esbr; ++ unsigned char *decode_buffer; ++} libaacDecodeCTX; ++ ++static const AVChannelLayout aac_ch_layouts[7] = { ++ AV_CHANNEL_LAYOUT_MONO, ++ AV_CHANNEL_LAYOUT_STEREO, ++ AV_CHANNEL_LAYOUT_SURROUND, ++ AV_CHANNEL_LAYOUT_4POINT0, ++ AV_CHANNEL_LAYOUT_5POINT0_BACK, ++ AV_CHANNEL_LAYOUT_5POINT1_BACK, ++ { 0 }, ++}; ++ ++static const AVOption aac_dec_options[] = { ++ { "conceal", "Error concealment", offsetof(libaacDecodeCTX, error_conceal), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, ++ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacDecodeCTX, esbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, ++ { NULL } ++}; ++ ++static const AVClass aac_dec_class = { ++ .class_name = "libaac", ++ .item_name = av_default_item_name, ++ .option = aac_dec_options, ++ .version = LIBAVUTIL_VERSION_INT, ++}; ++ ++static void aac_dec_error_handler(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle) { ++ AVCodecContext *ctx = (AVCodecContext *)handle; ++ av_log(ctx, AV_LOG_ERROR, "%s: %s (0x%08X)\n", section, errorMsg, errorCode); ++} ++ ++static av_cold int libaac_decode_init(AVCodecContext *avctx) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ AACDecodeSettings cfg = {0}; ++ ++ cfg.bitsPerSamples = 16; ++ cfg.errorConceal = s->error_conceal; ++ cfg.eSBR = s->esbr; ++ cfg.frameSize = 0; ++ cfg.asc = avctx->extradata; ++ cfg.ascSize = avctx->extradata_size; ++ cfg.errorHandleCtx = avctx; ++ cfg.errorHandler = aac_dec_error_handler; ++ ++ s->decoder = aac_decode_open(cfg); ++ if (!s->decoder) ++ { ++ return AVERROR(EINVAL); ++ } ++ ++ s->decode_buffer = av_mallocz(4096 * 8); ++ if (!s->decode_buffer) ++ { ++ return AVERROR(ENOMEM); ++ } ++ ++ avctx->sample_fmt = AV_SAMPLE_FMT_S16; ++ return 0; ++} ++ ++static av_cold int libaac_decode_close(AVCodecContext *avctx) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ ++ if (s->decoder) ++ aac_decode_close(s->decoder); ++ ++ return 0; ++} ++ ++static int libaac_decode_frame(AVCodecContext *avctx, AVFrame *frame, ++ int *got_frame_ptr, AVPacket *avpkt) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ uint32_t decode_size, read_size; ++ int ret; ++ ++ ret = aac_decode(s->decoder, avpkt->data, avpkt->size, s->decode_buffer, &decode_size, &read_size); ++ if (ret < 0) ++ return AVERROR_EXTERNAL; ++ ++ avctx->sample_rate = s->decoder->sampleRate; ++ avctx->profile = s->decoder->aot - 1; ++ avctx->ch_layout = aac_ch_layouts[s->decoder->noChannels - 1]; ++ avctx->frame_size = 1024; ++ ++ if (decode_size <= 0) ++ return AVERROR_EOF; ++ ++ frame->nb_samples = decode_size / av_get_bytes_per_sample(avctx->sample_fmt) / avctx->ch_layout.nb_channels; ++ ++ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) ++ return ret; ++ ++ av_log(avctx, AV_LOG_TRACE, "aac decode size: %d, decode buf: %d\n", decode_size, avctx->ch_layout.nb_channels * frame->nb_samples * av_get_bytes_per_sample(avctx->sample_fmt)); ++ memcpy(frame->data[0], s->decode_buffer, decode_size); ++ ++ *got_frame_ptr = 1; ++ return read_size; ++} ++ ++static av_cold void libaac_decode_flush(AVCodecContext *avctx) ++{ ++ libaacDecodeCTX *s = avctx->priv_data; ++ ++ if (!s->decoder) ++ return; ++ ++ aac_decode_flush_buffer(s->decoder); ++} ++ ++const FFCodec ff_libaac_next_decoder = { ++ .p.name = "libaac", ++ CODEC_LONG_NAME("custom libxaac-based AAC decoder"), ++ .p.type = AVMEDIA_TYPE_AUDIO, ++ .p.id = AV_CODEC_ID_AAC, ++ .priv_data_size = sizeof(libaacDecodeCTX), ++ .init = libaac_decode_init, ++ FF_CODEC_DECODE_CB(libaac_decode_frame), ++ .close = libaac_decode_close, ++ .flush = libaac_decode_flush, ++ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, ++ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, ++ .p.priv_class = &aac_dec_class, ++ .p.wrapper_name = "libaac", ++}; +diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c +new file mode 100755 +index 0000000000..3c34c24a63 +--- /dev/null ++++ b/libavcodec/libaac_nextenc.c +@@ -0,0 +1,306 @@ ++/* ++ * Libaac-next encoder (libxaac based) ++ * Copyright (c) 2025 Wrapper ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++/** ++ * @file ++ * Interface to libaac-next encoder. ++ */ ++ ++#include ++ ++#include "libavutil/channel_layout.h" ++#include "libavutil/internal.h" ++#include "libavutil/intreadwrite.h" ++#include "libavutil/log.h" ++#include "libavutil/opt.h" ++#include "libavutil/mem.h" ++#include "avcodec.h" ++#include "defs.h" ++#include "audio_frame_queue.h" ++#include "codec_internal.h" ++#include "encode.h" ++#include "libavutil/samplefmt.h" ++#include "profiles.h" ++ ++typedef struct ++{ ++ const AVClass *class; ++ AACContext *encoder; ++ int delay_sent; ++ int flush_delay; ++ ++ int eld_v2; ++ int esbr; ++ int frame_length; ++ int iq; ++ int tns; ++ ++ AudioFrameQueue afq; ++} libaacEncodeCTX; ++ ++static const AVOption aac_enc_options[] = { ++ { "eld_v2", "Enable ELDv2 (LD-MPS extension for ELD stereo signals)", offsetof(libaacEncodeCTX, eld_v2), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "esbr", "Enable the use of Enhanced SBR", offsetof(libaacEncodeCTX, esbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "frame_length", "The desired frame length", offsetof(libaacEncodeCTX, frame_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1024, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "iq", "Inverse quantization", offsetof(libaacEncodeCTX, frame_length), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, 2, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ { "tns", "Temporal Noise Shaping", offsetof(libaacEncodeCTX, tns), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, ++ FF_AAC_PROFILE_OPTS ++ { NULL } ++}; ++ ++static const AVClass aac_enc_class = { ++ .class_name = "libaac", ++ .item_name = av_default_item_name, ++ .option = aac_enc_options, ++ .version = LIBAVUTIL_VERSION_INT, ++}; ++ ++static void aac_enc_error_handler(uint32_t errorCode, const char *section, const char *errorMsg, bool isFatal, void *handle) { ++ AVCodecContext *ctx = (AVCodecContext *)handle; ++ av_log(ctx, AV_LOG_ERROR, "%s: %s (0x%08X)\n", section, errorMsg, errorCode); ++} ++ ++static av_cold int libaac_encode_init(AVCodecContext *avctx) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ AACSettings cfg = {0}; ++ ++ /* number of channels */ ++ if (avctx->ch_layout.nb_channels < 1 || avctx->ch_layout.nb_channels > 6) ++ { ++ av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->ch_layout.nb_channels); ++ return AVERROR(EINVAL); ++ } ++ ++ cfg.sampleRate = avctx->sample_rate; ++ cfg.noChannels = avctx->ch_layout.nb_channels; ++ cfg.bitsPerSamples = avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? 32 : 16; ++ cfg.bitrate = avctx->bit_rate; ++ cfg.adts = !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER); ++ cfg.cutoff = avctx->cutoff; ++ switch (avctx->profile) { ++ case AV_PROFILE_AAC_LOW: ++ case AV_PROFILE_UNKNOWN: ++ cfg.profile = AAC_LC; ++ break; ++ ++ case AV_PROFILE_AAC_HE: ++ cfg.profile = AAC_HE; ++ break; ++ ++ case AV_PROFILE_AAC_HE_V2: ++ cfg.profile = AAC_HEV2; ++ break; ++ ++ case AV_PROFILE_AAC_LD: ++ cfg.profile = AAC_LD; ++ break; ++ ++ case AV_PROFILE_AAC_ELD: ++ cfg.profile = AAC_ELD; ++ break; ++ ++ default: ++ av_log(avctx, AV_LOG_ERROR, "unsupported profile, supported profiles are LC, HE, HEv2, LD and ELD\n"); ++ return AVERROR(EINVAL); ++ } ++ cfg.tns = s->tns; ++ cfg.frameSize = s->frame_length; ++ cfg.eSBR = s->esbr; ++ cfg.iq = s->iq; ++ ++ cfg.errorHandleCtx = avctx; ++ cfg.errorHandler = aac_enc_error_handler; ++ ++ s->encoder = aac_encode_open(cfg); ++ ++ if (!s->encoder) ++ { ++ return AVERROR(EINVAL); ++ } ++ ++ avctx->frame_size = s->encoder->no_samples / avctx->ch_layout.nb_channels; ++ avctx->initial_padding = s->encoder->inputDelay; ++ s->flush_delay = s->encoder->inputDelay; ++ ++ av_log(avctx, AV_LOG_TRACE, "frame size: %d, initial delay: %d\n", avctx->frame_size, avctx->initial_padding); ++ ++ ff_af_queue_init(avctx, &s->afq); ++ ++ /* Set decoder specific info */ ++ avctx->extradata_size = 0; ++ if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ++ { ++ avctx->extradata = av_mallocz(s->encoder->ascSize + AV_INPUT_BUFFER_PADDING_SIZE); ++ ++ if (!avctx->extradata) ++ { ++ return AVERROR(ENOMEM); ++ } ++ ++ memcpy(avctx->extradata, s->encoder->asc, s->encoder->ascSize); ++ } ++ return 0; ++} ++ ++static int libaac_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ++ const AVFrame *frame, int *got_packet) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ int ret; ++ int discard_padding; ++ ++ if ((ret = ff_alloc_packet(avctx, pkt, s->encoder->max_out_bytes)) < 0) ++ return ret; ++ ++ if (!frame) ++ { ++ av_log(avctx, AV_LOG_TRACE, "flush_delay: %d\n", s->flush_delay); ++ ++ if (s->flush_delay <= 0) ++ return 0; ++ ++ /* Flushing */ ++ if ((ret = aac_encode(s->encoder, NULL, 0, pkt->data, (unsigned int *)&pkt->size)) < 0) ++ { ++ return AVERROR(EINVAL); ++ } ++ ++ s->flush_delay -= avctx->frame_size; ++ } ++ else ++ { ++ /* Encoding */ ++ if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) ++ return ret; ++ ++ int encodeSize = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->ch_layout.nb_channels * frame->nb_samples; ++ av_log(avctx, AV_LOG_TRACE, "encode size: %d\n", encodeSize); ++ ++ if ((ret = aac_encode(s->encoder, frame->data[0], encodeSize, pkt->data, (unsigned int *)&pkt->size)) < 0) ++ { ++ return AVERROR(EINVAL); ++ } ++ } ++ ++ ff_af_queue_remove(&s->afq, avctx->frame_size, &pkt->pts, &pkt->duration); ++ ++ /* discard padding copied from fdkaac encoder */ ++ discard_padding = avctx->frame_size - pkt->duration; ++ ++ // Check if subtraction resulted in an overflow ++ if ((discard_padding < avctx->frame_size) != (pkt->duration > 0)) ++ { ++ av_log(avctx, AV_LOG_ERROR, "discard padding overflow\n"); ++ return AVERROR(EINVAL); ++ } ++ ++ if ((!s->delay_sent && avctx->initial_padding > 0) || discard_padding > 0) ++ { ++ uint8_t *side_data = ++ av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10); ++ if (!side_data) ++ return AVERROR(ENOMEM); ++ if (!s->delay_sent) ++ { ++ AV_WL32(side_data, avctx->initial_padding); ++ s->delay_sent = 1; ++ } ++ AV_WL32(side_data + 4, discard_padding); ++ } ++ ++ pkt->flags |= AV_PKT_FLAG_KEY; ++ *got_packet = 1; ++ return 0; ++} ++ ++static void libaac_encode_flush(AVCodecContext *avctx) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ uint8_t sink_null[32768]; ++ int64_t pts, duration; ++ uint32_t out_bytes; ++ ++ av_log(avctx, AV_LOG_TRACE, "encoder flush\n"); ++ ff_af_queue_remove(&s->afq, s->afq.frame_count, &pts, &duration); ++ aac_encode(s->encoder, NULL, 0, sink_null, &out_bytes); ++} ++ ++static av_cold int libaac_encode_close(AVCodecContext *avctx) ++{ ++ libaacEncodeCTX *s = avctx->priv_data; ++ ++ if (s->encoder) ++ aac_encode_close(s->encoder); ++ ++ ff_af_queue_close(&s->afq); ++ ++ return 0; ++} ++ ++static const FFCodecDefault defaults[] = { ++ {"b", "128000"}, ++ {NULL}}; ++ ++static const AVProfile libaac_profiles[] = { ++ { AV_PROFILE_AAC_LOW, "LC" }, ++ { AV_PROFILE_AAC_HE, "HE-AAC" }, ++ { AV_PROFILE_AAC_HE_V2, "HE-AACv2" }, ++ { AV_PROFILE_AAC_LD, "LD" }, ++ { AV_PROFILE_AAC_ELD, "ELD" }, ++ {AV_PROFILE_UNKNOWN}, ++}; ++ ++static const int aac_sample_rates[] = { ++ 96000, 88200, 64000, 48000, 44100, 32000, ++ 24000, 22050, 16000, 12000, 11025, 8000, 0 ++}; ++ ++static const AVChannelLayout aac_ch_layouts[7] = { ++ AV_CHANNEL_LAYOUT_MONO, ++ AV_CHANNEL_LAYOUT_STEREO, ++ AV_CHANNEL_LAYOUT_SURROUND, ++ AV_CHANNEL_LAYOUT_4POINT0, ++ AV_CHANNEL_LAYOUT_5POINT0_BACK, ++ AV_CHANNEL_LAYOUT_5POINT1_BACK, ++ { 0 }, ++}; ++ ++const FFCodec ff_libaac_next_encoder = { ++ .p.name = "libaac", ++ CODEC_LONG_NAME("custom libxaac-based AAC encoder"), ++ .p.type = AVMEDIA_TYPE_AUDIO, ++ .p.id = AV_CODEC_ID_AAC, ++ .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_ENCODER_FLUSH, ++ .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, ++ .priv_data_size = sizeof(libaacEncodeCTX), ++ .init = libaac_encode_init, ++ FF_CODEC_ENCODE_CB(libaac_encode_frame), ++ .flush = libaac_encode_flush, ++ .close = libaac_encode_close, ++ CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_S16), ++ .p.priv_class = &aac_enc_class, ++ .defaults = defaults, ++ .p.profiles = libaac_profiles, ++ CODEC_SAMPLERATES_ARRAY(aac_sample_rates), ++ .p.wrapper_name = "libaac", ++ CODEC_CH_LAYOUTS_ARRAY(aac_ch_layouts), ++}; From 55a0abdad04af0e9886aebea4605d7f7959c2f40 Mon Sep 17 00:00:00 2001 From: wrapper Date: Sat, 6 Sep 2025 12:02:16 +0700 Subject: [PATCH 29/29] fix extra data --- ffmpeg-git-s16only.patch | 5 +++-- ffmpeg-git.patch | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ffmpeg-git-s16only.patch b/ffmpeg-git-s16only.patch index 8223fee..e07cf16 100644 --- a/ffmpeg-git-s16only.patch +++ b/ffmpeg-git-s16only.patch @@ -241,10 +241,10 @@ index 0000000000..61345ec021 +}; diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c new file mode 100755 -index 0000000000..3c34c24a63 +index 0000000000..f9d7706285 --- /dev/null +++ b/libavcodec/libaac_nextenc.c -@@ -0,0 +1,306 @@ +@@ -0,0 +1,307 @@ +/* + * Libaac-next encoder (libxaac based) + * Copyright (c) 2025 Wrapper @@ -403,6 +403,7 @@ index 0000000000..3c34c24a63 + return AVERROR(ENOMEM); + } + ++ avctx->extradata_size = s->encoder->ascSize; + memcpy(avctx->extradata, s->encoder->asc, s->encoder->ascSize); + } + return 0; diff --git a/ffmpeg-git.patch b/ffmpeg-git.patch index c9b9375..56faf72 100644 --- a/ffmpeg-git.patch +++ b/ffmpeg-git.patch @@ -241,10 +241,10 @@ index 0000000000..61345ec021 +}; diff --git a/libavcodec/libaac_nextenc.c b/libavcodec/libaac_nextenc.c new file mode 100755 -index 0000000000..3c34c24a63 +index 0000000000..f9d7706285 --- /dev/null +++ b/libavcodec/libaac_nextenc.c -@@ -0,0 +1,306 @@ +@@ -0,0 +1,307 @@ +/* + * Libaac-next encoder (libxaac based) + * Copyright (c) 2025 Wrapper @@ -403,6 +403,7 @@ index 0000000000..3c34c24a63 + return AVERROR(ENOMEM); + } + ++ avctx->extradata_size = s->encoder->ascSize; + memcpy(avctx->extradata, s->encoder->asc, s->encoder->ascSize); + } + return 0;