diff --git a/.gitignore b/.gitignore index 6a5acaa..db72140 100644 --- a/.gitignore +++ b/.gitignore @@ -42,5 +42,4 @@ _start-cmd.bat wiki .cache/ -unused/ -externals/libxaac/ \ No newline at end of file +unused/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..3141162 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "externals/libxaac"] + path = externals/libxaac + url = https://code.ucomsite.my.id/wrapper/libxaac diff --git a/CMakeLists.txt b/CMakeLists.txt index 80e3980..5951f45 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 new file mode 100644 index 0000000..fc04fa9 --- /dev/null +++ b/externals/CMakeLists.txt @@ -0,0 +1,17 @@ +# 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 deleted file mode 100644 index c9ef275..0000000 --- a/externals/externals.txt +++ /dev/null @@ -1,15 +0,0 @@ -include(ExternalProject) -ExternalProject_Add(libxaac - URL https://github.com/ittiam-systems/libxaac/archive/ae572598c3d9f4757fd743553750981c673ddfb5.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 patch -p1 < "${CMAKE_SOURCE_DIR}/patch/libxaac.patch" -) - -ExternalProject_Get_Property(libxaac BINARY_DIR) -set(XAAC_BIN_DIR ${BINARY_DIR}) diff --git a/externals/libxaac b/externals/libxaac index 388435c..80a67bd 160000 --- a/externals/libxaac +++ b/externals/libxaac @@ -1 +1 @@ -Subproject commit 388435c8f8f43fe0e44bf0d31dd3965283f119ec +Subproject commit 80a67bda85225d6c4a1b122691004dec170c0612 diff --git a/ffmpeg-git-s16only.patch b/ffmpeg-git-s16only.patch deleted file mode 100644 index e07cf16..0000000 --- a/ffmpeg-git-s16only.patch +++ /dev/null @@ -1,554 +0,0 @@ -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..f9d7706285 ---- /dev/null -+++ b/libavcodec/libaac_nextenc.c -@@ -0,0 +1,307 @@ -+/* -+ * 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); -+ } -+ -+ avctx->extradata_size = s->encoder->ascSize; -+ 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), -+}; diff --git a/ffmpeg-git.patch b/ffmpeg-git.patch deleted file mode 100644 index 56faf72..0000000 --- a/ffmpeg-git.patch +++ /dev/null @@ -1,554 +0,0 @@ -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..f9d7706285 ---- /dev/null -+++ b/libavcodec/libaac_nextenc.c -@@ -0,0 +1,307 @@ -+/* -+ * 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); -+ } -+ -+ avctx->extradata_size = s->encoder->ascSize; -+ 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_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), -+}; diff --git a/patch/libxaac.patch b/patch/libxaac.patch index 4487f89..2145e71 100644 --- a/patch/libxaac.patch +++ b/patch/libxaac.patch @@ -1,13 +1,3 @@ -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 @@ -21,7 +11,7 @@ index 5d9cd37..3196501 100644 # Adds libraries needed for executables diff --git a/decoder/ixheaacd_api.c b/decoder/ixheaacd_api.c -index 5e6a0ac..3504a10 100644 +index 5e6a0ac..c4ae8e0 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,23 +23,6 @@ index 5e6a0ac..3504a10 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_channel_mode; - - 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 @@ -83,21 +56,8 @@ 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 +index 6d5c47e..22fe7e4 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 @@ -129,20 +89,11 @@ index 6d5c47e..749cac6 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; } 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; @@ -364,49 +315,143 @@ 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..1f08fbd 100644 +index 7eec5a9..192907e 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) { +@@ -158,31 +158,31 @@ static WORD32 ixheaace_get_start_freq(WORD32 fs, WORD32 start_freq) { + WORD32 minimum_k0; 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]; +- case 16000: ++ case 8000: + minimum_k0 = 24; 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]; +- case 22050: ++ case 11025: + minimum_k0 = 17; 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]; +- case 24000: ++ case 12000: + minimum_k0 = 16; break; - case 32000: +- 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; -@@ -260,6 +260,24 @@ static WORD32 ixheaace_get_stop_freq(WORD32 fs, WORD32 stop_freq) { + + 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; + v_stop_freq = (WORD32 *)vector_stop_freq_48; break; -+ case 64000: ++ case 32000: + k1_min = 20; + + v_stop_freq = (WORD32 *)vector_stop_freq_64; + break; + -+ case 88200: ++ case 44100: + k1_min = 15; + + v_stop_freq = (WORD32 *)vector_stop_freq_88; + break; + -+ case 96000: ++ case 48000: + k1_min = 13; + + v_stop_freq = (WORD32 *)vector_stop_freq_96; @@ -416,7 +461,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..62928da 100644 +index 893d215..9e13b13 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) { @@ -444,41 +489,15 @@ index 893d215..62928da 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 (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; -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..bb52192 100644 +index 90e94c5..435fc2e 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, 29, 31, 34, 37, 41, 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_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}; @@ -492,13 +511,13 @@ index 90e94c5..bb52192 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,200 @@ const ixheaace_str_qmf_tabs ixheaace_qmf_tab = { +@@ -738,6 +742,238 @@ const ixheaace_str_qmf_tabs ixheaace_qmf_tab = { {0}}} }, +#else + {{{ -+ /*** 8000hz 1ch SBR_AAC ***/ ++ /*** 8000hz 1ch ***/ + {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 +526,7 @@ index 90e94c5..bb52192 100644 + {32000, 48001, {14, 15}, 2, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 8000hz 2ch SBR_AAC ***/ ++ /*** 8000hz 2ch ***/ + {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 +538,7 @@ index 90e94c5..bb52192 100644 + {0}}}, + + {{ -+ /*** 11025hz 1ch SBR_AAC ***/ ++ /*** 11025hz 1ch ***/ + {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 +546,10 @@ index 90e94c5..bb52192 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, 66001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {48000, 64001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 11025hz 2ch SBR_AAC ***/ ++ /*** 11025hz 2ch ***/ + {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 +557,11 @@ index 90e94c5..bb52192 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, 132301, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 128001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 12000hz 1ch SBR_AAC ***/ ++ /*** 12000hz 1ch ***/ + {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 +569,10 @@ index 90e94c5..bb52192 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, 72001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {48000, 64001, {15, 15}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 12000hz 2ch SBR_AAC ***/ ++ /*** 12000hz 2ch ***/ + {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 +580,11 @@ index 90e94c5..bb52192 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, 144001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 128001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 16000hz 1ch SBR_AAC ***/ ++ /*** 16000hz 1ch ***/ + {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 +594,10 @@ index 90e94c5..bb52192 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, 96001, {15, 13}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {44000, 64001, {15, 13}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 16000hz 2ch SBR_AAC ***/ ++ /*** 16000hz 2ch ***/ + {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 +605,11 @@ index 90e94c5..bb52192 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, 192001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 128001, {15, 13}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 22050hz 1ch SBR_AAC ***/ ++ /*** 22050hz 1ch ***/ + {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,10 +617,12 @@ index 90e94c5..bb52192 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, 132151, {13, 12}, 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}, + {0}}, + { -+ /*** 22050hz 2ch SBR_AAC ***/ ++ /*** 22050hz 2ch ***/ + {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}, @@ -610,11 +631,11 @@ index 90e94c5..bb52192 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, 264601, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {101000, 128001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 24000hz 1ch SBR_AAC ***/ ++ /*** 24000hz 1ch ***/ + {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}, @@ -622,10 +643,12 @@ index 90e94c5..bb52192 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, 144001, {13, 11}, 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}, + {0}}, + { -+ /*** 24000hz 2ch SBR_AAC ***/ ++ /*** 24000hz 2ch ***/ + {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}, @@ -633,58 +656,92 @@ index 90e94c5..bb52192 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, 288001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {76000, 128001, {15, 12}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, + {0}}}, + + {{ -+ /*** 32000hz 1ch SBR_AAC ***/ ++ /*** 32000hz 1ch ***/ + {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, 192001, {13, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, ++ {100000, 160001, {13, 11}, 1, {2, 0, 3}, IXHEAACE_SBR_MODE_MONO}, + {0}}, + { -+ /*** 32000hz 2ch SBR_AAC ***/ ++ /*** 32000hz 2ch ***/ + {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, 384001, {13, 11}, 1, {3, 0, -3}, IXHEAACE_SBR_MODE_LEFT_RIGHT}, ++ {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}, + {0}}}, + + {{ -+ /*** 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}, ++ /*** 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}, + {0}}, + { -+ /*** 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}, ++ /*** 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}, + {0}}}, + + {{ -+ /*** 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}, ++ /*** 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}, + {0}}, + { -+ /*** 48000hz 2ch SBR_AAC ***/ -+ {32000, 60000, {4, 9}, 3, {2, 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}, ++ /*** 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}, + {0}}} + + }, @@ -693,7 +750,7 @@ index 90e94c5..bb52192 100644 {{{{0}}}, {{{0}}}, -@@ -824,7 +1022,146 @@ const ixheaace_str_qmf_tabs ixheaace_qmf_tab = { +@@ -824,7 +1060,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}}}} @@ -705,7 +762,7 @@ index 90e94c5..bb52192 100644 + {{ + /*** 12000hz 1ch ***/ + {8000, 32000, {1, 0}, 3, {1, 0, 6}, IXHEAACE_SBR_MODE_MONO}, -+ {0}}, ++ {0}}, + { + {0}}}, + @@ -759,7 +816,7 @@ index 90e94c5..bb52192 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}, @@ -801,7 +858,7 @@ index 90e94c5..bb52192 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}, diff --git a/source/examples/aacdec/CMakeLists.txt b/source/examples/aacdec/CMakeLists.txt index 16edb4e..b450984 100644 --- a/source/examples/aacdec/CMakeLists.txt +++ b/source/examples/aacdec/CMakeLists.txt @@ -55,10 +55,6 @@ set_target_properties(${target} # # Include directories # -target_link_directories(${target} - PRIVATE - ${XAAC_BIN_DIR} -) target_include_directories(${target} PRIVATE diff --git a/source/examples/aacdec/aacdec.cpp b/source/examples/aacdec/aacdec.cpp index 4fff675..9f4a322 100644 --- a/source/examples/aacdec/aacdec.cpp +++ b/source/examples/aacdec/aacdec.cpp @@ -78,7 +78,6 @@ 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>(); @@ -92,14 +91,12 @@ 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"); @@ -179,7 +176,6 @@ 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}, @@ -250,7 +246,6 @@ 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; } @@ -283,9 +278,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); diff --git a/source/examples/aacenc/CMakeLists.txt b/source/examples/aacenc/CMakeLists.txt index 1af95e8..4f624cb 100644 --- a/source/examples/aacenc/CMakeLists.txt +++ b/source/examples/aacenc/CMakeLists.txt @@ -67,10 +67,6 @@ 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 3ca996d..216b88c 100644 --- a/source/libaac/CMakeLists.txt +++ b/source/libaac/CMakeLists.txt @@ -59,8 +59,6 @@ add_library(${target} ${headers} ) -add_dependencies(${target} libxaac) - # Create namespaced alias add_library(${META_PROJECT_NAME}::${target} ALIAS ${target}) @@ -130,20 +128,14 @@ target_include_directories(${target} # # Libraries # -target_link_directories(${target} - PRIVATE - ${XAAC_BIN_DIR} -) target_link_libraries(${target} PRIVATE - $<$:xaacenc> - $<$:xaacdec> + libxaacenc + libxaacdec PUBLIC ${DEFAULT_LIBRARIES} - $<$>:xaacenc> - $<$>:xaacdec> INTERFACE ) @@ -235,13 +227,5 @@ 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/include/aacnext/libaac.h b/source/libaac/include/aacnext/libaac.h index 480aea2..513b8a0 100644 --- a/source/libaac/include/aacnext/libaac.h +++ b/source/libaac/include/aacnext/libaac.h @@ -24,8 +24,6 @@ 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 { @@ -40,8 +38,6 @@ 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); @@ -67,8 +63,6 @@ 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 { @@ -77,16 +71,11 @@ typedef struct { uint64_t noChannels; // Number of channels int32_t bitsPerSamples; // Bits per samples uint32_t frameSize; // Frame size - 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 + bool eSBR; // Enhanced SBR } AACDecodeSettings; 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_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/pkg-config.pc.in b/source/libaac/pkg-config.pc.in index 4415c7a..ee70d20 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} @LIBAAC_LINKERS@ +Libs: -L${libdir} -l@target@ Cflags: -I${includedir} diff --git a/source/libaac/source/libaac.c b/source/libaac/source/libaac.c index ad148dc..b0f37fb 100644 --- a/source/libaac/source/libaac.c +++ b/source/libaac/source/libaac.c @@ -313,18 +313,14 @@ void aac_encode_strerror(unsigned int error, char *errorStr, int *isFatal) { } } -int aac_encode_handle_error(AACContext * aac, IA_ERRORCODE ret, const char *section) { +int aac_encode_handle_error(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); - 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); - } + fprintf(stderr, "libaac%s %s: %s\n", isFatal ? " fatal error:" : "", section, strerror); return isFatal; } @@ -435,11 +431,8 @@ 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(aac, ret, "init-encoder")) goto fail; + if (aac_encode_handle_error(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; @@ -484,7 +477,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(aac, ret, "encode")) return -1; + if (aac_encode_handle_error(ret, "encode")) return -1; memcpy(outData, aac_out_buf, aac_out_config->i_out_bytes); *outSize = aac_out_config->i_out_bytes; @@ -657,18 +650,14 @@ void aac_decode_strerror(unsigned int error, char *errorStr, int *isFatal) { } } -int aac_decode_handle_error(AACDecode * aacDec, IA_ERRORCODE ret, const char *section) { +int aac_decode_handle_error(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); - 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); - } + fprintf(stderr, "libaac%s %s: %s\n", isFatal ? " fatal error:" : "", section, strerror); return isFatal; } @@ -690,33 +679,27 @@ 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(aacDec, ret, "preconfig")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "updating mp4 flag")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "updating bits per samples")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "updating frame length (ld)")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "updating frame length")) goto fail; + if (aac_decode_handle_error(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(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; + if (aac_decode_handle_error(ret, "updating esbr")) goto fail; aacDec->eSBR = cfg.eSBR; aacDec->asc = cfg.asc; @@ -725,32 +708,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(aacDec, ret, "memtab size")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "set memtabs ptr")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "postconfig")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "get meminfo 1")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "get meminfo 2")) goto fail; + if (aac_decode_handle_error(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(aacDec, ret, "get meminfo 3")) goto fail; + if (aac_decode_handle_error(ret, "get meminfo 3")) goto fail; ui_alignment = (ui_alignment + sizeof(void *) - 1) / sizeof(void *); ui_alignment = ui_alignment * sizeof(void *); @@ -763,7 +746,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(aacDec, ret, "set meminfo")) goto fail; + if (aac_decode_handle_error(ret, "set meminfo")) goto fail; aacDec->memBuffer[i] = temp; @@ -780,7 +763,7 @@ AACDecode * aac_decode_open(AACDecodeSettings cfg) { fail: if (aacDec) { - for (int i = 0; i < 4; i++) free_global(aacDec->memBuffer[i]); + for (int i = 0; i < 4; i++) free(aacDec->memBuffer[i]); free(aacDec->memInfoTab); free(aacDec->apiObj); @@ -794,33 +777,29 @@ 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(aacd, ret, "upload buffer"); + aac_decode_handle_error(ret, "upload buffer"); } 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, &done); + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INIT, IA_CMD_TYPE_INIT_DONE_QUERY, isInitDone); 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, &done); + ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_EXECUTE, IA_CMD_TYPE_DONE_QUERY, isDone); 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; } @@ -835,7 +814,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(aacd, ret, "init-decoder")) return -1; + if (aac_decode_handle_error(ret, "init-decoder")) return -1; aacd->ascDone = 1; timeInited++; @@ -843,7 +822,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(aacd, ret, "init-decoder")) return -1; + if (aac_decode_handle_error(ret, "init-decoder")) return -1; if (ret == IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES) return 0; @@ -876,14 +855,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(aacd, ret, "decode")) return -1; + if (aac_decode_handle_error(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(aacd, ret, "preroll handling")) return -1; + if (aac_decode_handle_error(ret, "preroll handling")) return -1; if (aacd->sbrMode && (aacd->aot < 23) && aacd->eSBR) { if (aacd->frameCounter > 0) @@ -903,31 +882,9 @@ int aac_decode(AACDecode *aacd, unsigned char *inData, unsigned int inDataSize, return 1; } -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) { ixheaacd_dec_api(aacd->apiObj, IA_API_CMD_INPUT_OVER, 0, NULL); - for (int i = 0; i < 4; i++) free_global(aacd->memBuffer[i]); + for (int i = 0; i < 4; i++) free(aacd->memBuffer[i]); free(aacd->memInfoTab); free(aacd->apiObj);