[FFmpeg-devel] [PATCH 01/28] Added: Ticket #5481 - added support for LATM encapsulated AAC audio streams within FFmpeg (thanks Paul Kendall).

Mans Rullgard mans
Wed Jun 30 11:09:29 CEST 2010


From: Cory Fields <theuni-nospam- at xbmc.org>

Need to configure with --enable-external-libfaad to use.
---
 configure                |    3 +
 libavcodec/Makefile      |    2 +
 libavcodec/allcodecs.c   |    2 +
 libavcodec/avcodec.h     |    1 +
 libavcodec/latm_parser.c |  118 ++++++++++++++
 libavcodec/latmaac.c     |  391 ++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/avformat.h   |    3 +-
 libavformat/mpeg.c       |    3 +
 libavformat/mpeg.h       |    1 +
 libavformat/mpegts.c     |    2 +-
 libavformat/mpegts.h     |    1 +
 11 files changed, 525 insertions(+), 2 deletions(-)
 create mode 100644 libavcodec/latm_parser.c
 create mode 100644 libavcodec/latmaac.c

diff --git a/configure b/configure
index 60775b5..4dd9ed7 100755
--- a/configure
+++ b/configure
@@ -1276,6 +1276,7 @@ vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
 
 # parsers
 h264_parser_select="golomb h264dsp"
+latm_parser_deps="libfaad"
 
 # bitstream_filters
 aac_adtstoasc_bsf_select="aac_parser"
@@ -1284,6 +1285,8 @@ aac_adtstoasc_bsf_select="aac_parser"
 libdirac_decoder_deps="libdirac !libschroedinger"
 libdirac_encoder_deps="libdirac"
 libfaac_encoder_deps="libfaac"
+libfaad_latm_decoder_deps="libfaad"
+libfaadbin_decoder_extralibs='$ldl'
 libgsm_decoder_deps="libgsm"
 libgsm_encoder_deps="libgsm"
 libgsm_ms_decoder_deps="libgsm"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index c0531c6..116777f 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -523,6 +523,7 @@ OBJS-$(CONFIG_WEBM_MUXER)              += xiph.o mpeg4audio.o \
 OBJS-$(CONFIG_LIBDIRAC_DECODER)           += libdiracdec.o
 OBJS-$(CONFIG_LIBDIRAC_ENCODER)           += libdiracenc.o libdirac_libschro.o
 OBJS-$(CONFIG_LIBFAAC_ENCODER)            += libfaac.o
+OBJS-$(CONFIG_LIBFAAD_LATM_DECODER)       += latmaac.o
 OBJS-$(CONFIG_LIBGSM_DECODER)             += libgsm.o
 OBJS-$(CONFIG_LIBGSM_ENCODER)             += libgsm.o
 OBJS-$(CONFIG_LIBGSM_MS_DECODER)          += libgsm.o
@@ -565,6 +566,7 @@ OBJS-$(CONFIG_H264_PARSER)             += h264_parser.o h264.o            \
                                           h264_loopfilter.o h264_cabac.o \
                                           h264_cavlc.o h264_ps.o \
                                           mpegvideo.o error_resilience.o
+OBJS-$(CONFIG_LATM_PARSER)             += latm_parser.o
 OBJS-$(CONFIG_MJPEG_PARSER)            += mjpeg_parser.o
 OBJS-$(CONFIG_MLP_PARSER)              += mlp_parser.o mlp.o
 OBJS-$(CONFIG_MPEG4VIDEO_PARSER)       += mpeg4video_parser.o h263.o \
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 0e3b9b3..06b5c8f 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -341,6 +341,7 @@ void avcodec_register_all(void)
     /* external libraries */
     REGISTER_ENCDEC  (LIBDIRAC, libdirac);
     REGISTER_ENCODER (LIBFAAC, libfaac);
+    REGISTER_DECODER (LIBFAAD_LATM, libfaad_latm);
     REGISTER_ENCDEC  (LIBGSM, libgsm);
     REGISTER_ENCDEC  (LIBGSM_MS, libgsm_ms);
     REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
@@ -367,6 +368,7 @@ void avcodec_register_all(void)
     REGISTER_PARSER  (H261, h261);
     REGISTER_PARSER  (H263, h263);
     REGISTER_PARSER  (H264, h264);
+    REGISTER_PARSER  (LATM, latm);
     REGISTER_PARSER  (MJPEG, mjpeg);
     REGISTER_PARSER  (MLP, mlp);
     REGISTER_PARSER  (MPEG4VIDEO, mpeg4video);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 0389915..d444b31 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -288,6 +288,7 @@ enum CodecID {
     CODEC_ID_MP2= 0x15000,
     CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
     CODEC_ID_AAC,
+    CODEC_ID_AAC_LATM,
     CODEC_ID_AC3,
     CODEC_ID_DTS,
     CODEC_ID_VORBIS,
diff --git a/libavcodec/latm_parser.c b/libavcodec/latm_parser.c
new file mode 100644
index 0000000..4ac90c8
--- /dev/null
+++ b/libavcodec/latm_parser.c
@@ -0,0 +1,118 @@
+/*
+ * copyright (c) 2008 Paul Kendall <paul at kcbbs.gen.nz>
+ *
+ * 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 latm_parser.c
+ * LATM parser
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include "parser.h"
+
+#define LATM_HEADER     0x56e000	// 0x2b7 (11 bits)
+#define LATM_MASK       0xFFE000	// top 11 bits
+#define LATM_SIZE_MASK  0x001FFF	// bottom 13 bits
+
+typedef struct LATMParseContext{
+    ParseContext pc;
+    int count;
+} LATMParseContext;
+
+/**
+ * finds the end of the current frame in the bitstream.
+ * @return the position of the first byte of the next frame, or -1
+ */
+static int latm_find_frame_end(AVCodecParserContext *s1, const uint8_t *buf,
+                               int buf_size) {
+    LATMParseContext *s = s1->priv_data;
+    ParseContext *pc = &s->pc;
+    int pic_found, i;
+    uint32_t state;
+
+    pic_found = pc->frame_start_found;
+    state = pc->state;
+
+    i = 0;
+    if(!pic_found){
+        for(i=0; i<buf_size; i++){
+            state = (state<<8) | buf[i];
+            if((state & LATM_MASK) == LATM_HEADER) {
+                i++;
+                s->count = - i;
+                pic_found=1;
+                break;
+            }
+        }
+    }
+
+    if(pic_found){
+        /* EOF considered as end of frame */
+        if (buf_size == 0)
+            return 0;
+        if((state & LATM_SIZE_MASK) - s->count <= buf_size) {
+            pc->frame_start_found = 0;
+            pc->state = -1;
+            return (state & LATM_SIZE_MASK) - s->count;
+	}
+    }
+
+    s->count += buf_size;
+    pc->frame_start_found = pic_found;
+    pc->state = state;
+    return END_NOT_FOUND;
+}
+
+static int latm_parse(AVCodecParserContext *s1,
+                           AVCodecContext *avctx,
+                           const uint8_t **poutbuf, int *poutbuf_size,
+                           const uint8_t *buf, int buf_size)
+{
+    LATMParseContext *s = s1->priv_data;
+    ParseContext *pc = &s->pc;
+    int next;
+
+    if(s1->flags & PARSER_FLAG_COMPLETE_FRAMES){
+        next = buf_size;
+    }else{
+        next = latm_find_frame_end(s1, buf, buf_size);
+
+        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
+            *poutbuf = NULL;
+            *poutbuf_size = 0;
+            return buf_size;
+        }
+    }
+    *poutbuf = buf;
+    *poutbuf_size = buf_size;
+    return next;
+}
+
+AVCodecParser latm_parser = {
+    { CODEC_ID_AAC_LATM },
+    sizeof(LATMParseContext),
+    NULL,
+    latm_parse,
+    ff_parse_close
+};
diff --git a/libavcodec/latmaac.c b/libavcodec/latmaac.c
new file mode 100644
index 0000000..c224164
--- /dev/null
+++ b/libavcodec/latmaac.c
@@ -0,0 +1,391 @@
+/*
+ * copyright (c) 2008 Paul Kendall <paul at kcbbs.gen.nz>
+ *
+ * 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 latmaac.c
+ * LATM wrapped AAC decoder
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include "parser.h"
+#include "get_bits.h"
+#include "put_bits.h"
+#include "mpeg4audio.h"
+#include "neaacdec.h"
+
+#define min(a,b) ((a)<(b) ? (a) : (b))
+
+/*
+    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.
+*/
+
+#define SYNC_LATM   0x2b7       // 11 bits
+#define MAX_SIZE    8*1024
+
+typedef struct AACDecoder
+{
+    faacDecHandle   aac_decoder;
+    uint8_t         initialized;
+
+    // parser data
+    uint8_t         audio_mux_version_A;
+    uint8_t         frameLengthType;
+    uint8_t         extra[64];            // should be way enough
+    int             extrasize;
+} AACDecoder;
+
+static inline int64_t latm_get_value(GetBitContext *b)
+{
+    uint8_t bytesForValue = get_bits(b, 2);
+    int64_t value = 0;
+    int i;
+    for (i=0; i<=bytesForValue; i++) {
+        value <<= 8;
+        value |= get_bits(b, 8);
+    }
+    return value;
+}
+
+static void readGASpecificConfig(int audioObjectType, GetBitContext *b, PutBitContext *o)
+{
+    int framelen_flag;
+    int dependsOnCoder;
+    int ext_flag;
+
+    framelen_flag = get_bits(b, 1);
+    put_bits(o, 1, framelen_flag);
+    dependsOnCoder = get_bits(b, 1);
+    put_bits(o, 1, dependsOnCoder);
+    if (dependsOnCoder) {
+        int delay = get_bits(b, 14);
+        put_bits(o, 14, delay);
+    }
+    ext_flag = get_bits(b, 1);
+    put_bits(o, 1, ext_flag);
+    
+    if (audioObjectType == 6 || audioObjectType == 20) {
+        int layerNr = get_bits(b, 3);
+        put_bits(o, 3, layerNr);
+    }
+    if (ext_flag) {
+        if (audioObjectType == 22) {
+            skip_bits(b, 5);                    // numOfSubFrame
+            skip_bits(b, 11);                   // layer_length
+
+            put_bits(o, 16, 0);
+        }
+        if (audioObjectType == 17 ||
+                audioObjectType == 19 ||
+                audioObjectType == 20 ||
+                audioObjectType == 23) {
+
+            skip_bits(b, 3);                    // stuff
+            put_bits(o, 3, 0);
+        }
+
+        skip_bits(b, 1);                        // extflag3
+        put_bits(o, 1, 0);
+    }
+}
+
+static int readAudioSpecificConfig(struct AACDecoder *decoder, GetBitContext *b)
+{
+    PutBitContext o;
+    int ret = 0;
+    int audioObjectType;
+    int samplingFrequencyIndex;
+    int channelConfiguration;
+
+    init_put_bits(&o, decoder->extra, sizeof(decoder->extra));
+
+    audioObjectType = get_bits(b, 5);
+    put_bits(&o, 5, audioObjectType);
+    if (audioObjectType == 31) {
+        uint8_t extended = get_bits(b, 6);
+        put_bits(&o, 6, extended);
+        audioObjectType = 32 + extended;
+    }
+
+    samplingFrequencyIndex = get_bits(b, 4);
+    put_bits(&o, 4, samplingFrequencyIndex);
+    if (samplingFrequencyIndex == 0x0f) {
+        uint32_t f = get_bits_long(b, 24);
+        put_bits(&o, 24, f);
+    }
+    channelConfiguration = get_bits(b, 4);
+    put_bits(&o, 4, channelConfiguration);
+
+    if (audioObjectType == 1 || audioObjectType == 2 || audioObjectType == 3
+            || audioObjectType == 4 || audioObjectType == 6 || audioObjectType == 7) {
+        readGASpecificConfig(audioObjectType, b, &o);
+    } else if (audioObjectType == 5) {
+        int sbr_present = 1;
+        samplingFrequencyIndex = get_bits(b, 4);
+        if (samplingFrequencyIndex == 0x0f) {
+            uint32_t f = get_bits_long(b, 24);
+            put_bits(&o, 24, f);
+        }
+        audioObjectType = get_bits(b, 5);
+        put_bits(&o, 5, audioObjectType);
+    } else if (audioObjectType >= 17) {
+        int epConfig;
+        readGASpecificConfig(audioObjectType, b, &o);
+        epConfig = get_bits(b, 2);
+        put_bits(&o, 2, epConfig);
+    }
+
+    // count the extradata
+    ret = put_bits_count(&o);
+    decoder->extrasize = (ret + 7) / 8;
+
+    flush_put_bits(&o);
+    return ret;
+}
+
+static void readStreamMuxConfig(struct AACDecoder *parser, GetBitContext *b)
+{
+    int audio_mux_version = get_bits(b, 1);
+    parser->audio_mux_version_A = 0;
+    if (audio_mux_version == 1) {                // audioMuxVersion
+        parser->audio_mux_version_A = get_bits(b, 1);
+    }
+
+    if (parser->audio_mux_version_A == 0) {
+        int frame_length_type;
+
+        if (audio_mux_version == 1) {
+            // taraFullness
+            latm_get_value(b);
+        }
+        get_bits(b, 1);                    // allStreamSameTimeFraming = 1
+        get_bits(b, 6);                    // numSubFrames = 0
+        get_bits(b, 4);                    // numPrograms = 0
+
+        // for each program (which there is only on in DVB)
+        get_bits(b, 3);                    // numLayer = 0
+
+        // for each layer (which there is only on in DVB)
+        if (audio_mux_version == 0) {
+            readAudioSpecificConfig(parser, b);
+        } else {
+            int ascLen = latm_get_value(b);
+            ascLen -= readAudioSpecificConfig(parser, b);
+
+            // skip left over bits
+            while (ascLen > 16) {
+                skip_bits(b, 16);
+                ascLen -= 16;
+            }
+            skip_bits(b, ascLen);
+        }
+
+        // these are not needed... perhaps
+        frame_length_type = get_bits(b, 3);
+        parser->frameLengthType = frame_length_type;
+        if (frame_length_type == 0) {
+            get_bits(b, 8);
+        } else if (frame_length_type == 1) {
+            get_bits(b, 9);
+        } else if (frame_length_type == 3 || frame_length_type == 4 || frame_length_type == 5) {
+            // celp_table_index
+            get_bits(b, 6);
+        } else if (frame_length_type == 6 || frame_length_type == 7) {
+            // hvxc_table_index
+            get_bits(b, 1);
+        }
+
+        // other data
+        if (get_bits(b, 1)) {
+            // other data present
+            if (audio_mux_version == 1) {
+                // other_data_bits
+                latm_get_value(b);
+            } else {
+                int esc, tmp;
+                // other data bits
+                int64_t other_data_bits = 0;
+                do {
+                    esc = get_bits(b, 1);
+                    tmp = get_bits(b, 8);
+                    other_data_bits = other_data_bits << 8 | tmp;
+                } while (esc);
+            }
+        }
+
+        // CRC if necessary
+        if (get_bits(b, 1)) {
+            // config_crc
+            get_bits(b, 8);
+        }
+    } else {
+        // TBD
+    }
+}
+
+static int readPayloadLengthInfo(struct AACDecoder *parser, GetBitContext *b)
+{
+    if (parser->frameLengthType == 0) {
+        uint8_t tmp;
+        int muxSlotLengthBytes = 0;
+        do {
+            tmp = get_bits(b, 8);
+            muxSlotLengthBytes += tmp;
+        } while (tmp == 255);
+        return muxSlotLengthBytes;
+    } else {
+        if (parser->frameLengthType == 3 ||
+                parser->frameLengthType == 5 ||
+                parser->frameLengthType == 7) {
+            get_bits(b, 2);
+        }
+        return 0;
+    }
+}
+
+static void readAudioMuxElement(struct AACDecoder *parser, GetBitContext *b, uint8_t *payload, int *payloadsize)
+{
+    uint8_t use_same_mux = get_bits(b, 1);
+    if (!use_same_mux) {
+        readStreamMuxConfig(parser, b);
+    }
+    if (parser->audio_mux_version_A == 0) {
+        int j;
+        int muxSlotLengthBytes = readPayloadLengthInfo(parser, b);
+        muxSlotLengthBytes = min(muxSlotLengthBytes, *payloadsize);
+        for (j=0; j<muxSlotLengthBytes; j++) {
+            *payload++ = get_bits(b, 8);
+        }
+        *payloadsize = muxSlotLengthBytes;
+    }
+}
+
+static int readAudioSyncStream(struct AACDecoder *parser, GetBitContext *b, int size, uint8_t *payload, int *payloadsize)
+{
+    int muxlength;
+
+    if (get_bits(b, 11) != SYNC_LATM) return -1;    // not LATM
+
+    muxlength = get_bits(b, 13);
+    if (muxlength+3 > size) return -1;          // not enough data, the parser should have sorted this
+
+    readAudioMuxElement(parser, b, payload, payloadsize);
+
+    return 0;
+}
+
+static void channel_setup(AVCodecContext *avctx)
+{
+    AACDecoder *decoder = avctx->priv_data;
+    
+    if (avctx->request_channels == 2 && avctx->channels > 2) {
+        NeAACDecConfigurationPtr faac_cfg;
+        avctx->channels = 2;
+        faac_cfg = NeAACDecGetCurrentConfiguration(decoder->aac_decoder);
+        if (faac_cfg) {
+            faac_cfg->downMatrix = 1;
+            faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate;
+            NeAACDecSetConfiguration(decoder->aac_decoder, faac_cfg);
+        }
+    }
+}
+
+static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size, AVPacket *avpkt)
+{
+    AACDecoder          *decoder = avctx->priv_data;
+    uint8_t             tempbuf[MAX_SIZE];
+    int                 bufsize = sizeof(tempbuf);
+    int                 max_size = *out_size;
+    NeAACDecFrameInfo   info;
+    GetBitContext       b;
+    
+    init_get_bits(&b, avpkt->data, avpkt->size * 8);
+    if (readAudioSyncStream(decoder, &b, avpkt->size, tempbuf, &bufsize)) {
+        return -1;
+    }
+
+    if (!decoder->initialized) {
+        // we are going to initialize from decoder specific info when available
+        if (decoder->extrasize > 0) {
+            if (NeAACDecInit2(decoder->aac_decoder, decoder->extra, decoder->extrasize, &avctx->sample_rate, &avctx->channels)) {
+                return -1;
+            }
+            channel_setup(avctx);
+            decoder->initialized = 1;
+        } else {
+            *out_size = 0;
+            return avpkt->size;
+        }
+    }
+
+    if (!NeAACDecDecode2(decoder->aac_decoder, &info, tempbuf, bufsize, &out, max_size)) {
+        return -1;
+    }
+    *out_size = info.samples * sizeof(short);
+    return avpkt->size;
+}
+
+static int latm_decode_init(AVCodecContext *avctx)
+{
+    AACDecoder *decoder = avctx->priv_data;
+    NeAACDecConfigurationPtr faac_cfg;
+
+    avctx->bit_rate = 0;
+    avctx->sample_fmt = SAMPLE_FMT_S16;
+    decoder->aac_decoder = NeAACDecOpen();
+    if (!decoder->aac_decoder) {
+        return -1;
+    }
+
+    faac_cfg = NeAACDecGetCurrentConfiguration(decoder->aac_decoder);
+    if (faac_cfg) {
+        faac_cfg->outputFormat = FAAD_FMT_16BIT;
+        faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate;
+        faac_cfg->defObjectType = LC;
+        NeAACDecSetConfiguration(decoder->aac_decoder, faac_cfg);
+    }
+
+    decoder->initialized = 0;
+    return 0;
+}
+
+static int latm_decode_end(AVCodecContext *avctx)
+{
+    AACDecoder *decoder = avctx->priv_data;
+    NeAACDecClose(decoder->aac_decoder);
+    return 0;
+}
+
+AVCodec libfaad_latm_decoder = {
+    .name = "AAC/LATM",
+    .type = CODEC_TYPE_AUDIO,
+    .id = CODEC_ID_AAC_LATM,
+    .priv_data_size = sizeof (AACDecoder),
+    .init = latm_decode_init,
+    .close = latm_decode_end,
+    .decode = latm_decode_frame,
+    .long_name = "AAC over LATM",
+};
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 283b5b9..c2bb144 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -396,6 +396,7 @@ typedef struct AVIndexEntry {
 #define AV_DISPOSITION_COMMENT   0x0008
 #define AV_DISPOSITION_LYRICS    0x0010
 #define AV_DISPOSITION_KARAOKE   0x0020
+#define AV_DISPOSITION_FORCED    0x0040
 
 /**
  * Stream structure.
@@ -568,7 +569,7 @@ typedef struct AVChapter {
 } AVChapter;
 
 #if LIBAVFORMAT_VERSION_MAJOR < 53
-#define MAX_STREAMS 20
+#define MAX_STREAMS 100
 #endif
 
 /**
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 4d1db25..e6f0990 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -458,6 +458,9 @@ static int mpegps_read_packet(AVFormatContext *s,
         } else if(es_type == STREAM_TYPE_AUDIO_AAC){
             codec_id = CODEC_ID_AAC;
             type = AVMEDIA_TYPE_AUDIO;
+        } else if(es_type == STREAM_TYPE_AUDIO_AAC_LATM){
+            codec_id = CODEC_ID_AAC_LATM;
+            type = CODEC_TYPE_AUDIO;
         } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){
             codec_id = CODEC_ID_MPEG4;
             type = AVMEDIA_TYPE_VIDEO;
diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h
index d09b2e8..c207d3a 100644
--- a/libavformat/mpeg.h
+++ b/libavformat/mpeg.h
@@ -53,6 +53,7 @@
 #define STREAM_TYPE_PRIVATE_DATA    0x06
 #define STREAM_TYPE_AUDIO_AAC       0x0f
 #define STREAM_TYPE_VIDEO_MPEG4     0x10
+#define STREAM_TYPE_AUDIO_AAC_LATM  0x11
 #define STREAM_TYPE_VIDEO_H264      0x1b
 
 #define STREAM_TYPE_AUDIO_AC3       0x81
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 5960338..5d90f01 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -497,7 +497,7 @@ static const StreamType ISO_types[] = {
     { 0x04, AVMEDIA_TYPE_AUDIO,        CODEC_ID_MP3 },
     { 0x0f, AVMEDIA_TYPE_AUDIO,        CODEC_ID_AAC },
     { 0x10, AVMEDIA_TYPE_VIDEO,      CODEC_ID_MPEG4 },
-  //{ 0x11, AVMEDIA_TYPE_AUDIO,        CODEC_ID_AAC }, /* LATM syntax */
+    { 0x11, AVMEDIA_TYPE_AUDIO,        CODEC_ID_AAC }, /* LATM syntax */
     { 0x1b, AVMEDIA_TYPE_VIDEO,       CODEC_ID_H264 },
     { 0xd1, AVMEDIA_TYPE_VIDEO,      CODEC_ID_DIRAC },
     { 0xea, AVMEDIA_TYPE_VIDEO,        CODEC_ID_VC1 },
diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h
index 6be9b73..a6fc56d 100644
--- a/libavformat/mpegts.h
+++ b/libavformat/mpegts.h
@@ -49,6 +49,7 @@
 #define STREAM_TYPE_PRIVATE_DATA    0x06
 #define STREAM_TYPE_AUDIO_AAC       0x0f
 #define STREAM_TYPE_VIDEO_MPEG4     0x10
+#define STREAM_TYPE_AUDIO_AAC_LATM  0x11
 #define STREAM_TYPE_VIDEO_H264      0x1b
 #define STREAM_TYPE_VIDEO_VC1       0xea
 #define STREAM_TYPE_VIDEO_DIRAC     0xd1
-- 
1.7.1.1




More information about the ffmpeg-devel mailing list