*/
static const uint8_t rematrix_band_tab[5] = { 13, 25, 37, 61, 253 };
-/**
- * table for exponent to scale_factor mapping
- * scale_factors[i] = 2 ^ -i
- */
-static float scale_factors[25];
-
/** table for grouping exponents */
static uint8_t exp_ungroup_tab[128][3];
/** tables for ungrouping mantissas */
-static float b1_mantissas[32][3];
-static float b2_mantissas[128][3];
-static float b3_mantissas[8];
-static float b4_mantissas[128][2];
-static float b5_mantissas[16];
+static int b1_mantissas[32][3];
+static int b2_mantissas[128][3];
+static int b3_mantissas[8];
+static int b4_mantissas[128][2];
+static int b5_mantissas[16];
/**
* Quantization table: levels for symmetric. bits for asymmetric.
int phase_flags_in_use; ///< phase flags in use
int phase_flags[18]; ///< phase flags
int cpl_band_struct[18]; ///< coupling band structure
- int rematrixing_strategy; ///< rematrixing strategy
int num_rematrixing_bands; ///< number of rematrixing bands
int rematrixing_flags[4]; ///< rematrixing flags
int exp_strategy[AC3_MAX_CHANNELS]; ///< exponent strategies
int output_mode; ///< output channel configuration
int out_channels; ///< number of output channels
+ int center_mix_level; ///< Center mix level index
+ int surround_mix_level; ///< Surround mix level index
float downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients
+ float downmix_coeff_adjust[2]; ///< adjustment needed for each output channel when downmixing
float dynamic_range[2]; ///< dynamic range
- float cpl_coords[AC3_MAX_CHANNELS][18]; ///< coupling coordinates
+ int cpl_coords[AC3_MAX_CHANNELS][18]; ///< coupling coordinates
int num_cpl_bands; ///< number of coupling bands
int num_cpl_subbands; ///< number of coupling sub bands
int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin
int16_t band_psd[AC3_MAX_CHANNELS][50]; ///< interpolated exponents
int16_t mask[AC3_MAX_CHANNELS][50]; ///< masking curve values
+ int fixed_coeffs[AC3_MAX_CHANNELS][256]; ///> fixed-point transform coefficients
DECLARE_ALIGNED_16(float, transform_coeffs[AC3_MAX_CHANNELS][256]); ///< transform coefficients
+ int downmixed; ///< indicates if coeffs are currently downmixed
/* For IMDCT. */
MDCTContext imdct_512; ///< for 512 sample IMDCT
float add_bias; ///< offset for float_to_int16 conversion
float mul_bias; ///< scaling for float_to_int16 conversion
- DECLARE_ALIGNED_16(float, output[AC3_MAX_CHANNELS-1][256]); ///< output after imdct transform and windowing
+ DECLARE_ALIGNED_16(float, output[AC3_MAX_CHANNELS][256]); ///< output after imdct transform and windowing
DECLARE_ALIGNED_16(short, int_output[AC3_MAX_CHANNELS-1][256]); ///< final 16-bit integer output
- DECLARE_ALIGNED_16(float, delay[AC3_MAX_CHANNELS-1][256]); ///< delay - added to the next block
+ DECLARE_ALIGNED_16(float, delay[AC3_MAX_CHANNELS][256]); ///< delay - added to the next block
DECLARE_ALIGNED_16(float, tmp_imdct[256]); ///< temporary storage for imdct transform
DECLARE_ALIGNED_16(float, tmp_output[512]); ///< temporary storage for output before windowing
DECLARE_ALIGNED_16(float, window[256]); ///< window coefficients
AVCodecContext *avctx; ///< parent context
} AC3DecodeContext;
-/**
- * Generate a Kaiser-Bessel Derived Window.
- */
-static void ac3_window_init(float *window)
-{
- int i, j;
- double sum = 0.0, bessel, tmp;
- double local_window[256];
- double alpha2 = (5.0 * M_PI / 256.0) * (5.0 * M_PI / 256.0);
-
- for (i = 0; i < 256; i++) {
- tmp = i * (256 - i) * alpha2;
- bessel = 1.0;
- for (j = 100; j > 0; j--) /* default to 100 iterations */
- bessel = bessel * tmp / (j * j) + 1;
- sum += bessel;
- local_window[i] = sum;
- }
-
- sum++;
- for (i = 0; i < 256; i++)
- window[i] = sqrt(local_window[i] / sum);
-}
-
/**
* Symmetrical Dequantization
* reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization
* Tables 7.19 to 7.23
*/
-static inline float
+static inline int
symmetric_dequant(int code, int levels)
{
- return (code - (levels >> 1)) * (2.0f / levels);
+ return ((code - (levels >> 1)) << 24) / levels;
}
/*
* Initialize tables at runtime.
*/
-static void ac3_tables_init(void)
+static av_cold void ac3_tables_init(void)
{
int i;
dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20);
}
- /* generate scale factors for exponents and asymmetrical dequantization
- reference: Section 7.3.2 Expansion of Mantissas for Asymmetric Quantization */
- for (i = 0; i < 25; i++)
- scale_factors[i] = pow(2.0, -i);
-
/* generate exponent tables
reference: Section 7.1.3 Exponent Decoding */
for(i=0; i<128; i++) {
/**
* AVCodec initialization
*/
-static int ac3_decode_init(AVCodecContext *avctx)
+static av_cold int ac3_decode_init(AVCodecContext *avctx)
{
AC3DecodeContext *s = avctx->priv_data;
s->avctx = avctx;
ac3_tables_init();
ff_mdct_init(&s->imdct_256, 8, 1);
ff_mdct_init(&s->imdct_512, 9, 1);
- ac3_window_init(s->window);
+ ff_kbd_window_init(s->window, 5.0, 256);
dsputil_init(&s->dsp, avctx);
av_init_random(0, &s->dith_state);
avctx->request_channels <= 2) {
avctx->channels = avctx->request_channels;
}
+ s->downmixed = 1;
return 0;
}
{
AC3HeaderInfo hdr;
GetBitContext *gbc = &s->gbc;
- float center_mix_level, surround_mix_level;
int err, i;
err = ff_ac3_parse_header(gbc->buffer, &hdr);
if(s->lfe_on)
s->output_mode |= AC3_OUTPUT_LFEON;
+ /* set default mix levels */
+ s->center_mix_level = 3; // -4.5dB
+ s->surround_mix_level = 4; // -6.0dB
+
/* skip over portion of header which has already been read */
skip_bits(gbc, 16); // skip the sync_word
skip_bits(gbc, 16); // skip crc1
skip_bits(gbc, 2); // skip dsurmod
} else {
if((s->channel_mode & 1) && s->channel_mode != AC3_CHMODE_MONO)
- center_mix_level = gain_levels[center_levels[get_bits(gbc, 2)]];
+ s->center_mix_level = center_levels[get_bits(gbc, 2)];
if(s->channel_mode & 4)
- surround_mix_level = gain_levels[surround_levels[get_bits(gbc, 2)]];
+ s->surround_mix_level = surround_levels[get_bits(gbc, 2)];
}
skip_bits1(gbc); // skip lfeon
} while(i--);
}
- /* set stereo downmixing coefficients
- reference: Section 7.8.2 Downmixing Into Two Channels */
+ return 0;
+}
+
+/**
+ * Set stereo downmixing coefficients based on frame header info.
+ * reference: Section 7.8.2 Downmixing Into Two Channels
+ */
+static void set_downmix_coeffs(AC3DecodeContext *s)
+{
+ int i;
+ float cmix = gain_levels[s->center_mix_level];
+ float smix = gain_levels[s->surround_mix_level];
+
for(i=0; i<s->fbw_channels; i++) {
s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
}
if(s->channel_mode > 1 && s->channel_mode & 1) {
- s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = center_mix_level;
+ s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = cmix;
}
if(s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) {
int nf = s->channel_mode - 2;
- s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = surround_mix_level * LEVEL_MINUS_3DB;
+ s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB;
}
if(s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
int nf = s->channel_mode - 4;
- s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = surround_mix_level;
+ s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix;
}
- return 0;
+ /* calculate adjustment needed for each channel to avoid clipping */
+ s->downmix_coeff_adjust[0] = s->downmix_coeff_adjust[1] = 0.0f;
+ for(i=0; i<s->fbw_channels; i++) {
+ s->downmix_coeff_adjust[0] += s->downmix_coeffs[i][0];
+ s->downmix_coeff_adjust[1] += s->downmix_coeffs[i][1];
+ }
+ s->downmix_coeff_adjust[0] = 1.0f / s->downmix_coeff_adjust[0];
+ s->downmix_coeff_adjust[1] = 1.0f / s->downmix_coeff_adjust[1];
}
/**
for(j=0; j<12; j++) {
for(ch=1; ch<=s->fbw_channels; ch++) {
if(s->channel_in_cpl[ch]) {
- s->transform_coeffs[ch][i] = s->transform_coeffs[CPL_CH][i] * s->cpl_coords[ch][bnd] * 8.0f;
+ s->fixed_coeffs[ch][i] = ((int64_t)s->fixed_coeffs[CPL_CH][i] * (int64_t)s->cpl_coords[ch][bnd]) >> 23;
if (ch == 2 && s->phase_flags[bnd])
- s->transform_coeffs[ch][i] = -s->transform_coeffs[ch][i];
+ s->fixed_coeffs[ch][i] = -s->fixed_coeffs[ch][i];
}
}
i++;
* Grouped mantissas for 3-level 5-level and 11-level quantization
*/
typedef struct {
- float b1_mant[3];
- float b2_mant[3];
- float b4_mant[2];
+ int b1_mant[3];
+ int b2_mant[3];
+ int b4_mant[2];
int b1ptr;
int b2ptr;
int b4ptr;
int i, gcode, tbap, start, end;
uint8_t *exps;
uint8_t *bap;
- float *coeffs;
+ int *coeffs;
exps = s->dexps[ch_index];
bap = s->bap[ch_index];
- coeffs = s->transform_coeffs[ch_index];
+ coeffs = s->fixed_coeffs[ch_index];
start = s->start_freq[ch_index];
end = s->end_freq[ch_index];
tbap = bap[i];
switch (tbap) {
case 0:
- coeffs[i] = ((av_random(&s->dith_state) & 0xFFFF) / 65535.0f) - 0.5f;
+ coeffs[i] = (av_random(&s->dith_state) & 0x7FFFFF) - 4194304;
break;
case 1:
coeffs[i] = b5_mantissas[get_bits(gbc, 4)];
break;
- default:
+ default: {
/* asymmetric dequantization */
- coeffs[i] = get_sbits(gbc, quantization_tab[tbap]) * scale_factors[quantization_tab[tbap]-1];
+ int qlevel = quantization_tab[tbap];
+ coeffs[i] = get_sbits(gbc, qlevel) << (24 - qlevel);
break;
+ }
}
- coeffs[i] *= scale_factors[exps[i]];
+ coeffs[i] >>= exps[i];
}
return 0;
static void remove_dithering(AC3DecodeContext *s) {
int ch, i;
int end=0;
- float *coeffs;
+ int *coeffs;
uint8_t *bap;
for(ch=1; ch<=s->fbw_channels; ch++) {
if(!s->dither_flag[ch]) {
- coeffs = s->transform_coeffs[ch];
+ coeffs = s->fixed_coeffs[ch];
bap = s->bap[ch];
if(s->channel_in_cpl[ch])
end = s->start_freq[CPL_CH];
end = s->end_freq[ch];
for(i=0; i<end; i++) {
if(!bap[i])
- coeffs[i] = 0.0f;
+ coeffs[i] = 0;
}
if(s->channel_in_cpl[ch]) {
bap = s->bap[CPL_CH];
for(; i<s->end_freq[CPL_CH]; i++) {
if(!bap[i])
- coeffs[i] = 0.0f;
+ coeffs[i] = 0;
}
}
}
{
int bnd, i;
int end, bndend;
- float tmp0, tmp1;
+ int tmp0, tmp1;
end = FFMIN(s->end_freq[1], s->end_freq[2]);
if(s->rematrixing_flags[bnd]) {
bndend = FFMIN(end, rematrix_band_tab[bnd+1]);
for(i=rematrix_band_tab[bnd]; i<bndend; i++) {
- tmp0 = s->transform_coeffs[1][i];
- tmp1 = s->transform_coeffs[2][i];
- s->transform_coeffs[1][i] = tmp0 + tmp1;
- s->transform_coeffs[2][i] = tmp0 - tmp1;
+ tmp0 = s->fixed_coeffs[1][i];
+ tmp1 = s->fixed_coeffs[2][i];
+ s->fixed_coeffs[1][i] = tmp0 + tmp1;
+ s->fixed_coeffs[2][i] = tmp0 - tmp1;
}
}
}
* Convert frequency domain coefficients to time-domain audio samples.
* reference: Section 7.9.4 Transformation Equations
*/
-static inline void do_imdct(AC3DecodeContext *s)
+static inline void do_imdct(AC3DecodeContext *s, int channels)
{
int ch;
- int channels;
-
- /* Don't perform the IMDCT on the LFE channel unless it's used in the output */
- channels = s->fbw_channels;
- if(s->output_mode & AC3_OUTPUT_LFEON)
- channels++;
for (ch=1; ch<=channels; ch++) {
if (s->block_switch[ch]) {
/**
* Downmix the output to mono or stereo.
*/
-static void ac3_downmix(AC3DecodeContext *s)
+static void ac3_downmix(AC3DecodeContext *s,
+ float samples[AC3_MAX_CHANNELS][256], int ch_offset)
{
int i, j;
- float v0, v1, s0, s1;
+ float v0, v1;
for(i=0; i<256; i++) {
- v0 = v1 = s0 = s1 = 0.0f;
+ v0 = v1 = 0.0f;
for(j=0; j<s->fbw_channels; j++) {
- v0 += s->output[j][i] * s->downmix_coeffs[j][0];
- v1 += s->output[j][i] * s->downmix_coeffs[j][1];
- s0 += s->downmix_coeffs[j][0];
- s1 += s->downmix_coeffs[j][1];
+ v0 += samples[j+ch_offset][i] * s->downmix_coeffs[j][0];
+ v1 += samples[j+ch_offset][i] * s->downmix_coeffs[j][1];
}
- v0 /= s0;
- v1 /= s1;
+ v0 *= s->downmix_coeff_adjust[0];
+ v1 *= s->downmix_coeff_adjust[1];
if(s->output_mode == AC3_CHMODE_MONO) {
- s->output[0][i] = (v0 + v1) * LEVEL_MINUS_3DB;
+ samples[ch_offset][i] = (v0 + v1) * LEVEL_MINUS_3DB;
} else if(s->output_mode == AC3_CHMODE_STEREO) {
- s->output[0][i] = v0;
- s->output[1][i] = v1;
+ samples[ ch_offset][i] = v0;
+ samples[1+ch_offset][i] = v1;
}
}
}
+/**
+ * Upmix delay samples from stereo to original channel layout.
+ */
+static void ac3_upmix_delay(AC3DecodeContext *s)
+{
+ int channel_data_size = sizeof(s->delay[0]);
+ switch(s->channel_mode) {
+ case AC3_CHMODE_DUALMONO:
+ case AC3_CHMODE_STEREO:
+ /* upmix mono to stereo */
+ memcpy(s->delay[1], s->delay[0], channel_data_size);
+ break;
+ case AC3_CHMODE_2F2R:
+ memset(s->delay[3], 0, channel_data_size);
+ case AC3_CHMODE_2F1R:
+ memset(s->delay[2], 0, channel_data_size);
+ break;
+ case AC3_CHMODE_3F2R:
+ memset(s->delay[4], 0, channel_data_size);
+ case AC3_CHMODE_3F1R:
+ memset(s->delay[3], 0, channel_data_size);
+ case AC3_CHMODE_3F:
+ memcpy(s->delay[2], s->delay[1], channel_data_size);
+ memset(s->delay[1], 0, channel_data_size);
+ break;
+ }
+}
+
/**
* Parse an audio block from AC-3 bitstream.
*/
int fbw_channels = s->fbw_channels;
int channel_mode = s->channel_mode;
int i, bnd, seg, ch;
+ int different_transforms;
+ int downmix_output;
GetBitContext *gbc = &s->gbc;
uint8_t bit_alloc_stages[AC3_MAX_CHANNELS];
memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS);
/* block switch flags */
- for (ch = 1; ch <= fbw_channels; ch++)
+ different_transforms = 0;
+ 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 */
s->dither_all = 1;
s->num_cpl_bands--;
}
}
+ s->cpl_band_struct[s->num_cpl_subbands-1] = 0;
} else {
/* coupling not in use */
for (ch = 1; ch <= fbw_channels; ch++)
cpl_coord_exp = get_bits(gbc, 4);
cpl_coord_mant = get_bits(gbc, 4);
if (cpl_coord_exp == 15)
- s->cpl_coords[ch][bnd] = cpl_coord_mant / 16.0f;
+ s->cpl_coords[ch][bnd] = cpl_coord_mant << 22;
else
- s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16.0f) / 32.0f;
- s->cpl_coords[ch][bnd] *= scale_factors[cpl_coord_exp + master_cpl_coord];
+ s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21;
+ s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);
}
}
}
/* stereo rematrixing strategy and band structure */
if (channel_mode == AC3_CHMODE_STEREO) {
- s->rematrixing_strategy = get_bits1(gbc);
- if (s->rematrixing_strategy) {
+ if (get_bits1(gbc)) {
s->num_rematrixing_bands = 4;
if(s->cpl_in_use && s->start_freq[CPL_CH] <= 61)
s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37);
/* apply scaling to coefficients (headroom, dynrng) */
for(ch=1; ch<=s->channels; ch++) {
- float gain = 2.0f * s->mul_bias;
+ float gain = s->mul_bias / 4194304.0f;
if(s->channel_mode == AC3_CHMODE_DUALMONO) {
gain *= s->dynamic_range[ch-1];
} else {
gain *= s->dynamic_range[0];
}
- for(i=0; i<s->end_freq[ch]; i++) {
- s->transform_coeffs[ch][i] *= gain;
+ for(i=0; i<256; i++) {
+ s->transform_coeffs[ch][i] = s->fixed_coeffs[ch][i] * gain;
}
}
- do_imdct(s);
+ /* downmix and MDCT. order depends on whether block switching is used for
+ any channel in this block. this is because coefficients for the long
+ and short transforms cannot be mixed. */
+ downmix_output = s->channels != s->out_channels &&
+ !((s->output_mode & AC3_OUTPUT_LFEON) &&
+ s->fbw_channels == s->out_channels);
+ if(different_transforms) {
+ /* the delay samples have already been downmixed, so we upmix the delay
+ samples in order to reconstruct all channels before downmixing. */
+ if(s->downmixed) {
+ s->downmixed = 0;
+ ac3_upmix_delay(s);
+ }
- /* downmix output if needed */
- if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
- s->fbw_channels == s->out_channels)) {
- ac3_downmix(s);
+ do_imdct(s, s->channels);
+
+ if(downmix_output) {
+ ac3_downmix(s, s->output, 0);
+ }
+ } else {
+ if(downmix_output) {
+ ac3_downmix(s, s->transform_coeffs, 1);
+ }
+
+ if(!s->downmixed) {
+ s->downmixed = 1;
+ ac3_downmix(s, s->delay, 0);
+ }
+
+ do_imdct(s, s->out_channels);
}
/* convert float to 16-bit integer */
/**
* Decode a single AC-3 frame.
*/
-static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
+static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
+ const uint8_t *buf, int buf_size)
{
AC3DecodeContext *s = avctx->priv_data;
int16_t *out_samples = (int16_t *)data;
}
/* check for crc mismatch */
- if(avctx->error_resilience > 0) {
+ if(avctx->error_resilience >= FF_ER_CAREFUL) {
if(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size-2)) {
av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");
return -1;
}
avctx->channels = s->out_channels;
+ /* set downmixing coefficients if needed */
+ if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
+ s->fbw_channels == s->out_channels)) {
+ set_downmix_coeffs(s);
+ }
+
/* parse the audio blocks */
for (blk = 0; blk < NB_BLOCKS; blk++) {
if (ac3_parse_audio_block(s, blk)) {
/**
* Uninitialize the AC-3 decoder.
*/
-static int ac3_decode_end(AVCodecContext *avctx)
+static av_cold int ac3_decode_end(AVCodecContext *avctx)
{
AC3DecodeContext *s = avctx->priv_data;
ff_mdct_end(&s->imdct_512);