diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index b2e4f81704..431f67dc23 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -185,14 +185,6 @@ 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 && avctx->request_channels < avctx->channels && @@ -201,12 +193,14 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) } s->downmixed = 1; - /* ffdshow custom code */ -#if CONFIG_AUDIO_FLOAT - avctx->sample_fmt = AV_SAMPLE_FMT_FLT; -#else - avctx->sample_fmt = AV_SAMPLE_FMT_S16; -#endif + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) { + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + s->mul_bias = 1.0f; + } else { + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + /* set scale value for float to int16 conversion */ + s->mul_bias = 32767.0f; + } return 0; } @@ -1301,12 +1295,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; - /* ffdshow custom code */ -#if CONFIG_AUDIO_FLOAT - float *out_samples = (float *)data; -#else + float *out_samples_flt = (float *)data; int16_t *out_samples = (int16_t *)data; -#endif int blk, ch, err; const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; @@ -1412,15 +1402,16 @@ 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; + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { + float_interleave_noscale(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, output, 256, s->out_channels); + out_samples += 256 * s->out_channels; + } } - *data_size = s->num_blocks * 256 * avctx->channels * sizeof (out_samples[0]); /* ffdshow custom code */ + *data_size = s->num_blocks * 256 * avctx->channels; + *data_size *= avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? sizeof(*out_samples_flt) : sizeof(*out_samples); return FFMIN(buf_size, s->frame_size); } diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 10866a1ee0..58a38fa88c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2877,6 +2877,14 @@ typedef struct AVCodecContext { int64_t pts_correction_last_pts; /// PTS of the last frame int64_t pts_correction_last_dts; /// DTS of the last frame + /** + * desired sample format + * - encoding: Not used. + * - decoding: Set by user. + * Decoder will decode to this format if it can. + */ + enum AVSampleFormat request_sample_fmt; + } AVCodecContext; /** diff --git a/libavcodec/options.c b/libavcodec/options.c index 2c395510a8..ebe228ee2f 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -447,6 +447,7 @@ static const AVOption options[]={ {"em", "Emergency", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_EMERGENCY, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"vo", "Voice Over", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_VOICE_OVER, INT_MIN, INT_MAX, A|E, "audio_service_type"}, {"ka", "Karaoke", 0, FF_OPT_TYPE_CONST, AV_AUDIO_SERVICE_TYPE_KARAOKE, INT_MIN, INT_MAX, A|E, "audio_service_type"}, +{"request_sample_fmt", "sample format audio decoders should prefer", OFFSET(request_sample_fmt), FF_OPT_TYPE_INT, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NONE, AV_SAMPLE_FMT_NB-1, A|D}, {NULL}, };