[FFmpeg-devel] [PATCH] av_find_best_stream
Stefano Sabatini
stefano.sabatini-lala
Wed Dec 22 15:29:30 CET 2010
On date Wednesday 2010-12-22 10:12:01 +0100, Nicolas George encoded:
> Le primidi 1er niv?se, an CCXIX, Stefano Sabatini a ?crit?:
> > Uhm I believe you posted the old patch.
>
> Indeed. Sorry anout that.
>
> Regards,
>
> --
> Nicolas George
> doc/APIchanges | 3 +++
> ffplay.c | 40 ++++++++++++----------------------------
> libavformat/avformat.h | 26 ++++++++++++++++++++++++++
> libavformat/utils.c | 36 ++++++++++++++++++++++++++++++++++++
> 4 files changed, 77 insertions(+), 28 deletions(-)
>
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 9612a9f..99752b9 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -13,6 +13,9 @@ libavutil: 2009-03-08
>
> API changes, most recent first:
>
> +2010-12-XX - r260XX - lavformat 52.XX.0 - av_find_best_stream()
> + Add av_find_best_stream to libavformat/avformat.h.
> +
> 2010-12-19 - r26056 - lavutil 50.35.0 - error.h
> Add "not found" error codes:
> AVERROR_DEMUXER_NOT_FOUND
> diff --git a/ffplay.c b/ffplay.c
> index 38a2fe1..8229005 100644
> --- a/ffplay.c
> +++ b/ffplay.c
> @@ -2398,8 +2398,6 @@ static int decode_thread(void *arg)
> AVFormatContext *ic;
> int err, i, ret;
> int st_index[AVMEDIA_TYPE_NB];
> - int st_count[AVMEDIA_TYPE_NB]={0};
> - int st_best_packet_count[AVMEDIA_TYPE_NB];
> AVPacket pkt1, *pkt = &pkt1;
> AVFormatParameters params, *ap = ¶ms;
> int eof=0;
> @@ -2408,7 +2406,6 @@ static int decode_thread(void *arg)
> ic = avformat_alloc_context();
>
> memset(st_index, -1, sizeof(st_index));
> - memset(st_best_packet_count, -1, sizeof(st_best_packet_count));
> is->video_stream = -1;
> is->audio_stream = -1;
> is->subtitle_stream = -1;
> @@ -2464,32 +2461,19 @@ static int decode_thread(void *arg)
> }
> }
>
> - for(i = 0; i < ic->nb_streams; i++) {
> - AVStream *st= ic->streams[i];
> - AVCodecContext *avctx = st->codec;
> + for (i = 0; i < ic->nb_streams; i++)
> ic->streams[i]->discard = AVDISCARD_ALL;
> - if(avctx->codec_type >= (unsigned)AVMEDIA_TYPE_NB)
> - continue;
> - if(st_count[avctx->codec_type]++ != wanted_stream[avctx->codec_type] && wanted_stream[avctx->codec_type] >= 0)
> - continue;
> -
> - if(st_best_packet_count[avctx->codec_type] >= st->codec_info_nb_frames)
> - continue;
> - st_best_packet_count[avctx->codec_type]= st->codec_info_nb_frames;
> -
> - switch(avctx->codec_type) {
> - case AVMEDIA_TYPE_AUDIO:
> - if (!audio_disable)
> - st_index[AVMEDIA_TYPE_AUDIO] = i;
> - break;
> - case AVMEDIA_TYPE_VIDEO:
> - case AVMEDIA_TYPE_SUBTITLE:
> - if (!video_disable)
> - st_index[avctx->codec_type] = i;
> - break;
> - default:
> - break;
> - }
> + if (!audio_disable)
> + st_index[AVMEDIA_TYPE_AUDIO] =
> + av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO,
> + wanted_stream[AVMEDIA_TYPE_AUDIO], NULL, 0);
> + if (!video_disable) {
> + st_index[AVMEDIA_TYPE_VIDEO] =
> + av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO,
> + wanted_stream[AVMEDIA_TYPE_VIDEO], NULL, 0);
> + st_index[AVMEDIA_TYPE_SUBTITLE] =
> + av_find_best_stream(ic, AVMEDIA_TYPE_SUBTITLE,
> + wanted_stream[AVMEDIA_TYPE_SUBTITLE], NULL, 0);
> }
> if (show_status) {
> dump_format(ic, 0, is->filename, 0);
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 3079b38..e1651bf 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -1140,6 +1140,32 @@ AVFormatContext *avformat_alloc_context(void);
> int av_find_stream_info(AVFormatContext *ic);
>
> /**
> + * Find the "best" stream in the file.
> + * The best stream is determined according to various heuristics as the most
> + * likely to be what the user expects.
> + * If the decoder parameter is not NULL, av_find_best_stream will find the
> + * default decoder for the stream's codec; streams for which no decoder can
> + * be found are ignored.
> + *
> + * @param ic media file handle
> + * @param type stream type: video, audio, subtitles, etc.
> + * @param user user-requested stream number, or -1 for automatic selection
user is a confusing name, I'd prefer something like user_stream_nb or
wanted_stream_nb.
> + * @param decoder if not NULL, returns the decoder for the stream's codec
not NULL -> non-NULL
"returns the decoder for the stream's codec"
a bit confusing, I suggest:
returns the decoder for the selected stream
> + * @param flags flags; none are currently defined
> + * @return the non-negative stream number in case of success,
> + * AVERROR_STREAM_NOT_FOUND if no stream with the requested type
> + * could be found,
> + * AVERROR_DECODER_NOT_FOUND if streams were found but no decoder
> + * @note If av_find_best_stream returns successfully and codec is not NULL,
> + * then *codec is guaranteed to be set to a valid AVCodec.
*codec -> *decoder (or ther other way change the parameter name as it
fits you best)
> + */
> +int av_find_best_stream(AVFormatContext *ic,
> + enum AVMediaType type,
> + int user,
> + AVCodec **decoder,
> + int flags);
> +
> +/**
> * Read a transport packet from a media file.
> *
> * This function is obsolete and should never be used.
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index c8e6d66..6c3ecce 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -2457,6 +2457,42 @@ int av_find_stream_info(AVFormatContext *ic)
> return ret;
> }
>
> +int av_find_best_stream(AVFormatContext *ic,
> + enum AVMediaType type,
> + int user,
> + AVCodec **decoder,
> + int flags)
> +{
> + int i, ret = AVERROR_STREAM_NOT_FOUND, stream_number = 0, best_count = -1;
> + AVCodec *dec = NULL, *best_dec = NULL;
dec and decoder -> confusing
my suggestion:
decoder_ptr
decoder
best_decoder
> + for (i = 0; i < ic->nb_streams; i++) {
> + AVStream *st= ic->streams[i];
> + AVCodecContext *avctx = st->codec;
> + ic->streams[i]->discard = AVDISCARD_ALL;
> + if (avctx->codec_type != type)
> + continue;
> + if (user >= 0 && stream_number++ != user)
> + continue;
> + if (decoder) {
> + dec = avcodec_find_decoder(ic->streams[i]->codec->codec_id);
> + if (!dec) {
> + if (ret < 0)
> + ret = AVERROR_DECODER_NOT_FOUND;
> + continue;
> + }
> + }
> + if (best_count >= st->codec_info_nb_frames)
> + continue;
> + best_count = st->codec_info_nb_frames;
> + ret = i;
> + best_dec = dec;
> + }
> + if (decoder)
> + *decoder = best_dec;
> + return ret;
> +}
--
FFmpeg = Friendly and Fostering Mean Perennial Ermetic Governor
More information about the ffmpeg-devel
mailing list