From f0ccc65bc9ab9ddf1366066395564c71bcc825ee Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Mon, 18 Jul 2016 19:50:33 +0200 Subject: [PATCH] ac3dec: Split coupling-specific code from decode_audio_block() Signed-off-by: Diego Biurrun --- libavcodec/ac3dec.c | 207 +++++++++++++++++++++++++------------------- 1 file changed, 116 insertions(+), 91 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 4de7475981..f3e3da52fb 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -849,6 +849,118 @@ static inline void spx_coordinates(AC3DecodeContext *s) } } +static inline int coupling_strategy(AC3DecodeContext *s, int blk, + uint8_t *bit_alloc_stages) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int channel_mode = s->channel_mode; + int ch; + + memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); + if (!s->eac3) + s->cpl_in_use[blk] = get_bits1(bc); + if (s->cpl_in_use[blk]) { + /* coupling in use */ + int cpl_start_subband, cpl_end_subband; + + if (channel_mode < AC3_CHMODE_STEREO) { + av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); + return AVERROR_INVALIDDATA; + } + + /* check for enhanced coupling */ + if (s->eac3 && get_bits1(bc)) { + /* TODO: parse enhanced coupling strategy info */ + avpriv_request_sample(s->avctx, "Enhanced coupling"); + return AVERROR_PATCHWELCOME; + } + + /* 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(bc); + } + + /* phase flags in use */ + if (channel_mode == AC3_CHMODE_STEREO) + s->phase_flags_in_use = get_bits1(bc); + + /* coupling frequency range */ + cpl_start_subband = get_bits(bc, 4); + cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 : + get_bits(bc, 4) + 3; + if (cpl_start_subband >= cpl_end_subband) { + av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", + cpl_start_subband, cpl_end_subband); + return AVERROR_INVALIDDATA; + } + s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; + s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; + + decode_band_structure(bc, blk, s->eac3, 0, cpl_start_subband, + cpl_end_subband, + ff_eac3_default_cpl_band_struct, + &s->num_cpl_bands, s->cpl_band_sizes); + } else { + /* coupling not in use */ + for (ch = 1; ch <= fbw_channels; ch++) { + s->channel_in_cpl[ch] = 0; + s->first_cpl_coords[ch] = 1; + } + s->first_cpl_leak = s->eac3; + s->phase_flags_in_use = 0; + } + + return 0; +} + +static inline int coupling_coordinates(AC3DecodeContext *s, int blk) +{ + GetBitContext *bc = &s->gbc; + int fbw_channels = s->fbw_channels; + int ch, bnd; + int cpl_coords_exist = 0; + + for (ch = 1; ch <= fbw_channels; ch++) { + if (s->channel_in_cpl[ch]) { + if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(bc)) { + int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; + s->first_cpl_coords[ch] = 0; + cpl_coords_exist = 1; + master_cpl_coord = 3 * get_bits(bc, 2); + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + cpl_coord_exp = get_bits(bc, 4); + cpl_coord_mant = get_bits(bc, 4); + if (cpl_coord_exp == 15) + s->cpl_coords[ch][bnd] = cpl_coord_mant << 22; + else + s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21; + s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord); + } + } else if (!blk) { + av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " + "be present in block 0\n"); + return AVERROR_INVALIDDATA; + } + } else { + /* channel not in coupling */ + s->first_cpl_coords[ch] = 1; + } + } + /* phase flags */ + if (s->channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) { + for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { + s->phase_flags[bnd] = s->phase_flags_in_use ? get_bits1(bc) : 0; + } + } + + return 0; +} + /** * Decode a single audio block from the AC-3 bitstream. */ @@ -916,63 +1028,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* coupling strategy */ if (s->eac3 ? s->cpl_strategy_exists[blk] : 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_start_subband, cpl_end_subband; - - if (channel_mode < AC3_CHMODE_STEREO) { - av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); - return AVERROR_INVALIDDATA; - } - - /* check for enhanced coupling */ - if (s->eac3 && get_bits1(gbc)) { - /* TODO: parse enhanced coupling strategy info */ - avpriv_request_sample(s->avctx, "Enhanced coupling"); - return AVERROR_PATCHWELCOME; - } - - /* 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 */ - cpl_start_subband = get_bits(gbc, 4); - cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 : - get_bits(gbc, 4) + 3; - if (cpl_start_subband >= cpl_end_subband) { - av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", - cpl_start_subband, cpl_end_subband); - return AVERROR_INVALIDDATA; - } - s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; - s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; - - decode_band_structure(gbc, blk, s->eac3, 0, cpl_start_subband, - cpl_end_subband, - ff_eac3_default_cpl_band_struct, - &s->num_cpl_bands, s->cpl_band_sizes); - } else { - /* coupling not in use */ - for (ch = 1; ch <= fbw_channels; ch++) { - s->channel_in_cpl[ch] = 0; - s->first_cpl_coords[ch] = 1; - } - s->first_cpl_leak = s->eac3; - s->phase_flags_in_use = 0; - } + if ((ret = coupling_strategy(s, blk, bit_alloc_stages)) < 0) + return ret; } else if (!s->eac3) { if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must " @@ -986,40 +1043,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* coupling coordinates */ if (cpl_in_use) { - int cpl_coords_exist = 0; - - for (ch = 1; ch <= fbw_channels; ch++) { - if (s->channel_in_cpl[ch]) { - if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(gbc)) { - int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; - s->first_cpl_coords[ch] = 0; - cpl_coords_exist = 1; - master_cpl_coord = 3 * get_bits(gbc, 2); - for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { - 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 << 22; - else - s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21; - s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord); - } - } else if (!blk) { - av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " - "be present in block 0\n"); - return AVERROR_INVALIDDATA; - } - } else { - /* channel not in coupling */ - s->first_cpl_coords[ch] = 1; - } - } - /* phase flags */ - if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) { - for (bnd = 0; bnd < s->num_cpl_bands; bnd++) { - s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0; - } - } + if ((ret = coupling_coordinates(s, blk)) < 0) + return ret; } /* stereo rematrixing strategy and band structure */