On 04/25/2011 10:14 AM, Ronald S. Bultje wrote:

> 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:

Well, I see what you mean.  It's written specifically for decoders that
support S16 or FLT.  I decided to make it less generic because ideally
we would like to remove this function rather than expand its use.

> /* 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.

That looks fine though. It's simple enough. I'll integrate it into the
next patch revision.

>> @@ -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...


possibly... it doesn't do much though. if not for the flags it would
basically be a loop around set_context_opts().

i can shorten it if you want. :)

for (i = 0; i < ic->nb_streams; i++) {
    AVCodecContext *dec = ic->streams[i]->codec;
    int oflag = 0;
    switch (dec->codec_type) {
    case AVMEDIA_TYPE_AUDIO: oflag = AVMEDIA_TYPE_AUDIO; break;
    case AVMEDIA_TYPE_VIDEO: oflag = AVMEDIA_TYPE_VIDEO; break;
    }
    if (oflag)
        set_context_opts(dec, avcodec_opts[dec->codec_type],
                          oflag | AV_OPT_FLAG_DECODING_PARAM, NULL);
}


Thanks,
Justin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to