[FFmpeg-cvslog] aacdec: move LATM decode functions into a separate file

Lynne git at videolan.org
Tue Apr 23 09:59:04 EEST 2024


ffmpeg | branch: master | Lynne <dev at lynne.ee> | Sat Mar 16 23:34:46 2024 +0100| [ce740618d194e6c8523466ba15be2d662da37105] | committer: Lynne

aacdec: move LATM decode functions into a separate file

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ce740618d194e6c8523466ba15be2d662da37105
---

 libavcodec/aac/aacdec_latm.h | 350 +++++++++++++++++++++++++++++++++++++++++++
 libavcodec/aacdec.c          | 315 +-------------------------------------
 2 files changed, 351 insertions(+), 314 deletions(-)

diff --git a/libavcodec/aac/aacdec_latm.h b/libavcodec/aac/aacdec_latm.h
new file mode 100644
index 0000000000..0226aebba4
--- /dev/null
+++ b/libavcodec/aac/aacdec_latm.h
@@ -0,0 +1,350 @@
+/*
+ * AAC decoder
+ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
+ * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2008-2013 Alex Converse <alex.converse at gmail.com>
+ *
+ * AAC LATM decoder
+ * Copyright (c) 2008-2010 Paul Kendall <paul at kcbbs.gen.nz>
+ * Copyright (c) 2010      Janne Grunau <janne-libav at jannau.net>
+ *
+ * AAC decoder fixed-point implementation
+ * Copyright (c) 2013
+ *      MIPS Technologies, Inc., California.
+ *
+ * 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
+ */
+
+#ifndef AVCODEC_AAC_AACDEC_LATM_H
+#define AVCODEC_AAC_AACDEC_LATM_H
+
+#define LOAS_SYNC_WORD   0x2b7       ///< 11 bits LOAS sync word
+
+struct LATMContext {
+    AACDecContext aac_ctx;  ///< containing AACContext
+    int initialized;        ///< initialized after a valid extradata was seen
+
+    // parser data
+    int audio_mux_version_A; ///< LATM syntax version
+    int frame_length_type;   ///< 0/1 variable/fixed frame length
+    int frame_length;        ///< frame length for fixed frame length
+};
+
+static inline uint32_t latm_get_value(GetBitContext *b)
+{
+    int length = get_bits(b, 2);
+
+    return get_bits_long(b, (length+1)*8);
+}
+
+static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
+                                             GetBitContext *gb, int asclen)
+{
+    AACDecContext *ac     = &latmctx->aac_ctx;
+    AVCodecContext *avctx = ac->avctx;
+    MPEG4AudioConfig m4ac = { 0 };
+    GetBitContext gbc;
+    int config_start_bit  = get_bits_count(gb);
+    int sync_extension    = 0;
+    int bits_consumed, esize, i;
+
+    if (asclen > 0) {
+        sync_extension = 1;
+        asclen         = FFMIN(asclen, get_bits_left(gb));
+        init_get_bits(&gbc, gb->buffer, config_start_bit + asclen);
+        skip_bits_long(&gbc, config_start_bit);
+    } else if (asclen == 0) {
+        gbc = *gb;
+    } else {
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (get_bits_left(gb) <= 0)
+        return AVERROR_INVALIDDATA;
+
+    bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &m4ac,
+                                                    &gbc, config_start_bit,
+                                                    sync_extension);
+
+    if (bits_consumed < config_start_bit)
+        return AVERROR_INVALIDDATA;
+    bits_consumed -= config_start_bit;
+
+    if (asclen == 0)
+      asclen = bits_consumed;
+
+    if (!latmctx->initialized ||
+        ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
+        ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
+
+        if (latmctx->initialized) {
+            av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n", m4ac.sample_rate, m4ac.chan_config);
+        } else {
+            av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
+        }
+        latmctx->initialized = 0;
+
+        esize = (asclen + 7) / 8;
+
+        if (avctx->extradata_size < esize) {
+            av_free(avctx->extradata);
+            avctx->extradata = av_malloc(esize + AV_INPUT_BUFFER_PADDING_SIZE);
+            if (!avctx->extradata)
+                return AVERROR(ENOMEM);
+        }
+
+        avctx->extradata_size = esize;
+        gbc = *gb;
+        for (i = 0; i < esize; i++) {
+          avctx->extradata[i] = get_bits(&gbc, 8);
+        }
+        memset(avctx->extradata+esize, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+    }
+    skip_bits_long(gb, asclen);
+
+    return 0;
+}
+
+static int read_stream_mux_config(struct LATMContext *latmctx,
+                                  GetBitContext *gb)
+{
+    int ret, audio_mux_version = get_bits(gb, 1);
+
+    latmctx->audio_mux_version_A = 0;
+    if (audio_mux_version)
+        latmctx->audio_mux_version_A = get_bits(gb, 1);
+
+    if (!latmctx->audio_mux_version_A) {
+
+        if (audio_mux_version)
+            latm_get_value(gb);                 // taraFullness
+
+        skip_bits(gb, 1);                       // allStreamSameTimeFraming
+        skip_bits(gb, 6);                       // numSubFrames
+        // numPrograms
+        if (get_bits(gb, 4)) {                  // numPrograms
+            avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs");
+            return AVERROR_PATCHWELCOME;
+        }
+
+        // for each program (which there is only one in DVB)
+
+        // for each layer (which there is only one in DVB)
+        if (get_bits(gb, 3)) {                   // numLayer
+            avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers");
+            return AVERROR_PATCHWELCOME;
+        }
+
+        // for all but first stream: use_same_config = get_bits(gb, 1);
+        if (!audio_mux_version) {
+            if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0)
+                return ret;
+        } else {
+            int ascLen = latm_get_value(gb);
+            if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0)
+                return ret;
+        }
+
+        latmctx->frame_length_type = get_bits(gb, 3);
+        switch (latmctx->frame_length_type) {
+        case 0:
+            skip_bits(gb, 8);       // latmBufferFullness
+            break;
+        case 1:
+            latmctx->frame_length = get_bits(gb, 9);
+            break;
+        case 3:
+        case 4:
+        case 5:
+            skip_bits(gb, 6);       // CELP frame length table index
+            break;
+        case 6:
+        case 7:
+            skip_bits(gb, 1);       // HVXC frame length table index
+            break;
+        }
+
+        if (get_bits(gb, 1)) {                  // other data
+            if (audio_mux_version) {
+                latm_get_value(gb);             // other_data_bits
+            } else {
+                int esc;
+                do {
+                    if (get_bits_left(gb) < 9)
+                        return AVERROR_INVALIDDATA;
+                    esc = get_bits(gb, 1);
+                    skip_bits(gb, 8);
+                } while (esc);
+            }
+        }
+
+        if (get_bits(gb, 1))                     // crc present
+            skip_bits(gb, 8);                    // config_crc
+    }
+
+    return 0;
+}
+
+static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb)
+{
+    uint8_t tmp;
+
+    if (ctx->frame_length_type == 0) {
+        int mux_slot_length = 0;
+        do {
+            if (get_bits_left(gb) < 8)
+                return AVERROR_INVALIDDATA;
+            tmp = get_bits(gb, 8);
+            mux_slot_length += tmp;
+        } while (tmp == 255);
+        return mux_slot_length;
+    } else if (ctx->frame_length_type == 1) {
+        return ctx->frame_length;
+    } else if (ctx->frame_length_type == 3 ||
+               ctx->frame_length_type == 5 ||
+               ctx->frame_length_type == 7) {
+        skip_bits(gb, 2);          // mux_slot_length_coded
+    }
+    return 0;
+}
+
+static int read_audio_mux_element(struct LATMContext *latmctx,
+                                  GetBitContext *gb)
+{
+    int err;
+    uint8_t use_same_mux = get_bits(gb, 1);
+    if (!use_same_mux) {
+        if ((err = read_stream_mux_config(latmctx, gb)) < 0)
+            return err;
+    } else if (!latmctx->aac_ctx.avctx->extradata) {
+        av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG,
+               "no decoder config found\n");
+        return 1;
+    }
+    if (latmctx->audio_mux_version_A == 0) {
+        int mux_slot_length_bytes = read_payload_length_info(latmctx, gb);
+        if (mux_slot_length_bytes < 0 || mux_slot_length_bytes * 8LL > get_bits_left(gb)) {
+            av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n");
+            return AVERROR_INVALIDDATA;
+        } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) {
+            av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
+                   "frame length mismatch %d << %d\n",
+                   mux_slot_length_bytes * 8, get_bits_left(gb));
+            return AVERROR_INVALIDDATA;
+        }
+    }
+    return 0;
+}
+
+
+static int latm_decode_frame(AVCodecContext *avctx, AVFrame *out,
+                             int *got_frame_ptr, AVPacket *avpkt)
+{
+    struct LATMContext *latmctx = avctx->priv_data;
+    int                 muxlength, err;
+    GetBitContext       gb;
+
+    if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
+        return err;
+
+    // check for LOAS sync word
+    if (get_bits(&gb, 11) != LOAS_SYNC_WORD)
+        return AVERROR_INVALIDDATA;
+
+    muxlength = get_bits(&gb, 13) + 3;
+    // not enough data, the parser should have sorted this out
+    if (muxlength > avpkt->size)
+        return AVERROR_INVALIDDATA;
+
+    if ((err = read_audio_mux_element(latmctx, &gb)))
+        return (err < 0) ? err : avpkt->size;
+
+    if (!latmctx->initialized) {
+        if (!avctx->extradata) {
+            *got_frame_ptr = 0;
+            return avpkt->size;
+        } else {
+            push_output_configuration(&latmctx->aac_ctx);
+            if ((err = decode_audio_specific_config(
+                    &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac,
+                    avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) {
+                pop_output_configuration(&latmctx->aac_ctx);
+                return err;
+            }
+            latmctx->initialized = 1;
+        }
+    }
+
+    if (show_bits(&gb, 12) == 0xfff) {
+        av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
+               "ADTS header detected, probably as result of configuration "
+               "misparsing\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    switch (latmctx->aac_ctx.oc[1].m4ac.object_type) {
+    case AOT_ER_AAC_LC:
+    case AOT_ER_AAC_LTP:
+    case AOT_ER_AAC_LD:
+    case AOT_ER_AAC_ELD:
+        err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb);
+        break;
+    default:
+        err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt);
+    }
+    if (err < 0)
+        return err;
+
+    return muxlength;
+}
+
+static av_cold int latm_decode_init(AVCodecContext *avctx)
+{
+    struct LATMContext *latmctx = avctx->priv_data;
+    int ret = aac_decode_init(avctx);
+
+    if (avctx->extradata_size > 0)
+        latmctx->initialized = !ret;
+
+    return ret;
+}
+
+/*
+    Note: This decoder filter is intended to decode LATM streams transferred
+    in MPEG transport streams which only contain one program.
+    To do a more complex LATM demuxing a separate LATM demuxer should be used.
+*/
+const FFCodec ff_aac_latm_decoder = {
+    .p.name          = "aac_latm",
+    CODEC_LONG_NAME("AAC LATM (Advanced Audio Coding LATM syntax)"),
+    .p.type          = AVMEDIA_TYPE_AUDIO,
+    .p.id            = AV_CODEC_ID_AAC_LATM,
+    .priv_data_size  = sizeof(struct LATMContext),
+    .init            = latm_decode_init,
+    .close           = ff_aac_decode_close,
+    FF_CODEC_DECODE_CB(latm_decode_frame),
+    .p.sample_fmts   = (const enum AVSampleFormat[]) {
+        AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
+    },
+    .p.capabilities  = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
+    .caps_internal   = FF_CODEC_CAP_INIT_CLEANUP,
+    .p.ch_layouts    = ff_aac_ch_layout,
+    .flush = flush,
+    .p.profiles      = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
+};
+
+#endif /* AVCODEC_AAC_AACDEC_LATM_H */
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 1e7bdb6416..bf1b1c29c7 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -65,296 +65,7 @@
 
 #include "aacdec_template.c"
 
-#define LOAS_SYNC_WORD   0x2b7       ///< 11 bits LOAS sync word
-
-struct LATMContext {
-    AACDecContext aac_ctx;  ///< containing AACContext
-    int initialized;        ///< initialized after a valid extradata was seen
-
-    // parser data
-    int audio_mux_version_A; ///< LATM syntax version
-    int frame_length_type;   ///< 0/1 variable/fixed frame length
-    int frame_length;        ///< frame length for fixed frame length
-};
-
-static inline uint32_t latm_get_value(GetBitContext *b)
-{
-    int length = get_bits(b, 2);
-
-    return get_bits_long(b, (length+1)*8);
-}
-
-static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
-                                             GetBitContext *gb, int asclen)
-{
-    AACDecContext *ac     = &latmctx->aac_ctx;
-    AVCodecContext *avctx = ac->avctx;
-    MPEG4AudioConfig m4ac = { 0 };
-    GetBitContext gbc;
-    int config_start_bit  = get_bits_count(gb);
-    int sync_extension    = 0;
-    int bits_consumed, esize, i;
-
-    if (asclen > 0) {
-        sync_extension = 1;
-        asclen         = FFMIN(asclen, get_bits_left(gb));
-        init_get_bits(&gbc, gb->buffer, config_start_bit + asclen);
-        skip_bits_long(&gbc, config_start_bit);
-    } else if (asclen == 0) {
-        gbc = *gb;
-    } else {
-        return AVERROR_INVALIDDATA;
-    }
-
-    if (get_bits_left(gb) <= 0)
-        return AVERROR_INVALIDDATA;
-
-    bits_consumed = decode_audio_specific_config_gb(NULL, avctx, &m4ac,
-                                                    &gbc, config_start_bit,
-                                                    sync_extension);
-
-    if (bits_consumed < config_start_bit)
-        return AVERROR_INVALIDDATA;
-    bits_consumed -= config_start_bit;
-
-    if (asclen == 0)
-      asclen = bits_consumed;
-
-    if (!latmctx->initialized ||
-        ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
-        ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
-
-        if (latmctx->initialized) {
-            av_log(avctx, AV_LOG_INFO, "audio config changed (sample_rate=%d, chan_config=%d)\n", m4ac.sample_rate, m4ac.chan_config);
-        } else {
-            av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
-        }
-        latmctx->initialized = 0;
-
-        esize = (asclen + 7) / 8;
-
-        if (avctx->extradata_size < esize) {
-            av_free(avctx->extradata);
-            avctx->extradata = av_malloc(esize + AV_INPUT_BUFFER_PADDING_SIZE);
-            if (!avctx->extradata)
-                return AVERROR(ENOMEM);
-        }
-
-        avctx->extradata_size = esize;
-        gbc = *gb;
-        for (i = 0; i < esize; i++) {
-          avctx->extradata[i] = get_bits(&gbc, 8);
-        }
-        memset(avctx->extradata+esize, 0, AV_INPUT_BUFFER_PADDING_SIZE);
-    }
-    skip_bits_long(gb, asclen);
-
-    return 0;
-}
-
-static int read_stream_mux_config(struct LATMContext *latmctx,
-                                  GetBitContext *gb)
-{
-    int ret, audio_mux_version = get_bits(gb, 1);
-
-    latmctx->audio_mux_version_A = 0;
-    if (audio_mux_version)
-        latmctx->audio_mux_version_A = get_bits(gb, 1);
-
-    if (!latmctx->audio_mux_version_A) {
-
-        if (audio_mux_version)
-            latm_get_value(gb);                 // taraFullness
-
-        skip_bits(gb, 1);                       // allStreamSameTimeFraming
-        skip_bits(gb, 6);                       // numSubFrames
-        // numPrograms
-        if (get_bits(gb, 4)) {                  // numPrograms
-            avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs");
-            return AVERROR_PATCHWELCOME;
-        }
-
-        // for each program (which there is only one in DVB)
-
-        // for each layer (which there is only one in DVB)
-        if (get_bits(gb, 3)) {                   // numLayer
-            avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers");
-            return AVERROR_PATCHWELCOME;
-        }
-
-        // for all but first stream: use_same_config = get_bits(gb, 1);
-        if (!audio_mux_version) {
-            if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0)
-                return ret;
-        } else {
-            int ascLen = latm_get_value(gb);
-            if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0)
-                return ret;
-        }
-
-        latmctx->frame_length_type = get_bits(gb, 3);
-        switch (latmctx->frame_length_type) {
-        case 0:
-            skip_bits(gb, 8);       // latmBufferFullness
-            break;
-        case 1:
-            latmctx->frame_length = get_bits(gb, 9);
-            break;
-        case 3:
-        case 4:
-        case 5:
-            skip_bits(gb, 6);       // CELP frame length table index
-            break;
-        case 6:
-        case 7:
-            skip_bits(gb, 1);       // HVXC frame length table index
-            break;
-        }
-
-        if (get_bits(gb, 1)) {                  // other data
-            if (audio_mux_version) {
-                latm_get_value(gb);             // other_data_bits
-            } else {
-                int esc;
-                do {
-                    if (get_bits_left(gb) < 9)
-                        return AVERROR_INVALIDDATA;
-                    esc = get_bits(gb, 1);
-                    skip_bits(gb, 8);
-                } while (esc);
-            }
-        }
-
-        if (get_bits(gb, 1))                     // crc present
-            skip_bits(gb, 8);                    // config_crc
-    }
-
-    return 0;
-}
-
-static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb)
-{
-    uint8_t tmp;
-
-    if (ctx->frame_length_type == 0) {
-        int mux_slot_length = 0;
-        do {
-            if (get_bits_left(gb) < 8)
-                return AVERROR_INVALIDDATA;
-            tmp = get_bits(gb, 8);
-            mux_slot_length += tmp;
-        } while (tmp == 255);
-        return mux_slot_length;
-    } else if (ctx->frame_length_type == 1) {
-        return ctx->frame_length;
-    } else if (ctx->frame_length_type == 3 ||
-               ctx->frame_length_type == 5 ||
-               ctx->frame_length_type == 7) {
-        skip_bits(gb, 2);          // mux_slot_length_coded
-    }
-    return 0;
-}
-
-static int read_audio_mux_element(struct LATMContext *latmctx,
-                                  GetBitContext *gb)
-{
-    int err;
-    uint8_t use_same_mux = get_bits(gb, 1);
-    if (!use_same_mux) {
-        if ((err = read_stream_mux_config(latmctx, gb)) < 0)
-            return err;
-    } else if (!latmctx->aac_ctx.avctx->extradata) {
-        av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG,
-               "no decoder config found\n");
-        return 1;
-    }
-    if (latmctx->audio_mux_version_A == 0) {
-        int mux_slot_length_bytes = read_payload_length_info(latmctx, gb);
-        if (mux_slot_length_bytes < 0 || mux_slot_length_bytes * 8LL > get_bits_left(gb)) {
-            av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n");
-            return AVERROR_INVALIDDATA;
-        } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) {
-            av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
-                   "frame length mismatch %d << %d\n",
-                   mux_slot_length_bytes * 8, get_bits_left(gb));
-            return AVERROR_INVALIDDATA;
-        }
-    }
-    return 0;
-}
-
-
-static int latm_decode_frame(AVCodecContext *avctx, AVFrame *out,
-                             int *got_frame_ptr, AVPacket *avpkt)
-{
-    struct LATMContext *latmctx = avctx->priv_data;
-    int                 muxlength, err;
-    GetBitContext       gb;
-
-    if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
-        return err;
-
-    // check for LOAS sync word
-    if (get_bits(&gb, 11) != LOAS_SYNC_WORD)
-        return AVERROR_INVALIDDATA;
-
-    muxlength = get_bits(&gb, 13) + 3;
-    // not enough data, the parser should have sorted this out
-    if (muxlength > avpkt->size)
-        return AVERROR_INVALIDDATA;
-
-    if ((err = read_audio_mux_element(latmctx, &gb)))
-        return (err < 0) ? err : avpkt->size;
-
-    if (!latmctx->initialized) {
-        if (!avctx->extradata) {
-            *got_frame_ptr = 0;
-            return avpkt->size;
-        } else {
-            push_output_configuration(&latmctx->aac_ctx);
-            if ((err = decode_audio_specific_config(
-                    &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac,
-                    avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) {
-                pop_output_configuration(&latmctx->aac_ctx);
-                return err;
-            }
-            latmctx->initialized = 1;
-        }
-    }
-
-    if (show_bits(&gb, 12) == 0xfff) {
-        av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
-               "ADTS header detected, probably as result of configuration "
-               "misparsing\n");
-        return AVERROR_INVALIDDATA;
-    }
-
-    switch (latmctx->aac_ctx.oc[1].m4ac.object_type) {
-    case AOT_ER_AAC_LC:
-    case AOT_ER_AAC_LTP:
-    case AOT_ER_AAC_LD:
-    case AOT_ER_AAC_ELD:
-        err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb);
-        break;
-    default:
-        err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt);
-    }
-    if (err < 0)
-        return err;
-
-    return muxlength;
-}
-
-static av_cold int latm_decode_init(AVCodecContext *avctx)
-{
-    struct LATMContext *latmctx = avctx->priv_data;
-    int ret = aac_decode_init(avctx);
-
-    if (avctx->extradata_size > 0)
-        latmctx->initialized = !ret;
-
-    return ret;
-}
+#include "libavcodec/aac/aacdec_latm.h"
 
 const FFCodec ff_aac_decoder = {
     .p.name          = "aac",
@@ -376,30 +87,6 @@ const FFCodec ff_aac_decoder = {
     .p.profiles      = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
 };
 
-/*
-    Note: This decoder filter is intended to decode LATM streams transferred
-    in MPEG transport streams which only contain one program.
-    To do a more complex LATM demuxing a separate LATM demuxer should be used.
-*/
-const FFCodec ff_aac_latm_decoder = {
-    .p.name          = "aac_latm",
-    CODEC_LONG_NAME("AAC LATM (Advanced Audio Coding LATM syntax)"),
-    .p.type          = AVMEDIA_TYPE_AUDIO,
-    .p.id            = AV_CODEC_ID_AAC_LATM,
-    .priv_data_size  = sizeof(struct LATMContext),
-    .init            = latm_decode_init,
-    .close           = ff_aac_decode_close,
-    FF_CODEC_DECODE_CB(latm_decode_frame),
-    .p.sample_fmts   = (const enum AVSampleFormat[]) {
-        AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
-    },
-    .p.capabilities  = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
-    .caps_internal   = FF_CODEC_CAP_INIT_CLEANUP,
-    .p.ch_layouts    = ff_aac_ch_layout,
-    .flush = flush,
-    .p.profiles      = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
-};
-
 const FFCodec ff_aac_fixed_decoder = {
     .p.name          = "aac_fixed",
     CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),



More information about the ffmpeg-cvslog mailing list