rendered paste bodyIndex: libhb/stream.c===================================================================--- libhb/stream.c (revision 1546)+++ libhb/stream.c (working copy)@@ -51,7 +51,7 @@ st(0x0e, U, 0, 0, "ISO 13818-1 auxiliary"), st(0x0f, A, HB_ACODEC_MPGA, CODEC_ID_AAC, "ISO 13818-7 AAC Audio"), st(0x10, V, WORK_DECAVCODECV, CODEC_ID_MPEG4, "MPEG4"),- st(0x11, A, HB_ACODEC_MPGA, CODEC_ID_AAC, "MPEG4 LATM AAC"),+ st(0x11, A, HB_ACODEC_MPGA, CODEC_ID_AAC_LATM, "MPEG4 LATM AAC"), st(0x12, U, 0, 0, "MPEG4 generic"), st(0x14, U, 0, 0, "ISO 13818-6 DSM-CC download"),Index: contrib/patch-ffmpeg-latm.patch===================================================================--- contrib/patch-ffmpeg-latm.patch (revision 0)+++ contrib/patch-ffmpeg-latm.patch (revision 0)@@ -0,0 +1,895 @@+Index: libavcodec/Makefile+===================================================================+--- libavcodec/Makefile (revision 14016)++++ libavcodec/Makefile (working copy)+@@ -322,7 +322,7 @@+ OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o+ OBJS-$(CONFIG_LIBDIRAC_ENCODER) += libdiracenc.o libdirac_libschro.o+ OBJS-$(CONFIG_LIBFAAC) += libfaac.o+-OBJS-$(CONFIG_LIBFAAD) += libfaad.o++OBJS-$(CONFIG_LIBFAAD) += libfaad.o latmaac.o+ OBJS-$(CONFIG_LIBGSM) += libgsm.o+ OBJS-$(CONFIG_LIBMP3LAME) += libmp3lame.o+ OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o libschroedinger.o libdirac_libschro.o+@@ -333,7 +333,7 @@+ OBJS-$(CONFIG_LIBXVID) += libxvidff.o libxvid_rc.o+ + +-OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o mpeg4audio.o++OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o mpeg4audio.o latm_parser.o+ OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o aac_ac3_parser.o+ OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o+ OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o+Index: libavcodec/latmaac.c+===================================================================+--- libavcodec/latmaac.c (revision 0)++++ libavcodec/latmaac.c (revision 0)+@@ -0,0 +1,624 @@++/*++ * copyright (c) 2008 Paul Kendall <paul@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 "bitstream.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 are only supposed to contain one program.++ To do a more complex LATM demuxing a separate LATM demuxer should be used.++*/++++#define AAC_NONE 0 // mode not detected (or indicated in mediatype)++#define AAC_LATM 1 // LATM packets (ISO/IEC 14496-3 1.7.3 Multiplex layer)++++#define SYNC_LATM 0x2b7 // 11 bits++++#define MAX_SIZE 8*1024++++typedef struct AACConfig++{++ uint8_t extra[64]; // should be way enough++ int extrasize;++++ int audioObjectType;++ int samplingFrequencyIndex;++ int samplingFrequency;++ int channelConfiguration;++ int channels;++} AACConfig;++++typedef struct AACParser++{++ AACConfig config;++ uint8_t frameLengthType;++ uint16_t muxSlotLengthBytes;++++ uint8_t audio_mux_version;++ uint8_t audio_mux_version_A;++ int taraFullness;++ uint8_t config_crc;++ int64_t other_data_bits;++++ int mode;++ int offset; // byte offset in "buf" buffer++ uint8_t buf[MAX_SIZE]; // allocated buffer++ int count; // number of bytes written in buffer++} AACParser;++++typedef struct AACDecoder ++{++ AACParser *parser;++ faacDecHandle aac_decoder;++ int open;++ uint32_t in_samplerate;++ uint8_t in_channels;++} AACDecoder;++++typedef struct {++ AACDecoder* decoder;++} FAACContext;++++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(struct AACConfig *cfg, GetBitContext *b, PutBitContext *o)++{++ int framelen_flag = get_bits(b, 1);++ put_bits(o, 1, framelen_flag);++ int dependsOnCoder = get_bits(b, 1);++ put_bits(o, 1, dependsOnCoder);++ int ext_flag;++ int delay;++ int layerNr;++++ if (dependsOnCoder) {++ delay = get_bits(b, 14);++ put_bits(o, 14, delay);++ }++ ext_flag = get_bits(b, 1);++ put_bits(o, 1, ext_flag);++ if (!cfg->channelConfiguration) {++ // program config element++ // TODO:++ }++++ if (cfg->audioObjectType == 6 || cfg->audioObjectType == 20) {++ layerNr = get_bits(b, 3);++ put_bits(o, 3, layerNr);++ }++ if (ext_flag) {++ if (cfg->audioObjectType == 22) {++ skip_bits(b, 5); // numOfSubFrame++ skip_bits(b, 11); // layer_length++++ put_bits(o, 16, 0);++ }++ if (cfg->audioObjectType == 17 ||++ cfg->audioObjectType == 19 ||++ cfg->audioObjectType == 20 ||++ cfg->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 AACConfig *cfg, GetBitContext *b)++{++ PutBitContext o;++ init_put_bits(&o, cfg->extra, sizeof(cfg->extra));++++ // returns the number of bits read++ int ret = 0;++ int sbr_present = -1;++++ // object++ cfg->audioObjectType = get_bits(b, 5);++ put_bits(&o, 5, cfg->audioObjectType);++ if (cfg->audioObjectType == 31) {++ uint8_t n = get_bits(b, 6);++ put_bits(&o, 6, n);++ cfg->audioObjectType = 32 + n;++ }++++ cfg->samplingFrequencyIndex = get_bits(b, 4);++ cfg->samplingFrequency = ff_mpeg4audio_sample_rates[cfg->samplingFrequencyIndex];++ put_bits(&o, 4, cfg->samplingFrequencyIndex);++ if (cfg->samplingFrequencyIndex == 0x0f) {++ uint32_t f = get_bits_long(b, 24);++ put_bits(&o, 24, f);++ cfg->samplingFrequency = f;++ }++ cfg->channelConfiguration = get_bits(b, 4);++ put_bits(&o, 4, cfg->channelConfiguration);++ cfg->channels = ff_mpeg4audio_channels[cfg->channelConfiguration];++++ if (cfg->audioObjectType == 5) {++ sbr_present = 1;++++ // TODO: parsing !!!!!!!!!!!!!!!!++ }++++ switch (cfg->audioObjectType) {++ case 1:++ case 2:++ case 3:++ case 4:++ case 6:++ case 7:++ case 17:++ case 19:++ case 20:++ case 21:++ case 22:++ case 23:++ readGASpecificConfig(cfg, b, &o);++ break;++ }++++ if (sbr_present == -1) {++ if (cfg->samplingFrequency <= 24000) {++ cfg->samplingFrequency *= 2;++ } ++ }++++ // count the extradata++ ret = put_bits_count(&o);++ align_put_bits(&o);++ flush_put_bits(&o);++ cfg->extrasize = (ret + 7) >> 3;++ return ret;++}++++static void readStreamMuxConfig(struct AACParser *parser, GetBitContext *b)++{++ parser->audio_mux_version_A = 0;++ parser->audio_mux_version = get_bits(b, 1);++ if (parser->audio_mux_version == 1) { // audioMuxVersion++ parser->audio_mux_version_A = get_bits(b, 1);++ }++++ if (parser->audio_mux_version_A == 0) {++ if (parser->audio_mux_version == 1) {++ parser->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++ get_bits(b, 3); // numLayer = 0++++ // for each layer++ if (parser->audio_mux_version == 0) {++ // audio specific config.++ readAudioSpecificConfig(&parser->config, b);++ } else {++ int ascLen = latm_get_value(b);++ ascLen -= readAudioSpecificConfig(&parser->config, b);++++ // fill bits++ while (ascLen > 16) {++ skip_bits(b, 16);++ ascLen -= 16;++ }++ skip_bits(b, ascLen); ++ }++++ // these are not needed... perhaps++ int 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) {++ int celp_table_index = get_bits(b, 6);++ } else if (frame_length_type == 6 ||++ frame_length_type == 7) {++ int hvxc_table_index = get_bits(b, 1);++ }++++ // other data++ parser->other_data_bits = 0;++ if (get_bits(b, 1)) {++ // other data present++ if (parser->audio_mux_version == 1) {++ parser->other_data_bits = latm_get_value(b);++ } else {++ // other data not present++ parser->other_data_bits = 0;++ int esc, tmp;++ do {++ parser->other_data_bits <<= 8;++ esc = get_bits(b, 1);++ tmp = get_bits(b, 8);++ parser->other_data_bits |= tmp;++ } while (esc);++ }++ }++++ // CRC++ if (get_bits(b, 1)) {++ parser->config_crc = get_bits(b, 8);++ }++ } else {++ // tbd++ }++}++++static void readPayloadLengthInfo(struct AACParser *parser, GetBitContext *b)++{++ uint8_t tmp;++ if (parser->frameLengthType == 0) {++ parser->muxSlotLengthBytes = 0;++ do {++ tmp = get_bits(b, 8);++ parser->muxSlotLengthBytes += tmp;++ } while (tmp == 255);++ } else {++ if (parser->frameLengthType == 5 ||++ parser->frameLengthType == 7 ||++ parser->frameLengthType == 3) {++ get_bits(b, 2);++ }++ }++}++++static void readAudioMuxElement(struct AACParser *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;++++ readPayloadLengthInfo(parser, b);++++ // copy data++ for (j=0; j<parser->muxSlotLengthBytes; j++) {++ *payload++ = get_bits(b, 8);++ }++ *payloadsize = parser->muxSlotLengthBytes;++++ // ignore otherdata++ } else {++ // TBD++ }++}++++static int readAudioSyncStream(struct AACParser *parser, GetBitContext *b, int size, uint8_t *payload, int *payloadsize)++{++ // ISO/IEC 14496-3 Table 1.28 - Syntax of AudioMuxElement()++ if (get_bits(b, 11) != 0x2b7) return -1; // not LATM++ int muxlength = get_bits(b, 13);++++ if (3+muxlength > size) return 0; // not enough data++++ readAudioMuxElement(parser, b, payload, payloadsize);++++ // we don't parse anything else here...++ return (3+muxlength);++}++++++static void flush_buf(struct AACParser *parser, int offset) {++ int bytes_to_flush = min(parser->count, offset);++ int left = (parser->count - bytes_to_flush);++++ if (bytes_to_flush > 0) {++ if (left > 0) {++ memcpy(parser->buf, parser->buf+bytes_to_flush, left);++ parser->count = left;++ } else {++ parser->count = 0;++ }++ }++}++++static struct AACParser *latm_create_parser()++{++ struct AACParser *parser = (struct AACParser *)av_malloc(sizeof(struct AACParser));++ memset(parser, 0, sizeof(struct AACParser));++ return parser;++}++++static void latm_destroy_parser(struct AACParser *parser)++{++ av_free(parser);++}++++static void latm_flush(struct AACParser *parser)++{++ parser->offset = 0;++ parser->count = 0;++}++++static void latm_write_data(struct AACParser *parser, uint8_t *data, int len)++{++ // buffer overflow check... just ignore the data before++ if (parser->count + len > MAX_SIZE) {++ flush_buf(parser, parser->offset);++ parser->offset = 0;++ if (parser->count + len > MAX_SIZE) {++ int to_flush = (parser->count+len) - MAX_SIZE;++ flush_buf(parser, to_flush);++ }++ }++++ // append data++ memcpy(parser->buf+parser->count, data, len);++ parser->count += len;++}++++static int latm_parse_packet(struct AACParser *parser, uint8_t *data, int maxsize)++{++ /*++ Return value is either number of bytes parsed or++ -1 when failed.++ 0 = need more data.++ */++++ uint8_t *start = parser->buf + parser->offset;++ int bytes = parser->count - parser->offset;++ GetBitContext b;++ init_get_bits(&b, start, bytes);++++ if (parser->mode == AAC_LATM) {++ int outsize = 0;++ int ret = readAudioSyncStream(parser, &b, bytes, data, &outsize);++++ if (ret < 0) return -1;++ if (ret == 0) return 0;++++ // update the offset++ parser->offset += ret;++ return outsize;++ }++++ // check for syncwords++ while (bytes > 2) {++ if (show_bits(&b, 11) == SYNC_LATM) {++ // we must parse config first...++ int outsize = 0;++++ // check if there is a complete packet available...++ int ret = readAudioSyncStream(parser, &b, bytes, data, &outsize);++ if (ret < 0) return -1;++ if (ret == 0) return 0;++ parser->offset += ret;++++ parser->mode = AAC_LATM;++ return outsize;++ }++ skip_bits(&b, 8);++ parser->offset++;++ bytes--;++ }++ return 0;++}++++static void aac_filter_close(AACDecoder *decoder)++{++ if (decoder->aac_decoder) {++ NeAACDecClose(decoder->aac_decoder);++ decoder->aac_decoder = NULL;++ }++ decoder->open = 0;++}++++static int aac_decoder_open(AACDecoder *decoder)++{++ if (decoder->aac_decoder) return 0;++++ decoder->aac_decoder = NeAACDecOpen();++ if (!decoder->aac_decoder) return -1;++++ // are we going to initialize from decoder specific info ?++ if (decoder->parser->config.extrasize > 0) {++ char ret = NeAACDecInit2(decoder->aac_decoder, (unsigned char*)decoder->parser->config.extra, decoder->parser->config.extrasize, &decoder->in_samplerate, &decoder->in_channels);++ if (ret < 0) {++ aac_filter_close(decoder); // gone wrong ?++ return -1;++ }++ decoder->open = 1;++ } else {++ // we'll open the decoder later...++ decoder->open = 0;++ }++ return 0;++}++++AACDecoder *aac_filter_create()++{++ AACDecoder *decoder = (AACDecoder *)av_malloc(sizeof(AACDecoder));++ decoder->parser = latm_create_parser();++ decoder->aac_decoder = NULL;++ decoder->open = 0;++ return (void *)decoder;++}++++void aac_filter_destroy(AACDecoder *decoder)++{++ aac_filter_close(decoder);++ latm_destroy_parser(decoder->parser);++ av_free(decoder);++}++++int aac_filter_receive(AACDecoder *decoder, void *out, int *out_size, uint8_t *data, int size)++{++ uint8_t tempbuf[32*1024];++ int ret;++ int consumed = size;++ int decoded;++ int max_size = *out_size;++ ++ *out_size = 0;++++ //-------------------------------------------------------------------------++ // Multiplex Parsing++ //-------------------------------------------------------------------------++++ latm_write_data(decoder->parser, data, size);++++ do {++ ret = latm_parse_packet(decoder->parser, tempbuf, sizeof(tempbuf));++ if (ret < 0) {++ latm_flush(decoder->parser);++ return consumed;++ }++ if (ret == 0) return consumed;++++ data = tempbuf;++ size = ret;++++ //-------------------------------------------------------------------------++ // Initialize decoder (if necessary)++ //-------------------------------------------------------------------------++ if (!decoder->open) {++ aac_filter_close(decoder);++ if (decoder->parser->mode == AAC_LATM) {++ ret = aac_decoder_open(decoder);++ if (ret < 0) return consumed;++ }++++ if(!decoder->open) return consumed;++ }++++ //-------------------------------------------------------------------------++ // Decode samples++ //-------------------------------------------------------------------------++ NeAACDecFrameInfo info;++ void *buf = NeAACDecDecode(decoder->aac_decoder, &info, data, size);++++ if (buf) {++ decoder->in_samplerate = info.samplerate;++ decoder->in_channels = info.channels;++++ //---------------------------------------------------------------------++ // Deliver decoded samples++ //---------------------------------------------------------------------++++ // kram dekoduje 16-bit. my vypustame 16-bit. takze by to malo byt okej++ decoded = info.samples * sizeof(short);++++ // napraskame tam sample++ *out_size += decoded;++ if(*out_size > max_size) {++ av_log(NULL, AV_LOG_ERROR, "overflow!\n");++ } else {++ memcpy(out, buf, decoded);++ out = (unsigned char *)out + decoded;++ }++ } else {++ // need more data++ break;++ }++++ } while (1); // decode all packets++ return consumed;++}++++void aac_filter_getinfo(AACDecoder *decoder, int *sample_rate, int *channels)++{++ if(!decoder->open) return;++ *sample_rate = decoder->in_samplerate;++ *channels = decoder->in_channels;++}++++static int faac_decode_init(AVCodecContext *avctx)++{++ FAACContext *s = avctx->priv_data;++ avctx->frame_size = 360;++ avctx->sample_rate = 48000;++ avctx->channels = 2;++ avctx->bit_rate = 8192 * 8 * avctx->sample_rate / avctx->frame_size;++ s->decoder = aac_filter_create();++ return 0;++}++++static int faac_decode_frame(AVCodecContext *avctx,++ void *data, int *data_size,++ uint8_t *buf, int buf_size)++{++ FAACContext *s = avctx->priv_data;++ int ret;++++ if (s->decoder == NULL) faac_decode_init(avctx);++ ret = aac_filter_receive(s->decoder, data, data_size, buf, buf_size);++ aac_filter_getinfo(s->decoder, &(avctx->sample_rate), &(avctx->channels));++ return ret;++}++++static int faac_decode_end(AVCodecContext *avctx)++{++ FAACContext *s = avctx->priv_data;++ if(s->decoder != NULL) {++ aac_filter_destroy(s->decoder);++ }++ return 0;++}++++AVCodec libfaad2_decoder = {++ .name = "AAC_LATM",++ .type = CODEC_TYPE_AUDIO,++ .id = CODEC_ID_AAC_LATM,++ .priv_data_size = sizeof (FAACContext),++ .init = faac_decode_init,++ .close = faac_decode_end,++ .decode = faac_decode_frame,++ .long_name = "AAC over LATM",++};+++Index: libavcodec/latm_parser.c+===================================================================+--- libavcodec/latm_parser.c (revision 0)++++ libavcodec/latm_parser.c (revision 0)+@@ -0,0 +1,128 @@++/*++ * LATM parser++ * Copyright (c) 2008 Paul Kendall <paul@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 "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;++}++++static int latm_split(AVCodecContext *avctx,++ const uint8_t *buf, int buf_size)++{++ int i;++ uint32_t state= -1;++++ for(i=0; i<buf_size; i++){++ state= (state<<8) | buf[i];++ if((state & LATM_MASK) == LATM_HEADER)++ return i-2;++ }++ return 0;++}++++AVCodecParser aac_latm_parser = {++ { CODEC_ID_AAC_LATM },++ sizeof(LATMParseContext),++ NULL,++ latm_parse,++ ff_parse_close,++ latm_split,++};+Index: libavcodec/allcodecs.c+===================================================================+--- libavcodec/allcodecs.c (revision 14016)++++ libavcodec/allcodecs.c (working copy)+@@ -280,6 +280,7 @@+ REGISTER_ENCDEC (LIBDIRAC, libdirac);+ REGISTER_ENCODER (LIBFAAC, libfaac);+ REGISTER_DECODER (LIBFAAD, libfaad);++ REGISTER_DECODER (LIBFAAD, libfaad2);+ REGISTER_ENCDEC (LIBGSM, libgsm);+ REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);+ REGISTER_ENCODER (LIBMP3LAME, libmp3lame);+@@ -294,6 +295,7 @@+ + /* parsers */+ REGISTER_PARSER (AAC, aac);++ REGISTER_PARSER (AAC, aac_latm);+ REGISTER_PARSER (AC3, ac3);+ REGISTER_PARSER (CAVSVIDEO, cavsvideo);+ REGISTER_PARSER (DCA, dca);+Index: libavcodec/avcodec.h+===================================================================+--- libavcodec/avcodec.h (revision 14016)++++ libavcodec/avcodec.h (working copy)+@@ -259,6 +259,7 @@+ #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)+ CODEC_ID_MPEG4AAC,+ #endif++ CODEC_ID_AAC_LATM,+ CODEC_ID_AC3,+ CODEC_ID_DTS,+ CODEC_ID_VORBIS,+Index: libavformat/mpegts.c+===================================================================+--- libavformat/mpegts.c (revision 14016)++++ libavformat/mpegts.c (working copy)+@@ -611,6 +611,7 @@+ case STREAM_TYPE_VIDEO_H264:+ case STREAM_TYPE_VIDEO_VC1:+ case STREAM_TYPE_AUDIO_AAC:++ case STREAM_TYPE_AUDIO_AAC_LATM:+ case STREAM_TYPE_AUDIO_AC3:+ case STREAM_TYPE_AUDIO_DTS:+ case STREAM_TYPE_AUDIO_HDMV_DTS:+@@ -832,7 +833,7 @@+ code = pes->header[3] | 0x100;+ if (!((code >= 0x1c0 && code <= 0x1df) ||+ (code >= 0x1e0 && code <= 0x1ef) ||+- (code == 0x1bd) || (code == 0x1fd)))++ (code == 0x1bd) || (code == 0x1fa) || (code == 0x1fd)))+ goto skip;+ if (!pes->st) {+ /* allocate stream */+@@ -948,6 +949,10 @@+ codec_type = CODEC_TYPE_AUDIO;+ codec_id = CODEC_ID_AAC;+ break;++ case STREAM_TYPE_AUDIO_AAC_LATM:++ codec_type = CODEC_TYPE_AUDIO;++ codec_id = CODEC_ID_AAC_LATM;++ break;+ case STREAM_TYPE_AUDIO_AC3:+ codec_type = CODEC_TYPE_AUDIO;+ codec_id = CODEC_ID_AC3;+Index: libavformat/mpegts.h+===================================================================+--- libavformat/mpegts.h (revision 14016)++++ libavformat/mpegts.h (working copy)+@@ -50,6 +50,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+ +Index: libavformat/mpeg.c+===================================================================+--- libavformat/mpeg.c (revision 14016)++++ libavformat/mpeg.c (working copy)+@@ -281,7 +281,7 @@+ /* find matching stream */+ if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||+ (startcode >= 0x1e0 && startcode <= 0x1ef) ||+- (startcode == 0x1bd) || (startcode == 0x1fd)))++ (startcode == 0x1bd) || (startcode == 0x1fa) || (startcode == 0x1fd)))+ goto redo;+ if (ppos) {+ *ppos = url_ftell(s->pb) - 4;+@@ -439,6 +439,9 @@+ } else if(es_type == STREAM_TYPE_AUDIO_AAC){+ codec_id = CODEC_ID_AAC;+ type = CODEC_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 = CODEC_TYPE_VIDEO;+Index: libavformat/mpeg.h+===================================================================+--- libavformat/mpeg.h (revision 14016)++++ libavformat/mpeg.h (working copy)+@@ -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 0x81Index: contrib/Jamfile===================================================================--- contrib/Jamfile (revision 1546)+++ contrib/Jamfile (working copy)@@ -78,6 +78,7 @@ rule LibAvCodec { FFMPEG_PATCH = "$(PATCH) -p0 < ../patch-ffmpeg.patch" ;+ FFMPEG_PATCH += " && $(PATCH) -p0 < ../patch-ffmpeg-latm.patch " ; if $(OS) = CYGWIN { FFMPEG_PATCH += " && $(PATCH) -p1 < ../patch-ffmpeg-cygwin.patch " ;