Commit bf09b550 authored by Justin Ruggles's avatar Justin Ruggles

commit the OKed parts of the E-AC-3 decoder

Originally committed as revision 14860 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent e6300276
/* /*
* AC-3 Audio Decoder * 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) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com).
* Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com>
* Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com> * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com>
* *
* Portions of this code are derived from liba52 * Portions of this code are derived from liba52
...@@ -302,10 +304,23 @@ static int parse_frame_header(AC3DecodeContext *s) ...@@ -302,10 +304,23 @@ static int parse_frame_header(AC3DecodeContext *s)
s->channel_in_cpl[s->lfe_ch] = 0; s->channel_in_cpl[s->lfe_ch] = 0;
} }
if(hdr.bitstream_id > 10) if (hdr.bitstream_id <= 10) {
return AC3_PARSE_ERROR_BSID; 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); return ac3_parse_header(s);
} else {
/*s->eac3 = 1;
return ff_eac3_parse_header(s);*/
return AC3_PARSE_ERROR_BSID;
}
} }
/** /**
...@@ -533,6 +548,25 @@ static void remove_dithering(AC3DecodeContext *s) { ...@@ -533,6 +548,25 @@ static void remove_dithering(AC3DecodeContext *s) {
} }
} }
#if 0
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);
for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
s->fixed_coeffs[ch][bin] = s->pre_mantissa[ch][bin][blk] >> s->dexps[ch][bin];
}
}
}
#endif
/** /**
* Get the transform coefficients. * Get the transform coefficients.
*/ */
...@@ -698,19 +732,23 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ...@@ -698,19 +732,23 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
/* block switch flags */ /* block switch flags */
different_transforms = 0; different_transforms = 0;
if (s->block_switch_syntax) {
for (ch = 1; ch <= fbw_channels; ch++) { for (ch = 1; ch <= fbw_channels; ch++) {
s->block_switch[ch] = get_bits1(gbc); s->block_switch[ch] = get_bits1(gbc);
if(ch > 1 && s->block_switch[ch] != s->block_switch[1]) if(ch > 1 && s->block_switch[ch] != s->block_switch[1])
different_transforms = 1; different_transforms = 1;
} }
}
/* dithering flags */ /* dithering flags */
if (s->dither_flag_syntax) {
s->dither_all = 1; s->dither_all = 1;
for (ch = 1; ch <= fbw_channels; ch++) { for (ch = 1; ch <= fbw_channels; ch++) {
s->dither_flag[ch] = get_bits1(gbc); s->dither_flag[ch] = get_bits1(gbc);
if(!s->dither_flag[ch]) if(!s->dither_flag[ch])
s->dither_all = 0; s->dither_all = 0;
} }
}
/* dynamic range */ /* dynamic range */
i = !(s->channel_mode); i = !(s->channel_mode);
...@@ -870,6 +908,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ...@@ -870,6 +908,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
} }
/* bit allocation information */ /* bit allocation information */
if (s->bit_allocation_syntax) {
if (get_bits1(gbc)) { 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.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; s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;
...@@ -882,6 +921,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ...@@ -882,6 +921,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must be present in block 0\n"); av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must be present in block 0\n");
return -1; return -1;
} }
}
/* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */ /* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */
if (get_bits1(gbc)) { if (get_bits1(gbc)) {
...@@ -910,7 +950,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ...@@ -910,7 +950,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
} }
/* delta bit allocation information */ /* delta bit allocation information */
if (get_bits1(gbc)) { if (s->dba_syntax && get_bits1(gbc)) {
/* delta bit allocation exists (strategy) */ /* delta bit allocation exists (strategy) */
for (ch = !cpl_in_use; ch <= fbw_channels; ch++) { for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {
s->dba_mode[ch] = get_bits(gbc, 2); s->dba_mode[ch] = get_bits(gbc, 2);
...@@ -959,16 +999,18 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ...@@ -959,16 +999,18 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
} }
if(bit_alloc_stages[ch] > 0) { if(bit_alloc_stages[ch] > 0) {
/* Compute bit allocation */ /* 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], ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch],
s->start_freq[ch], s->end_freq[ch], s->start_freq[ch], s->end_freq[ch],
s->snr_offset[ch], s->snr_offset[ch],
s->bit_alloc_params.floor, s->bit_alloc_params.floor,
ff_ac3_bap_tab, s->bap[ch]); bap_tab, s->bap[ch]);
} }
} }
/* unused dummy data */ /* unused dummy data */
if (get_bits1(gbc)) { if (s->skip_syntax && get_bits1(gbc)) {
int skipl = get_bits(gbc, 9); int skipl = get_bits(gbc, 9);
while(skipl--) while(skipl--)
skip_bits(gbc, 8); skip_bits(gbc, 8);
...@@ -978,6 +1020,10 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ...@@ -978,6 +1020,10 @@ static int decode_audio_block(AC3DecodeContext *s, int blk)
this also uncouples channels if coupling is in use. */ this also uncouples channels if coupling is in use. */
get_transform_coeffs(s); get_transform_coeffs(s);
/* TODO: generate enhanced coupling coordinates and uncouple */
/* TODO: apply spectral extension */
/* recover coefficients if rematrixing is in use */ /* recover coefficients if rematrixing is in use */
if(s->channel_mode == AC3_CHMODE_STEREO) if(s->channel_mode == AC3_CHMODE_STEREO)
do_rematrixing(s); do_rematrixing(s);
...@@ -1161,5 +1207,5 @@ AVCodec ac3_decoder = { ...@@ -1161,5 +1207,5 @@ AVCodec ac3_decoder = {
.init = ac3_decode_init, .init = ac3_decode_init,
.close = ac3_decode_end, .close = ac3_decode_end,
.decode = ac3_decode_frame, .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)"),
}; };
...@@ -1365,5 +1365,5 @@ AVCodec ac3_encoder = { ...@@ -1365,5 +1365,5 @@ AVCodec ac3_encoder = {
AC3_encode_close, AC3_encode_close,
NULL, NULL,
.sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, .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)"),
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment