From 0e09997fa452565e59bfbdf81a96917b3c503470 Mon Sep 17 00:00:00 2001 From: clsid2 Date: Mon, 7 Mar 2011 00:08:34 +0000 Subject: [PATCH] Libavcodec AC3/E-AC3/DTS decoders now output floating point data. git-svn-id: https://ffdshow-tryout.svn.sourceforge.net/svnroot/ffdshow-tryout@3769 3b938f2f-1a1a-0410-8054-a526ea5ff92c --- libavcodec/ac3dec.c | 22 +++++++++++++++++++++- libavcodec/dca.c | 21 +++++++++++++++++++-- libavcodec/fmtconvert.c | 31 +++++++++++++++++++++++++++++++ libavcodec/fmtconvert.h | 4 ++++ 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 8a0f96a11c..b0e7647877 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -188,8 +188,13 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) ff_fmt_convert_init(&s->fmt_conv, avctx); av_lfg_init(&s->dith_state, 0); + /* ffdshow custom code */ +#if CONFIG_AUDIO_FLOAT + s->mul_bias = 1.0f; +#else /* set scale value for float to int16 conversion */ s->mul_bias = 32767.0f; +#endif /* allow downmixing to stereo or mono */ if (avctx->channels > 0 && avctx->request_channels > 0 && @@ -204,7 +209,12 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) if (!s->input_buffer) return AVERROR(ENOMEM); + /* ffdshow custom code */ +#if CONFIG_AUDIO_FLOAT + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; +#else avctx->sample_fmt = AV_SAMPLE_FMT_S16; +#endif return 0; } @@ -1299,7 +1309,12 @@ 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; + /* ffdshow custom code */ +#if CONFIG_AUDIO_FLOAT + float *out_samples = (float *)data; +#else int16_t *out_samples = (int16_t *)data; +#endif int blk, ch, err; const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; @@ -1405,10 +1420,15 @@ 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; } + /* ffdshow custom code */ +#if CONFIG_AUDIO_FLOAT + float_interleave_noscale(out_samples, output, 256, s->out_channels); +#else s->fmt_conv.float_to_int16_interleave(out_samples, output, 256, s->out_channels); +#endif out_samples += 256 * s->out_channels; } - *data_size = s->num_blocks * 256 * avctx->channels * sizeof (int16_t); + *data_size = s->num_blocks * 256 * avctx->channels * sizeof (out_samples[0]); /* ffdshow custom code */ return FFMIN(buf_size, s->frame_size); } diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 14b0b2d10a..2053121dc6 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -1626,7 +1626,12 @@ static int dca_decode_frame(AVCodecContext * avctx, int lfe_samples; int num_core_channels = 0; int i; + /* ffdshow custom code */ +#if CONFIG_AUDIO_FLOAT + float *samples = data; +#else int16_t *samples = data; +#endif DCAContext *s = avctx->priv_data; int channels; int core_ss_end; @@ -1812,9 +1817,10 @@ static int dca_decode_frame(AVCodecContext * avctx, return -1; } - if (*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) + /* ffdshow custom code */ + if (*data_size < (s->sample_blocks / 8) * 256 * sizeof(samples[0]) * channels) return -1; - *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels; + *data_size = 256 / 8 * s->sample_blocks * sizeof(samples[0]) * channels; /* filter to get final output */ for (i = 0; i < (s->sample_blocks / 8); i++) { @@ -1833,7 +1839,13 @@ static int dca_decode_frame(AVCodecContext * avctx, } } + /* interleave samples */ +#if CONFIG_AUDIO_FLOAT + /* ffdshow custom code */ + float_interleave(samples, s->samples_chanptr, 256, channels); +#else s->fmt_conv.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels); +#endif samples += 256 * channels; } @@ -1870,7 +1882,12 @@ static av_cold int dca_decode_init(AVCodecContext * avctx) for (i = 0; i < DCA_PRIM_CHANNELS_MAX+1; i++) s->samples_chanptr[i] = s->samples + i * 256; + /* ffdshow custom code */ +#if CONFIG_AUDIO_FLOAT + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; +#else avctx->sample_fmt = AV_SAMPLE_FMT_S16; +#endif s->scale_bias = 1.0; diff --git a/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c index e27c1f69f4..0e8aa5e909 100644 --- a/libavcodec/fmtconvert.c +++ b/libavcodec/fmtconvert.c @@ -66,3 +66,34 @@ av_cold void ff_fmt_convert_init(FmtConvertContext *c, AVCodecContext *avctx) if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx); if (HAVE_MMX) ff_fmt_convert_init_x86(c, avctx); } + +/* ffdshow custom code */ +void float_interleave(float *dst, const float **src, long len, int channels) +{ + int i,j,c; + if(channels==2){ + for(i=0; i