Hi,
On Sun, Apr 24, 2011 at 10:06 PM, Justin Ruggles
<[email protected]> wrote:
> ---
> Updated patch.
> Need to initialize resampling if sample rate changes mid-stream.
>
> ffmpeg.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> ffplay.c | 17 ++++++++++++++++
> 2 files changed, 78 insertions(+), 2 deletions(-)
[..]
> +/**
> + * 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;
> + }
> + }
> + }
> + }
> +}
This smells a little like a hack. How about:
/* if decoder supports more than one output format */
if (dec_codec->sample_fmts[0] != AV_SAMPLE_FMT_NONE &&
dec_codec->sample_fmts[1] != AV_SAMPLE_FMT_NONE) {
int min_dec = -1, min_inc = -1;
/* 1) find a matching one */
for (p = dec_codec->sample_fmts; *p != AV_SAMPLE_FMT_NONE; p++) {
if (*p == enc->sample_fmt) {
dec->request_sample_fmt = *p;
return;
} else if (*p > enc->sample_fmt) {
min_inc = FFMIN(min_inc, *p - enc->sample_fmt);
} else
min_dec = FFMIN(min_dec, enc->sample_fmt - *p);
}
/* if none match, provide the one that matches quality closest */
dec->request_sample_fmt = min_inc > 0 ? enc->sample_fmt + min_inc
: enc->sample_fmt - min_dec;
}
That would be a little bit more generic.
> @@ -3163,6 +3205,23 @@ static void opt_input_file(const char *filename)
> + 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;
> + }
> + }
[..]
> diff --git a/ffplay.c b/ffplay.c
[..]
> @@ -2416,6 +2416,23 @@ static int decode_thread(void *arg)
> + /* 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;
> + }
> + }
Can possibly be generalized in cmdutils.c...
Ronald
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel