diff options
Diffstat (limited to 'libavcodec/ac3dec.c')
-rw-r--r-- | libavcodec/ac3dec.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 82ae61857d..7adcb5c0da 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -7,20 +7,20 @@ * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -444,7 +444,7 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma case 0: /* random noise with approximate range of -0.707 to 0.707 */ if (dither) - mantissa = (av_lfg_get(&s->dith_state) / 362) - 5932275; + mantissa = (((av_lfg_get(&s->dith_state)>>8)*181)>>8) - 5931008; else mantissa = 0; break; @@ -1324,7 +1324,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (s->frame_size > buf_size) { av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); err = AAC_AC3_PARSE_ERROR_FRAME_SIZE; - } else if (avctx->err_recognition & AV_EF_CRCCHECK) { + } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { /* check for crc mismatch */ if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size - 2)) { @@ -1353,6 +1353,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, avctx->channels = s->out_channels; avctx->channel_layout = s->channel_layout; + s->loro_center_mix_level = gain_levels[s-> center_mix_level]; + s->loro_surround_mix_level = gain_levels[s->surround_mix_level]; + s->ltrt_center_mix_level = LEVEL_MINUS_3DB; + s->ltrt_surround_mix_level = LEVEL_MINUS_3DB; /* set downmixing coefficients if needed */ if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && s->fbw_channels == s->out_channels)) { @@ -1363,6 +1367,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (s->out_channels < s->channels) s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; } + if (avctx->channels != s->out_channels) { + av_log(avctx, AV_LOG_ERROR, "channel number mismatching on damaged frame\n"); + return AVERROR_INVALIDDATA; + } /* set audio service type based on bitstream mode for AC-3 */ avctx->audio_service_type = s->bitstream_mode; if (s->bitstream_mode == 0x7 && s->channels > 1) @@ -1378,12 +1386,13 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* decode the audio blocks */ channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; + for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) { + output[ch] = s->output[ch]; + s->outptr[ch] = s->output[ch]; + } for (ch = 0; ch < s->channels; ch++) { if (ch < s->out_channels) s->outptr[channel_map[ch]] = (float *)s->frame.data[ch]; - else - s->outptr[ch] = s->output[ch]; - output[ch] = s->output[ch]; } for (blk = 0; blk < s->num_blocks; blk++) { if (!err && decode_audio_block(s, blk)) { @@ -1392,13 +1401,17 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, } if (err) for (ch = 0; ch < s->out_channels; ch++) - memcpy(s->outptr[channel_map[ch]], output[ch], 1024); - for (ch = 0; ch < s->out_channels; ch++) { + memcpy(((float*)s->frame.data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], 1024); + for (ch = 0; ch < s->out_channels; ch++) output[ch] = s->outptr[channel_map[ch]]; - s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE; + for (ch = 0; ch < s->out_channels; ch++) { + if (!ch || channel_map[ch]) + s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE; } } + s->frame.decode_error_flags = err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0; + /* keep last block for error concealment in next frame */ for (ch = 0; ch < s->out_channels; ch++) memcpy(s->output[ch], output[ch], 1024); @@ -1425,6 +1438,13 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) #define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM) static const AVOption options[] = { { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 1.0, PAR }, + +{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, 0, "dmix_mode"}, +{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, + { NULL}, }; |