X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fac3dec.c;h=663acc0ac978c3dd36be821c7b9c26e79de7b1dc;hb=87cf70eb237e7586cc7399627dafa1b980ec0b7d;hp=b089adcb21c3b2398b35afce4f55bd0379b8df26;hpb=a45fbda994df54600101e845e29f0af60e456e95;p=ffmpeg diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index b089adcb21c..663acc0ac97 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -30,6 +30,7 @@ #include #include "libavutil/crc.h" +#include "libavutil/opt.h" #include "internal.h" #include "aac_ac3_parser.h" #include "ac3_parser.h" @@ -67,16 +68,6 @@ static const uint8_t quantization_tab[16] = { static float dynamic_range_tab[256]; /** Adjustments in dB gain */ -#define LEVEL_PLUS_3DB 1.4142135623730950 -#define LEVEL_PLUS_1POINT5DB 1.1892071150027209 -#define LEVEL_MINUS_1POINT5DB 0.8408964152537145 -#define LEVEL_MINUS_3DB 0.7071067811865476 -#define LEVEL_MINUS_4POINT5DB 0.5946035575013605 -#define LEVEL_MINUS_6DB 0.5000000000000000 -#define LEVEL_MINUS_9DB 0.3535533905932738 -#define LEVEL_ZERO 0.0000000000000000 -#define LEVEL_ONE 1.0000000000000000 - static const float gain_levels[9] = { LEVEL_PLUS_3DB, LEVEL_PLUS_1POINT5DB, @@ -194,11 +185,18 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) ff_mdct_init(&s->imdct_512, 9, 1, 1.0); ff_kbd_window_init(s->window, 5.0, 256); dsputil_init(&s->dsp, avctx); + ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT); ff_fmt_convert_init(&s->fmt_conv, avctx); av_lfg_init(&s->dith_state, 0); /* set scale value for float to int16 conversion */ - s->mul_bias = 32767.0f; + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) { + s->mul_bias = 1.0f; + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + } else { + s->mul_bias = 32767.0f; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + } /* allow downmixing to stereo or mono */ if (avctx->channels > 0 && avctx->request_channels > 0 && @@ -209,13 +207,10 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) s->downmixed = 1; /* allocate context input buffer */ - if (avctx->error_recognition >= FF_ER_CAREFUL) { s->input_buffer = av_mallocz(AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!s->input_buffer) return AVERROR(ENOMEM); - } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } @@ -275,6 +270,7 @@ static int parse_frame_header(AC3DecodeContext *s) /* get decoding parameters from header info */ 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; @@ -1183,8 +1179,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* channel delta offset, len and bit allocation */ for (ch = !cpl_in_use; ch <= fbw_channels; ch++) { if (s->dba_mode[ch] == DBA_NEW) { - s->dba_nsegs[ch] = get_bits(gbc, 3); - for (seg = 0; seg <= s->dba_nsegs[ch]; seg++) { + s->dba_nsegs[ch] = get_bits(gbc, 3) + 1; + for (seg = 0; seg < s->dba_nsegs[ch]; seg++) { s->dba_offsets[ch][seg] = get_bits(gbc, 5); s->dba_lengths[ch][seg] = get_bits(gbc, 4); s->dba_values[ch][seg] = get_bits(gbc, 3); @@ -1224,7 +1220,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* Compute bit allocation */ const uint8_t *bap_tab = s->channel_uses_aht[ch] ? ff_eac3_hebap_tab : ff_ac3_bap_tab; - ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch], + s->ac3dsp.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, @@ -1309,20 +1305,23 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AC3DecodeContext *s = avctx->priv_data; - int16_t *out_samples = (int16_t *)data; + float *out_samples_flt = data; + int16_t *out_samples_s16 = data; int blk, ch, err; const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; - /* initialize the GetBitContext with the start of valid AC-3 Frame */ - if (s->input_buffer) { - /* copy input buffer to decoder context to avoid reading past the end - of the buffer, which can be caused by a damaged input stream. */ + /* copy input buffer to decoder context to avoid reading past the end + of the buffer, which can be caused by a damaged input stream. */ + if (buf_size >= 2 && AV_RB16(buf) == 0x770B) { + // seems to be byte-swapped AC-3 + int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1; + s->dsp.bswap16_buf((uint16_t *)s->input_buffer, (const uint16_t *)buf, cnt); + } else memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE)); - init_get_bits(&s->gbc, s->input_buffer, buf_size * 8); - } else { - init_get_bits(&s->gbc, buf, buf_size * 8); - } + buf = s->input_buffer; + /* initialize the GetBitContext with the start of valid AC-3 Frame */ + init_get_bits(&s->gbc, buf, buf_size * 8); /* parse the syncinfo */ *data_size = 0; @@ -1399,6 +1398,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, if(s->out_channels < s->channels) s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; } + /* 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) + avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; /* decode the audio blocks */ channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on]; @@ -1409,10 +1412,18 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n"); err = 1; } - s->fmt_conv.float_to_int16_interleave(out_samples, output, 256, s->out_channels); - out_samples += 256 * s->out_channels; + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + s->fmt_conv.float_interleave(out_samples_flt, output, 256, + s->out_channels); + out_samples_flt += 256 * s->out_channels; + } else { + s->fmt_conv.float_to_int16_interleave(out_samples_s16, output, 256, + s->out_channels); + out_samples_s16 += 256 * s->out_channels; + } } - *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t); + *data_size = s->num_blocks * 256 * avctx->channels * + av_get_bytes_per_sample(avctx->sample_fmt); return FFMIN(buf_size, s->frame_size); } @@ -1430,6 +1441,20 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) return 0; } +#define OFFSET(x) offsetof(AC3DecodeContext, x) +#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), FF_OPT_TYPE_FLOAT, {1.0}, 0.0, 1.0, PAR }, + { NULL}, +}; + +static const AVClass ac3_decoder_class = { + .class_name = "(E-)AC3 decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVCodec ff_ac3_decoder = { .name = "ac3", .type = AVMEDIA_TYPE_AUDIO, @@ -1439,6 +1464,10 @@ AVCodec ff_ac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE + }, + .priv_class = &ac3_decoder_class, }; #if CONFIG_EAC3_DECODER @@ -1451,5 +1480,9 @@ AVCodec ff_eac3_decoder = { .close = ac3_decode_end, .decode = ac3_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE + }, + .priv_class = &ac3_decoder_class, }; #endif