Based on patches by clsid2 in ffdshow-tryout.
---
configure | 2 ++
libavcodec/aacdec.c | 31 +++++++++++++++++++++++++++----
libavcodec/ac3dec.c | 35 ++++++++++++++++++++++++++++++++++-
libavcodec/dca.c | 28 +++++++++++++++++++++++++---
libavcodec/vorbis_dec.c | 23 ++++++++++++++++++++++-
5 files changed, 110 insertions(+), 9 deletions(-)
diff --git a/configure b/configure
index dd44ba4..64779fd 100755
--- a/configure
+++ b/configure
@@ -95,6 +95,7 @@ Configuration options:
--enable-x11grab enable X11 grabbing [no]
--disable-network disable network support [no]
--disable-mpegaudio-hp faster (but less accurate) MPEG audio decoding [no]
+ --enable-audio-float floating-point output from some audio decoders [no]
--enable-gray enable full grayscale support (slower color)
--disable-swscale-alpha disable alpha channel support in swscale
--disable-fastdiv disable table-based division
@@ -901,6 +902,7 @@ CONFIG_LIST="
$COMPONENT_LIST
aandct
ac3dsp
+ audio_float
avcodec
avdevice
avfilter
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index c9761a1..6db8252 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -549,7 +549,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
return -1;
}
+#if CONFIG_AUDIO_FLOAT
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+#else
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+#endif
AAC_INIT_VLC_STATIC( 0, 304);
AAC_INIT_VLC_STATIC( 1, 270);
@@ -574,7 +578,11 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
// 60 - Required to scale values to the correct range [-32768,32767]
// for float to int16 conversion. (1 << (60 / 4)) == 32768
ac->sf_scale = 1. / -1024.;
+#if CONFIG_AUDIO_FLOAT
+ ac->sf_offset = 0;
+#else
ac->sf_offset = 60;
+#endif
ff_aac_tableinit();
@@ -2166,7 +2174,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
avctx->frame_size = samples;
}
- data_size_tmp = samples * avctx->channels * sizeof(int16_t);
+ data_size_tmp = samples * avctx->channels *
+ (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8);
if (*data_size < data_size_tmp) {
av_log(avctx, AV_LOG_ERROR,
"Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n",
@@ -2175,8 +2184,14 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
}
*data_size = data_size_tmp;
- if (samples)
+ if (samples) {
+#if CONFIG_AUDIO_FLOAT
+ ac->fmt_conv.float_interleave(data, (const float **)ac->output_data,
+ samples, avctx->channels);
+#else
ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avctx->channels);
+#endif
+ }
if (ac->output_configured)
ac->output_configured = OC_LOCKED;
@@ -2494,7 +2509,11 @@ AVCodec ff_aac_decoder = {
aac_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
.sample_fmts = (const enum AVSampleFormat[]) {
- AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE
+#if CONFIG_AUDIO_FLOAT
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE
+#else
+ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+#endif
},
.channel_layouts = aac_channel_layout,
};
@@ -2514,7 +2533,11 @@ AVCodec ff_aac_latm_decoder = {
.decode = latm_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Codec LATM syntax)"),
.sample_fmts = (const enum AVSampleFormat[]) {
- AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE
+#if CONFIG_AUDIO_FLOAT
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE
+#else
+ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+#endif
},
.channel_layouts = aac_channel_layout,
};
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c
index 015ebae..1ae25ef 100644
--- a/libavcodec/ac3dec.c
+++ b/libavcodec/ac3dec.c
@@ -24,6 +24,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#define CONFIG_AUDIO_FLOAT 1
+
#include <stdio.h>
#include <stddef.h>
#include <math.h>
@@ -189,7 +191,11 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
av_lfg_init(&s->dith_state, 0);
/* set scale value for float to int16 conversion */
+#if CONFIG_AUDIO_FLOAT
+ s->mul_bias = 1.0f;
+#else
s->mul_bias = 32767.0f;
+#endif
/* allow downmixing to stereo or mono */
if (avctx->channels > 0 && avctx->request_channels > 0 &&
@@ -204,7 +210,12 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx)
if (!s->input_buffer)
return AVERROR(ENOMEM);
+#if CONFIG_AUDIO_FLOAT
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+#else
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+#endif
+
return 0;
}
@@ -1299,7 +1310,11 @@ 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;
+#if CONFIG_AUDIO_FLOAT
+ float *out_samples = 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,14 @@ 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;
}
+#if CONFIG_AUDIO_FLOAT
+ s->fmt_conv.float_interleave(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);
return FFMIN(buf_size, s->frame_size);
}
@@ -1435,6 +1454,13 @@ 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[]) {
+#if CONFIG_AUDIO_FLOAT
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE
+#else
+ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+#endif
+ },
};
#if CONFIG_EAC3_DECODER
@@ -1447,5 +1473,12 @@ 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[]) {
+#if CONFIG_AUDIO_FLOAT
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE
+#else
+ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+#endif
+ },
};
#endif
diff --git a/libavcodec/dca.c b/libavcodec/dca.c
index e3c6466..457c5b4 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;
+#if CONFIG_AUDIO_FLOAT
+ float *samples = data;
+#else
int16_t *samples = data;
+#endif
+ int out_size;
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)
+ out_size = 256 / 8 * s->sample_blocks * sizeof(*samples) * channels;
+ if (*data_size < out_size)
return -1;
- *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels;
+ *data_size = out_size;
/* filter to get final output */
for (i = 0; i < (s->sample_blocks / 8); i++) {
@@ -1833,7 +1839,11 @@ static int dca_decode_frame(AVCodecContext * avctx,
}
}
+#if CONFIG_AUDIO_FLOAT
+ s->fmt_conv.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,9 +1880,14 @@ 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;
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+#if CONFIG_AUDIO_FLOAT
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ s->scale_bias = 1.0 / 32768.0;
+#else
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
s->scale_bias = 1.0;
+#endif
/* allow downmixing to stereo */
if (avctx->channels > 0 && avctx->request_channels < avctx->channels &&
@@ -1909,5 +1924,12 @@ AVCodec ff_dca_decoder = {
.close = dca_decode_end,
.long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"),
.capabilities = CODEC_CAP_CHANNEL_CONF,
+ .sample_fmts = (const enum AVSampleFormat[]) {
+#if CONFIG_AUDIO_FLOAT
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE
+#else
+ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+#endif
+ },
.profiles = NULL_IF_CONFIG_SMALL(profiles),
};
diff --git a/libavcodec/vorbis_dec.c b/libavcodec/vorbis_dec.c
index 5fa7be1..d55329b 100644
--- a/libavcodec/vorbis_dec.c
+++ b/libavcodec/vorbis_dec.c
@@ -962,7 +962,11 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
dsputil_init(&vc->dsp, avccontext);
ff_fmt_convert_init(&vc->fmt_conv, avccontext);
+#if CONFIG_AUDIO_FLOAT
+ vc->scale_bias = 1.0f;
+#else
vc->scale_bias = 32768.0f;
+#endif
if (!headers_len) {
av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n");
@@ -1007,7 +1011,12 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext)
avccontext->channels = vc->audio_channels;
avccontext->sample_rate = vc->audio_samplerate;
avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2;
+
+#if CONFIG_AUDIO_FLOAT
+ avccontext->sample_fmt = AV_SAMPLE_FMT_FLT;
+#else
avccontext->sample_fmt = AV_SAMPLE_FMT_S16;
+#endif
return 0 ;
}
@@ -1635,9 +1644,14 @@ static int vorbis_decode_frame(AVCodecContext *avccontext,
len * ff_vorbis_channel_layout_offsets[vc->audio_channels - 1][i];
}
+#if CONFIG_AUDIO_FLOAT
+ vc->fmt_conv.float_interleave(data, channel_ptrs, len, vc->audio_channels);
+#else
vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len,
vc->audio_channels);
- *data_size = len * 2 * vc->audio_channels;
+#endif
+ *data_size = len * vc->audio_channels *
+ (av_get_bits_per_sample_fmt(avccontext->sample_fmt) / 8);
return buf_size ;
}
@@ -1664,5 +1678,12 @@ AVCodec ff_vorbis_decoder = {
vorbis_decode_frame,
.long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
.channel_layouts = ff_vorbis_channel_layouts,
+ .sample_fmts = (const enum AVSampleFormat[]) {
+#if CONFIG_AUDIO_FLOAT
+ AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_NONE
+#else
+ AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
+#endif
+ },
};
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel