[FFmpeg-soc] [soc]: r1783 - in eac3: TODO ac3dec.c ac3dec.h eac3dec.c
jbr
subversion at mplayerhq.hu
Mon Jan 7 03:57:27 CET 2008
Author: jbr
Date: Mon Jan 7 03:57:26 2008
New Revision: 1783
Log:
add E-AC3 support to the AC3 block parser
Modified:
eac3/TODO
eac3/ac3dec.c
eac3/ac3dec.h
eac3/eac3dec.c
Modified: eac3/TODO
==============================================================================
--- eac3/TODO (original)
+++ eac3/TODO Mon Jan 7 03:57:26 2008
@@ -30,7 +30,6 @@ Features:
similar to RealAudio DolbyNet, but we need a sample to test.
General:
-* Get the AC3 block decoder working with E-AC3
* Try to simplify and document AHT decoding
Cosmetic:
Modified: eac3/ac3dec.c
==============================================================================
--- eac3/ac3dec.c (original)
+++ eac3/ac3dec.c Mon Jan 7 03:57:26 2008
@@ -762,16 +762,20 @@ static int ac3_parse_audio_block(AC3Deco
memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS);
/* block switch flags */
+ if (!s->eac3 || s->block_switch_syntax) {
for (ch = 1; ch <= fbw_channels; ch++)
s->block_switch[ch] = get_bits1(gbc);
+ }
/* dithering flags */
+ if (!s->eac3 || 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);
@@ -784,46 +788,83 @@ static int ac3_parse_audio_block(AC3Deco
}
} while(i--);
+ /* spectral extension strategy */
+ if (s->eac3 && (!blk || get_bits1(gbc))) {
+ if (get_bits1(gbc)) {
+ ff_eac3_log_missing_feature(s->avctx, "Spectral extension");
+ return -1;
+ }
+ /* TODO: parse spectral extension strategy info */
+ }
+
+ /* TODO: spectral extension coordinates */
+
/* coupling strategy */
- if(blk)
- s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
- if (get_bits1(gbc)) {
+ if ((s->eac3 && s->cpl_strategy_exists[blk]) || (!s->eac3 && get_bits1(gbc))) {
memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
+ if (!s->eac3)
s->cpl_in_use[blk] = get_bits1(gbc);
if (s->cpl_in_use[blk]) {
/* coupling in use */
int cpl_begin_freq, cpl_end_freq;
+ /* check for enhanced coupling */
+ if (s->eac3 && get_bits1(gbc)) {
+ /* TODO: parse enhanced coupling strategy info */
+ ff_eac3_log_missing_feature(s->avctx, "Enhanced coupling");
+ return -1;
+ }
+
/* determine which channels are coupled */
+ if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) {
+ s->channel_in_cpl[1] = 1;
+ s->channel_in_cpl[2] = 1;
+ } else {
for (ch = 1; ch <= fbw_channels; ch++)
s->channel_in_cpl[ch] = get_bits1(gbc);
+ }
/* phase flags in use */
if (channel_mode == AC3_CHMODE_STEREO)
s->phase_flags_in_use = get_bits1(gbc);
- /* coupling frequency range and band structure */
+ /* coupling frequency range */
+ /* TODO: modify coupling end freq if spectral extension is used */
cpl_begin_freq = get_bits(gbc, 4);
cpl_end_freq = get_bits(gbc, 4);
if (3 + cpl_end_freq - cpl_begin_freq < 0) {
av_log(s->avctx, AV_LOG_ERROR, "3+cplendf = %d < cplbegf = %d\n", 3+cpl_end_freq, cpl_begin_freq);
return -1;
}
- s->num_cpl_bands = s->num_cpl_subbands = 3 + cpl_end_freq - cpl_begin_freq;
+ s->num_cpl_subbands = 3 + cpl_end_freq - cpl_begin_freq;
s->start_freq[CPL_CH] = cpl_begin_freq * 12 + 37;
s->end_freq[CPL_CH] = cpl_end_freq * 12 + 73;
+
+ /* coupling band structure */
+ if (!s->eac3 || get_bits1(gbc)) {
for (bnd = 0; bnd < s->num_cpl_subbands - 1; bnd++) {
- if (get_bits1(gbc)) {
- s->cpl_band_struct[bnd] = 1;
- s->num_cpl_bands--;
+ s->cpl_band_struct[bnd] = get_bits1(gbc);
+ }
+ } else if (!blk) {
+ for (bnd = 0; bnd < s->num_cpl_subbands - 1; bnd++) {
+ s->cpl_band_struct[bnd] = ff_eac3_default_cpl_band_struct[bnd+cpl_begin_freq+1];
}
}
s->cpl_band_struct[s->num_cpl_subbands-1] = 0;
+
+ /* calculate number of coupling bands based on band structure */
+ s->num_cpl_bands = s->num_cpl_subbands;
+ for (bnd = 0; bnd < s->num_cpl_subbands-1; bnd++) {
+ s->num_cpl_bands -= s->cpl_band_struct[bnd];
+ }
} else {
/* coupling not in use */
for (ch = 1; ch <= fbw_channels; ch++)
s->channel_in_cpl[ch] = 0;
}
+ } else if (!s->eac3 && blk) {
+ /* for AC3, copy coupling use strategy from last block */
+ s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
}
/* coupling coordinates */
@@ -832,7 +873,17 @@ static int ac3_parse_audio_block(AC3Deco
for (ch = 1; ch <= fbw_channels; ch++) {
if (s->channel_in_cpl[ch]) {
- if (get_bits1(gbc)) {
+ int new_cpl_coords = 0;
+
+ /* determine if coupling coordinates are new or reused */
+ if (s->eac3 && s->first_cpl_coords[ch]) {
+ new_cpl_coords = 1;
+ s->first_cpl_coords[ch] = 0;
+ } else {
+ new_cpl_coords = get_bits1(gbc);
+ }
+
+ if (new_cpl_coords) {
int master_cpl_coord, cpl_coord_exp, cpl_coord_mant;
cpl_coords_exist = 1;
master_cpl_coord = 3 * get_bits(gbc, 2);
@@ -846,6 +897,9 @@ static int ac3_parse_audio_block(AC3Deco
s->cpl_coords[ch][bnd] *= ff_ac3_scale_factors[cpl_coord_exp + master_cpl_coord];
}
}
+ } else {
+ /* channel not in coupling */
+ s->first_cpl_coords[ch] = 1;
}
}
/* phase flags */
@@ -858,7 +912,7 @@ static int ac3_parse_audio_block(AC3Deco
/* stereo rematrixing strategy and band structure */
if (channel_mode == AC3_CHMODE_STEREO) {
- if (get_bits1(gbc)) {
+ if ((s->eac3 && !blk) || get_bits1(gbc)) {
s->num_rematrixing_bands = 4;
if(s->cpl_in_use[blk] && s->start_freq[CPL_CH] <= 61)
s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37);
@@ -868,13 +922,14 @@ static int ac3_parse_audio_block(AC3Deco
}
/* exponent strategies for each channel */
- s->exp_strategy[blk][CPL_CH] = EXP_REUSE;
- s->exp_strategy[blk][s->lfe_ch] = EXP_REUSE;
+ if (!s->eac3) {
+ for (ch = !s->cpl_in_use[blk]; ch <= s->channels; ch++) {
+ s->exp_strategy[blk][ch] = get_bits(gbc, 2 - (ch == s->lfe_ch));
+ }
+ }
+
+ /* check exponent strategies to set bit allocation stages */
for (ch = !s->cpl_in_use[blk]; ch <= s->channels; ch++) {
- if(ch == s->lfe_ch)
- s->exp_strategy[blk][ch] = get_bits(gbc, 1);
- else
- s->exp_strategy[blk][ch] = get_bits(gbc, 2);
if(s->exp_strategy[blk][ch] != EXP_REUSE)
bit_alloc_stages[ch] = 3;
}
@@ -919,6 +974,7 @@ static int ac3_parse_audio_block(AC3Deco
}
/* bit allocation information */
+ if (!s->eac3 || 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;
@@ -929,27 +985,76 @@ static int ac3_parse_audio_block(AC3Deco
bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
}
}
+ }
/* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */
- if (get_bits1(gbc)) {
+ if ((!s->eac3 || (s->snr_offset_strategy && !blk)) && get_bits1(gbc)) {
+ int snr = 0;
int csnr;
csnr = (get_bits(gbc, 6) - 15) << 4;
- for (ch = !s->cpl_in_use[blk]; ch <= s->channels; ch++) { /* snr offset and fast gain */
- s->snr_offset[ch] = (csnr + get_bits(gbc, 4)) << 2;
+ for (i = ch = !s->cpl_in_use[blk]; ch <= s->channels; ch++) {
+ /* snr offset */
+ if (!s->eac3 || ch == i || s->snr_offset_strategy == 2)
+ snr = (csnr + get_bits(gbc, 4)) << 2;
+ /* run at least last bit allocation stage if snr offset changes */
+ if(blk && s->snr_offset[ch] != snr) {
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 1);
+ }
+ s->snr_offset[ch] = snr;
+
+ /* fast gain (normal AC3 only) */
+ if (!s->eac3) {
+ int prev = s->fast_gain[ch];
s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
+ /* run last 2 bit allocation stages if fast gain changes */
+ if(blk && prev != s->fast_gain[ch])
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
+ }
}
- memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
+ }
+
+ /* fast gain (E-AC3 only) */
+ if(s->eac3) {
+ if (s->fast_gain_syntax && get_bits1(gbc)) {
+ for (ch = !s->cpl_in_use[blk]; ch <= s->channels; ch++) {
+ int prev = s->fast_gain[ch];
+ s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
+ /* run last 2 bit allocation stages if fast gain changes */
+ if(blk && prev != s->fast_gain[ch])
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
+ }
+ } else if (!blk) {
+ for (ch = !s->cpl_in_use[blk]; ch <= s->channels; ch++)
+ s->fast_gain[ch] = ff_ac3_fast_gain_tab[4];
+ }
+ }
+
+ /* E-AC3 to AC3 converter SNR offset */
+ if (s->eac3 && s->stream_type == EAC3_STREAM_TYPE_INDEPENDENT &&
+ get_bits1(gbc)) {
+ skip_bits(gbc, 10); // skip converter snr offset
}
/* coupling leak information */
- if (s->cpl_in_use[blk] && get_bits1(gbc)) {
+ if (s->cpl_in_use[blk]) {
+ if ((s->eac3 && s->first_cpl_leak) || get_bits1(gbc)) {
+ int prev_fl = s->bit_alloc_params.cpl_fast_leak;
+ int prev_sl = s->bit_alloc_params.cpl_slow_leak;
s->bit_alloc_params.cpl_fast_leak = get_bits(gbc, 3);
s->bit_alloc_params.cpl_slow_leak = get_bits(gbc, 3);
- bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2);
+ /* run last 2 bit allocation stages for coupling channel if
+ coupling leak changes */
+ if(blk && (prev_fl != s->bit_alloc_params.cpl_fast_leak ||
+ prev_sl != s->bit_alloc_params.cpl_slow_leak)) {
+ bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2);
+ }
+ }
+ if(s->first_cpl_leak)
+ s->first_cpl_leak = 0;
}
/* delta bit allocation information */
- if (get_bits1(gbc)) {
+ if ((!s->eac3 || s->dba_syntax) && get_bits1(gbc)) {
/* delta bit allocation exists (strategy) */
for (ch = !s->cpl_in_use[blk]; ch <= fbw_channels; ch++) {
s->dba_mode[ch] = get_bits(gbc, 2);
@@ -968,6 +1073,8 @@ static int ac3_parse_audio_block(AC3Deco
s->dba_lengths[ch][seg] = get_bits(gbc, 4);
s->dba_values[ch][seg] = get_bits(gbc, 3);
}
+ /* run last 2 bit allocation stages if new dba values */
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
}
}
} else if(blk == 0) {
@@ -996,16 +1103,22 @@ static int ac3_parse_audio_block(AC3Deco
}
if(bit_alloc_stages[ch] > 0) {
/* Compute bit allocation */
+ if (!s->eac3 || s->channel_uses_aht[ch] == 0)
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]);
+ else
+ 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_eac3_hebap_tab,
+ s->hebap[ch]);
}
}
/* unused dummy data */
- if (get_bits1(gbc)) {
+ if ((!s->eac3 || s->skip_syntax) && get_bits1(gbc)) {
int skipl = get_bits(gbc, 9);
while(skipl--)
skip_bits(gbc, 8);
@@ -1092,12 +1205,16 @@ static int ac3_decode_frame(AVCodecConte
/* parse the audio blocks */
for (blk = 0; blk < s->num_blocks; blk++) {
- if (ff_eac3_parse_audio_block(s, blk)) {
+ if (ac3_parse_audio_block(s, blk)) {
av_log(avctx, AV_LOG_ERROR, "error parsing the audio block\n");
*data_size = 0;
return s->frame_size;
}
+ /* 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);
Modified: eac3/ac3dec.h
==============================================================================
--- eac3/ac3dec.h (original)
+++ eac3/ac3dec.h Mon Jan 7 03:57:26 2008
@@ -48,6 +48,14 @@
#define MAX_BLOCKS 6
#define MAX_SPX_CODES 18
+/** Stream Type */
+typedef enum {
+ EAC3_STREAM_TYPE_INDEPENDENT = 0,
+ EAC3_STREAM_TYPE_DEPENDENT,
+ EAC3_STREAM_TYPE_AC3_CONVERT,
+ EAC3_STREAM_TYPE_RESERVED
+} EAC3StreamType;
+
/** dynamic range table. converts codes to scale factors. */
extern float ff_ac3_dynamic_range_tab[256];
@@ -235,6 +243,7 @@ int ff_eac3_parse_audio_block(AC3DecodeC
void ff_eac3_get_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch);
void ff_eac3_idct_transform_coeffs_ch(AC3DecodeContext *s, int ch, int blk);
void ff_eac3_tables_init(void);
+void ff_eac3_log_missing_feature(AVCodecContext *avctx, const char *log);
int ff_ac3_get_transform_coeffs(AC3DecodeContext *s, int blk);
Modified: eac3/eac3dec.c
==============================================================================
--- eac3/eac3dec.c (original)
+++ eac3/eac3dec.c Mon Jan 7 03:57:26 2008
@@ -32,21 +32,13 @@ typedef enum {
EAC3_GAQ_124
} EAC3GaqMode;
-/** Stream Type */
-typedef enum {
- EAC3_STREAM_TYPE_INDEPENDENT = 0,
- EAC3_STREAM_TYPE_DEPENDENT,
- EAC3_STREAM_TYPE_AC3_CONVERT,
- EAC3_STREAM_TYPE_RESERVED
-} EAC3StreamType;
-
#define EAC3_SR_CODE_REDUCED 3
static float idct_cos_tab[6][5];
static int gaq_ungroup_tab[32][3];
-static void log_missing_feature(AVCodecContext *avctx, const char *log){
+void ff_eac3_log_missing_feature(AVCodecContext *avctx, const char *log){
av_log(avctx, AV_LOG_ERROR, "%s is not implemented. If you want to help, "
"update your FFmpeg version to the newest one from SVN. If the "
"problem still occurs, it means that your file has extension "
@@ -281,7 +273,7 @@ static int parse_bsi(AC3DecodeContext *s
skip_bits(gbc, 16); // skip the sync word
s->stream_type = get_bits(gbc, 2);
if (s->stream_type == EAC3_STREAM_TYPE_DEPENDENT) {
- log_missing_feature(s->avctx, "Dependent substream");
+ ff_eac3_log_missing_feature(s->avctx, "Dependent substream");
return -1;
} else if (s->stream_type == EAC3_STREAM_TYPE_RESERVED) {
av_log(s->avctx, AV_LOG_ERROR, "Reserved stream type\n");
@@ -303,7 +295,7 @@ static int parse_bsi(AC3DecodeContext *s
rates in bit allocation. The best assumption would be that it is
handled like AC3 DolbyNet, but we cannot be sure until we have a
sample which utilizes this feature. */
- log_missing_feature(s->avctx, "Reduced Sampling Rates");
+ ff_eac3_log_missing_feature(s->avctx, "Reduced Sampling Rates");
return -1;
#if 0
s->bit_alloc_params.sr_code = get_bits(gbc, 2);
@@ -706,7 +698,7 @@ int ff_eac3_parse_audio_block(AC3DecodeC
}
}
#else
- log_missing_feature(s->avctx, "Spectral extension");
+ ff_eac3_log_missing_feature(s->avctx, "Spectral extension");
return -1;
#endif
#if TEST_SPX
@@ -871,7 +863,7 @@ int ff_eac3_parse_audio_block(AC3DecodeC
s->necplbnd -= s->ecplbndstrc[bnd];
}
#else
- log_missing_feature(s->avctx, "Enhanced coupling");
+ ff_eac3_log_missing_feature(s->avctx, "Enhanced coupling");
return -1;
#endif
}
More information about the FFmpeg-soc
mailing list