[FFmpeg-devel] [PATCH 01/28] Added: Ticket #5481 - added support for LATM encapsulated AAC audio streams within FFmpeg (thanks Paul Kendall).
Alex Converse
alex.converse
Wed Jun 30 18:45:49 CEST 2010
On Wed, Jun 30, 2010 at 5:09 AM, Mans Rullgard <mans at mansr.com> wrote:
> From: Cory Fields <theuni-nospam- at xbmc.org>
>
> Need to configure with --enable-external-libfaad to use.
This seems completely unchanged since I rejected it yesterday, and
substantively unchanged since it was rejected in 2008.
> ---
> ?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"
Why is the glued to 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,
You know as well as I do why this is wrong...
> ? ? 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))
FFMIN
> +
> +/*
> + ? ?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
> + ? ?}
> +}
This looks a lot like code already in aacdec.c and mpeg4audio.c
> +
> +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