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

Tomas Härdin tomas.hardin
Fri Oct 29 09:13:02 CEST 2010


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).

> +    }
> +
> +    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?

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

ditto, possibly some more.

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

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

/Tomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: This is a digitally signed message part
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101029/28ecbf87/attachment.pgp>



More information about the ffmpeg-devel mailing list