[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