diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-04-22 21:30:19 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-05-18 17:27:06 -0400 |
commit | 9aa8193a234ccb6a79cba5cc550531f62ffb0a17 (patch) | |
tree | 699dce38e0c73e2daf1aa8afb2d31e42da860515 /libavcodec/ac3dec.c | |
parent | bc778a0cea3027941afa1ff6bbb424b3159a0b27 (diff) | |
download | ffmpeg-9aa8193a234ccb6a79cba5cc550531f62ffb0a17.tar.gz |
Add floating-point sample format support to the ac3, eac3, dca, aac, and vorbis
decoders.
Based on patches by clsid2 in ffdshow-tryout.
Diffstat (limited to 'libavcodec/ac3dec.c')
-rw-r--r-- | libavcodec/ac3dec.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 015ebaebec..2966c33b25 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -189,7 +189,13 @@ static av_cold int ac3_decode_init(AVCodecContext *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 && @@ -204,7 +210,6 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) if (!s->input_buffer) return AVERROR(ENOMEM); - avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; } @@ -1299,7 +1304,8 @@ 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]; @@ -1405,10 +1411,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_bits_per_sample_fmt(avctx->sample_fmt) / 8); return FFMIN(buf_size, s->frame_size); } @@ -1435,6 +1449,9 @@ 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 + }, }; #if CONFIG_EAC3_DECODER @@ -1447,5 +1464,8 @@ 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 + }, }; #endif |