---
ffmpeg.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
ffplay.c | 17 +++++++++++++++++
2 files changed, 77 insertions(+), 1 deletions(-)
diff --git a/ffmpeg.c b/ffmpeg.c
index d54785d..1f6a86a 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -543,6 +543,37 @@ static void choose_sample_fmt(AVStream *st, AVCodec *codec)
}
}
+/**
+ * Update the requested input sample format based on the output sample format.
+ * This is currently only used to request float output from decoders which
+ * support multiple sample formats, one of which is AV_SAMPLE_FMT_FLT.
+ * Ideally this will be removed in the future when decoders do not do format
+ * conversion and only output in their native format.
+ */
+static void update_sample_fmt(AVCodecContext *dec, AVCodec *dec_codec,
+ AVCodecContext *enc)
+{
+ /* if sample formats match or a decoder sample format has already been
+ requested, just return */
+ if (enc->sample_fmt == dec->sample_fmt ||
+ dec->request_sample_fmt > AV_SAMPLE_FMT_NONE)
+ return;
+
+ if (dec_codec && dec_codec->sample_fmts) {
+ if (enc->sample_fmt == AV_SAMPLE_FMT_FLT ||
+ enc->sample_fmt == AV_SAMPLE_FMT_DBL ||
+ enc->sample_fmt == AV_SAMPLE_FMT_S32) {
+ const enum AVSampleFormat *p = dec_codec->sample_fmts;
+ for (; *p != AV_SAMPLE_FMT_NONE; p++) {
+ if (*p == AV_SAMPLE_FMT_FLT) {
+ dec->request_sample_fmt = *p;
+ break;
+ }
+ }
+ }
+ }
+}
+
static void choose_sample_rate(AVStream *st, AVCodec *codec)
{
if(codec && codec->supported_samplerates){
@@ -765,7 +796,7 @@ need_realloc:
ost->resample_sample_rate == enc->sample_rate) {
ost->resample = NULL;
ost->audio_resample = 0;
- } else {
+ } else if (ost->audio_resample) {
if (dec->sample_fmt != AV_SAMPLE_FMT_S16)
fprintf(stderr, "Warning, using s16 intermediate sample format for resampling\n");
ost->resample = av_audio_resample_init(enc->channels, dec->channels,
@@ -2287,6 +2318,17 @@ static int transcode(AVFormatContext **output_files,
ret = AVERROR(EINVAL);
goto dump_format;
}
+
+ /* update requested sample format for the decoder based on the
+ corresponding encoder sample format */
+ for (j = 0; j < nb_ostreams; j++) {
+ ost = ost_table[j];
+ if (ost->source_index == i) {
+ update_sample_fmt(ist->st->codec, codec, ost->st->codec);
+ break;
+ }
+ }
+
if (avcodec_open(ist->st->codec, codec) < 0) {
snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d",
ist->file_index, ist->index);
@@ -3163,6 +3205,23 @@ static void opt_input_file(const char *filename)
ic->loop_input = loop_input;
+ /* Set AVCodecContext options so they will be seen by av_find_stream_info() */
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVCodecContext *dec = ic->streams[i]->codec;
+ switch (dec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO],
+ AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
+ NULL);
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO],
+ AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
+ NULL);
+ break;
+ }
+ }
+
/* If not enough info to get the stream parameters, we decode the
first frames to get it. (used in mpeg case for example) */
ret = av_find_stream_info(ic);
diff --git a/ffplay.c b/ffplay.c
index 18010ef..cb3c5b8 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -2416,6 +2416,23 @@ static int decode_thread(void *arg)
if(genpts)
ic->flags |= AVFMT_FLAG_GENPTS;
+ /* Set AVCodecContext options so they will be seen by av_find_stream_info() */
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVCodecContext *dec = ic->streams[i]->codec;
+ switch (dec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO],
+ AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
+ NULL);
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO],
+ AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM,
+ NULL);
+ break;
+ }
+ }
+
err = av_find_stream_info(ic);
if (err < 0) {
fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel