[FFmpeg-devel] [PATCH] E-AC-3 decoder, round 3

Michael Niedermayer michaelni
Wed Aug 20 00:16:29 CEST 2008


On Sun, Aug 17, 2008 at 07:30:26PM -0400, Justin Ruggles wrote:
> Hi,
> 
> Here is a new patch to complete support for E-AC-3 decoding within the
> current AC-3 decoder.  It will be followed up by a cosmetic commit to
> indent and align.
> 
> -Justin
> 

> Index: libavcodec/ac3dec.c
> ===================================================================
> --- libavcodec/ac3dec.c	(revision 14819)
> +++ libavcodec/ac3dec.c	(working copy)
> @@ -1,8 +1,10 @@
>  /*
>   * AC-3 Audio Decoder
> - * This code is developed as part of Google Summer of Code 2006 Program.
> + * This code was developed as part of Google Summer of Code 2006.
> + * E-AC-3 support was added as part of Google Summer of Code 2007.
>   *
>   * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com).
> + * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
>   * Copyright (c) 2007 Justin Ruggles <justin.ruggles at gmail.com>
>   *
>   * Portions of this code are derived from liba52

ok


> @@ -37,8 +39,8 @@
>  #include "ac3dec.h"
>  #include "ac3dec_data.h"
>  
> -/** Maximum possible frame size when the specification limit is ignored */
> -#define AC3_MAX_FRAME_SIZE 21695
> +/** Large enough for maximum possible frame size when the specification limit is ignored */
> +#define AC3_FRAME_BUFFER_SIZE 32768
>  
>  /**
>   * table for ungrouping 3 values in 7 bits.
> @@ -215,7 +217,7 @@
>  
>      /* allocate context input buffer */
>      if (avctx->error_resilience >= FF_ER_CAREFUL) {
> -        s->input_buffer = av_mallocz(AC3_MAX_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
> +        s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
>          if (!s->input_buffer)
>              return AVERROR_NOMEM;
>      }

ok as seperate commit togteher with the related hunk later



> @@ -302,10 +304,22 @@
>          s->channel_in_cpl[s->lfe_ch] = 0;
>      }
>  
> -    if(hdr.bitstream_id > 10)
> -        return AC3_PARSE_ERROR_BSID;
> -
> +    if (hdr.bitstream_id <= 10) {
> +        s->eac3                  = 0;
> +        s->snr_offset_strategy   = 2;
> +        s->block_switch_syntax   = 1;
> +        s->dither_flag_syntax    = 1;
> +        s->bit_allocation_syntax = 1;
> +        s->fast_gain_syntax      = 0;
> +        s->first_cpl_leak        = 0;
> +        s->dba_syntax            = 1;
> +        s->skip_syntax           = 1;
> +        memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht));
>      return ac3_parse_header(s);
> +    } else {
> +        s->eac3 = 1;
> +        return ff_eac3_parse_header(s);
> +    }
>  }
>  

ok


[...]
> @@ -533,10 +547,27 @@
>      }
>  }
>  
> +static void get_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch,
> +                                    mant_groups *m)
> +{
> +    if (!s->channel_uses_aht[ch]) {
> +        ac3_get_transform_coeffs_ch(s, ch, m);
> +    } else {
> +        /* if AHT is used, mantissas for all blocks are encoded in the first
> +           block of the frame. */
> +        int bin;
> +        if (!blk)

> +            ff_eac3_get_transform_coeffs_aht_ch(s, ch);

am i blind? or where is this function, i cannot find it in this patch
nor in svn


[...]
> @@ -657,7 +688,7 @@
>   */
>  static void ac3_upmix_delay(AC3DecodeContext *s)
>  {
> -    int channel_data_size = 128*sizeof(float);
> +    int channel_data_size = sizeof(s->delay[0]);
>      switch(s->channel_mode) {
>          case AC3_CHMODE_DUALMONO:
>          case AC3_CHMODE_STEREO:

ok as seperate commit


> @@ -698,19 +729,23 @@
>  
>      /* block switch flags */
>      different_transforms = 0;
> +    if (s->block_switch_syntax) {
>      for (ch = 1; ch <= fbw_channels; ch++) {
>          s->block_switch[ch] = get_bits1(gbc);
>          if(ch > 1 && s->block_switch[ch] != s->block_switch[1])
>              different_transforms = 1;
>      }
> +    }
>  
>      /* dithering flags */
> +    if (s->dither_flag_syntax) {
>      s->dither_all = 1;
>      for (ch = 1; ch <= fbw_channels; ch++) {
>          s->dither_flag[ch] = get_bits1(gbc);
>          if(!s->dither_flag[ch])
>              s->dither_all = 0;
>      }
> +    }
>  
>      /* dynamic range */
>      i = !(s->channel_mode);

ok


[...]
> @@ -870,6 +965,7 @@
>      }
>  
>      /* bit allocation information */
> +    if (s->bit_allocation_syntax) {
>      if (get_bits1(gbc)) {
>          s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;
>          s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;
> @@ -882,35 +978,78 @@
>          av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must be present in block 0\n");
>          return -1;
>      }
> +    }

you inconsistently use 
s->bit_allocation_syntax && get_bits1(gbc) and above

[...]

>  
>      /* delta bit allocation information */
> -    if (get_bits1(gbc)) {
> +    if (s->dba_syntax && get_bits1(gbc)) {
>          /* delta bit allocation exists (strategy) */
>          for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {
>              s->dba_mode[ch] = get_bits(gbc, 2);
> @@ -959,16 +1098,18 @@
>          }
>          if(bit_alloc_stages[ch] > 0) {
>              /* Compute bit allocation */
> +            const uint8_t *bap_tab = s->channel_uses_aht[ch] ?
> +                                     ff_eac3_hebap_tab : ff_ac3_bap_tab;
>              ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch],
>                                        s->start_freq[ch], s->end_freq[ch],
>                                        s->snr_offset[ch],
>                                        s->bit_alloc_params.floor,
> -                                      ff_ac3_bap_tab, s->bap[ch]);
> +                                      bap_tab, s->bap[ch]);
>          }
>      }
>  
>      /* unused dummy data */
> -    if (get_bits1(gbc)) {
> +    if (s->skip_syntax && get_bits1(gbc)) {
>          int skipl = get_bits(gbc, 9);
>          while(skipl--)
>              skip_bits(gbc, 8);

ok


> @@ -976,8 +1117,12 @@
>  
>      /* unpack the transform coefficients
>         this also uncouples channels if coupling is in use. */
> -    get_transform_coeffs(s);
> +    get_transform_coeffs(s, blk);

>  
> +    /* TODO: generate enhanced coupling coordinates and uncouple */
> +
> +    /* TODO: apply spectral extension */
> +
>      /* recover coefficients if rematrixing is in use */
>      if(s->channel_mode == AC3_CHMODE_STEREO)
>          do_rematrixing(s);

ok


> @@ -1042,7 +1187,7 @@
>      if (s->input_buffer) {
>          /* copy input buffer to decoder context to avoid reading past the end
>             of the buffer, which can be caused by a damaged input stream. */
> -        memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_MAX_FRAME_SIZE));
> +        memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));
>          init_get_bits(&s->gbc, s->input_buffer, buf_size * 8);
>      } else {
>          init_get_bits(&s->gbc, buf, buf_size * 8);

ok (with the other 2 related hunks from above


> @@ -1161,5 +1306,5 @@
>      .init = ac3_decode_init,
>      .close = ac3_decode_end,
>      .decode = ac3_decode_frame,
> -    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 / AC-3"),
> +    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 (AC-3, E-AC-3)"),
>  };

ok


[...]
> Index: libavcodec/ac3enc.c
> ===================================================================
> --- libavcodec/ac3enc.c	(revision 14819)
> +++ libavcodec/ac3enc.c	(working copy)
> @@ -1365,5 +1365,5 @@
>      AC3_encode_close,
>      NULL,
>      .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
> -    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 / AC-3"),
> +    .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52 (AC-3, E-AC-3)"),
>  };

ok

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Awnsering whenever a program halts or runs forever is
On a turing machine, in general impossible (turings halting problem).
On any real computer, always possible as a real computer has a finite number
of states N, and will either halt in less than N cycles or never halt.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080820/55740b07/attachment.pgp>



More information about the ffmpeg-devel mailing list