[FFmpeg-devel] [PATCH 5/7] Add single stream LATM/LOAS decoder

Janne Grunau janne-ffmpeg
Fri Oct 29 22:11:51 CEST 2010


On Fri, Oct 29, 2010 at 09:13:02AM +0200, Tomas H?rdin wrote:
> On Fri, 2010-10-29 at 00:44 +0200, Janne Grunau wrote:
> > The decoder is basicly just a wrapper around the AAC decoder.
> > based on patch by Paul Kendall { paul <?t> kcbbs gen nz }
> > ---
> >  Changelog                |    1 +
> >  configure                |    1 +
> >  libavcodec/Makefile      |    1 +
> >  libavcodec/aacdec.c      |  285 ++++++++++++++++++++++++++++++++++++++++++++++
> >  libavcodec/allcodecs.c   |    2 +
> >  libavcodec/avcodec.h     |    1 +
> >  libavcodec/latm_parser.c |  119 +++++++++++++++++++
> >  7 files changed, 410 insertions(+), 0 deletions(-)
> >  create mode 100644 libavcodec/latm_parser.c
> > 
> > diff --git a/Changelog b/Changelog
> > index 1289036..979e713 100644
> > --- a/Changelog
> > +++ b/Changelog
> > @@ -50,6 +50,7 @@ version <next>:
> >  - transpose filter added
> >  - ffmpeg -force_key_frames option added
> >  - demuxer for receiving raw rtp:// URLs without an SDP description
> > +- single stream LATM/LOAS decoder
> >  
> > 
> >  version 0.6:
> > diff --git a/configure b/configure
> > index 27f807a..3ad8aab 100755
> > --- a/configure
> > +++ b/configure
> > @@ -1188,6 +1188,7 @@ rdft_select="fft"
> >  # decoders / encoders / hardware accelerators
> >  aac_decoder_select="mdct rdft"
> >  aac_encoder_select="mdct"
> > +aac_latm_decoder_select="aac_decoder aac_latm_parser"
> >  ac3_decoder_select="mdct ac3_parser"
> >  alac_encoder_select="lpc"
> >  amrnb_decoder_select="lsp"
> > diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> > index 385ae02..5abc495 100644
> > --- a/libavcodec/Makefile
> > +++ b/libavcodec/Makefile
> > @@ -576,6 +576,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_AAC_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/aacdec.c b/libavcodec/aacdec.c
> > index f592266..a210cf5 100644
> > --- a/libavcodec/aacdec.c
> > +++ b/libavcodec/aacdec.c
> > @@ -3,6 +3,10 @@
> >   * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
> >   * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
> >   *
> > + * AAC LATM decoder
> > + * Copyright (c) 2008-2010 Paul Kendall <paul at kcbbs.gen.nz>
> > + * Copyright (c) 2010      Janne Grunau <janne-ffmpeg at jannau.net>
> > + *
> >   * This file is part of FFmpeg.
> >   *
> >   * FFmpeg is free software; you can redistribute it and/or
> > @@ -2090,6 +2094,267 @@ static av_cold int aac_decode_close(AVCodecContext *avctx)
> >      return 0;
> >  }
> >  
> > +
> > +#define LOAS_SYNC_WORD   0x2b7       ///< 11 bits LOAS sync word
> > +
> > +struct LATMContext {
> > +    AACContext      aac_ctx;             ///< containing AACContext
> > +    int             initialized;         ///< initilized 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)
> > +{
> > +    AVCodecContext *avctx = latmctx->aac_ctx.avctx;
> > +    MPEG4AudioConfig m4ac;
> > +    int  config_start_bit = get_bits_count(gb);
> > +    int     bits_consumed, esize;
> > +
> > +    if (config_start_bit % 8) {
> > +        av_log_missing_feature(latmctx->aac_ctx.avctx, "audio specific "
> > +                               "config not byte aligned.\n", 1);
> > +        return AVERROR_INVALIDDATA;
> > +    } else {
> > +        bits_consumed =
> > +            decode_audio_specific_config(&latmctx->aac_ctx, &m4ac,
> > +                                         gb->buffer + (config_start_bit / 8),
> > +                                         get_bits_left(gb) / 8);
> > +
> > +        if (bits_consumed < 0)
> > +            return AVERROR_INVALIDDATA;
> > +
> > +        esize = (bits_consumed+7) / 8;
> > +
> > +        if (avctx->extradata_size <= esize) {
> > +            av_free(avctx->extradata);
> > +            avctx->extradata = av_malloc(esize + FF_INPUT_BUFFER_PADDING_SIZE);
> > +            if (!avctx->extradata)
> > +                return AVERROR(ENOMEM);
> > +        }
> > +
> > +        avctx->extradata_size = esize;
> > +        memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize);
> > +        memset(avctx->extradata+esize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
> 
> Is settings this to zero really needed? I thought the padding was there
> only so optimized bitstream reading works, and largely ignored (except
> for the documented MPEG case).

common code in av_find_stream_info() does it and rmdec, rtp_h264|xiph

> > +    }
> > +
> > +    return bits_consumed;
> > +}
> > +
> > +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
> > +            av_log_missing_feature(latmctx->aac_ctx.avctx,
> > +                                   "multiple programs are not supported\n", 1);
> > +            return AVERROR_PATCHWELCOME;
> > +        }
> > +
> > +        // for each program (which there is only on in DVB)
> > +
> > +        // for each layer (which there is only on in DVB)
> > +        if (get_bits(gb, 3)) {                   // numLayer
> > +            av_log_missing_feature(latmctx->aac_ctx.avctx,
> > +                                   "multiple layers are not supported\n", 1);
> > +            return AVERROR_PATCHWELCOME;
> > +        }
> > +
> > +        // for all but first stream: use_same_config = get_bits(gb, 1);
> > +        if (!audio_mux_version) {
> > +            ret = latm_decode_audio_specific_config(latmctx, gb);
> > +            if (ret < 0)
> > +                return ret;
> 
> if ((ret = ...) < 0)
>     return ret;
> 
> perhaps?

I'm used to kernel coding standards

> > +        } else {
> > +            int ascLen = latm_get_value(gb);
> > +            ret = latm_decode_audio_specific_config(latmctx, gb);
> > +            if (ret < 0)
> > +                return ret;
> 
> ditto, possibly some more.

probably all of this kind. I prefer to avoid assignments in if but the
aacdec.c style seems to be assignments in if. I'll change it.

> Also, I didn't see a lavc minor version bump in there.

I try to remember to add it before commit, Changelog merging alone is
anoying enough

> Finally, you should also probably add en entry in docs/general.texi.

If you have a good idea where I'm all ears. It doesn't fit into the
file formats since it's in the current form not handled by libavformat
and doesn't justify an extra entry in the audio codecs table since it's
still just AAC.

Janne



More information about the ffmpeg-devel mailing list