diff options
Diffstat (limited to 'ffmpeg/libavcodec/ac3dec.c')
| -rw-r--r-- | ffmpeg/libavcodec/ac3dec.c | 102 |
1 files changed, 62 insertions, 40 deletions
diff --git a/ffmpeg/libavcodec/ac3dec.c b/ffmpeg/libavcodec/ac3dec.c index a70d92a..1995412 100644 --- a/ffmpeg/libavcodec/ac3dec.c +++ b/ffmpeg/libavcodec/ac3dec.c @@ -29,6 +29,7 @@ #include <math.h> #include <string.h> +#include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "libavutil/opt.h" #include "internal.h" @@ -178,11 +179,20 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo or mono */ - if (avctx->channels > 0 && avctx->request_channels > 0 && - avctx->request_channels < avctx->channels && - avctx->request_channels <= 2) { - avctx->channels = avctx->request_channels; - } +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channels == 1) + avctx->request_channel_layout = AV_CH_LAYOUT_MONO; + else if (avctx->request_channels == 2) + avctx->request_channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (avctx->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) + avctx->channels = 1; + else if (avctx->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) + avctx->channels = 2; s->downmixed = 1; for (i = 0; i < AC3_MAX_CHANNELS; i++) { @@ -251,7 +261,6 @@ static int parse_frame_header(AC3DecodeContext *s) s->bit_alloc_params.sr_code = hdr.sr_code; s->bitstream_mode = hdr.bitstream_mode; s->channel_mode = hdr.channel_mode; - s->channel_layout = hdr.channel_layout; s->lfe_on = hdr.lfe_on; s->bit_alloc_params.sr_shift = hdr.sr_shift; s->sample_rate = hdr.sample_rate; @@ -290,7 +299,7 @@ static int parse_frame_header(AC3DecodeContext *s) return ff_eac3_parse_header(s); } else { av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n"); - return -1; + return AVERROR(ENOSYS); } } @@ -429,7 +438,7 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma int end_freq = s->end_freq[ch_index]; uint8_t *baps = s->bap[ch_index]; int8_t *exps = s->dexps[ch_index]; - int *coeffs = s->fixed_coeffs[ch_index]; + int32_t *coeffs = s->fixed_coeffs[ch_index]; int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index]; GetBitContext *gbc = &s->gbc; int freq; @@ -488,6 +497,10 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma break; default: /* 6 to 15 */ /* Shift mantissa and sign-extend it. */ + if (bap > 15) { + av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap); + bap = 15; + } mantissa = get_sbits(gbc, quantization_tab[bap]); mantissa <<= 24 - quantization_tab[bap]; break; @@ -747,8 +760,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) i = !s->channel_mode; do { if (get_bits1(gbc)) { - s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)] - 1.0) * - s->drc_scale) + 1.0; + s->dynamic_range[i] = powf(dynamic_range_tab[get_bits(gbc, 8)], + s->drc_scale); } else if (blk == 0) { s->dynamic_range[i] = 1.0f; } @@ -786,12 +799,12 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (start_subband >= end_subband) { av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " "range (%d >= %d)\n", start_subband, end_subband); - return -1; + return AVERROR_INVALIDDATA; } if (dst_start_freq >= src_start_freq) { av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); - return -1; + return AVERROR_INVALIDDATA; } s->spx_dst_start_freq = dst_start_freq; @@ -868,7 +881,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (channel_mode < AC3_CHMODE_STEREO) { av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); - return -1; + return AVERROR_INVALIDDATA; } /* check for enhanced coupling */ @@ -898,7 +911,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) 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 -1; + return AVERROR_INVALIDDATA; } s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; @@ -920,7 +933,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } else { s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; } @@ -950,7 +963,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } else { /* channel not in coupling */ @@ -1005,7 +1018,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) int bandwidth_code = get_bits(gbc, 6); if (bandwidth_code > 60) { av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code); - return -1; + return AVERROR_INVALIDDATA; } s->end_freq[ch] = bandwidth_code * 3 + 73; } @@ -1028,7 +1041,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->num_exp_groups[ch], s->dexps[ch][0], &s->dexps[ch][s->start_freq[ch]+!!ch])) { av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n"); - return -1; + return AVERROR_INVALIDDATA; } if (ch != CPL_CH && ch != s->lfe_ch) skip_bits(gbc, 2); /* skip gainrng */ @@ -1048,7 +1061,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1079,7 +1092,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } } else if (!s->eac3 && !blk) { av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1118,7 +1131,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!s->eac3 && !blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } s->first_cpl_leak = 0; } @@ -1130,7 +1143,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->dba_mode[ch] = get_bits(gbc, 2); if (s->dba_mode[ch] == DBA_RESERVED) { av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n"); - return -1; + return AVERROR_INVALIDDATA; } bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); } @@ -1171,7 +1184,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->dba_offsets[ch], s->dba_lengths[ch], s->dba_values[ch], s->mask[ch])) { av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n"); - return -1; + return AVERROR_INVALIDDATA; } } if (bit_alloc_stages[ch] > 0) { @@ -1291,7 +1304,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, switch (err) { case AAC_AC3_PARSE_ERROR_SYNC: av_log(avctx, AV_LOG_ERROR, "frame sync error\n"); - return -1; + return AVERROR_INVALIDDATA; case AAC_AC3_PARSE_ERROR_BSID: av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n"); break; @@ -1305,17 +1318,20 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* skip frame if CRC is ok. otherwise use error concealment. */ /* TODO: add support for substreams and dependent frames */ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) { - av_log(avctx, AV_LOG_ERROR, "unsupported frame type : " + av_log(avctx, AV_LOG_WARNING, "unsupported frame type : " "skipping frame\n"); *got_frame_ptr = 0; - return s->frame_size; + return buf_size; } else { av_log(avctx, AV_LOG_ERROR, "invalid frame type\n"); } break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid header\n"); + case AAC_AC3_PARSE_ERROR_CRC: + case AAC_AC3_PARSE_ERROR_CHANNEL_CFG: break; + default: // Normal AVERROR do not try to recover. + *got_frame_ptr = 0; + return err; } } else { /* check that reported frame size fits in input buffer */ @@ -1327,6 +1343,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, 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"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; err = AAC_AC3_PARSE_ERROR_CRC; } } @@ -1344,14 +1362,15 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, s->output_mode = s->channel_mode; if (s->lfe_on) s->output_mode |= AC3_OUTPUT_LFEON; - if (avctx->request_channels > 0 && avctx->request_channels <= 2 && - avctx->request_channels < s->channels) { - s->out_channels = avctx->request_channels; - s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; - s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode]; + if (s->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) { + s->out_channels = 1; + s->output_mode = AC3_CHMODE_MONO; + } else if (s->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + s->out_channels = 2; + s->output_mode = AC3_CHMODE_STEREO; } - 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]; @@ -1367,6 +1386,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, return AVERROR_INVALIDDATA; } avctx->channels = s->out_channels; + avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON]; + if (s->output_mode & AC3_OUTPUT_LFEON) + avctx->channel_layout |= AV_CH_LOW_FREQUENCY; /* set audio service type based on bitstream mode for AC-3 */ avctx->audio_service_type = s->bitstream_mode; @@ -1374,7 +1396,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; /* get output buffer */ - frame->nb_samples = s->num_blocks * 256; + frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; @@ -1395,7 +1417,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, } if (err) for (ch = 0; ch < s->out_channels; ch++) - memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], 1024); + memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], sizeof(**output) * AC3_BLOCK_SIZE); for (ch = 0; ch < s->out_channels; ch++) output[ch] = s->outptr[channel_map[ch]]; for (ch = 0; ch < s->out_channels; ch++) { @@ -1408,7 +1430,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* keep last block for error concealment in next frame */ for (ch = 0; ch < s->out_channels; ch++) - memcpy(s->output[ch], output[ch], 1024); + memcpy(s->output[ch], output[ch], sizeof(**output) * AC3_BLOCK_SIZE); *got_frame_ptr = 1; @@ -1450,6 +1472,7 @@ static const AVClass ac3_decoder_class = { AVCodec ff_ac3_decoder = { .name = "ac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_AC3, .priv_data_size = sizeof (AC3DecodeContext), @@ -1457,7 +1480,6 @@ AVCodec ff_ac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .priv_class = &ac3_decoder_class, @@ -1473,6 +1495,7 @@ static const AVClass eac3_decoder_class = { AVCodec ff_eac3_decoder = { .name = "eac3", + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_EAC3, .priv_data_size = sizeof (AC3DecodeContext), @@ -1480,7 +1503,6 @@ AVCodec ff_eac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .priv_class = &eac3_decoder_class, |
